@hivcd-printshop/design-system 1.0.0 → 1.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/dist/index.js CHANGED
@@ -21,7 +21,20 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  // src/index.ts
22
22
  var index_exports = {};
23
23
  __export(index_exports, {
24
- CTA: () => CTA
24
+ BackButton: () => BackButton,
25
+ CTA: () => CTA,
26
+ CategorySegment: () => CategorySegment,
27
+ CategorySegmentedControl: () => CategorySegmentedControl,
28
+ NoticeBadge: () => NoticeBadge,
29
+ NoticeBar: () => NoticeBar,
30
+ SearchBar: () => SearchBar,
31
+ SideRadioAccordion: () => SideRadioAccordion,
32
+ TNB: () => TNB,
33
+ Tag: () => Tag,
34
+ Timetable: () => Timetable,
35
+ TitleInput: () => TitleInput,
36
+ Toast: () => Toast,
37
+ WeekNavigation: () => WeekNavigation
25
38
  });
26
39
  module.exports = __toCommonJS(index_exports);
27
40
 
@@ -52,8 +65,116 @@ function cn(...inputs) {
52
65
  return twMerge((0, import_clsx.clsx)(inputs));
53
66
  }
54
67
 
55
- // src/components/CTA/CTA.tsx
68
+ // src/assets/svgs/Icons.tsx
56
69
  var import_jsx_runtime = require("react/jsx-runtime");
