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