Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Toggle 컴포넌트 재구축 및 서비스 코드 반영, 디자인시스템 v1.3.10 배포 #793

Merged
merged 6 commits into from
Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion frontend-monorepo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"eslint-config-prettier": "^8.8.0",
"eslint-config-standard-with-typescript": "^43.0.1",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-n": "^16.6.2",
"eslint-plugin-n": "^15.0.0 || ^16.0.0 ",
"eslint-plugin-prettier": "4.0.0",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-react": "^7.33.2",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hang-log-design-system",
"version": "1.3.8",
"version": "1.3.10",
"description": "행록 디자인 시스템",
"homepage": "https://github.com/hang-log-design-system/design-system",
"main": "dist/index.js",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { ForwardedRef, PropsWithChildren } from 'react';
import { useContext, forwardRef } from 'react';
import { NewToggleContext } from '@components/NewToggle/NewToggle';

export interface ItemProps extends PropsWithChildren {
toggleKey: number | string;
}

const ToggleItem = ({ children, toggleKey }: ItemProps, ref?: ForwardedRef<HTMLDivElement>) => {
const context = useContext(NewToggleContext);

if (!context) throw new Error('NewToggle 컴포넌트가 Wrapping되어있지 않습니다.');

const { selectKey } = context;

return (
<div ref={ref} style={{ display: selectKey === toggleKey ? 'block' : 'none' }}>
{children}
</div>
);
};

export default forwardRef(ToggleItem);
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import type { ComponentPropsWithRef, ForwardedRef, KeyboardEvent } from 'react';
import { useContext, forwardRef } from 'react';

import { getListStyling } from '@components/NewToggle/Toggle.style';
import { NewToggleContext } from '@components/NewToggle/NewToggle';

export interface ToggleProps extends ComponentPropsWithRef<'li'> {
toggleKey: number | string;
text: string;
}

const List = (
{ toggleKey, text, ...attributes }: ToggleProps,
ref?: ForwardedRef<HTMLLIElement>
) => {
const context = useContext(NewToggleContext);

if (!context) throw new Error('NewToggle 컴포넌트가 Wrapping되어있지 않습니다.');

const { selectKey, handleSelect } = context;

const handleEnterKeyPress = (event: KeyboardEvent<HTMLLIElement>) => {
if (event.key === 'Enter') {
handleSelect(toggleKey);
}
};

return (
<li
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-to-interactive-role
role="radio"
aria-label={`${text}로 토글할 수 있는 버튼입니다. ${
selectKey === toggleKey ? '이미 선택되어있습니다.' : ''
}`}
tabIndex={0}
ref={ref}
css={getListStyling(selectKey === toggleKey)}
aria-checked={selectKey === toggleKey}
onClick={() => handleSelect(toggleKey)}
onKeyDown={handleEnterKeyPress}
{...attributes}
>
{text}
</li>
);
};

export default forwardRef(List);
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import type { PropsWithChildren } from 'react';
import { useCallback, useState, useMemo, createContext } from 'react';
import List from '@components/NewToggle/List';
import Item from '@components/NewToggle/Item';
import { flushSync } from 'react-dom';
import { getToggleWrapperStyling } from '@components/NewToggle/Toggle.style';

interface ToggleContextType {
selectKey: number | string;
handleSelect: (selectedId: number | string) => void;
}

export interface NewToggleProps extends PropsWithChildren {
initialSelect?: number | string;
additinalFunc?: (key: number | string) => void;
}

export const NewToggleContext = createContext<ToggleContextType | null>(null);

const NewToggle = ({ initialSelect = 0, additinalFunc, children }: NewToggleProps) => {
const [selected, setSelected] = useState<number | string>(initialSelect);

const handleSelect = useCallback(
(select: number | string) => {
flushSync(() => setSelected(select));
if (additinalFunc) additinalFunc(select);
},
[additinalFunc]
);

const context = useMemo(
() => ({
selectKey: selected,
handleSelect,
}),
[handleSelect, selected]
);

return (
<NewToggleContext.Provider value={context}>
<div css={getToggleWrapperStyling}>{children}</div>
</NewToggleContext.Provider>
);
};

NewToggle.List = List;
NewToggle.Item = Item;

export default NewToggle;
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { css } from '@emotion/react';

import { Theme } from '@styles/Theme';

export const getListStyling = (isSelected: boolean) =>
css({
display: 'flex',
alignItems: 'center',
justifyContent: 'center',

padding: '8px 12px',
border: `1px solid ${isSelected ? Theme.color.blue700 : Theme.color.gray200}`,

backgroundColor: isSelected ? Theme.color.blue100 : Theme.color.white,

fontSize: Theme.text.small.fontSize,
lineHeight: Theme.text.small.lineHeight,
color: isSelected ? Theme.color.blue700 : Theme.color.gray600,

transition: `all .2s ease-in`,

cursor: 'pointer',

'&:hover': {
color: isSelected ? Theme.color.blue700 : Theme.color.gray700,
backgroundColor: isSelected ? Theme.color.blue200 : Theme.color.gray100,
},
});