70
+ var IconChevronDownXS = ({
71
+ className,
72
+ stroke
73
+ }) => {
74
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
75
+ "svg",
76
+ {
77
+ className,
78
+ width: "20",
79
+ height: "20",
80
+ viewBox: "0 0 20 20",
81
+ fill: "none",
82
+ xmlns: "http://www.w3.org/2000/svg",
83
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
84
+ "path",
85
+ {
86
+ d: "M5 8.3335L10 13.3335L15 8.3335",
87
+ stroke: stroke || "#121212",
88
+ strokeWidth: "1.5",
89
+ strokeLinecap: "square"
90
+ }
91
+ )
92
+ }
93
+ );
94
+ };
95
+ var IconSearch = ({ className, stroke }) => {
96
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
97
+ "svg",
98
+ {
99
+ className,
100
+ width: "30",
101
+ height: "30",
102
+ viewBox: "0 0 30 30",
103
+ fill: "none",
104
+ xmlns: "http://www.w3.org/2000/svg",
105
+ children: [
106
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
107
+ "path",
108
+ {
109
+ d: "M20.1161 20.6888L24.1075 25.1791",
110
+ stroke: stroke || "black",
111
+ strokeWidth: "2",
112
+ strokeLinecap: "round"
113
+ }
114
+ ),
115
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
116
+ "path",
117
+ {
118
+ fillRule: "evenodd",
119
+ clipRule: "evenodd",
120
+ d: "M13.9289 23.0361C18.9587 23.0361 23.0361 18.9587 23.0361 13.9289C23.0361 8.89918 18.9587 4.82178 13.9289 4.82178C8.89918 4.82178 4.82178 8.89918 4.82178 13.9289C4.82178 18.9587 8.89918 23.0361 13.9289 23.0361Z",
121
+ stroke: stroke || "black",
122
+ strokeWidth: "2"
123
+ }
124
+ )
125
+ ]
126
+ }
127
+ );
128
+ };
129
+ var IconGoBack = ({ className, stroke }) => {
130
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
131
+ "svg",
132
+ {
133
+ className,
134
+ width: "32",
135
+ height: "32",
136
+ viewBox: "0 0 32 32",
137
+ fill: "none",
138
+ xmlns: "http://www.w3.org/2000/svg",
139
+ children: [
140
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
141
+ "path",
142
+ {
143
+ d: "M28 16.0001L4 16.0001",
144
+ stroke: stroke || "black",
145
+ strokeWidth: "2",
146
+ strokeLinecap: "round"
147
+ }
148
+ ),
149
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 8L4 16L12 24", stroke: stroke || "black", strokeWidth: "2", strokeLinecap: "round" })
150
+ ]
151
+ }
152
+ );
153
+ };
154
+
155
+ // src/components/BackButton/BackButton.tsx
156
+ var import_jsx_runtime2 = require("react/jsx-runtime");
157
+ var BackButton = ({ onClick, className }) => {
158
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
159
+ "button",
160
+ {
161
+ type: "button",
162
+ onClick,
163
+ className: cn(
164
+ "w-14 h-full py-3",
165
+ "flex flex-col items-center",
166
+ "box-border border-r border-gray02",
167
+ "bg-white hover:bg-gray00 active:bg-gray01",
168
+ "cursor-pointer",
169
+ className
170
+ ),
171
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconGoBack, {})
172
+ }
173
+ );
174
+ };
175
+
176
+ // src/components/CTA/CTA.tsx
177
+ var import_jsx_runtime3 = require("react/jsx-runtime");
57
178
  var CTA = ({
58
179
  primary = true,
59
180
  variable = "default",
@@ -61,7 +182,7 @@ var CTA = ({
61
182
  onClick,
62
183
  className
63
184
  }) => {
64
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
185
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
65
186
  "button",
66
187
  {
67
188
  type: "button",
@@ -85,8 +206,754 @@ var CTA = ({
85
206
  }
86
207
  );
87
208
  };
209
+
210
+ // src/components/createPost/CategorySegment.tsx
211
+ var import_jsx_runtime4 = require("react/jsx-runtime");
212
+ var CategorySegment = ({
213
+ selected = false,
214
+ label,
215
+ className,
216
+ onClick
217
+ }) => {
218
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
219
+ "div",
220
+ {
221
+ className: cn(
222
+ "w-fit h-8 px-3.5",
223
+ "flex items-center justify-center",
224
+ // 피그마랑 조금 다르게 적용하였음. 이게 더 효율적
225
+ "border-r border-gray02 cursor-pointer",
226
+ "text-body3-book text-strong",
227
+ selected ? "bg-black text-white" : "bg-white text-strong hover:bg-gray00 active:bg-gray01",
228
+ // default, hover, pressed 상태
229
+ className
230
+ ),
231
+ onClick,
232
+ children: label
233
+ }
234
+ );
235
+ };
236
+
237
+ // src/components/createPost/CategorySegmentedControl.tsx
238
+ var import_jsx_runtime5 = require("react/jsx-runtime");
239
+ var categorySegments = {
240
+ info: ["\uACF5\uC6A9 \uBB3C\uD488", "\uC77C\uBC18 \uAE30\uC790\uC7AC", "\uD2B9\uC218 \uAE30\uC790\uC7AC"],
241
+ archive: ["\uD504\uB9B0\uD2B8\uC2E4", "\uD64D\uC775\uC2DC\uB514"],
242
+ notice: ["\uC77C\uBC18 \uACF5\uC9C0", "\uAE34\uAE09 \uACF5\uC9C0"],
243
+ infoTag: ["\uAC00\uACF5", "\uC81C\uBCF8", "\uCD9C\uB825", "\uC2A4\uCE94", "\uAE30\uD0C0"]
244
+ };
245
+ var CategorySegmentedControl = ({
246
+ variable,
247
+ setSelectedCategory,
248
+ selectedCategory,
249
+ className
250
+ }) => {
251
+ const segments = categorySegments[variable];
252
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: cn("w-full h-fit flex items-center justify-start", className), children: [
253
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
254
+ "div",
255
+ {
256
+ className: cn(
257
+ "w-fit h-8 px-3.5",
258
+ "flex items-center justify-center",
259
+ // 피그마랑 조금 다르게 적용하였음. 이게 더 효율적
260
+ "border-r border-gray02",
261
+ "text-body3-medium text-strong"
262
+ ),
263
+ children: variable === "infoTag" ? "\uD0DC\uADF8 \uC120\uD0DD" : "\uCE74\uD14C\uACE0\uB9AC \uC120\uD0DD"
264
+ }
265
+ ),
266
+ segments.map((label) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
267
+ CategorySegment,
268
+ {
269
+ label,
270
+ selected: selectedCategory === label,
271
+ onClick: () => setSelectedCategory(label)
272
+ },
273
+ label
274
+ ))
275
+ ] });
276
+ };
277
+
278
+ // src/components/createPost/TitleInput.tsx
279
+ var import_jsx_runtime6 = require("react/jsx-runtime");
280
+ var TitleInput = ({ title, onChange, className }) => {
281
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
282
+ "input",
283
+ {
284
+ type: "text",
285
+ value: title,
286
+ onChange: (e) => onChange(e.target.value),
287
+ placeholder: "\uC81C\uBAA9\uC744 \uC785\uB825\uD558\uC138\uC694",
288
+ className: cn(
289
+ "w-full min-w-[200px] h-12 px-3",
290
+ // 피그마랑 매우 다름. focus되었을 때 테두리 중복 문제 등
291
+ "box-border border-b border-gray02 border-t border-t-white",
292
+ "focus:border-black focus:border focus:outline-none",
293
+ "text-head2-medium text-strong placeholder:text-gray03",
294
+ className
295
+ )
296
+ }
297
+ );
298
+ };
299
+
300
+ // src/components/notice/NoticeBadge.tsx
301
+ var import_jsx_runtime7 = require("react/jsx-runtime");
302
+ var NoticeBadge = ({ variable, className, onClick }) => {
303
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
304
+ "button",
305
+ {
306
+ type: "button",
307
+ className: cn(
308
+ // 너비 피그마에서는 fit으로 69px로 되어있는데, 69px로 하면 글자가 잘려서 72px로 잡음. 컨펌 필요
309
+ "w-18 h-8 box-border px-2 py-1 text-center text-body3-book cursor-pointer",
310
+ /** Urgent */
311
+ `${variable === "urgent" ? "bg-black text-white" : ""}`,
312
+ /** Common */
313
+ `${variable === "common" ? "border border-gray03 text-strong" : ""}`,
314
+ //이거 배경 없는 거 맞겠지...?
315
+ className
316
+ ),
317
+ onClick,
318
+ children: variable === "urgent" ? "\uAE34\uAE09 \uACF5\uC9C0" : "\uC77C\uBC18 \uACF5\uC9C0"
319
+ }
320
+ );
321
+ };
322
+
323
+ // src/components/notice/NoticeBar.tsx
324
+ var import_jsx_runtime8 = require("react/jsx-runtime");
325
+ var NoticeBar = ({
326
+ variable = "default",
327
+ badgeVariable,
328
+ title,
329
+ date,
330
+ className,
331
+ onClick
332
+ }) => {
333
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
334
+ "div",
335
+ {
336
+ className: cn(
337
+ "w-full min-w-200 h-15 px-4 py-3.5 flex items-center justify-between box-border border-b border-gray02 cursor-pointer",
338
+ variable === "default" && "bg-white hover:bg-gray00 active:bg-gray01",
339
+ variable === "hover" && "bg-gray00",
340
+ variable === "pressed" && "bg-gray01",
341
+ className
342
+ ),
343
+ onClick,
344
+ children: [
345
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("section", { className: "flex items-center gap-3", children: [
346
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(NoticeBadge, { variable: badgeVariable }),
347
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h1", { className: "text-head1-medium text-strong", children: title })
348
+ ] }),
349
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-body3-book text-tertiary", children: date })
350
+ ]
351
+ }
352
+ );
353
+ };
354
+
355
+ // src/components/SearchBar/SearchBar.tsx
356
+ var import_jsx_runtime9 = require("react/jsx-runtime");
357
+ var SearchBar = ({ value, onChange, className }) => {
358
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
359
+ "label",
360
+ {
361
+ className: cn(
362
+ "w-full h-12 pl-4 pr-3",
363
+ "flex items-center gap-2",
364
+ "box-border border-b border-gray02 border-t border-t-white",
365
+ "focus-within:border-black focus-within:border focus-within:outline-none",
366
+ className
367
+ ),
368
+ children: [
369
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(IconSearch, {}),
370
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
371
+ "input",
372
+ {
373
+ type: "text",
374
+ placeholder: "\uAC80\uC0C9\uC5B4\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694",
375
+ value,
376
+ onChange: (e) => onChange?.(e.target.value),
377
+ className: cn(
378
+ "w-full focus:outline-none",
379
+ "text-body1-book text-strong placeholder:text-quaternary"
380
+ )
381
+ }
382
+ )
383
+ ]
384
+ }
385
+ );
386
+ };
387
+
388
+ // src/components/SideRadioAccordion/SideRadioAccordion.tsx
389
+ var import_react = require("react");
390
+
391
+ // src/components/SideRadioAccordion/Exclamation.svg
392
+ var Exclamation_default = "./Exclamation-IUYZYYC4.svg";
393
+
394
+ // src/components/SideRadioAccordion/ChevronDown.svg
395
+ var ChevronDown_default = "./ChevronDown-XSALXCW4.svg";
396
+
397
+ // src/components/SideRadioAccordion/RadioSelected.svg
398
+ var RadioSelected_default = "./RadioSelected-DOLVV7ZM.svg";
399
+
400
+ // src/components/SideRadioAccordion/RadioUnselected.svg
401
+ var RadioUnselected_default = "./RadioUnselected-QN74EU46.svg";
402
+
403
+ // src/components/SideRadioAccordion/SideRadioAccordion.tsx
404
+ var import_jsx_runtime10 = require("react/jsx-runtime");
405
+ var printColorBgClass = {
406
+ Plotter: "bg-print-plotter",
407
+ Printer: "bg-print-printer",
408
+ Riso: "bg-print-riso",
409
+ Fluorescent: "bg-print-fluorescent",
410
+ UV: "bg-print-uv",
411
+ "Seet Cutting": "bg-print-seet-cutting",
412
+ "Laser Cutting": "bg-print-laser-cutting"
413
+ };
414
+ var SideRadioAccordion = ({
415
+ step,
416
+ title,
417
+ radioToggleList,
418
+ defaultSelected,
419
+ onSelect,
420
+ quantityLimitLabel,
421
+ onClickQuantityLimit,
422
+ className
423
+ }) => {
424
+ const [isOpen, setIsOpen] = (0, import_react.useState)(true);
425
+ const [selected, setSelected] = (0, import_react.useState)(defaultSelected);
426
+ const handleSelect = (itemTitle) => {
427
+ setSelected(itemTitle);
428
+ onSelect?.(itemTitle);
429
+ };
430
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: cn("w-full", className), children: [
431
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
432
+ Stepper,
433
+ {
434
+ step,
435
+ title,
436
+ isOpen,
437
+ onClick: () => setIsOpen((prev) => !prev)
438
+ }
439
+ ),
440
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-col", children: [
441
+ radioToggleList.map((item) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
442
+ RadioToggleItem,
443
+ {
444
+ ...item,
445
+ open: selected === item.title,
446
+ onSelect: () => handleSelect(item.title)
447
+ },
448
+ item.title
449
+ )),
450
+ quantityLimitLabel && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
451
+ TextButton,
452
+ {
453
+ label: quantityLimitLabel,
454
+ onClick: onClickQuantityLimit,
455
+ className: "mt-2"
456
+ }
457
+ )
458
+ ] })
459
+ ] });
460
+ };
461
+ var Stepper = ({ step, title, isOpen, onClick, className }) => {
462
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
463
+ "button",
464
+ {
465
+ type: "button",
466
+ onClick,
467
+ className: cn(
468
+ "w-full flex items-center justify-between px-3 py-2.5",
469
+ "text-body1-medium text-strong text-left cursor-pointer",
470
+ "bg-white hover:bg-gray00 active:bg-gray01",
471
+ className
472
+ ),
473
+ children: [
474
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
475
+ step,
476
+ " | ",
477
+ title
478
+ ] }),
479
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
480
+ "img",
481
+ {
482
+ src: ChevronDown_default,
483
+ alt: "",
484
+ className: cn("transition-transform", isOpen && "rotate-180")
485
+ }
486
+ )
487
+ ]
488
+ }
489
+ );
490
+ };
491
+ var RadioToggleItem = ({
492
+ title,
493
+ content,
494
+ badges,
495
+ printColor,
496
+ labelTextButton,
497
+ onClickTextButton,
498
+ open,
499
+ onSelect,
500
+ className
501
+ }) => {
502
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: cn("w-full", className), children: [
503
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
504
+ "button",
505
+ {
506
+ type: "button",
507
+ onClick: onSelect,
508
+ className: cn(
509
+ "w-full flex items-center gap-1.5 px-3 py-2.5",
510
+ "text-body2-regular text-primary text-left cursor-pointer",
511
+ open ? printColor ? printColorBgClass[printColor] : "bg-gray00" : "bg-white hover:bg-gray00"
512
+ ),
513
+ children: [
514
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Radio, { selected: open }),
515
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: title })
516
+ ]
517
+ }
518
+ ),
519
+ open && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-col gap-2 px-3 py-3 bg-white", children: [
520
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "text-caption-regular text-secondary", children: content }),
521
+ badges && badges.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex gap-1", children: badges.map((badge) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Badge, { label: badge }, badge)) }),
522
+ labelTextButton && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
523
+ TextButton,
524
+ {
525
+ label: labelTextButton,
526
+ onClick: onClickTextButton,
527
+ showIcon: true,
528
+ className: "self-end"
529
+ }
530
+ )
531
+ ] })
532
+ ] });
533
+ };
534
+ var Radio = ({ selected = false, className }) => {
535
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
536
+ "img",
537
+ {
538
+ src: selected ? RadioSelected_default : RadioUnselected_default,
539
+ alt: "",
540
+ className: cn("w-4 h-4", className)
541
+ }
542
+ );
543
+ };
544
+ var TextButton = ({ label, onClick, showIcon = false, className }) => {
545
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
546
+ "button",
547
+ {
548
+ type: "button",
549
+ onClick,
550
+ disabled: !onClick,
551
+ className: cn(
552
+ "w-fit h-fit px-1.5 py-0.5 flex items-center gap-1",
553
+ "text-primary text-caption-regular underline",
554
+ onClick && "cursor-pointer hover:bg-gray00 active:bg-gray01",
555
+ className
556
+ ),
557
+ children: [
558
+ showIcon && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("img", { src: Exclamation_default, alt: "" }),
559
+ label
560
+ ]
561
+ }
562
+ );
563
+ };
564
+ var Badge = ({ label, className }) => {
565
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
566
+ "div",
567
+ {
568
+ className: cn(
569
+ "w-fit h-fit px-2 py-0.5 border border-gray02",
570
+ "text-tertiary text-caption-book",
571
+ className
572
+ ),
573
+ children: label
574
+ }
575
+ );
576
+ };
577
+
578
+ // src/components/Tag/Tag.tsx
579
+ var import_jsx_runtime11 = require("react/jsx-runtime");
580
+ var Tag = ({
581
+ className,
582
+ children,
583
+ selected = false,
584
+ disabled = false,
585
+ bgColor,
586
+ onClick,
587
+ ...props
588
+ }) => {
589
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
590
+ "button",
591
+ {
592
+ className: cn(
593
+ "tag",
594
+ "w-fit h-8 px-2.5",
595
+ "text-primary text-body2-regular transition-colors",
596
+ "box-border border border-gray02",
597
+ "bg-white",
598
+ // bgColor && `bg-[${bgColor}] border-none`,
599
+ onClick && "cursor-pointer hover:bg-gray00 active:bg-gray01 cursor-pointer",
600
+ selected && "text-white bg-black border-black hover:bg-black active:bg-black",
601
+ "disabled:text-gray04 disabled:bg-gray02 disabled:border-gray02 disabled:cursor-not-allowed",
602
+ className
603
+ ),
604
+ onClick,
605
+ disabled,
606
+ style: bgColor ? { backgroundColor: bgColor, border: "none" } : void 0,
607
+ ...props,
608
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children })
609
+ }
610
+ );
611
+ };
612
+
613
+ // src/components/Timetable/dateUtils.ts
614
+ var KOREAN_WEEKDAYS = ["\uC77C", "\uC6D4", "\uD654", "\uC218", "\uBAA9", "\uAE08", "\uD1A0"];
615
+ var parseISODate = (date) => {
616
+ const [year, month, day] = date.split("-").map(Number);
617
+ return new Date(year, month - 1, day);
618
+ };
619
+ var toISODate = (d) => {
620
+ const year = d.getFullYear();
621
+ const month = String(d.getMonth() + 1).padStart(2, "0");
622
+ const day = String(d.getDate()).padStart(2, "0");
623
+ return `${year}-${month}-${day}`;
624
+ };
625
+ var addDays = (date, amount) => {
626
+ const d = parseISODate(date);
627
+ d.setDate(d.getDate() + amount);
628
+ return toISODate(d);
629
+ };
630
+ var formatDayLabel = (date) => {
631
+ const d = parseISODate(date);
632
+ return `${d.getMonth() + 1}\uC6D4 ${d.getDate()}\uC77C(${KOREAN_WEEKDAYS[d.getDay()]})`;
633
+ };
634
+ var formatMMDD = (date) => {
635
+ const d = parseISODate(date);
636
+ return `${String(d.getMonth() + 1).padStart(2, "0")}.${String(d.getDate()).padStart(2, "0")}`;
637
+ };
638
+ var formatWeekRange = (weekStart) => {
639
+ const weekEnd = addDays(weekStart, 4);
640
+ return `${formatMMDD(weekStart)} ~ ${formatMMDD(weekEnd)}`;
641
+ };
642
+
643
+ // src/components/Timetable/WeekNavigation.tsx
644
+ var import_jsx_runtime12 = require("react/jsx-runtime");
645
+ var weekLabel = {
646
+ thisWeek: "\uC774\uBC88 \uC8FC",
647
+ nextWeek: "\uB2E4\uC74C \uC8FC",
648
+ twoWeeksLater: "\uB2E4\uB2E4\uC74C \uC8FC"
649
+ };
650
+ var WeekNavigation = ({
651
+ date,
652
+ week,
653
+ onPrevWeek,
654
+ onNextWeek,
655
+ className
656
+ }) => {
657
+ const showPrev = week !== "thisWeek";
658
+ const showNext = week !== "twoWeeksLater";
659
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
660
+ "div",
661
+ {
662
+ className: cn(
663
+ "flex items-center justify-between",
664
+ "w-full h-11 px-3",
665
+ "bg-white border border-gray02",
666
+ "text-body2-regular text-primary",
667
+ className
668
+ ),
669
+ children: [
670
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ArrowButton, { direction: "left", visible: showPrev, onClick: onPrevWeek }),
671
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { children: [
672
+ weekLabel[week],
673
+ " (",
674
+ formatWeekRange(date),
675
+ ")"
676
+ ] }),
677
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ArrowButton, { direction: "right", visible: showNext, onClick: onNextWeek })
678
+ ]
679
+ }
680
+ );
681
+ };
682
+ var ArrowButton = ({ direction, visible, onClick }) => {
683
+ if (!visible) {
684
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "w-6 h-6" });
685
+ }
686
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
687
+ "button",
688
+ {
689
+ type: "button",
690
+ onClick,
691
+ className: cn(
692
+ "flex items-center justify-center w-6 h-6",
693
+ "text-gray06 cursor-pointer",
694
+ "hover:bg-gray00 active:bg-gray01"
695
+ ),
696
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
697
+ IconChevronDownXS,
698
+ {
699
+ className: direction === "left" ? "rotate-90" : "-rotate-90",
700
+ stroke: "currentColor"
701
+ }
702
+ )
703
+ }
704
+ );
705
+ };
706
+
707
+ // src/components/Timetable/Timetable.tsx
708
+ var import_jsx_runtime13 = require("react/jsx-runtime");
709
+ var printColorHoverClass = {
710
+ Plotter: "hover:bg-print-plotter",
711
+ Printer: "hover:bg-print-printer",
712
+ Riso: "hover:bg-print-riso",
713
+ Fluorescent: "hover:bg-print-fluorescent",
714
+ UV: "hover:bg-print-uv",
715
+ "Seet Cutting": "hover:bg-print-seet-cutting",
716
+ "Laser Cutting": "hover:bg-print-laser-cutting"
717
+ };
718
+ var Timetable = ({
719
+ weekStart,
720
+ week,
721
+ days,
722
+ onPrevWeek,
723
+ onNextWeek,
724
+ onSelectSlot,
725
+ className
726
+ }) => {
727
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: cn(className), children: [
728
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
729
+ WeekNavigation,
730
+ {
731
+ date: weekStart,
732
+ week,
733
+ onPrevWeek,
734
+ onNextWeek
735
+ }
736
+ ),
737
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "flex", children: days.map((day) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
738
+ DailyTimetable,
739
+ {
740
+ date: day.date,
741
+ slots: day.slots,
742
+ onSelectTime: onSelectSlot ? (time) => onSelectSlot(day.date, time) : void 0
743
+ },
744
+ day.date
745
+ )) })
746
+ ] });
747
+ };
748
+ var DailyTimetable = ({ date, slots, onSelectTime, className }) => {
749
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: cn("flex flex-col", className), children: [
750
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "h-13 flex items-center justify-center text-body3-medium text-secondary", children: formatDayLabel(date) }),
751
+ slots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
752
+ TimeItem,
753
+ {
754
+ state: slot.state,
755
+ label: slot.time,
756
+ printColor: slot.printColor,
757
+ onClick: onSelectTime ? () => onSelectTime(slot.time) : void 0
758
+ },
759
+ slot.time
760
+ ))
761
+ ] });
762
+ };
763
+ var TimeItem = ({ state, label, printColor, onClick, className }) => {
764
+ const clickable = (state === "default" || state === "selected") && !!onClick;
765
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
766
+ "div",
767
+ {
768
+ onClick: clickable ? onClick : void 0,
769
+ className: cn(
770
+ "w-18 h-18 flex items-center justify-center",
771
+ "text-body1-medium text-center bg-white text-primary",
772
+ state === "none" && "bg-gray00 text-transparent",
773
+ state === "selected" && "bg-black text-gray02 hover:cursor-pointer",
774
+ state === "disabled" && "bg-gray00 text-gray03",
775
+ state === "default" && [
776
+ "hover:cursor-pointer",
777
+ printColor ? printColorHoverClass[printColor] : "hover:bg-gray00"
778
+ ],
779
+ className
780
+ ),
781
+ children: label
782
+ }
783
+ );
784
+ };
785
+
786
+ // src/components/TNB/TNB.tsx
787
+ var import_react2 = require("react");
788
+ var import_jsx_runtime14 = require("react/jsx-runtime");
789
+ var TNB = ({
790
+ logo,
791
+ upperPartItemList,
792
+ upperPartIconList,
793
+ defaultSelected,
794
+ onSelectItem,
795
+ className
796
+ }) => {
797
+ const [selected, setSelected] = (0, import_react2.useState)(defaultSelected ?? upperPartItemList[0]?.label);
798
+ const [selectedLower, setSelectedLower] = (0, import_react2.useState)(
799
+ upperPartItemList.find((item) => item.label === selected)?.lowerPartItemList[0]?.label
800
+ );
801
+ const handleSelectUpper = (label) => {
802
+ setSelected(label);
803
+ setSelectedLower(
804
+ upperPartItemList.find((item) => item.label === label)?.lowerPartItemList[0]?.label
805
+ );
806
+ onSelectItem?.(label);
807
+ };
808
+ const currentLowerItemList = upperPartItemList.find((item) => item.label === selected)?.lowerPartItemList ?? [];
809
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("nav", { className: cn("w-full bg-white", className), children: [
810
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
811
+ UpperPart,
812
+ {
813
+ logo,
814
+ upperPartItemList,
815
+ upperPartIconList,
816
+ selected,
817
+ onSelectItem: handleSelectUpper
818
+ }
819
+ ),
820
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
821
+ LowerPart,
822
+ {
823
+ lowerPartItemList: currentLowerItemList,
824
+ selected: selectedLower,
825
+ onSelectItem: setSelectedLower
826
+ }
827
+ )
828
+ ] });
829
+ };
830
+ var UpperPart = ({
831
+ logo,
832
+ upperPartItemList,
833
+ upperPartIconList,
834
+ selected,
835
+ onSelectItem,
836
+ className
837
+ }) => {
838
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: cn("w-full h-13 px-4 flex items-center justify-between", className), children: [
839
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-6", children: [
840
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(NavIconButton, { ...logo }),
841
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "flex items-center gap-4", children: upperPartItemList.map((item) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
842
+ UpperPartTab,
843
+ {
844
+ label: item.label,
845
+ selected: item.label === selected,
846
+ onClick: () => onSelectItem(item.label)
847
+ },
848
+ item.label
849
+ )) })
850
+ ] }),
851
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "flex items-center gap-2", children: upperPartIconList.map((icon) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(NavIconButton, { ...icon }, icon.src)) })
852
+ ] });
853
+ };
854
+ var UpperPartTab = ({ label, selected, onClick, className }) => {
855
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
856
+ "button",
857
+ {
858
+ type: "button",
859
+ onClick,
860
+ className: cn(
861
+ "px-1 py-1.5 text-body2-regular cursor-pointer",
862
+ selected ? "text-strong font-medium underline underline-offset-4" : "text-quaternary hover:text-secondary",
863
+ className
864
+ ),
865
+ children: label
866
+ }
867
+ );
868
+ };
869
+ var NavIconButton = ({ src, alt, onClick, selected, className }) => {
870
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
871
+ "button",
872
+ {
873
+ type: "button",
874
+ onClick,
875
+ disabled: !onClick,
876
+ className: cn(
877
+ "w-8 h-8 flex items-center justify-center rounded-full",
878
+ onClick && "cursor-pointer",
879
+ selected ? "bg-black" : "bg-transparent hover:bg-gray00 active:bg-gray01",
880
+ className
881
+ ),
882
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("img", { src, alt: alt ?? "", className: "w-5 h-5" })
883
+ }
884
+ );
885
+ };
886
+ var LowerPart = ({ lowerPartItemList, selected, onSelectItem, className }) => {
887
+ if (lowerPartItemList.length === 0) {
888
+ return null;
889
+ }
890
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
891
+ "div",
892
+ {
893
+ className: cn("w-full h-9 px-4 flex items-center gap-4 border-t border-gray02", className),
894
+ children: lowerPartItemList.map((item) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
895
+ LowerPartItemButton,
896
+ {
897
+ label: item.label,
898
+ selected: item.label === selected,
899
+ onClick: () => {
900
+ item.onClick?.();
901
+ onSelectItem(item.label);
902
+ }
903
+ },
904
+ item.label
905
+ ))
906
+ }
907
+ );
908
+ };
909
+ var LowerPartItemButton = ({ label, selected, onClick, className }) => {
910
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
911
+ "button",
912
+ {
913
+ type: "button",
914
+ onClick,
915
+ className: cn(
916
+ "px-1.5 py-1 text-caption-regular cursor-pointer",
917
+ "hover:bg-gray00 active:bg-gray01",
918
+ selected ? "text-strong font-medium" : "text-quaternary",
919
+ className
920
+ ),
921
+ children: label
922
+ }
923
+ );
924
+ };
925
+
926
+ // src/components/Toast/Toast.tsx
927
+ var import_jsx_runtime15 = require("react/jsx-runtime");
928
+ var Toast = ({ message, className }) => {
929
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
930
+ "div",
931
+ {
932
+ className: cn(
933
+ `bg-gray06 w-dvw h-fit py-2.5`,
934
+ `font-pretendard text-white text-center font-semibold text-[17px]`,
935
+ `shadow-[0_2px_15px_rgba(0,0,0,0.18)]`,
936
+ className
937
+ ),
938
+ children: message
939
+ }
940
+ );
941
+ };
88
942
  // Annotate the CommonJS export names for ESM import in node:
89
943
  0 && (module.exports = {
90
- CTA
944
+ BackButton,
945
+ CTA,
946
+ CategorySegment,
947
+ CategorySegmentedControl,
948
+ NoticeBadge,
949
+ NoticeBar,
950
+ SearchBar,
951
+ SideRadioAccordion,
952
+ TNB,
953
+ Tag,
954
+ Timetable,
955
+ TitleInput,
956
+ Toast,
957
+ WeekNavigation
91
958
  });
92
959
  //# sourceMappingURL=index.js.map