Skip to content

Commit

Permalink
feat: add i18next libraries (KRDS-community#100)
Browse files Browse the repository at this point in the history
- apply i18next to the calendar and pagination components.
- add ko.ts and en.ts for i18n
- change storybook preview.ts for i18n

Signed-off-by: Jeongyong Park <[email protected]>
  • Loading branch information
Jeongyong-park committed Jan 8, 2025
1 parent d59ca18 commit 6c05d0a
Show file tree
Hide file tree
Showing 10 changed files with 224 additions and 27 deletions.
23 changes: 23 additions & 0 deletions .storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { Preview } from '@storybook/react';
import '../packages/core/dist/style.css';
import '../packages/core/lib/i18n';
import i18n from '../packages/core/lib/i18n';

const preview: Preview = {
parameters: {
Expand All @@ -10,6 +12,27 @@ const preview: Preview = {
},
},
},
decorators: [
(Story, context) => {
const { locale } = context.globals;
i18n.changeLanguage(locale);
return Story();
},
],
globalTypes: {
locale: {
name: 'Locale',
description: '언어 선택',
defaultValue: 'ko',
toolbar: {
icon: 'globe',
items: [
{ value: 'ko', title: '한국어' },
{ value: 'en', title: 'English' },
],
},
},
},
};

export default preview;
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@
"@storybook/test": "^8.2.7",
"@types/node": "^22.0.0",
"bundlewatch": "^0.4.0",
"i18next": "^24.2.1",
"react-i18next": "^15.4.0",
"i18next-browser-languagedetector": "^8.0.2",
"lerna": "^8.1.7",
"prettier": "1.19.1",
"storybook": "^8.2.7",
Expand Down
36 changes: 18 additions & 18 deletions packages/core/lib/components/Calendar.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,12 @@
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Label } from './Label';

interface CalendarProps {
mode: 'single' | 'range';
onSelect: (dates: string[]) => void;
}

const today = new Date();
const DAYS = ['일', '월', '화', '수', '목', '금', '토'];
const MONTHS = [
'1월',
'2월',
'3월',
'4월',
'5월',
'6월',
'7월',
'8월',
'9월',
'10월',
'11월',
'12월',
];

