Skip to content

Commit

Permalink
Merge pull request #475 from Mile-Writings/feat/#474/responsiveBasicS…
Browse files Browse the repository at this point in the history
…etting

[Feat/#474] responsive basic setting & main page 임시 responsive 뷰 적용
  • Loading branch information
ljh0608 authored Nov 17, 2024
2 parents 6b9ebe9 + 4cfb9e7 commit aed1cc8
Show file tree
Hide file tree
Showing 20 changed files with 634 additions and 94 deletions.
1 change: 1 addition & 0 deletions .stylelintrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"plugins": ["stylelint-order"],
"customSyntax": "postcss-styled-syntax",
"rules": {
"media-query-no-invalid": null,
"declaration-empty-line-before": [
"never",
{
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"dependencies": {
"@emotion/react": "^11.11.3",
"@emotion/styled": "^11.11.0",
"@radix-ui/react-slot": "^1.1.0",
"@tanstack/react-query": "^5.17.10",
"@tanstack/react-query-devtools": "^5.37.1",
"@tiptap/extension-blockquote": "^2.2.3",
Expand Down
25 changes: 17 additions & 8 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import styled from '@emotion/styled';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import router from './routers/Router';
import { RouterProvider } from 'react-router-dom';
import { Suspense } from 'react';
import { RouterProvider } from 'react-router-dom';
import ResponsiveProvider from './components/commons/Responsive/ResponsiveProvider';
import Loading from './pages/loading/Loading';

import router from './routers/Router';
import { MOBILE_MEDIA_QUERY } from './styles/mediaQuery';
const App = () => {
const queryClient = new QueryClient({
defaultOptions: {
Expand All @@ -16,16 +17,18 @@ const App = () => {
});
return (
<>
<div style={{ fontSize: '16px' }}>
<QueryClientProvider client={queryClient}>
{/* <div style={{ fontSize: '16px' }}> */}
<QueryClientProvider client={queryClient}>
<ResponsiveProvider>
<DesktopWrapper>
<Suspense fallback={<Loading />}>
<RouterProvider router={router} />
</Suspense>
</DesktopWrapper>
<ReactQueryDevtools initialIsOpen />
</QueryClientProvider>
</div>
</ResponsiveProvider>
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
{/* </div> */}
</>
);
};
Expand All @@ -38,4 +41,10 @@ const DesktopWrapper = styled.div`
align-items: center;
width: 100%;
scroll-behavior: smooth;
@media ${MOBILE_MEDIA_QUERY} {
/* width: 100%; */
width: 100%;
max-width: 83rem;
}
`;
13 changes: 11 additions & 2 deletions src/components/commons/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import styled from '@emotion/styled';

import Spacing from './Spacing';
import { FOOTER_LINK } from '../../constants/footerLink';
import Spacing from './Spacing';

import { MOBILE_MEDIA_QUERY } from '../../styles/mediaQuery';
import {
FooterInstaIc,
FooterLogoIc,
Expand Down Expand Up @@ -53,11 +54,19 @@ const FooterWrapper = styled.div`
display: flex;
justify-content: space-between;
width: 100%;
min-width: 136.7rem;
/* min-width: 136.7rem; */
height: 24.6rem;
padding: 8rem 16.5rem;
background-color: ${({ theme }) => theme.colors.grayViolet};
@media ${MOBILE_MEDIA_QUERY} {
flex-direction: column;
gap: 4rem;
align-items: center;
padding: 5rem;
}
`;

const FooterLayout = styled.div`
Expand Down
48 changes: 48 additions & 0 deletions src/components/commons/Responsive/Responsive.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Slot } from '@radix-ui/react-slot';
import { ReactNode, useContext, useEffect, useState } from 'react';
import { MOBILE_MEDIA_QUERY } from '../../../styles/mediaQuery';
import { ResponsiveContext } from './context';
interface ResponsivePropTypes {
children: ReactNode;
only: AvailableSize;
asChild?: boolean;
}

type AvailableSize = 'mobile' | 'desktop';

const Responsive = ({ children, only, asChild }: ResponsivePropTypes) => {
const [current, setCurrent] = useState<AvailableSize | null>(null);

const Comp = asChild ? Slot : 'div';

const { mobileOnlyClassName, desktopOnlyClassName } = useContext(ResponsiveContext);

const selectedClassName = () => {
if (only === 'desktop') {
return desktopOnlyClassName;
} else if (only === 'mobile') {
return mobileOnlyClassName;
} else {
throw new Error(`잘못된 타입의 only값 : ${only}`);
}
};

useEffect(() => {
const mobileMedia = window.matchMedia(MOBILE_MEDIA_QUERY);
const handleCurrentChange = (e: MediaQueryListEvent) => {
setCurrent(e.matches ? 'mobile' : 'desktop');
};
mobileMedia.addEventListener('change', handleCurrentChange);

return () => {
mobileMedia.removeEventListener('change', handleCurrentChange);
};
}, []);
return current === null || only === current ? (
<Comp className={`${selectedClassName()}`}>{children}</Comp>
) : (
<></>
);
};

export default Responsive;
38 changes: 38 additions & 0 deletions src/components/commons/Responsive/ResponsiveProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Global, css } from '@emotion/react';
import { ReactNode } from 'react';
import { MOBILE_MEDIA_QUERY } from '../../../styles/mediaQuery';
import { ResponsiveContext } from './context';
interface ResponsiveProviderProps {
children: ReactNode;
}

const ResponsiveProvider = ({ children }: ResponsiveProviderProps) => {
const mobileOnlyClassName = `responsive-mobile-only`;
const desktopOnlyClassName = `responsive-desktop-only`;

const ResponsiveClassName = css`
.${mobileOnlyClassName} {
display: none !important;
}
.${desktopOnlyClassName} {
display: block !important;
}
@media ${MOBILE_MEDIA_QUERY} {
.${mobileOnlyClassName} {
display: block !important;
}
.${desktopOnlyClassName} {
display: none !important;
}
}
`;
return (
<ResponsiveContext.Provider value={{ mobileOnlyClassName, desktopOnlyClassName }}>
<Global styles={ResponsiveClassName} />
{children}
</ResponsiveContext.Provider>
);
};

export default ResponsiveProvider;
15 changes: 15 additions & 0 deletions src/components/commons/Responsive/context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { createContext } from 'react';

interface ResponsiveContextValue {
mobileOnlyClassName: string;
desktopOnlyClassName: string;
}

export const ResponsiveContext = createContext<ResponsiveContextValue>(
//ResponsiveProvider로 감싸져있지 않은 컴포넌트에서 값을 접근했을 때 또는 Context가 제대로 초기화되지 않았을 때 에러를 발생시켜 디버깅을 쉽게하기 위함
new Proxy({} as ResponsiveContextValue, {
get() {
throw new Error('ResponsiveProvider가 필요합니다.');
},
}),
);
27 changes: 21 additions & 6 deletions src/pages/main/Main.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import styled from '@emotion/styled';
import { useParams } from 'react-router-dom';

import Responsive from '../../components/commons/Responsive/Responsive';
import { MOBILE_MEDIA_QUERY } from '../../styles/mediaQuery';
import { AuthorizationHeader, UnAuthorizationHeader } from './../../components/commons/Header';
import Spacing from './../../components/commons/Spacing';
import DailyKeyword from './components/DailyKeyword';
import FaqDropdown from './components/FaqDropdown';
import GroupCarousel from './components/GroupCarousel';
import Introduction from './components/Introduction';
import Manual from './components/Manual';
import OnBoarding from './components/OnBoarding';
import { SkeletonComponent } from './components/skeletons/SkeletonComponent';
import { FAQ_DATA } from './constants/faqData';
import { useGetGroupContent, useGetRecommendTopic } from './hooks/queries';

import Footer from './../../components/commons/Footer';
import { AuthorizationHeader, UnAuthorizationHeader } from './../../components/commons/Header';
import Spacing from './../../components/commons/Spacing';
import GroupCarousel from './components/GroupCarousel';
import Footer from '../../components/commons/Footer';
const Main = () => {
const { content, moimId } = useParams();
const topic = useGetRecommendTopic(content || '');
Expand All @@ -28,7 +29,9 @@ const Main = () => {

<GroupCarouselLayout>
<CarouselContainer>
<CarouselTitle>마일과 함께하고 있는 글 모임이에요</CarouselTitle>
<Responsive only={'desktop'}>
<CarouselTitle>마일과 함께하고 있는 글 모임이에요</CarouselTitle>
</Responsive>
{isLoading || isFetching ? (
<SkeletonComponent groupLength={groupLength} />
) : (
Expand All @@ -44,6 +47,7 @@ const Main = () => {
<Spacing marginBottom="10" />
<Introduction />
<Spacing marginBottom="10" />

<Manual />

<FaqLayout>
Expand All @@ -70,6 +74,10 @@ const MainPageWrapper = styled.div`
width: 100%;
background-color: ${({ theme }) => theme.colors.backGroundGray};
/* @media ${MOBILE_MEDIA_QUERY} {
max-width: 76rem;
} */
`;

const GroupCarouselLayout = styled.section`
Expand All @@ -82,6 +90,11 @@ const GroupCarouselLayout = styled.section`
const CarouselContainer = styled.div`
width: 93rem;
height: 100%;
@media ${MOBILE_MEDIA_QUERY} {
width: 100%;
max-width: 420px;
}
`;

const CarouselBox = styled.div`
Expand All @@ -102,6 +115,8 @@ const FaqLayout = styled.section`
`;

const FaqContainer = styled.div`
padding: 0 2rem;
cursor: default;
`;

Expand Down
Loading

0 comments on commit aed1cc8

Please sign in to comment.