Skip to content

Commit e38f15d

Browse files
kimyouknowsukyeongzztnrudzz13
authored
feat: add @react-simplikit/mobile package with monorepo structure (#308)
Co-authored-by: sukyeong <sukyeong@tossbank.com> Co-authored-by: zztnrudzz13 <zztnrudzz13@naver.com>
1 parent a6d186c commit e38f15d

521 files changed

Lines changed: 21264 additions & 817 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
!.yarn/sdks
88
!.yarn/versions
99

10+
# large yarn cache files (exceed GitHub 100MB limit)
11+
.yarn/cache/@next-swc-*.zip
12+
.yarn/cache/next-npm-*.zip
13+
1014
# build
1115
dist
1216
esm
@@ -24,6 +28,16 @@ coverage
2428
.vitepress/cache
2529
.vitepress/dist
2630

31+
# next
32+
.next
33+
2734
.env
2835

2936
.DS_Store
37+
38+
# claude
39+
.claude
40+
CLAUDE.md
41+
42+
# context files (session notes, etc.)
43+
context/

.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
registry=https://registry.npmjs.org/

.nvmrc

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1 @@
1-
lts/iron
2-
3-
# 'iron' is the 20.x node release line
4-
# ESLint requires Node.js >=18.18.0, >=20.9.0, or >=21.1.0 — ensure 20.9.0+ if using iron
5-
# See: https://eslint.org/docs/latest/use/getting-started#prerequisites
1+
v22.18.0

.pnp.cjs

Lines changed: 4332 additions & 265 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.scripts/commands/scaffold/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const prettierConfig: prettier.Options = {
1515
};
1616

1717
export async function scaffold(name: string, type: 'hook' | 'component' | 'util') {
18-
const directory = path.join(getRootPath(), `./src/${type}s/${name}`);
18+
const directory = path.join(getRootPath(), `./packages/core/src/${type}s/${name}`);
1919
const ext = type === 'component' ? 'tsx' : 'ts';
2020

2121
const tasks = new Listr(

.vitepress/config.mts

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,52 @@ export default defineConfig({
88
root: { label: 'English', ...en },
99
ko: { label: '한국어', ...ko },
1010
},
11-
srcDir: 'src',
11+
srcDir: '.',
12+
srcExclude: [
13+
'**/node_modules/**',
14+
'**/README*.md',
15+
'**/CHANGELOG.md',
16+
'CONTRIBUTING.md',
17+
'packages/**/*.ts',
18+
'packages/**/*.tsx',
19+
],
20+
vite: {
21+
resolve: {
22+
dedupe: ['vue', 'vitepress'],
23+
},
24+
},
1225
rewrites: {
13-
'docs/ko/:document.md': 'ko/:document.md',
14-
'docs/en/:document.md': ':document.md',
15-
'components/:implementation/ko/:implementation.md': 'ko/components/:implementation.md',
16-
'components/:implementation/:implementation.md': 'components/:implementation.md',
17-
'hooks/:implementation/ko/:implementation.md': 'ko/hooks/:implementation.md',
18-
'hooks/:implementation/:implementation.md': 'hooks/:implementation.md',
19-
'utils/:implementation/ko/:implementation.md': 'ko/utils/:implementation.md',
20-
'utils/:implementation/:implementation.md': 'utils/:implementation.md',
26+
// Landing page
27+
'docs/index.md': 'index.md',
28+
'docs/ko/index.md': 'ko/index.md',
29+
30+
// Core guide docs
31+
'docs/core/:doc.md': 'core/:doc.md',
32+
'docs/ko/core/:doc.md': 'ko/core/:doc.md',
33+
34+
// Mobile guide docs
35+
'docs/mobile/:doc.md': 'mobile/:doc.md',
36+
'docs/ko/mobile/:doc.md': 'ko/mobile/:doc.md',
37+
38+
// Core hooks
39+
'packages/core/src/hooks/:hook/:hook.md': 'core/hooks/:hook.md',
40+
'packages/core/src/hooks/:hook/ko/:hook.md': 'ko/core/hooks/:hook.md',
41+
42+
// Core components
43+
'packages/core/src/components/:component/:component.md': 'core/components/:component.md',
44+
'packages/core/src/components/:component/ko/:component.md': 'ko/core/components/:component.md',
45+
46+
// Core utils
47+
'packages/core/src/utils/:util/:util.md': 'core/utils/:util.md',
48+
'packages/core/src/utils/:util/ko/:util.md': 'ko/core/utils/:util.md',
49+
50+
// Mobile hooks
51+
'packages/mobile/src/hooks/:hook/:hook.md': 'mobile/hooks/:hook.md',
52+
'packages/mobile/src/hooks/:hook/ko/:hook.md': 'ko/mobile/hooks/:hook.md',
53+
54+
// Mobile keyboardHeight (special case - folder name differs from hook name)
55+
'packages/mobile/src/hooks/keyboardHeight/useKeyboardHeight.md': 'mobile/hooks/useKeyboardHeight.md',
56+
'packages/mobile/src/hooks/keyboardHeight/ko/useKeyboardHeight.md': 'ko/mobile/hooks/useKeyboardHeight.md',
2157
},
2258
head: [
2359
['link', { rel: 'stylesheet', href: 'https://static.toss.im/tps/main.css' }],
@@ -28,7 +64,7 @@ export default defineConfig({
2864
['link', { rel: 'apple-touch-icon', href: '/favicon/apple-touch-icon.png' }],
2965
['link', { rel: 'manifest', href: '/favicon/site.webmanifest' }],
3066
['meta', { name: 'author', content: 'Viva Republica, Inc.' }],
31-
['meta', { name: 'keywords', content: 'react, hooks, utility, library, react-simplikit' }],
67+
['meta', { name: 'keywords', content: 'react, hooks, utility, library, react-simplikit, mobile' }],
3268
['meta', { name: 'viewport', content: 'width=device-width, initial-scale=1' }],
3369
['meta', { property: 'og:type', content: 'website' }],
3470
['meta', { property: 'og:title', content: 'react-simplikit' }],

.vitepress/en.mts

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { defineConfig, DefaultTheme } from 'vitepress';
22
import { getSidebarItems } from './libs/getSidebarItems.mts';
33
import { sortByText } from './libs/sortByText.mts';
4-
import { sourceRoot } from './shared.mts';
4+
import { corePackageRoot, mobilePackageRoot } from './shared.mts';
55

66
export const en = defineConfig({
77
lang: 'en',
88
themeConfig: {
99
nav: nav(),
1010
sidebar: sidebar(),
1111
editLink: {
12-
pattern: 'https://github.com/toss/react-simplikit/edit/main/src/:path',
12+
pattern: 'https://github.com/toss/react-simplikit/edit/main/:path',
1313
text: 'Edit this page on GitHub',
1414
},
1515
footer: {
@@ -22,39 +22,74 @@ export const en = defineConfig({
2222
function nav(): DefaultTheme.NavItem[] {
2323
return [
2424
{ text: 'Home', link: '/' },
25-
{ text: 'Introduction', link: '/intro.html' },
26-
{ text: 'Reference', link: '/components/ImpressionArea.html' },
25+
{ text: 'Mobile', link: '/mobile/intro' },
26+
{ text: 'Core', link: '/core/intro' },
2727
];
2828
}
2929

3030
function sidebar(): DefaultTheme.Sidebar {
31+
return {
32+
'/core/': coreSidebar(),
33+
'/mobile/': mobileSidebar(),
34+
};
35+
}
36+
37+
function coreSidebar(): DefaultTheme.SidebarItem[] {
3138
return [
3239
{
3340
text: 'Guide',
3441
items: [
35-
{ text: 'Introduction', link: '/intro' },
36-
{ text: 'Why react-simplikit matters', link: '/why-react-simplikit-matters' },
37-
{ text: 'Installation', link: '/installation' },
38-
{ text: 'Design Principles', link: '/design-principles' },
39-
{ text: 'Contributing', link: '/contributing' },
42+
{ text: 'Introduction', link: '/core/intro' },
43+
{ text: 'Why react-simplikit matters', link: '/core/why-react-simplikit-matters' },
44+
{ text: 'Installation', link: '/core/installation' },
45+
{ text: 'Design Principles', link: '/core/design-principles' },
46+
{ text: 'Contributing', link: '/core/contributing' },
4047
],
4148
},
4249
{
4350
text: 'Reference',
4451
items: sortByText([
4552
{
4653
text: 'Components',
47-
items: getSidebarItems(sourceRoot, 'components', '*'),
54+
collapsed: false,
55+
items: getSidebarItems(corePackageRoot, 'components', '/core'),
4856
},
4957
{
5058
text: 'Hooks',
51-
items: getSidebarItems(sourceRoot, 'hooks', '*'),
59+
collapsed: false,
60+
items: getSidebarItems(corePackageRoot, 'hooks', '/core'),
5261
},
5362
{
5463
text: 'Utils',
55-
items: getSidebarItems(sourceRoot, 'utils', '*'),
64+
collapsed: false,
65+
items: getSidebarItems(corePackageRoot, 'utils', '/core'),
5666
},
5767
]),
5868
},
5969
];
6070
}
71+
72+
function mobileSidebar(): DefaultTheme.SidebarItem[] {
73+
return [
74+
{
75+
text: 'Guide',
76+
items: [
77+
{ text: 'Introduction', link: '/mobile/intro' },
78+
{ text: 'Roadmap', link: '/mobile/roadmap' },
79+
{ text: 'Installation', link: '/mobile/installation' },
80+
{ text: 'Design Principles', link: '/mobile/design-principles' },
81+
{ text: 'Contributing', link: '/mobile/contributing' },
82+
],
83+
},
84+
{
85+
text: 'Reference',
86+
items: [
87+
{
88+
text: 'Hooks',
89+
collapsed: false,
90+
items: getSidebarItems(mobilePackageRoot, 'hooks', '/mobile'),
91+
},
92+
],
93+
},
94+
];
95+
}

.vitepress/ko.mts

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { defineConfig, DefaultTheme } from 'vitepress';
22
import { getSidebarItems } from './libs/getSidebarItems.mts';
33
import { sortByText } from './libs/sortByText.mts';
4-
import { sourceRoot } from './shared.mts';
4+
import { corePackageRoot, mobilePackageRoot } from './shared.mts';
55

66
export const ko = defineConfig({
77
lang: 'ko',
88
themeConfig: {
99
nav: nav(),
1010
sidebar: sidebar(),
1111
editLink: {
12-
pattern: 'https://github.com/toss/react-simplikit/edit/main/src/:path',
12+
pattern: 'https://github.com/toss/react-simplikit/edit/main/:path',
1313
text: 'GitHub에서 수정하기',
1414
},
1515
footer: {
@@ -21,44 +21,79 @@ export const ko = defineConfig({
2121

2222
function nav(): DefaultTheme.NavItem[] {
2323
return [
24-
{ text: '홈', link: '/ko' },
25-
{ text: '소개', link: '/ko/intro.html' },
26-
{ text: '레퍼런스', link: '/ko/components/ImpressionArea.html' },
24+
{ text: '홈', link: '/ko/' },
25+
{ text: 'Mobile', link: '/ko/mobile/intro' },
26+
{ text: 'Core', link: '/ko/core/intro' },
2727
];
2828
}
2929

3030
function sidebar(): DefaultTheme.Sidebar {
31+
return {
32+
'/ko/core/': coreSidebar(),
33+
'/ko/mobile/': mobileSidebar(),
34+
};
35+
}
36+
37+
function coreSidebar(): DefaultTheme.SidebarItem[] {
3138
return [
3239
{
3340
text: '가이드',
3441
items: [
35-
{ text: '소개', link: '/ko/intro' },
36-
{ text: 'react-simplikit, 선택의 이유', link: '/ko/why-react-simplikit-matters' },
37-
{ text: '설치하기', link: '/ko/installation' },
38-
{ text: '설계 원칙', link: '/ko/design-principles' },
39-
{ text: '기여하기', link: '/ko/contributing' },
42+
{ text: '소개', link: '/ko/core/intro' },
43+
{ text: 'react-simplikit, 선택의 이유', link: '/ko/core/why-react-simplikit-matters' },
44+
{ text: '설치하기', link: '/ko/core/installation' },
45+
{ text: '설계 원칙', link: '/ko/core/design-principles' },
46+
{ text: '기여하기', link: '/ko/core/contributing' },
4047
],
4148
},
4249
{
4350
text: '레퍼런스',
4451
items: sortByText([
4552
{
4653
text: '컴포넌트',
47-
items: getSidebarItems(sourceRoot, 'components', '*', 'ko'),
54+
collapsed: false,
55+
items: getSidebarItems(corePackageRoot, 'components', '/core', 'ko'),
4856
},
4957
{
5058
text: '훅',
51-
items: getSidebarItems(sourceRoot, 'hooks', '*', 'ko'),
59+
collapsed: false,
60+
items: getSidebarItems(corePackageRoot, 'hooks', '/core', 'ko'),
5261
},
5362
{
5463
text: '유틸리티',
55-
items: getSidebarItems(sourceRoot, 'utils', '*', 'ko'),
64+
collapsed: false,
65+
items: getSidebarItems(corePackageRoot, 'utils', '/core', 'ko'),
5666
},
5767
]),
5868
},
5969
];
6070
}
6171

72+
function mobileSidebar(): DefaultTheme.SidebarItem[] {
73+
return [
74+
{
75+
text: '가이드',
76+
items: [
77+
{ text: '소개', link: '/ko/mobile/intro' },
78+
{ text: '앞으로의 방향', link: '/ko/mobile/roadmap' },
79+
{ text: '설치하기', link: '/ko/mobile/installation' },
80+
{ text: '설계 원칙', link: '/ko/mobile/design-principles' },
81+
{ text: '기여하기', link: '/ko/mobile/contributing' },
82+
],
83+
},
84+
{
85+
text: '레퍼런스',
86+
items: [
87+
{
88+
text: '훅',
89+
collapsed: false,
90+
items: getSidebarItems(mobilePackageRoot, 'hooks', '/mobile', 'ko'),
91+
},
92+
],
93+
},
94+
];
95+
}
96+
6297
export const search: DefaultTheme.LocalSearchOptions['locales'] = {
6398
ko: {
6499
translations: {

.vitepress/libs/getSidebarItems.mts

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,49 @@ import glob from 'fast-glob';
22
import path from 'node:path';
33
import { DefaultTheme } from 'vitepress';
44

5-
export function getSidebarItems(docsRoot: string, ...parts: string[]): DefaultTheme.SidebarItem[] {
6-
const files = glob.sync(path.join(docsRoot, ...parts, '*.md'));
7-
const locale = /^[a-z]{2}$/.test(parts[parts.length - 1]) ? parts.pop()! : '';
5+
/**
6+
* Get sidebar items from a package's source directory
7+
* @param packageRoot - Root directory of the package (e.g., packages/core/src)
8+
* @param category - Category like 'hooks', 'components', 'utils'
9+
* @param prefix - URL prefix like '/core' or '/mobile'
10+
* @param locale - Optional locale like 'ko'
11+
*/
12+
export function getSidebarItems(
13+
packageRoot: string,
14+
category: string,
15+
prefix: string,
16+
locale?: string
17+
): DefaultTheme.SidebarItem[] {
18+
// Find all .md files in the category directory
19+
const pattern = locale
20+
? path.join(packageRoot, category, '*', 'ko', '*.md')
21+
: path.join(packageRoot, category, '*', '*.md');
822

9-
return files.map(file => {
10-
const relativePath = path.relative(docsRoot, file);
11-
const filename = path.basename(file, '.md');
12-
const dirname = path.dirname(relativePath);
23+
const files = glob.sync(pattern, {
24+
ignore: ['**/ko/**/*.md'].filter(() => !locale), // Ignore ko folder when not looking for locale
25+
});
1326

14-
const link = locale === '' ? path.join('/', dirname) : path.join('/', locale, dirname.replace(`/${locale}`, ''));
27+
const items = files
28+
.filter(file => {
29+
// Only include files that match the folder name (e.g., useBooleanState/useBooleanState.md)
30+
const dirname = path.basename(path.dirname(locale ? path.dirname(file) : file));
31+
const filename = path.basename(file, '.md');
32+
return dirname === filename || dirname === 'keyboardHeight'; // Special case for keyboardHeight
33+
})
34+
.map(file => {
35+
const filename = path.basename(file, '.md');
36+
const link = locale ? `/${locale}${prefix}/${category}/${filename}` : `${prefix}/${category}/${filename}`;
1537

16-
return { text: filename, link };
17-
});
38+
return { text: filename, link };
39+
})
40+
.sort((a, b) => a.text.localeCompare(b.text));
41+
42+
return items;
43+
}
44+
45+
/**
46+
* Sort sidebar items alphabetically by text
47+
*/
48+
export function sortByText(items: DefaultTheme.SidebarItem[]): DefaultTheme.SidebarItem[] {
49+
return items.sort((a, b) => (a.text ?? '').localeCompare(b.text ?? ''));
1850
}

.vitepress/shared.mts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
import path from 'path';
22

3-
export const sourceRoot = path.resolve(import.meta.dirname, '..', 'src');
3+
export const projectRoot = path.resolve(import.meta.dirname, '..');
4+
export const corePackageRoot = path.join(projectRoot, 'packages/core/src');
5+
export const mobilePackageRoot = path.join(projectRoot, 'packages/mobile/src');
6+
export const docsRoot = path.join(projectRoot, 'docs');

0 commit comments

Comments
 (0)