@kusitms/ui 0.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 ADDED
@@ -0,0 +1,1315 @@
1
+ import { ToggleOpenSIcon, ArrowRightIcon, ArrowRightMIcon, RightSIcon, SnowGraphic, CancelMIcon, KeyboardArrowLeftIcon, KeyboardArrowRightIcon, KeyboardDoubleArrowLeftIcon, KeyboardDoubleArrowRightIcon, LinkIcon, GithubIcon, BehanceIcon } from '@kusitms/icons';
2
+ import * as RadixAccordion from '@radix-ui/react-accordion';
3
+ import { useRef, useState, useEffect, useId, Children, isValidElement, cloneElement, useCallback } from 'react';
4
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
+ import * as RadixSelect from '@radix-ui/react-select';
6
+
7
+ // src/components/Accordion/Accordion.tsx
8
+
9
+ // src/utils/cn.ts
10
+ function cn(...values) {
11
+ return values.filter(Boolean).join(" ");
12
+ }
13
+ function AccordionRoot({ className, children, ...props }) {
14
+ return /* @__PURE__ */ jsx(
15
+ RadixAccordion.Root,
16
+ {
17
+ className: cn("flex w-full flex-col gap-2 lg:gap-3", className),
18
+ ...props,
19
+ children
20
+ }
21
+ );
22
+ }
23
+ function AccordionItem({
24
+ value,
25
+ question,
26
+ answer,
27
+ className
28
+ }) {
29
+ const itemRef = useRef(null);
30
+ const innerRef = useRef(null);
31
+ const [isOpen, setIsOpen] = useState(false);
32
+ const [height, setHeight] = useState(0);
33
+ useEffect(() => {
34
+ const item = itemRef.current;
35
+ if (!item) return;
36
+ const update = () => {
37
+ const open = item.getAttribute("data-state") === "open";
38
+ setIsOpen(open);
39
+ setHeight(open ? innerRef.current?.scrollHeight ?? 0 : 0);
40
+ };
41
+ update();
42
+ const observer = new MutationObserver(update);
43
+ observer.observe(item, {
44
+ attributes: true,
45
+ attributeFilter: ["data-state"]
46
+ });
47
+ return () => observer.disconnect();
48
+ }, []);
49
+ return /* @__PURE__ */ jsxs(
50
+ RadixAccordion.Item,
51
+ {
52
+ ref: itemRef,
53
+ value,
54
+ className: cn(
55
+ "w-full bg-fill-netural",
56
+ "rounded-2xl px-5 py-4",
57
+ "lg:rounded-5 lg:px-10 lg:py-8",
58
+ className
59
+ ),
60
+ children: [
61
+ /* @__PURE__ */ jsx(RadixAccordion.Header, { className: "flex", children: /* @__PURE__ */ jsxs(
62
+ RadixAccordion.Trigger,
63
+ {
64
+ className: cn(
65
+ "group flex w-full cursor-pointer items-center justify-between gap-2 text-left outline-none",
66
+ "focus-visible:rounded-md focus-visible:ring-2 focus-visible:ring-brand-primary/40"
67
+ ),
68
+ children: [
69
+ /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-1 items-start gap-1 lg:items-center lg:gap-2", children: [
70
+ /* @__PURE__ */ jsx("span", { className: "shrink-0 text-center text-body-18sb text-brand-primary lg:w-5.75 lg:pb-1 lg:text-headline-24sb", children: "Q." }),
71
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 pt-0.5 text-body-16m text-label-normal lg:pt-0 lg:text-headline-24sb", children: question })
72
+ ] }),
73
+ /* @__PURE__ */ jsx(
74
+ ToggleOpenSIcon,
75
+ {
76
+ "aria-hidden": true,
77
+ className: cn(
78
+ "shrink-0 text-label-normal transition-transform duration-200",
79
+ "size-5 lg:size-6",
80
+ "group-data-[state=open]:-rotate-180"
81
+ )
82
+ }
83
+ )
84
+ ]
85
+ }
86
+ ) }),
87
+ /* @__PURE__ */ jsx(RadixAccordion.Content, { forceMount: true, children: /* @__PURE__ */ jsx(
88
+ "div",
89
+ {
90
+ style: {
91
+ height,
92
+ overflow: "hidden",
93
+ opacity: isOpen ? 1 : 0,
94
+ transition: [
95
+ `height ${isOpen ? 300 : 500}ms cubic-bezier(0.4, 0, 0.2, 1)`,
96
+ `opacity ${isOpen ? 200 : 400}ms`
97
+ ].join(", ")
98
+ },
99
+ children: /* @__PURE__ */ jsx(
100
+ "div",
101
+ {
102
+ ref: innerRef,
103
+ className: "whitespace-pre-line pt-3 text-body-16r text-label-netural lg:text-headline-20r",
104
+ children: answer
105
+ }
106
+ )
107
+ }
108
+ ) })
109
+ ]
110
+ }
111
+ );
112
+ }
113
+ var Accordion = Object.assign(AccordionRoot, {
114
+ Item: AccordionItem
115
+ });
116
+ function getChipClasses(type) {
117
+ switch (type) {
118
+ case "brand":
119
+ return cn(
120
+ "inline-flex items-center justify-center rounded px-4 py-1",
121
+ "bg-fill-primary text-brand-primary text-label-14sb whitespace-nowrap lg:w-16 lg:h-8"
122
+ );
123
+ case "secondary":
124
+ return cn(
125
+ "inline-flex items-center justify-center rounded-md px-3 py-1",
126
+ "bg-fill-netural text-label-alternative",
127
+ "text-caption-12sb lg:text-label-14sb whitespace-nowrap"
128
+ );
129
+ }
130
+ }
131
+ function Label({
132
+ children,
133
+ className,
134
+ type = "brand",
135
+ description,
136
+ ...props
137
+ }) {
138
+ if (type === "default") {
139
+ return /* @__PURE__ */ jsxs(
140
+ "span",
141
+ {
142
+ className: cn("inline-flex self-start items-center gap-2.5", className),
143
+ ...props,
144
+ children: [
145
+ /* @__PURE__ */ jsx(
146
+ "span",
147
+ {
148
+ className: cn(
149
+ "inline-flex h-7.5 w-20 items-center justify-center rounded-sm bg-fill-netural",
150
+ "text-label-normal text-label-14sb whitespace-nowrap"
151
+ ),
152
+ children
153
+ }
154
+ ),
155
+ description != null && description !== "" && /* @__PURE__ */ jsx("span", { className: "text-label-alternative text-label-14m whitespace-nowrap", children: description })
156
+ ]
157
+ }
158
+ );
159
+ }
160
+ return /* @__PURE__ */ jsx(
161
+ "span",
162
+ {
163
+ className: cn(getChipClasses(type), "self-start", className),
164
+ ...props,
165
+ children
166
+ }
167
+ );
168
+ }
169
+ function Blog({ imageUrl, title, content, labels }) {
170
+ return /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-row gap-3 lg:gap-7 pb-5 lg:pb-8 px-4 lg:pr-8 lg:pl-0", children: [
171
+ /* @__PURE__ */ jsx("div", { className: "size-26 lg:w-60 lg:h-41 rounded-lg bg-fill-netural shrink-0 self-stretch overflow-hidden", children: /* @__PURE__ */ jsx(
172
+ "img",
173
+ {
174
+ src: imageUrl,
175
+ alt: title,
176
+ className: "block h-full w-full object-cover"
177
+ }
178
+ ) }),
179
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col gap-2 lg:gap-4 py-1", children: [
180
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5 lg:gap-1", children: [
181
+ /* @__PURE__ */ jsx("p", { className: "text-body-16b text-label-netural lg:text-headline-20b line-clamp-1", children: title }),
182
+ /* @__PURE__ */ jsx("p", { className: "h-10 lg:h-13 text-label-14m text-label-alternative lg:text-body-16m line-clamp-2", children: content })
183
+ ] }),
184
+ labels.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-row flex-wrap gap-1 lg:gap-2", children: labels.map((label) => /* @__PURE__ */ jsx(Label, { type: "secondary", children: label }, label)) })
185
+ ] })
186
+ ] });
187
+ }
188
+ function BottomGradient({
189
+ height = 54,
190
+ className,
191
+ style,
192
+ ...props
193
+ }) {
194
+ return /* @__PURE__ */ jsx(
195
+ "div",
196
+ {
197
+ className: `absolute bottom-0 left-1/2 -translate-x-1/2 w-full pointer-events-none ${className ?? ""}`,
198
+ style: { height: `${height}px`, ...style },
199
+ ...props,
200
+ children: /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-linear-to-b from-transparent to-white rounded-b-2xl" })
201
+ }
202
+ );
203
+ }
204
+ function Button({
205
+ children,
206
+ className,
207
+ disabled,
208
+ showIcon = true,
209
+ ...props
210
+ }) {
211
+ return /* @__PURE__ */ jsxs(
212
+ "button",
213
+ {
214
+ type: "button",
215
+ disabled,
216
+ className: cn(
217
+ "group relative overflow-hidden inline-flex items-center justify-center rounded-full transition-colors",
218
+ "py-2 px-3 gap-1 lg:px-6 lg:gap-2",
219
+ disabled ? "text-label-14r lg:text-body-18m bg-fill-alternative text-label-light cursor-not-allowed" : "text-label-14m lg:text-body-18sb bg-brand-primary text-label-contrast cursor-pointer",
220
+ className
221
+ ),
222
+ ...props,
223
+ children: [
224
+ !disabled && /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute inset-0 bg-white/0 transition-colors group-hover:bg-white/25 group-active:bg-black/8" }),
225
+ /* @__PURE__ */ jsx("span", { className: showIcon ? "pl-2" : void 0, children }),
226
+ showIcon && /* @__PURE__ */ jsxs(Fragment, { children: [
227
+ /* @__PURE__ */ jsx(
228
+ ArrowRightIcon,
229
+ {
230
+ className: cn(
231
+ "size-5 shrink-0 lg:hidden",
232
+ disabled ? "text-label-light" : "text-label-contrast"
233
+ )
234
+ }
235
+ ),
236
+ /* @__PURE__ */ jsx(
237
+ ArrowRightMIcon,
238
+ {
239
+ className: cn(
240
+ "size-6 shrink-0 hidden lg:block",
241
+ disabled ? "text-label-light" : "text-label-contrast"
242
+ )
243
+ }
244
+ )
245
+ ] })
246
+ ]
247
+ }
248
+ );
249
+ }
250
+ function NavigationButton({
251
+ children,
252
+ className,
253
+ icon,
254
+ showArrow = true,
255
+ ...props
256
+ }) {
257
+ return /* @__PURE__ */ jsxs(
258
+ "button",
259
+ {
260
+ type: "button",
261
+ className: cn(
262
+ "group relative inline-flex items-center overflow-hidden rounded-lg bg-fill-netural pl-3 pr-2 py-2 gap-2 text-label-netural transition-colors cursor-pointer",
263
+ className
264
+ ),
265
+ ...props,
266
+ children: [
267
+ /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute inset-0 rounded-lg bg-transparent transition-colors group-hover:bg-interaction-hover-inverse" }),
268
+ icon ? /* @__PURE__ */ jsx("span", { className: "relative z-10 inline-flex size-5 shrink-0 items-center justify-center overflow-hidden", children: icon }) : null,
269
+ /* @__PURE__ */ jsx(
270
+ "span",
271
+ {
272
+ className: cn(
273
+ "relative z-10 flex-1 text-left text-body-16m",
274
+ !showArrow && "pr-1"
275
+ ),
276
+ children
277
+ }
278
+ ),
279
+ showArrow ? /* @__PURE__ */ jsx(
280
+ RightSIcon,
281
+ {
282
+ "aria-hidden": "true",
283
+ className: "relative z-10 size-5 shrink-0 text-label-alternative"
284
+ }
285
+ ) : null
286
+ ]
287
+ }
288
+ );
289
+ }
290
+ function PageNavButton({
291
+ className,
292
+ color = "light",
293
+ direction = "next",
294
+ ...props
295
+ }) {
296
+ return /* @__PURE__ */ jsxs(
297
+ "button",
298
+ {
299
+ type: "button",
300
+ "aria-label": direction === "next" ? "\uB2E4\uC74C \uD398\uC774\uC9C0\uB85C \uC774\uB3D9" : "\uC774\uC804 \uD398\uC774\uC9C0\uB85C \uC774\uB3D9",
301
+ className: cn(
302
+ "group relative inline-flex items-center justify-center overflow-hidden rounded-full transition-colors cursor-pointer",
303
+ "size-9 lg:size-13",
304
+ color === "light" ? "bg-fill-transparent-white text-static-white" : "bg-fill-transparent-black text-static-white",
305
+ direction === "prev" ? "rotate-180" : void 0,
306
+ className
307
+ ),
308
+ ...props,
309
+ children: [
310
+ /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute inset-0 rounded-full bg-transparent transition-colors group-active:bg-interaction-pressed" }),
311
+ /* @__PURE__ */ jsx(RightSIcon, { className: "relative z-10 size-7 lg:size-10 translate-x-px" })
312
+ ]
313
+ }
314
+ );
315
+ }
316
+ function ScrollTopButton({ className, ...props }) {
317
+ return /* @__PURE__ */ jsx(
318
+ "button",
319
+ {
320
+ type: "button",
321
+ "aria-label": "\uB9E8 \uC704\uB85C \uC774\uB3D9",
322
+ className: cn(
323
+ "group relative inline-flex items-center justify-center overflow-hidden rounded-full border transition-colors cursor-pointer",
324
+ "size-10 lg:size-12",
325
+ "border-line-neutral bg-fill-normal text-static-black active:bg-interaction-pressed",
326
+ className
327
+ ),
328
+ ...props,
329
+ children: /* @__PURE__ */ jsx(ArrowRightIcon, { "aria-hidden": true, className: "-rotate-90 size-5 lg:size-6" })
330
+ }
331
+ );
332
+ }
333
+ var variantStyles = {
334
+ default: {
335
+ container: "w-75 gap-5 px-4 pt-7 pb-9.5 pt-8.5 lg:pb-8.5 lg:pt-7.5",
336
+ content: ({ description }) => /* @__PURE__ */ jsx("p", { className: "text-label-14sb text-label-normal lg:text-body-16sb text-center whitespace-pre-line", children: description })
337
+ },
338
+ titled: {
339
+ container: "w-75 lg:w-55 gap-5 px-4 py-5 lg:pb-6.5",
340
+ content: ({ title, description }) => /* @__PURE__ */ jsx("div", { className: "flex flex-col items-center gap-5 text-center lg:gap-4.5", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 lg:gap-2.5", children: [
341
+ /* @__PURE__ */ jsx("p", { className: "text-brand-primary text-body-16b lg:text-body-18b", children: title }),
342
+ /* @__PURE__ */ jsx("div", { className: "w-3.5 h-[1.5px] bg-line-normal rounded-full mx-auto" }),
343
+ /* @__PURE__ */ jsx("p", { className: "text-label-normal text-label-14m whitespace-pre-line", children: description })
344
+ ] }) })
345
+ }
346
+ };
347
+ function RecruitmentCard({
348
+ type,
349
+ graphic: Graphic,
350
+ title,
351
+ description
352
+ }) {
353
+ const { container, content } = variantStyles[type];
354
+ return /* @__PURE__ */ jsxs(
355
+ "div",
356
+ {
357
+ className: `flex flex-col items-center rounded-2xl bg-fill-primary ${container}`,
358
+ children: [
359
+ /* @__PURE__ */ jsx("div", { className: "flex size-20 shrink-0 items-center justify-center rounded-full bg-fill-normal", children: /* @__PURE__ */ jsx(Graphic, {}) }),
360
+ content({ title, description })
361
+ ]
362
+ }
363
+ );
364
+ }
365
+ function ReviewCard({ name, part, body }) {
366
+ return /* @__PURE__ */ jsxs("div", { className: "w-72 lg:w-76 flex flex-col rounded-2xl bg-fill-primary p-5", children: [
367
+ /* @__PURE__ */ jsx("p", { className: "text-body-16b text-label-normal pb-1 lg:text-body-18b", children: name }),
368
+ /* @__PURE__ */ jsx("p", { className: "text-label-14sb text-brand-primary pb-3", children: part }),
369
+ /* @__PURE__ */ jsx("p", { className: "text-label-14m text-label-netural", children: body })
370
+ ] });
371
+ }
372
+ function ShowcaseCard({
373
+ name,
374
+ description,
375
+ th,
376
+ isMeetup = false,
377
+ type,
378
+ imageUrl
379
+ }) {
380
+ return /* @__PURE__ */ jsxs("div", { className: "flex w-85.75 lg:w-96 shrink-0 self-start flex-col rounded-2xl bg-fill-normal shadow-[0_1px_10px_0_rgba(179,179,188,0.25)]", children: [
381
+ /* @__PURE__ */ jsx("div", { className: "h-47.5 lg:h-64 w-full shrink-0 overflow-hidden rounded-t-2xl bg-fill-alternative", children: /* @__PURE__ */ jsx(
382
+ "img",
383
+ {
384
+ src: imageUrl,
385
+ alt: name,
386
+ className: "block h-full w-full object-cover"
387
+ }
388
+ ) }),
389
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col px-4 pt-4 pb-4.5 lg:px-5 lg:pb-5", children: [
390
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 mb-1", children: [
391
+ /* @__PURE__ */ jsxs("span", { className: "text-label-14b text-brand-primary lg:text-body-18b", children: [
392
+ th,
393
+ "\uAE30"
394
+ ] }),
395
+ isMeetup && /* @__PURE__ */ jsxs("div", { className: "flex flex-row gap-1.25 text-label-assitive text-caption-12r", children: [
396
+ /* @__PURE__ */ jsx("span", { children: "\xB7" }),
397
+ /* @__PURE__ */ jsx("span", { className: "lg:text-body-16m", children: type })
398
+ ] })
399
+ ] }),
400
+ /* @__PURE__ */ jsx("p", { className: "text-label-netural text-body-16b mb-0.5 lg:text-headline-20b", children: name }),
401
+ /* @__PURE__ */ jsx("div", { className: "h-10 lg:h-13 overflow-hidden shrink-0", children: /* @__PURE__ */ jsx("p", { className: "text-label-14m text-label-alternative lg:text-body-18m line-clamp-2", children: description }) })
402
+ ] })
403
+ ] });
404
+ }
405
+ function Dropdown({
406
+ options,
407
+ value,
408
+ defaultValue,
409
+ onValueChange,
410
+ placeholder = "\uC120\uD0DD",
411
+ disabled = false,
412
+ className
413
+ }) {
414
+ return /* @__PURE__ */ jsxs(
415
+ RadixSelect.Root,
416
+ {
417
+ value,
418
+ defaultValue,
419
+ onValueChange,
420
+ disabled,
421
+ children: [
422
+ /* @__PURE__ */ jsxs(
423
+ RadixSelect.Trigger,
424
+ {
425
+ className: cn(
426
+ "group flex cursor-pointer items-center gap-x-2 bg-fill-normal outline-none",
427
+ "border border-line-neutral",
428
+ "rounded-md py-1.5 pl-3 pr-2",
429
+ "lg:rounded-lg lg:py-2.5 lg:pl-5 lg:pr-4",
430
+ "text-label-14sb lg:text-body-18sb text-label-light",
431
+ "disabled:cursor-not-allowed disabled:opacity-40",
432
+ className
433
+ ),
434
+ "aria-label": placeholder,
435
+ children: [
436
+ /* @__PURE__ */ jsx(RadixSelect.Value, { placeholder }),
437
+ /* @__PURE__ */ jsx(RadixSelect.Icon, { asChild: true, children: /* @__PURE__ */ jsx(
438
+ ToggleOpenSIcon,
439
+ {
440
+ className: cn(
441
+ "shrink-0 text-label-light transition-transform duration-200",
442
+ "size-4 lg:size-5",
443
+ "group-data-[state=open]:-rotate-180"
444
+ )
445
+ }
446
+ ) })
447
+ ]
448
+ }
449
+ ),
450
+ /* @__PURE__ */ jsx(RadixSelect.Portal, { children: /* @__PURE__ */ jsx(
451
+ RadixSelect.Content,
452
+ {
453
+ position: "popper",
454
+ sideOffset: 4,
455
+ className: cn(
456
+ "z-50 min-w-[var(--radix-select-trigger-width)]",
457
+ "bg-fill-normal rounded-lg p-1",
458
+ "shadow-[0px_1px_10px_rgba(179,179,188,0.25)]",
459
+ "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
460
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
461
+ "data-[side=bottom]:slide-in-from-top-2"
462
+ ),
463
+ children: /* @__PURE__ */ jsx(RadixSelect.Viewport, { children: options.map((option) => /* @__PURE__ */ jsx(
464
+ RadixSelect.Item,
465
+ {
466
+ value: option.value,
467
+ className: cn(
468
+ "flex cursor-pointer items-center rounded-md outline-none select-none",
469
+ "text-label-alternative text-label-14m lg:text-body-18m",
470
+ "p-2 lg:px-3 lg:py-2",
471
+ "data-[state=checked]:text-brand-primary data-[state=checked]:text-label-14sb lg:data-[state=checked]:text-body-18sb",
472
+ "data-[highlighted]:bg-fill-netural data-[highlighted]:outline-none"
473
+ ),
474
+ children: /* @__PURE__ */ jsx(RadixSelect.ItemText, { children: option.label })
475
+ },
476
+ option.value
477
+ )) })
478
+ }
479
+ ) })
480
+ ]
481
+ }
482
+ );
483
+ }
484
+ function EmailInput({
485
+ value,
486
+ onChange,
487
+ onSubmit,
488
+ validate,
489
+ buttonLabel = "\uC54C\uB9BC \uBC1B\uAE30",
490
+ buttonProps,
491
+ disabled,
492
+ className,
493
+ placeholder = "\uC774\uBA54\uC77C\uC744 \uC785\uB825\uD558\uC138\uC694",
494
+ ...inputProps
495
+ }) {
496
+ const canSubmit = !disabled && (validate ? validate(value) : value.length > 0);
497
+ const handleSubmit = () => {
498
+ if (!canSubmit) return;
499
+ onSubmit?.(value);
500
+ };
501
+ const handleKeyDown = (event) => {
502
+ if (event.key === "Enter") {
503
+ event.preventDefault();
504
+ handleSubmit();
505
+ }
506
+ };
507
+ return /* @__PURE__ */ jsxs(
508
+ "div",
509
+ {
510
+ className: cn(
511
+ "flex items-center rounded-full bg-fill-netural",
512
+ "w-full gap-1 py-2 pl-5 pr-2.5 min-w-72",
513
+ "lg:w-163 lg:gap-2 lg:py-3 lg:pl-7 lg:pr-5",
514
+ className
515
+ ),
516
+ children: [
517
+ /* @__PURE__ */ jsx(
518
+ "input",
519
+ {
520
+ type: "email",
521
+ value,
522
+ onChange: (event) => onChange(event.target.value),
523
+ onKeyDown: handleKeyDown,
524
+ disabled,
525
+ placeholder,
526
+ className: cn(
527
+ "min-w-0 flex-1 bg-transparent outline-none",
528
+ "text-label-strong placeholder:text-label-alternative",
529
+ "disabled:cursor-not-allowed",
530
+ "text-body-16m lg:text-headline-20m"
531
+ ),
532
+ ...inputProps
533
+ }
534
+ ),
535
+ /* @__PURE__ */ jsx(
536
+ Button,
537
+ {
538
+ showIcon: false,
539
+ disabled: !canSubmit,
540
+ onClick: handleSubmit,
541
+ className: "shrink-0",
542
+ ...buttonProps,
543
+ children: buttonLabel
544
+ }
545
+ )
546
+ ]
547
+ }
548
+ );
549
+ }
550
+ var defaultBylawsLink = (device, href, label = "\uD559\uD68C\uC815\uAD00") => {
551
+ const className = cn(
552
+ "font-sans not-italic text-label-normal",
553
+ device === "desktop" ? "text-body-16sb" : "text-caption-12r"
554
+ );
555
+ if (!href) {
556
+ return /* @__PURE__ */ jsx("span", { className, children: label });
557
+ }
558
+ return /* @__PURE__ */ jsx("a", { className: `${className} underline decoration-solid`, href, children: label });
559
+ };
560
+ function Footer({
561
+ logo,
562
+ mobileLogo,
563
+ links,
564
+ contactIcons,
565
+ copyright = "KUSITMS (\uD050\uC2DC\uC998, \uD55C\uAD6D\uB300\uD559\uC0DDIT\uACBD\uC601\uD559\uD68C)\n\xA9 2023.KUSITMS. ALL rights reserved.",
566
+ scrollTopButton,
567
+ bylawsHref,
568
+ bylawsLabel = "\uD559\uD68C\uC815\uAD00",
569
+ className,
570
+ ...props
571
+ }) {
572
+ return /* @__PURE__ */ jsxs("footer", { className: cn("w-full", "bg-fill-normal", className), ...props, children: [
573
+ /* @__PURE__ */ jsx("div", { className: "hidden w-full flex-col items-center justify-center px-10 pb-15 lg:flex", children: /* @__PURE__ */ jsxs("div", { className: "flex w-full items-end justify-between", children: [
574
+ /* @__PURE__ */ jsxs("div", { className: "flex w-68.5 flex-col items-start", children: [
575
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col items-start pb-10 pt-15", children: logo }),
576
+ /* @__PURE__ */ jsx("div", { className: "flex w-full pb-3", children: links ?? defaultBylawsLink("desktop", bylawsHref, bylawsLabel) }),
577
+ /* @__PURE__ */ jsx("p", { className: "whitespace-pre-wrap font-sans text-body-16sb text-label-normal", children: copyright })
578
+ ] }),
579
+ /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 flex-col items-start gap-5", children: [
580
+ /* @__PURE__ */ jsx("p", { className: "w-full font-sans text-body-16sb text-label-normal", children: "Contact" }),
581
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-5", children: contactIcons })
582
+ ] })
583
+ ] }) }),
584
+ /* @__PURE__ */ jsx("div", { className: "flex w-full flex-col items-center justify-center px-4 pb-15 lg:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col items-start", children: [
585
+ /* @__PURE__ */ jsx("div", { className: "flex w-full flex-col items-start", children: /* @__PURE__ */ jsxs("div", { className: "flex w-full items-start justify-between gap-4", children: [
586
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col items-start", children: [
587
+ /* @__PURE__ */ jsx("div", { className: "pb-4 pt-15", children: mobileLogo ?? logo }),
588
+ /* @__PURE__ */ jsx("div", { className: "pb-2", children: links ?? defaultBylawsLink("mobile", bylawsHref, bylawsLabel) }),
589
+ /* @__PURE__ */ jsx("p", { className: "w-full whitespace-pre-wrap font-sans text-caption-12r text-label-normal", children: copyright })
590
+ ] }),
591
+ /* @__PURE__ */ jsx("div", { className: "shrink-0 pt-13", children: scrollTopButton })
592
+ ] }) }),
593
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col items-start gap-2 pt-7", children: [
594
+ /* @__PURE__ */ jsx("p", { className: "w-full font-sans text-body-16sb text-label-normal", children: "Contact" }),
595
+ /* @__PURE__ */ jsx("div", { className: "flex w-full flex-wrap items-center gap-1.5", children: contactIcons })
596
+ ] })
597
+ ] }) })
598
+ ] });
599
+ }
600
+ function HeaderMobileBar({
601
+ logo,
602
+ menuIcon,
603
+ closeIcon,
604
+ isOpen,
605
+ onToggle,
606
+ menuId
607
+ }) {
608
+ return /* @__PURE__ */ jsxs("div", { className: "flex h-17.25 w-full items-center justify-between bg-fill-normal px-4 py-5", children: [
609
+ /* @__PURE__ */ jsx("div", { className: "shrink-0", children: logo }),
610
+ /* @__PURE__ */ jsx(
611
+ "button",
612
+ {
613
+ type: "button",
614
+ className: cn(
615
+ "flex size-6 shrink-0 items-center justify-center transition-transform duration-200",
616
+ isOpen && "rotate-90"
617
+ ),
618
+ onClick: onToggle,
619
+ "aria-controls": menuId,
620
+ "aria-expanded": isOpen,
621
+ "aria-label": isOpen ? "Close navigation menu" : "Open navigation menu",
622
+ children: isOpen ? closeIcon : menuIcon
623
+ }
624
+ )
625
+ ] });
626
+ }
627
+ function HeaderMobileMenu({
628
+ children,
629
+ isOpen,
630
+ menuId
631
+ }) {
632
+ const contentRef = useRef(null);
633
+ const [height, setHeight] = useState(0);
634
+ const [isVisible, setIsVisible] = useState(false);
635
+ const updateHeight = useCallback(() => {
636
+ if (isOpen && contentRef.current) {
637
+ setHeight(contentRef.current.scrollHeight);
638
+ }
639
+ }, [isOpen]);
640
+ useEffect(() => {
641
+ updateHeight();
642
+ }, [updateHeight]);
643
+ useEffect(() => {
644
+ const content = contentRef.current;
645
+ if (!isOpen || !content || typeof ResizeObserver === "undefined") {
646
+ return;
647
+ }
648
+ const observer = new ResizeObserver(updateHeight);
649
+ observer.observe(content);
650
+ return () => observer.disconnect();
651
+ }, [isOpen, updateHeight]);
652
+ useEffect(() => {
653
+ if (isOpen) {
654
+ setIsVisible(true);
655
+ }
656
+ }, [isOpen]);
657
+ const handleTransitionEnd = (event) => {
658
+ if (event.target === event.currentTarget && !isOpen) {
659
+ setIsVisible(false);
660
+ }
661
+ };
662
+ return /* @__PURE__ */ jsx(
663
+ "div",
664
+ {
665
+ id: menuId,
666
+ className: "overflow-hidden transition-[max-height] duration-300 ease-in-out",
667
+ style: { maxHeight: isOpen ? height : 0 },
668
+ onTransitionEnd: handleTransitionEnd,
669
+ children: /* @__PURE__ */ jsx(
670
+ "nav",
671
+ {
672
+ ref: contentRef,
673
+ className: isVisible || isOpen ? "bg-fill-netural" : "hidden",
674
+ children
675
+ }
676
+ )
677
+ }
678
+ );
679
+ }
680
+ function HeaderMobileNavigationItem({
681
+ child
682
+ }) {
683
+ const className = cn(
684
+ "flex w-full flex-col items-center gap-3 bg-fill-netural px-4 py-5"
685
+ );
686
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [
687
+ /* @__PURE__ */ jsx("span", { className: "w-full overflow-hidden text-ellipsis whitespace-nowrap text-center font-sans text-headline-20sb text-label-normal", children: child.props.children }),
688
+ /* @__PURE__ */ jsx("span", { className: "h-px w-full bg-line-alternative" })
689
+ ] });
690
+ if (child.props.href) {
691
+ return /* @__PURE__ */ jsx("a", { className, href: child.props.href, children: content });
692
+ }
693
+ return /* @__PURE__ */ jsx("button", { className, type: "button", onClick: child.props.onClick, children: content });
694
+ }
695
+ function HeaderMobileNavigation({ children }) {
696
+ return Children.map(children, (child) => {
697
+ if (!isValidElement(child)) {
698
+ return child;
699
+ }
700
+ return /* @__PURE__ */ jsx(HeaderMobileNavigationItem, { child });
701
+ });
702
+ }
703
+ function Header2({
704
+ logo,
705
+ children,
706
+ mobileLogo,
707
+ menuIcon,
708
+ closeIcon,
709
+ isOpen,
710
+ defaultOpen = false,
711
+ onOpenChange,
712
+ menuId,
713
+ className,
714
+ ...props
715
+ }) {
716
+ const generatedMenuId = useId();
717
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
718
+ const hasResponsiveHeader = Boolean(mobileLogo || menuIcon || closeIcon);
719
+ const isMenuOpen = isOpen ?? uncontrolledOpen;
720
+ const resolvedMenuId = menuId ?? generatedMenuId;
721
+ const handleToggle = () => {
722
+ const nextOpen = !isMenuOpen;
723
+ if (isOpen === void 0) {
724
+ setUncontrolledOpen(nextOpen);
725
+ }
726
+ onOpenChange?.(nextOpen);
727
+ };
728
+ if (hasResponsiveHeader) {
729
+ return /* @__PURE__ */ jsxs("header", { className: cn("w-full bg-fill-normal", className), ...props, children: [
730
+ /* @__PURE__ */ jsxs("div", { className: "hidden items-center justify-between px-10 py-6 lg:flex", children: [
731
+ /* @__PURE__ */ jsx("div", { className: "shrink-0", children: logo }),
732
+ /* @__PURE__ */ jsx("nav", { className: "flex min-w-0 items-center justify-end gap-6 overflow-hidden", children })
733
+ ] }),
734
+ /* @__PURE__ */ jsxs("div", { className: "lg:hidden", children: [
735
+ /* @__PURE__ */ jsx(
736
+ HeaderMobileBar,
737
+ {
738
+ logo: mobileLogo ?? logo,
739
+ menuIcon,
740
+ closeIcon,
741
+ isOpen: isMenuOpen,
742
+ onToggle: handleToggle,
743
+ menuId: resolvedMenuId
744
+ }
745
+ ),
746
+ /* @__PURE__ */ jsx(HeaderMobileMenu, { menuId: resolvedMenuId, isOpen: isMenuOpen, children: /* @__PURE__ */ jsx(HeaderMobileNavigation, { children }) })
747
+ ] })
748
+ ] });
749
+ }
750
+ return /* @__PURE__ */ jsxs(
751
+ "header",
752
+ {
753
+ className: cn(
754
+ "flex items-center justify-between",
755
+ "w-full",
756
+ "bg-fill-normal px-10 py-6",
757
+ className
758
+ ),
759
+ ...props,
760
+ children: [
761
+ /* @__PURE__ */ jsx("div", { className: "shrink-0", children: logo }),
762
+ /* @__PURE__ */ jsx("nav", { className: "flex min-w-0 items-center justify-end gap-6 overflow-hidden", children })
763
+ ]
764
+ }
765
+ );
766
+ }
767
+ var stateStyles = {
768
+ default: "text-body-16m text-label-light hover:text-body-16b hover:text-label-normal active:text-body-16b active:text-brand-primary",
769
+ hovered: "text-body-16b text-label-normal",
770
+ pressed: "text-body-16b text-brand-primary"
771
+ };
772
+ function isLinkProps(props) {
773
+ return "href" in props && typeof props.href === "string";
774
+ }
775
+ function HeaderNavigation({
776
+ children,
777
+ className,
778
+ state = "default",
779
+ ...props
780
+ }) {
781
+ const sharedClassName = cn(
782
+ "flex max-w-full items-center justify-center overflow-hidden text-ellipsis whitespace-nowrap px-4",
783
+ "font-sans transition-colors",
784
+ stateStyles[state],
785
+ className
786
+ );
787
+ if (isLinkProps(props)) {
788
+ const linkProps = props;
789
+ return /* @__PURE__ */ jsx("a", { className: sharedClassName, ...linkProps, children });
790
+ }
791
+ const buttonProps = props;
792
+ return /* @__PURE__ */ jsx("button", { className: sharedClassName, ...buttonProps, type: "button", children });
793
+ }
794
+ function List({ title, items }) {
795
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
796
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-1", children: [
797
+ /* @__PURE__ */ jsx("div", { className: "w-5.5 h-6 lg:w-7.5 lg:h-8 shrink-0", children: /* @__PURE__ */ jsx(SnowGraphic, { className: "w-full h-full" }) }),
798
+ /* @__PURE__ */ jsx("span", { className: "text-body-16b text-label-normal lg:text-headline-20b", children: title })
799
+ ] }),
800
+ /* @__PURE__ */ jsxs("ul", { className: "list-disc list-inside space-y-3 rounded-2xl bg-fill-netural px-4 py-6 lg:px-6 lg:py-7 w-236", children: [
801
+ /* @__PURE__ */ jsx("li", { className: "text-body-16m text-label-netural lg:text-body-18m truncate", children: items[0] }),
802
+ /* @__PURE__ */ jsx("li", { className: "text-body-16m text-label-netural lg:text-body-18m truncate", children: items[1] }),
803
+ /* @__PURE__ */ jsx("li", { className: "text-body-16m text-label-netural lg:text-body-18m truncate", children: items[2] })
804
+ ] })
805
+ ] });
806
+ }
807
+ var LINK_ICONS = {
808
+ behance: BehanceIcon,
809
+ github: GithubIcon,
810
+ service: LinkIcon
811
+ };
812
+ function ModalLinkIcon({ type }) {
813
+ const Icon2 = LINK_ICONS[type];
814
+ return /* @__PURE__ */ jsx(Icon2, { className: "size-5 shrink-0" });
815
+ }
816
+ function Modal({
817
+ isOpen,
818
+ onClose,
819
+ onPrev,
820
+ onNext,
821
+ name,
822
+ th,
823
+ type,
824
+ imageUrl,
825
+ description,
826
+ teamRoles = [],
827
+ links = []
828
+ }) {
829
+ useEffect(() => {
830
+ if (!isOpen) return;
831
+ const prev = document.body.style.overflow;
832
+ document.body.style.overflow = "hidden";
833
+ return () => {
834
+ document.body.style.overflow = prev;
835
+ };
836
+ }, [isOpen]);
837
+ useEffect(() => {
838
+ if (!isOpen) return;
839
+ const handleKey = (e) => {
840
+ if (e.key === "Escape") onClose();
841
+ };
842
+ window.addEventListener("keydown", handleKey);
843
+ return () => window.removeEventListener("keydown", handleKey);
844
+ }, [isOpen, onClose]);
845
+ if (!isOpen) return null;
846
+ const hasNav = !!(onPrev || onNext);
847
+ return /* @__PURE__ */ jsxs(
848
+ "div",
849
+ {
850
+ className: "fixed inset-0 z-50 overflow-y-auto",
851
+ role: "dialog",
852
+ "aria-modal": "true",
853
+ "aria-label": name,
854
+ children: [
855
+ /* @__PURE__ */ jsx(
856
+ "div",
857
+ {
858
+ className: "fixed inset-0 bg-effect-dimmer",
859
+ onClick: onClose,
860
+ "aria-hidden": "true"
861
+ }
862
+ ),
863
+ /* @__PURE__ */ jsx("div", { className: "flex min-h-full items-start lg:items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center", children: [
864
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
865
+ hasNav && /* @__PURE__ */ jsx("div", { className: "hidden lg:flex mr-5", children: /* @__PURE__ */ jsx(
866
+ PageNavButton,
867
+ {
868
+ direction: "prev",
869
+ color: "light",
870
+ onClick: onPrev,
871
+ className: !onPrev ? "invisible pointer-events-none" : ""
872
+ }
873
+ ) }),
874
+ /* @__PURE__ */ jsxs("div", { className: "relative flex w-83.75 lg:w-156 max-h-144 lg:max-h-231.5 flex-col rounded-2xl bg-fill-normal overflow-hidden", children: [
875
+ /* @__PURE__ */ jsx("div", { className: "shrink-0 border-b-2 border-line-alternative p-4 lg:pl-7 lg:pr-8 lg:py-6", children: /* @__PURE__ */ jsx(
876
+ "button",
877
+ {
878
+ type: "button",
879
+ "aria-label": "\uB2EB\uAE30",
880
+ onClick: onClose,
881
+ className: "flex items-center justify-center text-label-alternative cursor-pointer",
882
+ children: /* @__PURE__ */ jsx(CancelMIcon, { "aria-hidden": true, className: "size-5 lg:size-8" })
883
+ }
884
+ ) }),
885
+ /* @__PURE__ */ jsx(
886
+ "div",
887
+ {
888
+ className: cn(
889
+ "flex-1 min-h-0 overflow-y-auto pt-3 pb-4 lg:pt-5 lg:pb-8",
890
+ "[&::-webkit-scrollbar]:w-0.75",
891
+ "[&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-track]:rounded-full",
892
+ "[&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-label-normal/75 [&::-webkit-scrollbar-thumb]:h-16"
893
+ ),
894
+ children: /* @__PURE__ */ jsxs("div", { className: "px-5 lg:px-8", children: [
895
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 flex-wrap", children: [
896
+ /* @__PURE__ */ jsx("p", { className: "text-headline-20b lg:text-pc-30b text-label-normal", children: name }),
897
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5 lg:gap-2", children: [
898
+ /* @__PURE__ */ jsxs(Label, { type: "brand", children: [
899
+ th,
900
+ "\uAE30"
901
+ ] }),
902
+ /* @__PURE__ */ jsx(Label, { type: "brand", children: type })
903
+ ] })
904
+ ] }),
905
+ /* @__PURE__ */ jsx("div", { className: "pt-4 lg:pt-5 pb-6 lg:pb-5", children: /* @__PURE__ */ jsx("div", { className: "w-full overflow-hidden rounded-xl border border-line-neutral bg-fill-alternative aspect-video", children: /* @__PURE__ */ jsx(
906
+ "img",
907
+ {
908
+ src: imageUrl,
909
+ alt: name,
910
+ className: "block h-full w-full object-cover"
911
+ }
912
+ ) }) }),
913
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-5 lg:gap-8", children: [
914
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 lg:gap-2", children: [
915
+ /* @__PURE__ */ jsx("p", { className: "text-body-16b lg:text-body-18b text-label-netural", children: "\uD504\uB85C\uC81D\uD2B8 \uC124\uBA85" }),
916
+ /* @__PURE__ */ jsx("p", { className: "text-label-light text-body-16r lg:text-body-16m lg:text-label-alternative", children: description })
917
+ ] }),
918
+ (teamRoles.length > 0 || links.length > 0) && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-5 lg:flex-row lg:gap-8", children: [
919
+ teamRoles.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 lg:gap-3 lg:flex-1", children: [
920
+ /* @__PURE__ */ jsx("p", { className: "text-body-16b lg:text-body-18b text-label-netural", children: "\uD504\uB85C\uC81D\uD2B8 \uD300\uC6D0" }),
921
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1.5", children: teamRoles.map(({ role, members }) => /* @__PURE__ */ jsxs(
922
+ "div",
923
+ {
924
+ className: "flex items-center gap-2.5",
925
+ children: [
926
+ /* @__PURE__ */ jsx(Label, { type: "default", children: role }),
927
+ /* @__PURE__ */ jsx("span", { className: "text-label-14m text-label-alternative", children: members.join(", ") })
928
+ ]
929
+ },
930
+ role
931
+ )) })
932
+ ] }),
933
+ links.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 lg:flex-1", children: [
934
+ /* @__PURE__ */ jsx("p", { className: "text-body-16b lg:text-body-18b text-label-netural", children: "\uB9C1\uD06C" }),
935
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2 items-start", children: links.map(({ type: linkType, label, url }) => /* @__PURE__ */ jsx(
936
+ NavigationButton,
937
+ {
938
+ icon: /* @__PURE__ */ jsx(ModalLinkIcon, { type: linkType }),
939
+ onClick: () => window.open(url, "_blank", "noreferrer"),
940
+ children: label
941
+ },
942
+ url
943
+ )) })
944
+ ] })
945
+ ] })
946
+ ] })
947
+ ] })
948
+ }
949
+ ),
950
+ /* @__PURE__ */ jsx(
951
+ BottomGradient,
952
+ {
953
+ height: 48,
954
+ className: "lg:left-5! lg:right-5! lg:w-auto! lg:translate-x-0!"
955
+ }
956
+ )
957
+ ] }),
958
+ hasNav && /* @__PURE__ */ jsx("div", { className: "hidden lg:flex ml-5", children: /* @__PURE__ */ jsx(
959
+ PageNavButton,
960
+ {
961
+ direction: "next",
962
+ color: "light",
963
+ onClick: onNext,
964
+ className: !onNext ? "invisible pointer-events-none" : ""
965
+ }
966
+ ) })
967
+ ] }),
968
+ hasNav && /* @__PURE__ */ jsxs("div", { className: "flex w-83.75 justify-between mt-4 lg:hidden", children: [
969
+ /* @__PURE__ */ jsx(
970
+ PageNavButton,
971
+ {
972
+ direction: "prev",
973
+ color: "light",
974
+ onClick: onPrev,
975
+ className: !onPrev ? "invisible pointer-events-none" : ""
976
+ }
977
+ ),
978
+ /* @__PURE__ */ jsx(
979
+ PageNavButton,
980
+ {
981
+ direction: "next",
982
+ color: "light",
983
+ onClick: onNext,
984
+ className: !onNext ? "invisible pointer-events-none" : ""
985
+ }
986
+ )
987
+ ] })
988
+ ] }) })
989
+ ]
990
+ }
991
+ );
992
+ }
993
+ var filterStyles = {
994
+ desktop: {
995
+ container: "justify-center gap-5",
996
+ item: "min-w-30 px-2.5 py-2.5",
997
+ activeItem: "bg-fill-primary",
998
+ text: "",
999
+ activeText: "text-headline-20b text-brand-primary",
1000
+ inactiveText: "text-headline-20m text-label-netural"
1001
+ },
1002
+ mobile: {
1003
+ container: "justify-start gap-1 overflow-x-auto [scrollbar-width:none] [-ms-overflow-style:none]",
1004
+ item: "py-1",
1005
+ activeItem: "bg-fill-primary px-4",
1006
+ inactiveItem: "px-3",
1007
+ text: "",
1008
+ activeText: "text-body-16sb text-brand-primary",
1009
+ inactiveText: "text-body-16m text-label-netural"
1010
+ },
1011
+ responsive: {
1012
+ container: "justify-start gap-1 overflow-x-auto pb-10 [scrollbar-width:none] [-ms-overflow-style:none] lg:justify-center lg:gap-5 lg:overflow-visible lg:px-50 lg:pb-15",
1013
+ item: "py-1 lg:min-w-30 lg:px-2.5 lg:py-2.5",
1014
+ activeItem: "bg-fill-primary px-4 lg:px-2.5",
1015
+ inactiveItem: "px-3 lg:px-2.5",
1016
+ text: "",
1017
+ activeText: "text-body-16sb text-brand-primary lg:text-headline-20b",
1018
+ inactiveText: "text-body-16m text-label-netural lg:text-headline-20m"
1019
+ }
1020
+ };
1021
+ function FilterItem({
1022
+ children,
1023
+ active = false,
1024
+ device = "responsive",
1025
+ className,
1026
+ ...props
1027
+ }) {
1028
+ const styles = filterStyles[device];
1029
+ return /* @__PURE__ */ jsx(
1030
+ "button",
1031
+ {
1032
+ "aria-pressed": active,
1033
+ className: cn(
1034
+ "flex shrink-0 items-center justify-center rounded-full whitespace-nowrap",
1035
+ styles.item,
1036
+ active ? styles.activeItem : styles.inactiveItem,
1037
+ className
1038
+ ),
1039
+ type: "button",
1040
+ ...props,
1041
+ children: /* @__PURE__ */ jsx(
1042
+ "span",
1043
+ {
1044
+ className: cn(
1045
+ "font-sans",
1046
+ styles.text,
1047
+ active ? styles.activeText : styles.inactiveText
1048
+ ),
1049
+ children
1050
+ }
1051
+ )
1052
+ }
1053
+ );
1054
+ }
1055
+ function NavigationFilter({
1056
+ children,
1057
+ device = "responsive",
1058
+ className,
1059
+ ...props
1060
+ }) {
1061
+ const styles = filterStyles[device];
1062
+ const childrenWithDevice = Children.map(children, (child) => {
1063
+ if (!isValidElement(child)) {
1064
+ return child;
1065
+ }
1066
+ return cloneElement(child, {
1067
+ device: child.props.device ?? device
1068
+ });
1069
+ });
1070
+ return /* @__PURE__ */ jsx(
1071
+ "div",
1072
+ {
1073
+ className: cn(
1074
+ "flex w-full items-center",
1075
+ device === "desktop" ? "flex-wrap" : void 0,
1076
+ device === "responsive" ? "lg:flex-wrap" : void 0,
1077
+ styles.container,
1078
+ className
1079
+ ),
1080
+ ...props,
1081
+ children: childrenWithDevice
1082
+ }
1083
+ );
1084
+ }
1085
+ var sizeStyles = {
1086
+ m: {
1087
+ container: "max-w-300",
1088
+ item: "h-31",
1089
+ text: "text-headline-24m",
1090
+ textOffset: "translate-y-4.75",
1091
+ activeText: "text-headline-24sb text-label-normal",
1092
+ inactiveText: "text-label-netural",
1093
+ underline: "after:h-0.75"
1094
+ },
1095
+ s: {
1096
+ container: "max-w-256",
1097
+ item: "h-26",
1098
+ text: "text-body-16m",
1099
+ textOffset: "translate-y-7",
1100
+ activeText: "text-body-16b text-label-normal",
1101
+ inactiveText: "text-label-netural",
1102
+ underline: "after:h-0.5"
1103
+ },
1104
+ responsive: {
1105
+ container: "max-w-256 lg:max-w-300",
1106
+ item: "h-26 lg:h-31",
1107
+ text: "text-body-16m lg:text-headline-24m",
1108
+ textOffset: "translate-y-7 lg:translate-y-4.75",
1109
+ activeText: "text-body-16b text-label-normal lg:text-headline-24sb lg:text-label-normal",
1110
+ inactiveText: "text-label-netural",
1111
+ underline: "after:h-0.5 lg:after:h-0.75"
1112
+ }
1113
+ };
1114
+ function NavigationTabItem({
1115
+ children,
1116
+ active = false,
1117
+ size = "responsive",
1118
+ className,
1119
+ ...props
1120
+ }) {
1121
+ const styles = sizeStyles[size];
1122
+ return /* @__PURE__ */ jsx(
1123
+ "button",
1124
+ {
1125
+ className: cn(
1126
+ "relative flex min-w-0 flex-1 basis-0 items-center justify-center border-b border-line-alternative px-4",
1127
+ styles.item,
1128
+ active ? "after:absolute after:bottom-0 after:left-0 after:w-full after:bg-brand-primary" : void 0,
1129
+ active ? styles.underline : void 0,
1130
+ className
1131
+ ),
1132
+ role: "tab",
1133
+ "aria-selected": active,
1134
+ type: "button",
1135
+ ...props,
1136
+ children: /* @__PURE__ */ jsx(
1137
+ "span",
1138
+ {
1139
+ className: cn(
1140
+ "max-w-full overflow-hidden text-ellipsis whitespace-nowrap font-sans",
1141
+ styles.text,
1142
+ styles.textOffset,
1143
+ active ? styles.activeText : styles.inactiveText
1144
+ ),
1145
+ children
1146
+ }
1147
+ )
1148
+ }
1149
+ );
1150
+ }
1151
+ function NavigationTab({
1152
+ children,
1153
+ size = "responsive",
1154
+ className,
1155
+ ...props
1156
+ }) {
1157
+ const styles = sizeStyles[size];
1158
+ const childrenWithSize = Children.map(children, (child) => {
1159
+ if (!isValidElement(child)) {
1160
+ return child;
1161
+ }
1162
+ return cloneElement(child, {
1163
+ size: child.props.size ?? size
1164
+ });
1165
+ });
1166
+ return /* @__PURE__ */ jsx(
1167
+ "div",
1168
+ {
1169
+ className: cn(
1170
+ "mx-auto flex w-full items-stretch",
1171
+ styles.container,
1172
+ className
1173
+ ),
1174
+ role: "tablist",
1175
+ "aria-orientation": "horizontal",
1176
+ ...props,
1177
+ children: childrenWithSize
1178
+ }
1179
+ );
1180
+ }
1181
+ var paginationControlClassName = "flex size-6 items-center justify-center disabled:pointer-events-none [&_svg]:size-6 [&_svg]:shrink-0";
1182
+ var getPageItems = (currentPage, totalPages) => {
1183
+ if (totalPages <= 7) {
1184
+ return Array.from({ length: totalPages }, (_, i) => i + 1);
1185
+ }
1186
+ const middleStart = Math.max(2, currentPage - 1);
1187
+ const middleEnd = Math.min(totalPages - 1, currentPage + 1);
1188
+ const items = [1];
1189
+ if (middleStart > 2) {
1190
+ items.push("ellipsis-start");
1191
+ }
1192
+ for (let page = middleStart; page <= middleEnd; page += 1) {
1193
+ items.push(page);
1194
+ }
1195
+ if (middleEnd < totalPages - 1) {
1196
+ items.push("ellipsis-end");
1197
+ }
1198
+ items.push(totalPages);
1199
+ return items;
1200
+ };
1201
+ function Pagination({
1202
+ currentPage = 1,
1203
+ totalPages = 5,
1204
+ onPageChange,
1205
+ prevIcon = /* @__PURE__ */ jsx(KeyboardArrowLeftIcon, { "aria-hidden": "true" }),
1206
+ nextIcon = /* @__PURE__ */ jsx(KeyboardArrowRightIcon, { "aria-hidden": "true" }),
1207
+ firstIcon = /* @__PURE__ */ jsx(KeyboardDoubleArrowLeftIcon, { "aria-hidden": "true" }),
1208
+ lastIcon = /* @__PURE__ */ jsx(KeyboardDoubleArrowRightIcon, { "aria-hidden": "true" }),
1209
+ className,
1210
+ ...props
1211
+ }) {
1212
+ const safeTotalPages = Math.max(1, Math.floor(totalPages));
1213
+ const safeCurrentPage = Math.min(
1214
+ safeTotalPages,
1215
+ Math.max(1, Math.floor(currentPage))
1216
+ );
1217
+ const pageItems = getPageItems(safeCurrentPage, safeTotalPages);
1218
+ const handlePageChange = (page) => {
1219
+ onPageChange?.(Math.min(safeTotalPages, Math.max(1, page)));
1220
+ };
1221
+ const isFirstPage = safeCurrentPage === 1;
1222
+ const isLastPage = safeCurrentPage === safeTotalPages;
1223
+ const getControlClassName = (disabled) => cn(
1224
+ paginationControlClassName,
1225
+ disabled ? "text-label-disable" : "text-label-normal"
1226
+ );
1227
+ return /* @__PURE__ */ jsxs(
1228
+ "div",
1229
+ {
1230
+ className: cn("inline-flex h-11 items-center gap-3 sm:gap-5", className),
1231
+ ...props,
1232
+ children: [
1233
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
1234
+ /* @__PURE__ */ jsx(
1235
+ "button",
1236
+ {
1237
+ type: "button",
1238
+ className: cn(getControlClassName(isFirstPage), "hidden sm:flex"),
1239
+ onClick: () => handlePageChange(1),
1240
+ disabled: isFirstPage,
1241
+ "aria-label": "First page",
1242
+ children: firstIcon
1243
+ }
1244
+ ),
1245
+ /* @__PURE__ */ jsx(
1246
+ "button",
1247
+ {
1248
+ type: "button",
1249
+ className: getControlClassName(isFirstPage),
1250
+ onClick: () => handlePageChange(safeCurrentPage - 1),
1251
+ disabled: isFirstPage,
1252
+ "aria-label": "Previous page",
1253
+ children: prevIcon
1254
+ }
1255
+ )
1256
+ ] }),
1257
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2 sm:gap-3", children: pageItems.map((pageItem) => {
1258
+ if (typeof pageItem !== "number") {
1259
+ return /* @__PURE__ */ jsx(
1260
+ "span",
1261
+ {
1262
+ "aria-hidden": "true",
1263
+ className: "font-sans text-body-16m text-label-disable",
1264
+ children: "..."
1265
+ },
1266
+ pageItem
1267
+ );
1268
+ }
1269
+ return /* @__PURE__ */ jsx(
1270
+ "button",
1271
+ {
1272
+ type: "button",
1273
+ className: cn(
1274
+ "whitespace-nowrap font-sans",
1275
+ pageItem === safeCurrentPage ? "text-body-16b text-label-normal" : "text-body-16m text-label-disable"
1276
+ ),
1277
+ onClick: () => handlePageChange(pageItem),
1278
+ "aria-current": pageItem === safeCurrentPage ? "page" : void 0,
1279
+ children: pageItem
1280
+ },
1281
+ pageItem
1282
+ );
1283
+ }) }),
1284
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
1285
+ /* @__PURE__ */ jsx(
1286
+ "button",
1287
+ {
1288
+ type: "button",
1289
+ className: getControlClassName(isLastPage),
1290
+ onClick: () => handlePageChange(safeCurrentPage + 1),
1291
+ disabled: isLastPage,
1292
+ "aria-label": "Next page",
1293
+ children: nextIcon
1294
+ }
1295
+ ),
1296
+ /* @__PURE__ */ jsx(
1297
+ "button",
1298
+ {
1299
+ type: "button",
1300
+ className: cn(getControlClassName(isLastPage), "hidden sm:flex"),
1301
+ onClick: () => handlePageChange(safeTotalPages),
1302
+ disabled: isLastPage,
1303
+ "aria-label": "Last page",
1304
+ children: lastIcon
1305
+ }
1306
+ )
1307
+ ] })
1308
+ ]
1309
+ }
1310
+ );
1311
+ }
1312
+
1313
+ export { Accordion, Blog, BottomGradient, Button, Dropdown, EmailInput, FilterItem, Footer, Header2 as Header, HeaderNavigation, Label, List, Modal, NavigationButton, NavigationFilter, NavigationTab, NavigationTabItem, PageNavButton, Pagination, RecruitmentCard, ReviewCard, ScrollTopButton, ShowcaseCard };
1314
+ //# sourceMappingURL=index.js.map
1315
+ //# sourceMappingURL=index.js.map