export const getToggleWrapperStyling = css({
width: 'fit-content',
borderRadius: Theme.borderRadius.small,

overflow: 'hidden',

'& :first-of-type': {
borderTopLeftRadius: Theme.borderRadius.small,
borderBottomLeftRadius: Theme.borderRadius.small,
},

'& :last-of-type': {
borderTopRightRadius: Theme.borderRadius.small,
borderBottomRightRadius: Theme.borderRadius.small,
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import Textarea from '@components/Textarea/Textarea';
import Toast from '@components/Toast/Toast';
import Toggle from '@components/Toggle/Toggle';
import ToggleGroup from '@components/ToggleGroup/ToggleGroup';
import NewToggle from '@components/NewToggle/NewToggle';

import { Theme } from '@styles/Theme';

Expand All @@ -56,6 +57,7 @@ export {
Badge,
Box,
SwitchToggle,
NewToggle,
Button,
Calendar,
Carousel,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { containerStyle } from '@stories/styles';
import type { Meta, StoryObj } from '@storybook/react';

import NewToggle from '@components/NewToggle/NewToggle';

const meta = {
title: 'NewToggle',
component: NewToggle,
args: {
initialSelect: 'toggle1',
},
argTypes: {
initialSelect: { control: 'string' },
},
decorators: [
(Story) => (
<ul css={containerStyle}>
<Story />
</ul>
),
],
} satisfies Meta<typeof NewToggle>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {
render: ({ ...args }) => (
<NewToggle
{...args}
additinalFunc={(id: number | string) => {
// eslint-disable-next-line no-console
console.log(id);
}}
>
<h6>NewToggle</h6>
<div style={{ display: 'flex' }}>
<NewToggle.List text="Toggle 1" toggleKey="toggle1" />
<NewToggle.List text="Toggle 2" toggleKey="toggle2" />
<NewToggle.List text="Toggle 3" toggleKey="toggle3" />
</div>
<div>
<NewToggle.Item toggleKey="toggle1">나는토글1</NewToggle.Item>
<NewToggle.Item toggleKey="toggle2">나는토글2</NewToggle.Item>
<NewToggle.Item toggleKey="toggle3">나는토글3</NewToggle.Item>
</div>
</NewToggle>
),
};
2 changes: 1 addition & 1 deletion frontend-monorepo/packages/hanglog-service/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"axios": "^1.4.0",
"browser-image-compression": "^2.0.2",
"dotenv": "^16.3.1",
"hang-log-design-system": "^1.3.8",
"hang-log-design-system": "^1.3.9",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.14.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/* tslint:disable */

/**
* Mock Service Worker (1.3.2).
* Mock Service Worker (1.2.3).
* @see https://github.com/mswjs/msw
* - Please do NOT modify this file.
* - Please do NOT serve this file on production.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useNavigate } from 'react-router-dom';

import { Box, Button, Flex, Heading, Text, Toggle, ToggleGroup } from 'hang-log-design-system';
import { Box, Button, Flex, Heading, Text, NewToggle as Toggle } from 'hang-log-design-system';

import TripsItem from '@components/trips/TripsItem/TripsItem';
import {
Expand All @@ -19,54 +19,57 @@ import type { TripsData } from '@type/trips';

import { ORDER_BY_DATE, ORDER_BY_REGISTRATION } from '@constants/order';
import { PATH } from '@constants/path';
import { sortByNewest, sortByStartDate } from '@utils/sort';
import { queryClient } from '@/hooks/api/queryClient';

interface TripsItemListProps {
trips: TripsData[];
order: string | number;
changeSelect: (selectedId: string | number) => void;
}
const TripsItemList = () => {
const tripsData = queryClient.getQueryData(['trips']) as TripsData[];

const handleSort = (select: number | string) => {
const sortedTrips =
select === ORDER_BY_DATE
? tripsData?.slice().sort(sortByStartDate)
: tripsData?.slice().sort(sortByNewest);

queryClient.setQueryData(['trips'], sortedTrips);
};

const TripsItemList = ({ trips, order, changeSelect }: TripsItemListProps) => {
return (
<section css={containerStyling}>
<Flex
tag="section"
styles={{ justify: 'right', paddingRight: '50px' }}
css={toggleGroupStyling}
>
<ToggleGroup>
<Toggle
<Toggle initialSelect={ORDER_BY_REGISTRATION} additinalFunc={handleSort}>
<Flex
tag="section"
styles={{ justify: 'right', paddingRight: '50px' }}
css={toggleGroupStyling}
>
<Toggle.List
text={ORDER_BY_REGISTRATION}
toggleId={ORDER_BY_REGISTRATION}
selectedId={order}
changeSelect={changeSelect}
toggleKey={ORDER_BY_REGISTRATION}
aria-label="등록순 정렬 버튼"
/>
<Toggle
<Toggle.List
text={ORDER_BY_DATE}
toggleId={ORDER_BY_DATE}
selectedId={order}
changeSelect={changeSelect}
toggleKey={ORDER_BY_DATE}
aria-label="날짜순 정렬 버튼"
/>
</ToggleGroup>
</Flex>
<Box tag="ol" css={gridBoxStyling}>
{trips.map((trip, index) => {
return (
<TripsItem
key={trip.id}
id={trip.id}
coverImage={trip.imageName}
cityTags={trip.cities}
itemName={trip.title}
duration={`${formatDate(trip.startDate)} - ${formatDate(trip.endDate)}`}
description={trip.description}
index={index}
/>
);
})}
</Box>
</Flex>
<Box tag="ol" css={gridBoxStyling}>
{tripsData.map((trip, index) => {
return (
<TripsItem
key={trip.id}
id={trip.id}
coverImage={trip.imageName}
cityTags={trip.cities}
itemName={trip.title}
duration={`${formatDate(trip.startDate)} - ${formatDate(trip.endDate)}`}
description={trip.description}
index={index}
/>
);
})}
</Box>
</Toggle>
</section>
);
};
Expand Down
Loading
Loading