@opsnow-mcp/opsnow-mcp-common-ui-server 1.0.21 → 1.0.22

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 (41) hide show
  1. package/build/components/data/icon-names.js +129 -0
  2. package/build/components/examples/opsnow-common-calendar-examples-data.js +48 -0
  3. package/build/components/examples/opsnow-common-chart-examples-data.js +6590 -0
  4. package/build/components/examples/opsnow-common-data-status-examples-data.js +65 -0
  5. package/build/components/examples/opsnow-common-file-upload-examples-data.js +95 -0
  6. package/build/components/examples/opsnow-common-forms-examples-data.js +1715 -0
  7. package/build/components/examples/opsnow-common-grid-examples-data.js +2389 -0
  8. package/build/components/examples/opsnow-common-icons-examples-data.js +72 -0
  9. package/build/components/examples/opsnow-common-layout-examples-data.js +97 -0
  10. package/build/components/examples/opsnow-common-notification-examples-data.js +78 -0
  11. package/build/components/examples/opsnow-common-pagination-examples-data.js +82 -0
  12. package/build/components/examples/opsnow-common-popup-examples-data.js +205 -0
  13. package/build/components/examples/opsnow-common-progress-examples-data.js +86 -0
  14. package/build/components/examples/opsnow-common-select-examples-data.js +121 -0
  15. package/build/components/examples/opsnow-common-stepper-examples-data.js +180 -0
  16. package/build/components/examples/opsnow-common-storage-examples-data.js +8 -0
  17. package/build/components/examples/opsnow-common-tab-examples-data.js +87 -0
  18. package/build/components/examples/opsnow-common-toast-popup-examples-data.js +129 -0
  19. package/build/components/examples/opsnow-common-tooltip-examples-data.js +80 -0
  20. package/build/components/examples/opsnow-common-typography-examples-data.js +366 -0
  21. package/build/components/opsnow-common-calendar.js +228 -0
  22. package/build/components/opsnow-common-chart.js +1643 -0
  23. package/build/components/opsnow-common-data-status.js +116 -0
  24. package/build/components/opsnow-common-examples.js +109 -0
  25. package/build/components/opsnow-common-file-upload.js +57 -0
  26. package/build/components/opsnow-common-forms.js +1009 -0
  27. package/build/components/opsnow-common-grid.js +352 -0
  28. package/build/components/opsnow-common-icons.js +139 -0
  29. package/build/components/opsnow-common-layout.js +141 -0
  30. package/build/components/opsnow-common-notification.js +110 -0
  31. package/build/components/opsnow-common-pagination.js +164 -0
  32. package/build/components/opsnow-common-popup.js +71 -0
  33. package/build/components/opsnow-common-progress.js +177 -0
  34. package/build/components/opsnow-common-select.js +135 -0
  35. package/build/components/opsnow-common-stepper.js +72 -0
  36. package/build/components/opsnow-common-tab.js +111 -0
  37. package/build/components/opsnow-common-toast-popup.js +135 -0
  38. package/build/components/opsnow-common-tooltip.js +204 -0
  39. package/build/components/opsnow-common-typography.js +93 -0
  40. package/build/index.js +135 -0
  41. package/package.json +1 -1
