@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.
Files changed (44) hide show
  1. package/README.md +102 -8
  2. package/bin/Makefile +23 -0
  3. package/bin/init-routes.cjs +422 -0
  4. package/dist/components/dev/DevPanel.d.ts +16 -11
  5. package/dist/components/dev/DevPanel.d.ts.map +1 -1
  6. package/dist/components/dev/DevPanel.js +71 -77
  7. package/dist/components/dev/DevPanel.test.d.ts +2 -0
  8. package/dist/components/dev/DevPanel.test.d.ts.map +1 -0
  9. package/dist/components/dev/DevPanel.test.js +194 -0
  10. package/dist/components/dev/DevToolsProvider/DevToolsProvider.d.ts +97 -0
  11. package/dist/components/dev/DevToolsProvider/DevToolsProvider.d.ts.map +1 -0
  12. package/dist/components/dev/DevToolsProvider/DevToolsProvider.js +122 -0
  13. package/dist/components/dev/DevToolsProvider/DevToolsProvider.test.d.ts +2 -0
  14. package/dist/components/dev/DevToolsProvider/DevToolsProvider.test.d.ts.map +1 -0
  15. package/dist/components/dev/DevToolsProvider/DevToolsProvider.test.js +104 -0
  16. package/dist/components/dev/DevToolsProvider/index.d.ts +3 -0
  17. package/dist/components/dev/DevToolsProvider/index.d.ts.map +1 -0
  18. package/dist/components/dev/DevToolsProvider/index.js +1 -0
  19. package/dist/components/dev/FormDevTools/FormDevTools.d.ts +5 -70
  20. package/dist/components/dev/FormDevTools/FormDevTools.d.ts.map +1 -1
  21. package/dist/components/dev/FormDevTools/FormDevTools.js +163 -236
  22. package/dist/components/dev/FormDevTools/FormDevToolsContent.d.ts +27 -0
  23. package/dist/components/dev/FormDevTools/FormDevToolsContent.d.ts.map +1 -0
  24. package/dist/components/dev/FormDevTools/FormDevToolsContent.js +298 -0
  25. package/dist/components/dev/TimezoneDevTools/TimezoneDevTools.d.ts +29 -0
  26. package/dist/components/dev/TimezoneDevTools/TimezoneDevTools.d.ts.map +1 -0
  27. package/dist/components/dev/TimezoneDevTools/TimezoneDevTools.js +122 -0
  28. package/dist/components/dev/TimezoneDevTools/TimezoneDevToolsContent.d.ts +4 -0
  29. package/dist/components/dev/TimezoneDevTools/TimezoneDevToolsContent.d.ts.map +1 -0
  30. package/dist/components/dev/TimezoneDevTools/TimezoneDevToolsContent.js +121 -0
  31. package/dist/components/dev/TimezoneDevTools/index.d.ts +3 -0
  32. package/dist/components/dev/TimezoneDevTools/index.d.ts.map +1 -0
  33. package/dist/components/dev/TimezoneDevTools/index.js +1 -0
  34. package/dist/components/dev/TimezoneDevTools/styles.d.ts +12 -0
  35. package/dist/components/dev/TimezoneDevTools/styles.d.ts.map +1 -0
  36. package/dist/components/dev/TimezoneDevTools/styles.js +65 -0
  37. package/dist/components/dev/ZIndexDebugger.js +1 -1
  38. package/dist/components/dev/index.d.ts +4 -2
  39. package/dist/components/dev/index.d.ts.map +1 -1
  40. package/dist/components/dev/index.js +6 -1
  41. package/dist/date/index.d.ts +11 -0
  42. package/dist/date/index.d.ts.map +1 -1
  43. package/dist/date/index.js +43 -0
  44. 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,3 @@
1
+ export { default as DevToolsProvider, useRegisterForm, useDevTools } from './DevToolsProvider';
2
+ export type { DevToolForm } from './DevToolsProvider';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -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 { FormDevTools } from '@blastlabs/utils/components/dev';
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
- * return (
60
- * <form onSubmit={form.handleSubmit(onSubmit)}>
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, position, title }: Props): React.JSX.Element;
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;AA2B3D,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,iCAAiC;IACjC,QAAQ,CAAC,EAAE,UAAU,GAAG,WAAW,GAAG,aAAa,GAAG,cAAc,CAAC;IACrE,mCAAmC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8FG;AACH,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,YAAY,EAAE,QAAwB,EAAE,KAAuB,EAAE,EAAE,KAAK,qBA8gBtI"}
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"}