const TriangleIcon: React.FC<{ direction: 'left' | 'right' }> = ({
direction,
}) => (
Expand All @@ -45,9 +29,17 @@ const TriangleIcon: React.FC<{ direction: 'left' | 'right' }> = ({
);

export const Calendar: React.FC<CalendarProps> = ({ mode, onSelect }) => {
const { t } = useTranslation();
const [currentDate, setCurrentDate] = useState(new Date());
const [selectedDates, setSelectedDates] = useState<Date[]>([]);

const DAYS = (t('calendar.days', {
returnObjects: true,
}) as unknown) as string[];
const MONTHS = (t('calendar.months', {
returnObjects: true,
}) as unknown) as string[];

const getDaysInMonth = (date: Date): Date[] => {
const year = date.getFullYear();
const month = date.getMonth();
Expand Down Expand Up @@ -151,6 +143,7 @@ export const Calendar: React.FC<CalendarProps> = ({ mode, onSelect }) => {
<button
onClick={() => changeMonth(-1)}
className="p-2 focus:outline-none"
aria-label={t('calendar.previousMonth')}
>
<TriangleIcon direction="left" />
</button>
Expand All @@ -163,6 +156,7 @@ export const Calendar: React.FC<CalendarProps> = ({ mode, onSelect }) => {
)
}
className="mr-2 p-1 border rounded"
aria-label={t('calendar.year')}
>
{Array.from(
{ length: 100 },
Expand All @@ -177,10 +171,15 @@ export const Calendar: React.FC<CalendarProps> = ({ mode, onSelect }) => {
value={currentDate.getMonth()}
onChange={(e) =>
setCurrentDate(
new Date(today.getFullYear(), parseInt(e.target.value), 1),
new Date(
currentDate.getFullYear(),
parseInt(e.target.value),
1,
),
)
}
className="p-1 border rounded"
aria-label={t('calendar.month')}
>
{MONTHS.map((month, index) => (
<option key={month} value={index}>
Expand All @@ -192,6 +191,7 @@ export const Calendar: React.FC<CalendarProps> = ({ mode, onSelect }) => {
<button
onClick={() => changeMonth(1)}
className="p-2 focus:outline-none"
aria-label={t('calendar.nextMonth')}
>
<TriangleIcon direction="right" />
</button>
Expand Down
20 changes: 11 additions & 9 deletions packages/core/lib/components/Pagination.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Label } from './Label';
import { Button } from './Button';

Expand Down Expand Up @@ -112,6 +113,7 @@ export const Pagination: React.FC<PaginationProps> = ({
allowDirectInput = false,
twoLines = false,
}) => {
const { t } = useTranslation();
const [inputPage, setInputPage] = useState<number>(currentPage);
const visiblePages = Math.max(
propVisiblePages % 2 === 0 ? propVisiblePages + 1 : propVisiblePages,
Expand Down Expand Up @@ -150,7 +152,7 @@ export const Pagination: React.FC<PaginationProps> = ({
: 'text-gray-70 hover:bg-gray-20'
}`}
aria-current={currentPage === page ? 'page' : undefined}
aria-label={`페이지 ${page}`}
aria-label={t('pagination.page') + ' ' + page}
>
{page}
</button>
Expand All @@ -165,10 +167,10 @@ export const Pagination: React.FC<PaginationProps> = ({
onClick={() => onPageChange(currentPage - 1)}
disabled={currentPage === 1}
className="flex items-center text-gray-70 justify-center p-2 pr-4 rounded-full focus:outline-none focus:ring-2 focus:ring-primary-50 disabled:opacity-50 hover:bg-gray-20"
aria-label="이전 페이지"
aria-label={t('pagination.previous')}
>
<PrevIcon />
이전
{t('pagination.previous')}
</button>
);

Expand All @@ -177,9 +179,9 @@ export const Pagination: React.FC<PaginationProps> = ({
onClick={() => onPageChange(currentPage + 1)}
disabled={currentPage === totalPages}
className="flex items-center text-gray-70 justify-center p-2 pl-4 rounded-full focus:outline-none focus:ring-2 focus:ring-primary-50 disabled:opacity-50 hover:bg-gray-20"
aria-label="다음 페이지"
aria-label={t('pagination.next')}
>
다음
{t('pagination.next')}
<NextIcon />
</button>
);
Expand All @@ -194,7 +196,7 @@ export const Pagination: React.FC<PaginationProps> = ({

return (
<nav
aria-label={'페이지 네비게이션'}
aria-label={t('pagination.pageNavigation')}
className={`${'flex items-center gap-6 flex-col'}`}
>
{showTwoLines && (
Expand All @@ -218,18 +220,18 @@ export const Pagination: React.FC<PaginationProps> = ({
min={1}
max={totalPages}
className="w-14 px-2 py-1 border border-gray-50 rounded-2 focus:outline-none focus:ring-2 focus:ring-primary-50 text-right"
aria-label="페이지 직접 입력"
aria-label={t('pagination.directInput')}
/>
<Label size="s" color="gray-60">
/ {totalPages}
{t('pagination.of')} {totalPages}
</Label>
<Button
onClick={handleDirectInput}
size="x-small"
variant="secondary"
className="focus:outline-none focus:ring-2 focus:ring-primary-50 ml-4"
>
이동
{t('pagination.move')}
</Button>
</div>
)}
Expand Down
27 changes: 27 additions & 0 deletions packages/core/lib/i18n.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import ko from './locales/ko';
import en from './locales/en';

i18n
.use(LanguageDetector)
.use(initReactI18next)
.init({
resources: {
ko: { translation: ko },
en: { translation: en },
},
lng: 'ko',
fallbackLng: 'ko',
ns: ['translation'],
defaultNS: 'translation',
interpolation: {
escapeValue: false,
},
react: {
useSuspense: false,
},
});

export default i18n;
1 change: 1 addition & 0 deletions packages/core/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import './index.css';
import './i18n';
import { Display } from './components/Display';
import { Heading } from './components/Heading';
import { Title } from './components/Title';
Expand Down
32 changes: 32 additions & 0 deletions packages/core/lib/locales/en.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
export default {
pagination: {
previous: 'Previous',
next: 'Next',
page: 'Page',
of: 'of',
move: 'Move',
pageNavigation: 'Page Navigation',
directInput: 'Direct page input',
},
calendar: {
days: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
months: [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
],
year: 'Year',
month: 'Month',
previousMonth: 'Previous Month',
nextMonth: 'Next Month',
},
} as const;
32 changes: 32 additions & 0 deletions packages/core/lib/locales/ko.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
export default {
pagination: {
previous: '이전',
next: '다음',
page: '페이지',
of: '/',
move: '이동',
pageNavigation: '페이지 네비게이션',
directInput: '페이지 직접 입력',
},
calendar: {
days: ['일', '월', '화', '수', '목', '금', '토'],
months: [
'1월',
'2월',
'3월',
'4월',
'5월',
'6월',
'7월',
'8월',
'9월',
'10월',
'11월',
'12월',
],
year: '년',
month: '월',
previousMonth: '이전 달',
nextMonth: '다음 달',
},
} as const;
3 changes: 3 additions & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@
"eslint": "^8.57.0",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-react-refresh": "^0.4.7",
"i18next": "^24.2.1",
"react-i18next": "^15.4.0",
"i18next-browser-languagedetector": "^8.0.2",
"postcss": "^8.4.40",
"rollup-plugin-visualizer": "^5.12.0",
"tailwindcss": "^3.4.7",
Expand Down
Loading

0 comments on commit 6c05d0a

Please sign in to comment.