@blastlabs/utils 1.21.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +102 -8
- package/bin/Makefile +23 -0
- package/bin/init-routes.cjs +422 -0
- package/dist/components/dev/DevPanel.d.ts +16 -11
- package/dist/components/dev/DevPanel.d.ts.map +1 -1
- package/dist/components/dev/DevPanel.js +71 -77
- package/dist/components/dev/DevPanel.test.d.ts +2 -0
- package/dist/components/dev/DevPanel.test.d.ts.map +1 -0
- package/dist/components/dev/DevPanel.test.js +194 -0
- package/dist/components/dev/DevToolsProvider/DevToolsProvider.d.ts +97 -0
- package/dist/components/dev/DevToolsProvider/DevToolsProvider.d.ts.map +1 -0
- package/dist/components/dev/DevToolsProvider/DevToolsProvider.js +122 -0
- package/dist/components/dev/DevToolsProvider/DevToolsProvider.test.d.ts +2 -0
- package/dist/components/dev/DevToolsProvider/DevToolsProvider.test.d.ts.map +1 -0
- package/dist/components/dev/DevToolsProvider/DevToolsProvider.test.js +104 -0
- package/dist/components/dev/DevToolsProvider/index.d.ts +3 -0
- package/dist/components/dev/DevToolsProvider/index.d.ts.map +1 -0
- package/dist/components/dev/DevToolsProvider/index.js +1 -0
- package/dist/components/dev/FormDevTools/FormDevTools.d.ts +5 -70
- package/dist/components/dev/FormDevTools/FormDevTools.d.ts.map +1 -1
- package/dist/components/dev/FormDevTools/FormDevTools.js +163 -236
- package/dist/components/dev/FormDevTools/FormDevToolsContent.d.ts +27 -0
- package/dist/components/dev/FormDevTools/FormDevToolsContent.d.ts.map +1 -0
- package/dist/components/dev/FormDevTools/FormDevToolsContent.js +298 -0
- package/dist/components/dev/TimezoneDevTools/TimezoneDevTools.d.ts +29 -0
- package/dist/components/dev/TimezoneDevTools/TimezoneDevTools.d.ts.map +1 -0
- package/dist/components/dev/TimezoneDevTools/TimezoneDevTools.js +122 -0
- package/dist/components/dev/TimezoneDevTools/TimezoneDevToolsContent.d.ts +4 -0
- package/dist/components/dev/TimezoneDevTools/TimezoneDevToolsContent.d.ts.map +1 -0
- package/dist/components/dev/TimezoneDevTools/TimezoneDevToolsContent.js +121 -0
- package/dist/components/dev/TimezoneDevTools/index.d.ts +3 -0
- package/dist/components/dev/TimezoneDevTools/index.d.ts.map +1 -0
- package/dist/components/dev/TimezoneDevTools/index.js +1 -0
- package/dist/components/dev/TimezoneDevTools/styles.d.ts +12 -0
- package/dist/components/dev/TimezoneDevTools/styles.d.ts.map +1 -0
- package/dist/components/dev/TimezoneDevTools/styles.js +65 -0
- package/dist/components/dev/ZIndexDebugger.js +1 -1
- package/dist/components/dev/index.d.ts +4 -2
- package/dist/components/dev/index.d.ts.map +1 -1
- package/dist/components/dev/index.js +6 -1
- package/dist/date/index.d.ts +11 -0
- package/dist/date/index.d.ts.map +1 -1
- package/dist/date/index.js +43 -0
- package/package.json +4 -2
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
3
|
+
import { render, screen } from '@testing-library/react';
|
|
4
|
+
import userEvent from '@testing-library/user-event';
|
|
5
|
+
import DevToolsProvider, { useDevTools } from './DevToolsProvider';
|
|
6
|
+
// Test helper component
|
|
7
|
+
function TestConsumer() {
|
|
8
|
+
const { tools, isMenuOpen, toggleTool, toggleMenu } = useDevTools();
|
|
9
|
+
return (React.createElement("div", null,
|
|
10
|
+
React.createElement("div", { "data-testid": "form-devtools" }, tools.formDevTools ? 'on' : 'off'),
|
|
11
|
+
React.createElement("div", { "data-testid": "timezone-devtools" }, tools.timezoneDevTools ? 'on' : 'off'),
|
|
12
|
+
React.createElement("div", { "data-testid": "menu-open" }, isMenuOpen ? 'open' : 'closed'),
|
|
13
|
+
React.createElement("button", { onClick: () => toggleTool('formDevTools') }, "Toggle Form"),
|
|
14
|
+
React.createElement("button", { onClick: () => toggleTool('timezoneDevTools') }, "Toggle Timezone"),
|
|
15
|
+
React.createElement("button", { onClick: toggleMenu }, "Toggle Menu")));
|
|
16
|
+
}
|
|
17
|
+
describe('DevToolsProvider', () => {
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
vi.clearAllMocks();
|
|
20
|
+
});
|
|
21
|
+
describe('기본 동작', () => {
|
|
22
|
+
it('Provider 내부에서 context를 제공한다', () => {
|
|
23
|
+
render(React.createElement(DevToolsProvider, null,
|
|
24
|
+
React.createElement(TestConsumer, null)));
|
|
25
|
+
expect(screen.getByTestId('form-devtools').textContent).toBe('off');
|
|
26
|
+
expect(screen.getByTestId('timezone-devtools').textContent).toBe('off');
|
|
27
|
+
expect(screen.getByTestId('menu-open').textContent).toBe('closed');
|
|
28
|
+
});
|
|
29
|
+
it('Provider 외부에서는 기본값을 반환한다', () => {
|
|
30
|
+
function TestComponent() {
|
|
31
|
+
const { tools, isMenuOpen } = useDevTools();
|
|
32
|
+
return (React.createElement("div", null,
|
|
33
|
+
React.createElement("div", { "data-testid": "form-devtools" }, tools.formDevTools ? 'on' : 'off'),
|
|
34
|
+
React.createElement("div", { "data-testid": "menu-open" }, isMenuOpen ? 'open' : 'closed')));
|
|
35
|
+
}
|
|
36
|
+
render(React.createElement(TestComponent, null));
|
|
37
|
+
expect(screen.getByTestId('form-devtools').textContent).toBe('off');
|
|
38
|
+
expect(screen.getByTestId('menu-open').textContent).toBe('closed');
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
describe('툴 토글', () => {
|
|
42
|
+
it('toggleTool로 formDevTools를 토글할 수 있다', async () => {
|
|
43
|
+
const user = userEvent.setup();
|
|
44
|
+
render(React.createElement(DevToolsProvider, null,
|
|
45
|
+
React.createElement(TestConsumer, null)));
|
|
46
|
+
expect(screen.getByTestId('form-devtools').textContent).toBe('off');
|
|
47
|
+
const toggleButton = screen.getByRole('button', { name: 'Toggle Form' });
|
|
48
|
+
await user.click(toggleButton);
|
|
49
|
+
expect(screen.getByTestId('form-devtools').textContent).toBe('on');
|
|
50
|
+
await user.click(toggleButton);
|
|
51
|
+
expect(screen.getByTestId('form-devtools').textContent).toBe('off');
|
|
52
|
+
});
|
|
53
|
+
it('toggleTool로 timezoneDevTools를 토글할 수 있다', async () => {
|
|
54
|
+
const user = userEvent.setup();
|
|
55
|
+
render(React.createElement(DevToolsProvider, null,
|
|
56
|
+
React.createElement(TestConsumer, null)));
|
|
57
|
+
expect(screen.getByTestId('timezone-devtools').textContent).toBe('off');
|
|
58
|
+
const toggleButton = screen.getByRole('button', { name: 'Toggle Timezone' });
|
|
59
|
+
await user.click(toggleButton);
|
|
60
|
+
expect(screen.getByTestId('timezone-devtools').textContent).toBe('on');
|
|
61
|
+
await user.click(toggleButton);
|
|
62
|
+
expect(screen.getByTestId('timezone-devtools').textContent).toBe('off');
|
|
63
|
+
});
|
|
64
|
+
it('각 툴이 독립적으로 토글된다', async () => {
|
|
65
|
+
const user = userEvent.setup();
|
|
66
|
+
render(React.createElement(DevToolsProvider, null,
|
|
67
|
+
React.createElement(TestConsumer, null)));
|
|
68
|
+
const formButton = screen.getByRole('button', { name: 'Toggle Form' });
|
|
69
|
+
const timezoneButton = screen.getByRole('button', { name: 'Toggle Timezone' });
|
|
70
|
+
await user.click(formButton);
|
|
71
|
+
await user.click(timezoneButton);
|
|
72
|
+
expect(screen.getByTestId('form-devtools').textContent).toBe('on');
|
|
73
|
+
expect(screen.getByTestId('timezone-devtools').textContent).toBe('on');
|
|
74
|
+
await user.click(formButton);
|
|
75
|
+
expect(screen.getByTestId('form-devtools').textContent).toBe('off');
|
|
76
|
+
expect(screen.getByTestId('timezone-devtools').textContent).toBe('on');
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
describe('메뉴 토글', () => {
|
|
80
|
+
it('toggleMenu로 메뉴를 토글할 수 있다', async () => {
|
|
81
|
+
const user = userEvent.setup();
|
|
82
|
+
render(React.createElement(DevToolsProvider, null,
|
|
83
|
+
React.createElement(TestConsumer, null)));
|
|
84
|
+
expect(screen.getByTestId('menu-open').textContent).toBe('closed');
|
|
85
|
+
const toggleButton = screen.getByRole('button', { name: 'Toggle Menu' });
|
|
86
|
+
await user.click(toggleButton);
|
|
87
|
+
expect(screen.getByTestId('menu-open').textContent).toBe('open');
|
|
88
|
+
await user.click(toggleButton);
|
|
89
|
+
expect(screen.getByTestId('menu-open').textContent).toBe('closed');
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
describe('useRegisterForm', () => {
|
|
93
|
+
it('form이 등록되지 않으면 getForm은 null을 반환한다', () => {
|
|
94
|
+
function TestGetForm() {
|
|
95
|
+
const { getForm } = useDevTools();
|
|
96
|
+
const form = getForm();
|
|
97
|
+
return React.createElement("div", null, form ? 'Form exists' : 'No form');
|
|
98
|
+
}
|
|
99
|
+
render(React.createElement(DevToolsProvider, null,
|
|
100
|
+
React.createElement(TestGetForm, null)));
|
|
101
|
+
expect(screen.getByText('No form')).toBeTruthy();
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/dev/DevToolsProvider/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC/F,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as DevToolsProvider, useRegisterForm, useDevTools } from './DevToolsProvider';
|
|
@@ -32,8 +32,6 @@ export type Props = {
|
|
|
32
32
|
}) => Promise<Record<string, any>> | Record<string, any>;
|
|
33
33
|
/** Validation 스키마 정보 (zod, yup 등) - 선택사항 */
|
|
34
34
|
validationSchema?: Record<string, any>;
|
|
35
|
-
/** 표시 위치 (기본값: 'bottom-left') */
|
|
36
|
-
position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
37
35
|
/** 패널 제목 (기본값: 'Form DevTools') */
|
|
38
36
|
title?: string;
|
|
39
37
|
};
|
|
@@ -43,9 +41,9 @@ export type Props = {
|
|
|
43
41
|
*
|
|
44
42
|
* @example
|
|
45
43
|
* ```tsx
|
|
46
|
-
* // Vite 프로젝트 - 간단한 사용법
|
|
47
44
|
* import { useForm } from 'react-hook-form';
|
|
48
|
-
* import {
|
|
45
|
+
* import { useRegisterForm } from '@blastlabs/utils/components/dev';
|
|
46
|
+
* import FormDevTools from '@blastlabs/utils/components/dev';
|
|
49
47
|
*
|
|
50
48
|
* function MyForm() {
|
|
51
49
|
* const form = useForm({
|
|
@@ -56,81 +54,18 @@ export type Props = {
|
|
|
56
54
|
* }
|
|
57
55
|
* });
|
|
58
56
|
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* <input {...form.register('username')} />
|
|
62
|
-
* <input {...form.register('email')} />
|
|
63
|
-
* <button type="submit">Submit</button>
|
|
64
|
-
*
|
|
65
|
-
* {import.meta.env.DEV && <FormDevTools form={form} />}
|
|
66
|
-
* </form>
|
|
67
|
-
* );
|
|
68
|
-
* }
|
|
69
|
-
* ```
|
|
70
|
-
*
|
|
71
|
-
* @example
|
|
72
|
-
* ```tsx
|
|
73
|
-
* // Mock 데이터 생성 기능 포함
|
|
74
|
-
* function MyForm() {
|
|
75
|
-
* const form = useForm({
|
|
76
|
-
* defaultValues: {
|
|
77
|
-
* username: '',
|
|
78
|
-
* email: '',
|
|
79
|
-
* age: 0,
|
|
80
|
-
* }
|
|
81
|
-
* });
|
|
57
|
+
* // 페이지에서 form 주입
|
|
58
|
+
* useRegisterForm(form);
|
|
82
59
|
*
|
|
83
60
|
* return (
|
|
84
61
|
* <form onSubmit={form.handleSubmit(onSubmit)}>
|
|
85
62
|
* <input {...form.register('username')} />
|
|
86
63
|
* <input {...form.register('email')} />
|
|
87
64
|
* <button type="submit">Submit</button>
|
|
88
|
-
*
|
|
89
|
-
* {import.meta.env.DEV && (
|
|
90
|
-
* <FormDevTools
|
|
91
|
-
* form={form}
|
|
92
|
-
* generateMock={async ({ values, originalValues }) => {
|
|
93
|
-
* // Mock 데이터 생성 로직
|
|
94
|
-
* return {
|
|
95
|
-
* username: 'test_user',
|
|
96
|
-
* email: 'test@example.com',
|
|
97
|
-
* age: 25,
|
|
98
|
-
* };
|
|
99
|
-
* }}
|
|
100
|
-
* />
|
|
101
|
-
* )}
|
|
102
|
-
* </form>
|
|
103
|
-
* );
|
|
104
|
-
* }
|
|
105
|
-
* ```
|
|
106
|
-
*
|
|
107
|
-
* @example
|
|
108
|
-
* ```tsx
|
|
109
|
-
* // 수정 폼 예시
|
|
110
|
-
* function EditForm({ userData }) {
|
|
111
|
-
* const form = useForm();
|
|
112
|
-
*
|
|
113
|
-
* useEffect(() => {
|
|
114
|
-
* form.reset(userData);
|
|
115
|
-
* }, [userData]);
|
|
116
|
-
*
|
|
117
|
-
* return (
|
|
118
|
-
* <form onSubmit={form.handleSubmit(onSubmit)}>
|
|
119
|
-
* <input {...form.register('username')} />
|
|
120
|
-
* <input {...form.register('email')} />
|
|
121
|
-
* <button type="submit">Update</button>
|
|
122
|
-
*
|
|
123
|
-
* {process.env.NODE_ENV === 'development' && (
|
|
124
|
-
* <FormDevTools
|
|
125
|
-
* form={form}
|
|
126
|
-
* position="top-right"
|
|
127
|
-
* title="Edit Form Debug"
|
|
128
|
-
* />
|
|
129
|
-
* )}
|
|
130
65
|
* </form>
|
|
131
66
|
* );
|
|
132
67
|
* }
|
|
133
68
|
* ```
|
|
134
69
|
*/
|
|
135
|
-
export default function FormDevTools({ form, validationSchema, generateMock,
|
|
70
|
+
export default function FormDevTools({ form, validationSchema, generateMock, title }: Props): React.JSX.Element;
|
|
136
71
|
//# sourceMappingURL=FormDevTools.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormDevTools.d.ts","sourceRoot":"","sources":["../../../../src/components/dev/FormDevTools/FormDevTools.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"FormDevTools.d.ts","sourceRoot":"","sources":["../../../../src/components/dev/FormDevTools/FormDevTools.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAyB3D,MAAM,MAAM,aAAa,CAAC,YAAY,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI;IAC1F,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,GAAG,CAAC;IAC3B,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,GAAG,CAAC;IAC/B,QAAQ,EAAE,CACR,IAAI,EAAE,GAAG,EACT,KAAK,EAAE,GAAG,EACV,OAAO,CAAC,EAAE;QACR,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,WAAW,CAAC,EAAE,OAAO,CAAC;KACvB,KACE,IAAI,CAAC;IACV,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3C,SAAS,EAAE;QACT,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC7B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAClC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACpC,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,aAAa,CAAC,EAAE,YAAY,CAAC;KAC9B,CAAC;IACF,YAAY,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;IACvC,QAAQ,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;IACnC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG;IAClB,6CAA6C;IAC7C,IAAI,EAAE,aAAa,CAAC;IACpB,8BAA8B;IAC9B,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE;QACtB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC7B,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KACtC,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACzD,4CAA4C;IAC5C,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACvC,mCAAmC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,YAAY,EAAE,KAAuB,EAAE,EAAE,KAAK,qBAme5G"}
|