@@ -0,0 +1,366 @@
1
+ // opsnow-common-typography 예제 데이터
2
+ export const TypographyExamples = [
3
+ // Regular 예제
4
+ {
5
+ title: 'regular-variant-step1',
6
+ code: `<OpsnowCommonTypography variant="e-r1">e-r1 / 50px</OpsnowCommonTypography>`,
7
+ description: 'Regular 1단계 타이포그라피 예제입니다.'
8
+ },
9
+ {
10
+ title: 'regular-variant-step2',
11
+ code: `<OpsnowCommonTypography variant="e-r2">e-r2 / 40px</OpsnowCommonTypography>`,
12
+ description: 'Regular 2단계 타이포그라피 예제입니다.'
13
+ },
14
+ {
15
+ title: 'regular-variant-step3',
16
+ code: `<OpsnowCommonTypography variant="e-r3">e-r3 / 32px</OpsnowCommonTypography>`,
17
+ description: 'Regular 3단계 타이포그라피 예제입니다.'
18
+ },
19
+ {
20
+ title: 'regular-variant-step4',
21
+ code: `<OpsnowCommonTypography variant="e-r4">e-r4 / 24px</OpsnowCommonTypography>`,
22
+ description: 'Regular 4단계 타이포그라피 예제입니다.'
23
+ },
24
+ {
25
+ title: 'regular-variant-step5',
26
+ code: `<OpsnowCommonTypography variant="e-r5">e-r5 / 22px</OpsnowCommonTypography>`,
27
+ description: 'Regular 5단계 타이포그라피 예제입니다.'
28
+ },
29
+ {
30
+ title: 'regular-variant-step6',
31
+ code: `<OpsnowCommonTypography variant="e-r6">e-r6 / 20px</OpsnowCommonTypography>`,
32
+ description: 'Regular 6단계 타이포그라피 예제입니다.'
33
+ },
34
+ {
35
+ title: 'regular-variant-step7',
36
+ code: `<OpsnowCommonTypography variant="e-r7">e-r7 / 18px</OpsnowCommonTypography>`,
37
+ description: 'Regular 7단계 타이포그라피 예제입니다.'
38
+ },
39
+ {
40
+ title: 'regular-variant-step8',
41
+ code: `<OpsnowCommonTypography variant="e-r8">e-r8 / 16px</OpsnowCommonTypography>`,
42
+ description: 'Regular 8단계 타이포그라피 예제입니다.'
43
+ },
44
+ {
45
+ title: 'regular-variant-step9',
46
+ code: `<OpsnowCommonTypography variant="e-r9">e-r9 / 15px</OpsnowCommonTypography>`,
47
+ description: 'Regular 9단계 타이포그라피 예제입니다.'
48
+ },
49
+ {
50
+ title: 'regular-variant-step10',
51
+ code: `<OpsnowCommonTypography variant="e-r10">e-r10 / 14px</OpsnowCommonTypography>`,
52
+ description: 'Regular 10단계 타이포그라피 예제입니다.'
53
+ },
54
+ {
55
+ title: 'regular-variant-step11',
56
+ code: `<OpsnowCommonTypography variant="e-r11">e-r11 / 13px</OpsnowCommonTypography>`,
57
+ description: 'Regular 11단계 타이포그라피 예제입니다.'
58
+ },
59
+ {
60
+ title: 'regular-variant-step12',
61
+ code: `<OpsnowCommonTypography variant="e-r12">e-r12 / 12px</OpsnowCommonTypography>`,
62
+ description: 'Regular 12단계 타이포그라피 예제입니다.'
63
+ },
64
+ {
65
+ title: 'regular-variant-step13',
66
+ code: `<OpsnowCommonTypography variant="e-r13">e-r13 / 11px</OpsnowCommonTypography>`,
67
+ description: 'Regular 13단계 타이포그라피 예제입니다.'
68
+ },
69
+ // Medium 예제
70
+ {
71
+ title: 'medium-variant-step1',
72
+ code: `<OpsnowCommonTypography variant="e-m1">e-m1 / 50px</OpsnowCommonTypography>`,
73
+ description: 'Medium 1단계 타이포그라피 예제입니다.'
74
+ },
75
+ {
76
+ title: 'medium-variant-step2',
77
+ code: `<OpsnowCommonTypography variant="e-m2">e-m2 / 40px</OpsnowCommonTypography>`,
78
+ description: 'Medium 2단계 타이포그라피 예제입니다.'
79
+ },
80
+ {
81
+ title: 'medium-variant-step3',
82
+ code: `<OpsnowCommonTypography variant="e-m3">e-m3 / 32px</OpsnowCommonTypography>`,
83
+ description: 'Medium 3단계 타이포그라피 예제입니다.'
84
+ },
85
+ {
86
+ title: 'medium-variant-step4',
87
+ code: `<OpsnowCommonTypography variant="e-m4">e-m4 / 24px</OpsnowCommonTypography>`,
88
+ description: 'Medium 4단계 타이포그라피 예제입니다.'
89
+ },
90
+ {
91
+ title: 'medium-variant-step5',
92
+ code: `<OpsnowCommonTypography variant="e-m5">e-m5 / 22px</OpsnowCommonTypography>`,
93
+ description: 'Medium 5단계 타이포그라피 예제입니다.'
94
+ },
95
+ {
96
+ title: 'medium-variant-step6',
97
+ code: `<OpsnowCommonTypography variant="e-m6">e-m6 / 20px</OpsnowCommonTypography>`,
98
+ description: 'Medium 6단계 타이포그라피 예제입니다.'
99
+ },
100
+ {
101
+ title: 'medium-variant-step7',
102
+ code: `<OpsnowCommonTypography variant="e-m7">e-m7 / 18px</OpsnowCommonTypography>`,
103
+ description: 'Medium 7단계 타이포그라피 예제입니다.'
104
+ },
105
+ {
106
+ title: 'medium-variant-step8',
107
+ code: `<OpsnowCommonTypography variant="e-m8">e-m8 / 16px</OpsnowCommonTypography>`,
108
+ description: 'Medium 8단계 타이포그라피 예제입니다.'
109
+ },
110
+ {
111
+ title: 'medium-variant-step9',
112
+ code: `<OpsnowCommonTypography variant="e-m9">e-m9 / 15px</OpsnowCommonTypography>`,
113
+ description: 'Medium 9단계 타이포그라피 예제입니다.'
114
+ },
115
+ {
116
+ title: 'medium-variant-step10',
117
+ code: `<OpsnowCommonTypography variant="e-m10">e-m10 / 14px</OpsnowCommonTypography>`,
118
+ description: 'Medium 10단계 타이포그라피 예제입니다.'
119
+ },
120
+ {
121
+ title: 'medium-variant-step11',
122
+ code: `<OpsnowCommonTypography variant="e-m11">e-m11 / 13px</OpsnowCommonTypography>`,
123
+ description: 'Medium 11단계 타이포그라피 예제입니다.'
124
+ },
125
+ {
126
+ title: 'medium-variant-step12',
127
+ code: `<OpsnowCommonTypography variant="e-m12">e-m12 / 12px</OpsnowCommonTypography>`,
128
+ description: 'Medium 12단계 타이포그라피 예제입니다.'
129
+ },
130
+ {
131
+ title: 'medium-variant-step13',
132
+ code: `<OpsnowCommonTypography variant="e-m13">e-m13 / 11px</OpsnowCommonTypography>`,
133
+ description: 'Medium 13단계 타이포그라피 예제입니다.'
134
+ },
135
+ // Bold 예제
136
+ {
137
+ title: 'bold-variant-step1',
138
+ code: `<OpsnowCommonTypography variant="e-b1">e-b1 / 50px</OpsnowCommonTypography>`,
139
+ description: 'Bold 1단계 타이포그라피 예제입니다.'
140
+ },
141
+ {
142
+ title: 'bold-variant-step2',
143
+ code: `<OpsnowCommonTypography variant="e-b2">e-b2 / 40px</OpsnowCommonTypography>`,
144
+ description: 'Bold 2단계 타이포그라피 예제입니다.'
145
+ },
146
+ {
147
+ title: 'bold-variant-step3',
148
+ code: `<OpsnowCommonTypography variant="e-b3">e-b3 / 32px</OpsnowCommonTypography>`,
149
+ description: 'Bold 3단계 타이포그라피 예제입니다.'
150
+ },
151
+ {
152
+ title: 'bold-variant-step4',
153
+ code: `<OpsnowCommonTypography variant="e-b4">e-b4 / 24px</OpsnowCommonTypography>`,
154
+ description: 'Bold 4단계 타이포그라피 예제입니다.'
155
+ },
156
+ {
157
+ title: 'bold-variant-step5',
158
+ code: `<OpsnowCommonTypography variant="e-b5">e-b5 / 22px</OpsnowCommonTypography>`,
159
+ description: 'Bold 5단계 타이포그라피 예제입니다.'
160
+ },
161
+ {
162
+ title: 'bold-variant-step6',
163
+ code: `<OpsnowCommonTypography variant="e-b6">e-b6 / 20px</OpsnowCommonTypography>`,
164
+ description: 'Bold 6단계 타이포그라피 예제입니다.'
165
+ },
166
+ {
167
+ title: 'bold-variant-step7',
168
+ code: `<OpsnowCommonTypography variant="e-b7">e-b7 / 18px</OpsnowCommonTypography>`,
169
+ description: 'Bold 7단계 타이포그라피 예제입니다.'
170
+ },
171
+ {
172
+ title: 'bold-variant-step8',
173
+ code: `<OpsnowCommonTypography variant="e-b8">e-b8 / 16px</OpsnowCommonTypography>`,
174
+ description: 'Bold 8단계 타이포그라피 예제입니다.'
175
+ },
176
+ {
177
+ title: 'bold-variant-step9',
178
+ code: `<OpsnowCommonTypography variant="e-b9">e-b9 / 15px</OpsnowCommonTypography>`,
179
+ description: 'Bold 9단계 타이포그라피 예제입니다.'
180
+ },
181
+ {
182
+ title: 'bold-variant-step10',
183
+ code: `<OpsnowCommonTypography variant="e-b10">e-b10 / 14px</OpsnowCommonTypography>`,
184
+ description: 'Bold 10단계 타이포그라피 예제입니다.'
185
+ },
186
+ {
187
+ title: 'bold-variant-step11',
188
+ code: `<OpsnowCommonTypography variant="e-b11">e-b11 / 13px</OpsnowCommonTypography>`,
189
+ description: 'Bold 11단계 타이포그라피 예제입니다.'
190
+ },
191
+ {
192
+ title: 'bold-variant-step12',
193
+ code: `<OpsnowCommonTypography variant="e-b12">e-b12 / 12px</OpsnowCommonTypography>`,
194
+ description: 'Bold 12단계 타이포그라피 예제입니다.'
195
+ },
196
+ {
197
+ title: 'bold-variant-step13',
198
+ code: `<OpsnowCommonTypography variant="e-b13">e-b13 / 11px</OpsnowCommonTypography>`,
199
+ description: 'Bold 13단계 타이포그라피 예제입니다.'
200
+ },
201
+ // Heading variants
202
+ {
203
+ title: 'heading-h1',
204
+ code: `<OpsnowCommonTypography variant="h1">typography/h1</OpsnowCommonTypography>`,
205
+ description: 'Heading h1 예제입니다.'
206
+ },
207
+ {
208
+ title: 'heading-h2',
209
+ code: `<OpsnowCommonTypography variant="h2">typography/h2</OpsnowCommonTypography>`,
210
+ description: 'Heading h2 예제입니다.'
211
+ },
212
+ {
213
+ title: 'heading-h3',
214
+ code: `<OpsnowCommonTypography variant="h3">typography/h3</OpsnowCommonTypography>`,
215
+ description: 'Heading h3 예제입니다.'
216
+ },
217
+ {
218
+ title: 'heading-h4',
219
+ code: `<OpsnowCommonTypography variant="h4">typography/h4</OpsnowCommonTypography>`,
220
+ description: 'Heading h4 예제입니다.'
221
+ },
222
+ {
223
+ title: 'heading-h5',
224
+ code: `<OpsnowCommonTypography variant="h5">typography/h5</OpsnowCommonTypography>`,
225
+ description: 'Heading h5 예제입니다.'
226
+ },
227
+ {
228
+ title: 'heading-h6',
229
+ code: `<OpsnowCommonTypography variant="h6">typography/h6</OpsnowCommonTypography>`,
230
+ description: 'Heading h6 예제입니다.'
231
+ },
232
+ // Caption, Overline, Subtitle, Body
233
+ {
234
+ title: 'caption-variant',
235
+ code: `<OpsnowCommonTypography variant="caption">typography/caption</OpsnowCommonTypography>`,
236
+ description: 'Caption 예제입니다.'
237
+ },
238
+ {
239
+ title: 'overline-variant',
240
+ code: `<OpsnowCommonTypography variant="overline">typography/overline</OpsnowCommonTypography>`,
241
+ description: 'Overline 예제입니다.'
242
+ },
243
+ {
244
+ title: 'subtitle1-variant',
245
+ code: `<OpsnowCommonTypography variant="subtitle1">typography/subtitle1</OpsnowCommonTypography>`,
246
+ description: 'Subtitle1 예제입니다.'
247
+ },
248
+ {
249
+ title: 'subtitle2-variant',
250
+ code: `<OpsnowCommonTypography variant="subtitle2">typography/subtitle2</OpsnowCommonTypography>`,
251
+ description: 'Subtitle2 예제입니다.'
252
+ },
253
+ {
254
+ title: 'body1-variant',
255
+ code: `<OpsnowCommonTypography variant="body1">typography/body1</OpsnowCommonTypography>`,
256
+ description: 'Body1 예제입니다.'
257
+ },
258
+ {
259
+ title: 'body2-variant',
260
+ code: `<OpsnowCommonTypography variant="body2">typography/body2</OpsnowCommonTypography>`,
261
+ description: 'Body2 예제입니다.'
262
+ },
263
+ // Theme variants
264
+ {
265
+ title: 'theme-primary',
266
+ code: `<OpsnowCommonTypography variant="h4" theme="primary">theme=primary</OpsnowCommonTypography>`,
267
+ description: 'primary 테마 예제입니다.'
268
+ },
269
+ {
270
+ title: 'theme-secondary',
271
+ code: `<OpsnowCommonTypography variant="h4" theme="secondary">theme=secondary</OpsnowCommonTypography>`,
272
+ description: 'secondary 테마 예제입니다.'
273
+ },
274
+ {
275
+ title: 'theme-warning',
276
+ code: `<OpsnowCommonTypography variant="h4" theme="warning">theme=warning</OpsnowCommonTypography>`,
277
+ description: 'warning 테마 예제입니다.'
278
+ },
279
+ {
280
+ title: 'theme-success',
281
+ code: `<OpsnowCommonTypography variant="h4" theme="success">theme=success</OpsnowCommonTypography>`,
282
+ description: 'success 테마 예제입니다.'
283
+ },
284
+ {
285
+ title: 'theme-error',
286
+ code: `<OpsnowCommonTypography variant="h4" theme="error">theme=error</OpsnowCommonTypography>`,
287
+ description: 'error 테마 예제입니다.'
288
+ },
289
+ {
290
+ title: 'theme-info',
291
+ code: `<OpsnowCommonTypography variant="h4" theme="info">theme=info</OpsnowCommonTypography>`,
292
+ description: 'info 테마 예제입니다.'
293
+ },
294
+ {
295
+ title: 'theme-description',
296
+ code: `<OpsnowCommonTypography variant="h4" theme="description">theme=description</OpsnowCommonTypography>`,
297
+ description: 'description 테마 예제입니다.'
298
+ },
299
+ {
300
+ title: 'theme-disabled',
301
+ code: `<OpsnowCommonTypography variant="h4" theme="disabled">theme=disabled</OpsnowCommonTypography>`,
302
+ description: 'disabled 테마 예제입니다.'
303
+ },
304
+ {
305
+ title: 'custom-color-green',
306
+ code: `<OpsnowCommonTypography variant="h4" color="commonPalette.green.300">custom color green.300</OpsnowCommonTypography>`,
307
+ description: 'custom color green.300 예제입니다.'
308
+ },
309
+ {
310
+ title: 'custom-color-orange',
311
+ code: `<OpsnowCommonTypography variant="h4" color="commonPalette.orange.300">custom color orange.300</OpsnowCommonTypography>`,
312
+ description: 'custom color orange.300 예제입니다.'
313
+ },
314
+ {
315
+ title: 'align-right',
316
+ code: `<OpsnowCommonTypography variant="h4" align="right">text align = right</OpsnowCommonTypography>`,
317
+ description: 'text align right 예제입니다.'
318
+ },
319
+ {
320
+ title: 'align-center',
321
+ code: `<OpsnowCommonTypography variant="h4" align="center">text align = center</OpsnowCommonTypography>`,
322
+ description: 'text align center 예제입니다.'
323
+ },
324
+ {
325
+ title: 'text-decoration',
326
+ code: `<OpsnowCommonTypography variant="h4" textDecoration="underline">text decoration</OpsnowCommonTypography>`,
327
+ description: 'text decoration underline 예제입니다.'
328
+ },
329
+ {
330
+ title: 'text-transform',
331
+ code: `<OpsnowCommonTypography variant="h4" textTransform="uppercase">text transform</OpsnowCommonTypography>`,
332
+ description: 'text transform uppercase 예제입니다.'
333
+ },
334
+ {
335
+ title: 'page-title',
336
+ code: `<Box sx={{ mb: 4, p: 3 }}>
337
+ <Stack spacing={1}>
338
+ <OpsnowCommonTypography
339
+ variant="e-b4"
340
+ color={'#0D0C22'}
341
+ >
342
+ Hub
343
+ </OpsnowCommonTypography>
344
+ <OpsnowCommonTypography
345
+ variant="e-r10"
346
+ color={'#5E6278'}
347
+ >
348
+ See a unified summary of your cloud financials, usage trends, and anomalies — across all accounts and providers
349
+ </OpsnowCommonTypography>
350
+ </Stack>
351
+ </Box>`,
352
+ description: '페이지 타이틀 예제입니다. Bold 4단계(e-b4)로 제목을, Regular 10단계(e-r10)로 설명을 표시합니다.'
353
+ },
354
+ {
355
+ title: 'subtitle-with-icon',
356
+ code: `<Box sx={{ mb: 6, p: 3 }}>
357
+ <Stack direction="row" alignItems="center" spacing={1}>
358
+ <OpsnowCommonIcon iconName="PocketMoney" size={24} color={'#2B2F5A'}/>
359
+ <OpsnowCommonTypography variant="e-m7" color={'#2B2F5A'}>
360
+ AWS Commitment Savings for
361
+ </OpsnowCommonTypography>
362
+ </Stack>
363
+ </Box>`,
364
+ description: '아이콘이 포함된 서브타이틀 예제입니다. Medium 7단계(e-m7)와 아이콘을 함께 사용합니다.'
365
+ }
366
+ ];
@@ -0,0 +1,228 @@
1
+ import { z } from "zod";
2
+ // Calendar 컴포넌트 관련 스키마 정의
3
+ export const CalendarSchema = z.object({
4
+ // 캘린더 관련 파라미터들
5
+ type: z
6
+ .enum(["date", "dateRange", "dateTime", "dateTimeRange"])
7
+ .describe("단일 날짜, 날짜 범위, 날짜 + 시간 타입 중 선택"),
8
+ date: z
9
+ .enum(["month", "week", "day"])
10
+ .optional()
11
+ .describe("날짜 (YYYY-MM-DD 형식)"),
12
+ views: z
13
+ .array(z.enum(["month", "year", "week", "day", "hours", "minutes", "seconds"]))
14
+ .optional()
15
+ .describe("캘린더 뷰 타입 (여러개 선택 가능)"),
16
+ activate: z
17
+ .boolean()
18
+ .describe("캘린더 전체 활성화/비활성화 (false시 전체 캘린더 사용 불가)"),
19
+ disabledDates: z
20
+ .array(z.string())
21
+ .optional()
22
+ .describe("캘린더는 활성화된 상태에서 특정 날짜만 비활성화 (YYYY-MM-DD 형식 배열)"),
23
+ minDate: z.string().optional().describe("최소 날짜 (YYYY-MM-DD 형식)"),
24
+ maxDate: z.string().optional().describe("최대 날짜 (YYYY-MM-DD 형식)"),
25
+ // useShortcusts 부분
26
+ useShortcuts: z
27
+ .boolean()
28
+ .optional()
29
+ .describe("쇼트컷 - 달력에서 자주 사용하는 날짜 범위를 빠르게 선택할 수 있는 원클릭 버튼들 표시 여부 (예: 오늘, 어제, 지난 7일, 이번 달 등)"),
30
+ customShortcuts: z
31
+ .array(z
32
+ .object({
33
+ num: z.number().optional().describe("숫자 (예: 2, 7, 30)"),
34
+ date: z
35
+ .enum(["Months", "Weeks", "Days", "Reset"])
36
+ .optional()
37
+ .describe("단위 (Months, Weeks, Days, Reset)"),
38
+ direction: z
39
+ .enum(["Last", "Next"])
40
+ .optional()
41
+ .describe("쇼트컷 방향(예: Last : 지난 달, 지난 3개월, Next : 다음 달, 다음 3개월)"),
42
+ })
43
+ .refine((data) => {
44
+ const hasNum = data.num !== undefined;
45
+ const hasDate = data.date !== undefined;
46
+ const hasDirection = data.direction !== undefined;
47
+ if (data.date === "Reset") {
48
+ return !hasNum && !hasDirection;
49
+ }
50
+ if (data.date && ["Months", "Days"].includes(data.date)) {
51
+ return hasNum && hasDirection;
52
+ }
53
+ if (!hasDate) {
54
+ return !hasNum && !hasDirection;
55
+ }
56
+ return true;
57
+ }, {
58
+ message: "Reset일 때는 num, direction 없이 사용하고, Months/Weeks/Days 때는 num과 direction을 모두 설정하세요.",
59
+ }))
60
+ .optional()
61
+ .describe("커스텀 쇼트컷 - 기본 쇼트컷 대신 사용자가 원하는 날짜 범위 버튼들을 직접 설정 (예: {num: 2, date: 'Months', direction: 'Last'}, {date: 'Reset'})"),
62
+ });
63
+ // Calendar 컴포넌트 함수 - 배열 반환
64
+ export function createCalendarComponent() {
65
+ return [
66
+ {
67
+ name: "createCalendar",
68
+ description: `캘린더 컴포넌트 - 날짜 선택 및 이벤트 관리
69
+ **주의사항:**
70
+ - 선택된 날짜를 표시할 때 selectedDate가 null인 경우 'None'으로 표시됩니다.
71
+ **사용 예시:**
72
+ \`\`\`jsx
73
+ <p>
74
+ Selected Date: {selectedDate ? selectedDate.format('YYYY-MM-DD') : 'None'}
75
+ </p>
76
+ \`\`\`
77
+ **import:**
78
+ \`\`\`javascript
79
+ import { useCommonComponents } from '@opsnow-common/opsnow-finops-common-ui-loader';
80
+ import i18n from '@opsnow-common/opsnow-finops-common-i18n'
81
+ const { OpsnowCommonDatePicker } = useCommonComponents();
82
+ \`\`\``,
83
+ parameters: CalendarSchema,
84
+ handler: async (args) => {
85
+ // 캘린더 컴포넌트 로직 구현
86
+ // 함수 정의 생성
87
+ let functionDefinitions = `const [locale, setLocale] = useState(i18n.getLocale());
88
+ useEffect(() => {
89
+ // i18n 라이브러리에서 언어 변경 이벤트 감지하여 상태 업데이트
90
+ const handleLanguageChange = () => {
91
+ setLocale(i18n.getLocale())
92
+ }
93
+
94
+ i18n.on('languageChanged', handleLanguageChange)
95
+
96
+ return () => {
97
+ i18n.off('languageChanged', handleLanguageChange)
98
+ }
99
+ }, [])`;
100
+ if (args.type) {
101
+ const isRange = args.type.includes("Range");
102
+ if (isRange) {
103
+ functionDefinitions += `
104
+ const [selectedDateRange, setSelectedDateRange] = useState([dayjs(), dayjs()]);
105
+ `;
106
+ }
107
+ else {
108
+ functionDefinitions += `
109
+ const [selectedDate, setSelectedDate] = useState(null);
110
+ `;
111
+ }
112
+ }
113
+ if (args.disabledDates) {
114
+ functionDefinitions += `const disableSpecificDates = (date) => {
115
+ const disabledDates = ${JSON.stringify(args.disabledDates)}
116
+ return disabledDates.includes(date.format('YYYY-MM-DD'))
117
+ }\n`;
118
+ }
119
+ // 커스텀 쇼트컷 생성
120
+ if (args.customShortcuts && args.customShortcuts.length > 0) {
121
+ functionDefinitions += `const customShortcuts = [\n`;
122
+ args.customShortcuts.forEach((shortcut) => {
123
+ if (shortcut.date === "Reset") {
124
+ // Reset 버튼
125
+ functionDefinitions += ` {\n label: 'Reset',\n getValue: () => [null, null],\n },\n`;
126
+ }
127
+ else {
128
+ // 일반 날짜 계산 버튼
129
+ const direction = shortcut.direction;
130
+ const unit = shortcut.date;
131
+ const num = shortcut.num;
132
+ const label = `${direction} ${num} ${unit}`;
133
+ if (direction === "Last" && unit) {
134
+ if (unit === "Months") {
135
+ functionDefinitions += ` {\n label: '${label}',\n getValue: () => {\n const today = dayjs()\n return [\n today.subtract(${num}, '${unit}').startOf('month'),\n today.subtract(${num}, 'month').endOf('month')\n ]\n },\n },\n`;
136
+ }
137
+ else {
138
+ functionDefinitions += ` {\n label: '${label}',\n getValue: () => {\n const today = dayjs()\n return [today.subtract(${num}, '${unit}'), today]\n },\n },\n`;
139
+ }
140
+ }
141
+ else if (direction === "Next" && unit) {
142
+ if (unit === "Months") {
143
+ functionDefinitions += ` {\n label: '${label}',\n getValue: () => {\n const today = dayjs()\n return [\n today.add(${num}, 'month').startOf('month'),\n today.add(${num}, '${unit}').endOf('month')\n ]\n },\n },\n`;
144
+ }
145
+ else {
146
+ functionDefinitions += ` {\n label: '${label}',\n getValue: () => {\n const today = dayjs()\n return [today, today.add(${num}, '${unit}')]\n },\n },\n`;
147
+ }
148
+ }
149
+ }
150
+ });
151
+ functionDefinitions += `]\n\n`;
152
+ }
153
+ // Props 생성
154
+ const props = [];
155
+ if (args.type)
156
+ props.push(`type="${args.type}"`);
157
+ props.push(`value={selectedDate}`);
158
+ if (!args.activate) {
159
+ props.push(`disabled={${!args.activate}}`);
160
+ props.push(`onChange={(newValue) => {
161
+ console.log('Selected Disabled Date:', newValue)
162
+ }}`);
163
+ }
164
+ else if (args.disabledDates) {
165
+ props.push(`shouldDisableDate={disableSpecificDates}`);
166
+ props.push(`onChange={(newValue) => {
167
+ console.log('Selected Date with specific disabled dates:', newValue)
168
+ setSelectedDate(newValue)
169
+ }}`);
170
+ }
171
+ else {
172
+ props.push(`onChange={(newValue) => {
173
+ console.log('Selected ${args.type}:', newValue)
174
+ setSelectedDate(newValue)
175
+ }}`);
176
+ }
177
+ if (args.minDate)
178
+ props.push(`minDate={dayjs("${args.minDate}")}`);
179
+ if (args.maxDate)
180
+ props.push(`maxDate={dayjs("${args.maxDate}")}`);
181
+ // customShortcuts가 있으면 useShortcuts는 무조건 true
182
+ if (args.useShortcuts || args.customShortcuts) {
183
+ props.push("useShortcuts");
184
+ }
185
+ if (args.customShortcuts)
186
+ props.push(`customShortcuts={customShortcuts}`);
187
+ props.push(`locale={locale}`);
188
+ if (args.views)
189
+ props.push(`views={[${args.views.map((view) => `'${view}'`).join(", ")}]}`);
190
+ const datePickerCode = `<OpsnowCommonDatePicker ${props.join(" ")} />`;
191
+ // OpsnowCommonDatePicker 아래 <p> 태그 생성
192
+ const generateSelectedDateCode = () => {
193
+ if (!args.activate || !args.type)
194
+ return "";
195
+ const isTime = args.type.includes("Time");
196
+ const isRange = args.type.includes("Range");
197
+ const format = isTime ? "YYYY-MM-DD HH:mm" : "YYYY-MM-DD";
198
+ if (isRange) {
199
+ const label = isTime
200
+ ? "Selected DateTime Range"
201
+ : "Selected Date Range";
202
+ return `<p>
203
+ ${label}: \${selectedDateRange[0] && selectedDateRange[1]
204
+ ? \`\${selectedDateRange[0].format('${format}')} ~ \${selectedDateRange[1].format('${format}')}\`
205
+ : 'None'}
206
+ </p>`;
207
+ }
208
+ else {
209
+ const label = isTime ? "Selected DateTime" : "Selected Date";
210
+ return `<p>
211
+ ${label}: \${selectedDate ? selectedDate.format('${format}') : 'None'}
212
+ </p>`;
213
+ }
214
+ };
215
+ const selectedDateCode = generateSelectedDateCode();
216
+ const code = `${functionDefinitions}\n${datePickerCode}\n${selectedDateCode}`;
217
+ return {
218
+ content: [
219
+ {
220
+ type: "text",
221
+ text: `\`\`\`jsx\n${code}\n\`\`\``,
222
+ },
223
+ ],
224
+ };
225
+ },
226
+ },
227
+ ];
228
+ }