@sarunyu/system-one 3.0.3 → 4.0.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
@@ -1,10 +1,10 @@
1
1
  "use client";
2
2
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
- import React__default, { forwardRef, useState, useCallback, useRef, useEffect, useMemo, useLayoutEffect } from "react";
4
+ import React__default, { forwardRef, useState, useRef, useEffect, useCallback, useMemo, useLayoutEffect, useContext, createContext } from "react";
5
5
  import { clsx } from "clsx";
6
6
  import { twMerge } from "tailwind-merge";
7
- import { Lock, CalendarBlank, MapPin, Users, Check, Plus, Minus, CaretLeft, CaretRight, CaretDoubleLeft, CaretDoubleRight, CaretUp, CaretDown, X, MagnifyingGlass, Circle, Clock } from "@phosphor-icons/react";
7
+ import { BookmarkSimpleIcon, BroadcastIcon, CalendarBlank, MapPin, Users, XCircle, CheckCircle, Lock, Check, Plus, Minus, CaretLeft, CaretRight, CaretDoubleLeft, CaretDoubleRight, CaretUp, CaretDown, X, MagnifyingGlass, Circle, ArrowUp, ArrowDown, ArrowsDownUp, Clock } from "@phosphor-icons/react";
8
8
  import { DayPicker, useNavigation } from "react-day-picker";
9
9
  import * as Popover from "@radix-ui/react-popover";
10
10
  import { Drawer as Drawer$1 } from "vaul";
@@ -229,17 +229,78 @@ const Button = forwardRef(function Button2({
229
229
  });
230
230
  Button.displayName = "Button";
231
231
  const imgBanner = "";
232
- function LockIcon() {
233
- return /* @__PURE__ */ jsx(Lock, { size: 16, weight: "regular", color: "var(--subtle-text)" });
234
- }
235
- function CalendarIcon() {
236
- return /* @__PURE__ */ jsx(CalendarBlank, { size: 16, weight: "regular", color: "var(--accent-orange)" });
232
+ function DurationBadge({
233
+ duration,
234
+ size
235
+ }) {
236
+ const isUpcoming = duration === "upcoming";
237
+ return /* @__PURE__ */ jsxs(
238
+ "div",
239
+ {
240
+ className: cn(
241
+ "absolute flex items-center gap-[4px] rounded-[4px] bg-black/60",
242
+ size === "lg" ? "bottom-[6px] right-[6px] h-[20px] px-[4px]" : "bottom-[4px] right-[4px] h-[16px] px-[2px]"
243
+ ),
244
+ children: [
245
+ isUpcoming && /* @__PURE__ */ jsx(BroadcastIcon, { size: 14, className: "text-white" }),
246
+ /* @__PURE__ */ jsx(
247
+ "p",
248
+ {
249
+ className: cn(
250
+ "whitespace-nowrap font-normal text-white",
251
+ size === "lg" ? "text-[14px] leading-[20px]" : "text-[12px] leading-[16px]"
252
+ ),
253
+ children: isUpcoming ? "Up Coming" : duration
254
+ }
255
+ )
256
+ ]
257
+ }
258
+ );
237
259
  }
238
- function LocationIcon() {
239
- return /* @__PURE__ */ jsx(MapPin, { size: 16, weight: "regular", color: "var(--subtle-text)" });
260
+ function LockBadgeChip({ flush = false }) {
261
+ const corner = flush ? "rounded-none rounded-bl-[4px]" : "rounded-[4px]";
262
+ const borderRing = flush ? "border-0 border-b border-l border-solid border-border" : "border border-solid border-border";
263
+ return /* @__PURE__ */ jsxs(
264
+ "div",
265
+ {
266
+ className: cn(
267
+ "relative flex items-center gap-[4px] bg-hover-bg px-[6px] py-[4px]",
268
+ corner
269
+ ),
270
+ children: [
271
+ /* @__PURE__ */ jsx(
272
+ "div",
273
+ {
274
+ "aria-hidden": "true",
275
+ className: cn(
276
+ "pointer-events-none absolute inset-0",
277
+ borderRing,
278
+ corner
279
+ )
280
+ }
281
+ ),
282
+ /* @__PURE__ */ jsx(Lock, { size: 16, weight: "regular", color: "var(--subtle-text)" }),
283
+ /* @__PURE__ */ jsx("p", { className: "whitespace-nowrap text-[12px] leading-[18px] text-subtle-text", children: "Lock" })
284
+ ]
285
+ }
286
+ );
240
287
  }
241
- function AudienceIcon() {
242
- return /* @__PURE__ */ jsx(Users, { size: 16, weight: "regular", color: "var(--subtle-text)" });
288
+ function LockBadge({
289
+ align = "left",
290
+ flush = false,
291
+ size = "desktop"
292
+ }) {
293
+ return /* @__PURE__ */ jsx(
294
+ "div",
295
+ {
296
+ className: cn(
297
+ "absolute z-10",
298
+ flush ? "top-0" : size === "mobile" ? "top-[6px]" : "top-[8px]",
299
+ align === "left" ? flush ? "left-0" : size === "mobile" ? "left-[6px]" : "left-[8px]" : flush ? "right-0" : size === "mobile" ? "right-[6px]" : "right-[8px]"
300
+ ),
301
+ children: /* @__PURE__ */ jsx(LockBadgeChip, { flush })
302
+ }
303
+ );
243
304
  }
244
305
  const tagConfig = {
245
306
  "not-registered": {
@@ -250,287 +311,775 @@ const tagConfig = {
250
311
  registered: {
251
312
  bg: "var(--success-bg)",
252
313
  text: "var(--success)",
253
- label: "ลงทะเบียนแล้ว"
314
+ label: "ลงทะเบียนแล้ว",
315
+ Icon: CheckCircle
254
316
  },
255
317
  full: {
256
318
  bg: "var(--error-bg)",
257
319
  text: "var(--destructive)",
258
- label: "เต็มแล้ว"
320
+ label: "เต็มแล้ว",
321
+ Icon: XCircle
259
322
  }
260
323
  };
261
324
  const Card = forwardRef(function Card2({
262
- variant = "desktop",
263
- title = "Lorem ipsum dolor sit amet consectetur. Lectus viverraasdasd",
264
- date = "23 มิ.ย. 2567",
265
- time = "08.30 - 12.00",
266
- location = "ณ หอประชุมศาสตราจารย์สังเวียน อินทรวิชัย ชั้น 7 ตลาดหลักทรัพย์แห่งประเทศไทย",
325
+ variant = "event",
326
+ size = "desktop",
327
+ title,
328
+ locked = true,
329
+ image,
330
+ className,
331
+ // event
332
+ date,
333
+ time,
334
+ location,
267
335
  showLocation = true,
268
336
  showAudience = true,
269
337
  count = "200/200",
270
- locked = true,
271
338
  tagStatus = "not-registered",
272
- image,
273
- className
339
+ // news
340
+ category,
341
+ bookmarked = false,
342
+ onBookmarkToggle,
343
+ // social
344
+ tags,
345
+ source,
346
+ // live
347
+ duration
274
348
  }, ref) {
275
- const widthClass = variant === "desktop" ? "w-[308px]" : variant === "tablet" ? "w-[224px]" : "w-[163px]";
276
- const padding = variant === "desktop" ? "p-4" : variant === "tablet" ? "p-3" : "p-2.5";
277
- const titleGap = variant === "desktop" ? "gap-1.5" : "gap-1";
278
- const bannerClass = variant === "desktop" ? "h-[173px]" : "aspect-video w-full";
279
- const tag = tagConfig[tagStatus];
280
349
  const bannerSrc = image ?? imgBanner;
350
+ if (variant === "social") {
351
+ const isDesktop = size === "desktop";
352
+ const cardWidth = isDesktop ? "w-[587px]" : "w-[343px]";
353
+ const cardPadding = isDesktop ? "p-4" : "p-3";
354
+ const cardGap = isDesktop ? "gap-3" : "gap-2";
355
+ const contentGap = isDesktop ? "gap-6" : "gap-3";
356
+ const textGap = isDesktop ? "gap-[10px]" : "gap-[6px]";
357
+ const titleText = isDesktop ? "text-[16px] leading-[24px]" : "text-[12px] leading-[16px]";
358
+ const tagChip = isDesktop ? "rounded-[4px] px-[6px] py-[4px] text-[12px] leading-[16px]" : "rounded-[4px] px-[4px] py-[2px] text-[9px] leading-[14px]";
359
+ const resolvedTags = tags ?? [
360
+ {
361
+ label: "Analysis",
362
+ bg: "var(--tag-bg-blue, #F3F8FE)",
363
+ text: "var(--tag-text-blue, #095EC4)"
364
+ },
365
+ {
366
+ label: "Stock",
367
+ bg: "var(--tag-bg-cyan, #F3F8FE)",
368
+ text: "var(--tag-text-cyan, #095EC4)"
369
+ },
370
+ {
371
+ label: "My Asset",
372
+ bg: "var(--tag-bg-purple, #F3E8FF)",
373
+ text: "var(--tag-text-purple, #59168B)"
374
+ }
375
+ ];
376
+ const resolvedTitle = title ?? "การออกแบบที่ตอบโจทย์ผู้ใช้: สร้างประสบการณ์ที่น่าจดจำ asdasdasdas";
377
+ const resolvedSource = source ?? "Wealth Design Daily";
378
+ const resolvedDate = date ?? "9 ธันวาคม 2567";
379
+ return /* @__PURE__ */ jsxs(
380
+ "div",
381
+ {
382
+ ref,
383
+ className: cn(
384
+ "relative flex flex-col overflow-clip bg-card shadow-card",
385
+ isDesktop ? "rounded-[8px]" : "rounded-[6px]",
386
+ cardWidth,
387
+ cardPadding,
388
+ cardGap,
389
+ className
390
+ ),
391
+ children: [
392
+ locked && /* @__PURE__ */ jsx(LockBadge, { align: "right", flush: true }),
393
+ /* @__PURE__ */ jsxs("div", { className: cn("flex flex-row items-start", contentGap), children: [
394
+ /* @__PURE__ */ jsxs("div", { className: cn("flex min-w-0 flex-1 flex-col", textGap), children: [
395
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-[8px]", children: resolvedTags.map((t) => /* @__PURE__ */ jsx(
396
+ "span",
397
+ {
398
+ className: cn(
399
+ "inline-flex whitespace-nowrap font-normal",
400
+ tagChip
401
+ ),
402
+ style: {
403
+ backgroundColor: t.bg ?? "var(--disabled-bg)",
404
+ color: t.text ?? "var(--foreground)"
405
+ },
406
+ children: t.label
407
+ },
408
+ t.label
409
+ )) }),
410
+ /* @__PURE__ */ jsx(
411
+ "p",
412
+ {
413
+ className: cn(
414
+ "line-clamp-2 font-semibold text-foreground",
415
+ titleText
416
+ ),
417
+ children: resolvedTitle
418
+ }
419
+ )
420
+ ] }),
421
+ /* @__PURE__ */ jsx("div", { className: "relative h-[84px] w-[149px] shrink-0 overflow-clip rounded-[6px]", children: /* @__PURE__ */ jsx(
422
+ "img",
423
+ {
424
+ alt: "social thumbnail",
425
+ className: "pointer-events-none absolute inset-0 size-full object-cover",
426
+ src: bannerSrc
427
+ }
428
+ ) })
429
+ ] }),
430
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
431
+ isDesktop ? /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-[12px]", children: [
432
+ /* @__PURE__ */ jsx("p", { className: "shrink-0 text-[12px] leading-[16px] text-subtle-text", children: resolvedSource }),
433
+ /* @__PURE__ */ jsx("p", { className: "min-w-0 truncate text-[12px] leading-[16px] text-muted-foreground", children: resolvedDate })
434
+ ] }) : /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col", children: [
435
+ /* @__PURE__ */ jsx("p", { className: "text-[12px] leading-[16px] text-subtle-text", children: resolvedSource }),
436
+ /* @__PURE__ */ jsx("p", { className: "text-[12px] leading-[16px] text-muted-foreground", children: resolvedDate })
437
+ ] }),
438
+ /* @__PURE__ */ jsx(
439
+ "button",
440
+ {
441
+ "aria-label": bookmarked ? "Remove bookmark" : "Add bookmark",
442
+ className: "flex size-6 shrink-0 items-center justify-center rounded transition-colors hover:bg-hover-bg cursor-pointer",
443
+ onClick: onBookmarkToggle,
444
+ type: "button",
445
+ children: /* @__PURE__ */ jsx(
446
+ BookmarkSimpleIcon,
447
+ {
448
+ size: 23.65,
449
+ weight: bookmarked ? "fill" : "regular",
450
+ color: bookmarked ? "var(--primary-action)" : "var(--subtle-text)"
451
+ }
452
+ )
453
+ }
454
+ )
455
+ ] })
456
+ ]
457
+ }
458
+ );
459
+ }
460
+ if (variant === "live") {
461
+ const isDesktop = size === "desktop";
462
+ const cardWidth = isDesktop ? "w-[704px]" : "w-[343px]";
463
+ const imgWidth = isDesktop ? "w-[212px]" : "w-[149px]";
464
+ const imgHeight = isDesktop ? "h-[119px]" : "h-[84px]";
465
+ const padding2 = isDesktop ? "p-4" : "p-3";
466
+ const gap = isDesktop ? "gap-6" : "gap-3";
467
+ const cardRadius = isDesktop ? "rounded-[8px]" : "rounded-[6px]";
468
+ const thumbRadius = isDesktop ? "rounded-[6px]" : "rounded-[4px]";
469
+ const metaTextClass = isDesktop ? "flex min-w-0 items-center gap-[12px]" : "flex min-w-0 flex-col";
470
+ const resolvedTitle = title ?? "6 หุ้นเด่นทางเทคนิค OSP, BTS, BANPU, SECURE, AH, DCC [TECHNICAL VIEW 17/07/2567]";
471
+ const resolvedSource = source ?? "Wealth Design Daily";
472
+ const resolvedDate = date ?? "9 ธันวาคม 2567";
473
+ const resolvedDuration = duration ?? "1:26:36";
474
+ return /* @__PURE__ */ jsx(
475
+ "div",
476
+ {
477
+ ref,
478
+ className: cn(
479
+ "flex flex-col overflow-clip bg-card shadow-card",
480
+ cardRadius,
481
+ cardWidth,
482
+ className
483
+ ),
484
+ children: /* @__PURE__ */ jsxs("div", { className: cn("flex flex-row items-stretch", padding2, gap), children: [
485
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col justify-between", children: [
486
+ /* @__PURE__ */ jsx(
487
+ "p",
488
+ {
489
+ className: cn(
490
+ "min-w-0 line-clamp-2 font-semibold text-foreground",
491
+ isDesktop ? "text-[16px] leading-[24px]" : "text-[12px] leading-[16px]"
492
+ ),
493
+ children: resolvedTitle
494
+ }
495
+ ),
496
+ /* @__PURE__ */ jsxs("div", { className: metaTextClass, children: [
497
+ /* @__PURE__ */ jsx("p", { className: "shrink-0 text-xs leading-4 text-subtle-text", children: resolvedSource }),
498
+ /* @__PURE__ */ jsx("p", { className: "min-w-0 truncate text-xs leading-4 text-muted-foreground", children: resolvedDate })
499
+ ] })
500
+ ] }),
501
+ /* @__PURE__ */ jsxs(
502
+ "div",
503
+ {
504
+ className: cn(
505
+ "relative shrink-0 overflow-clip",
506
+ thumbRadius,
507
+ imgWidth,
508
+ imgHeight
509
+ ),
510
+ children: [
511
+ /* @__PURE__ */ jsx(
512
+ "img",
513
+ {
514
+ alt: "live thumbnail",
515
+ className: "pointer-events-none absolute inset-0 size-full object-cover",
516
+ src: bannerSrc
517
+ }
518
+ ),
519
+ /* @__PURE__ */ jsxs(
520
+ "div",
521
+ {
522
+ className: "absolute h-[22px] left-[6px] top-[6px] flex items-center gap-[4px] rounded-[4px] px-[6px]",
523
+ style: { backgroundColor: "#FB2C36" },
524
+ children: [
525
+ /* @__PURE__ */ jsx("span", { className: "size-[6px] shrink-0 rounded-full bg-white" }),
526
+ /* @__PURE__ */ jsx("p", { className: "whitespace-nowrap text-[12px] font-semibold leading-[16px] text-white", children: "Live" })
527
+ ]
528
+ }
529
+ ),
530
+ /* @__PURE__ */ jsx(
531
+ DurationBadge,
532
+ {
533
+ duration: resolvedDuration,
534
+ size: isDesktop ? "lg" : "sm"
535
+ }
536
+ )
537
+ ]
538
+ }
539
+ )
540
+ ] })
541
+ }
542
+ );
543
+ }
544
+ if (variant === "news" && size === "desktop") {
545
+ return /* @__PURE__ */ jsxs(
546
+ "div",
547
+ {
548
+ ref,
549
+ className: cn(
550
+ "flex w-[343px] min-h-[120px] flex-col items-start overflow-clip rounded-[8px] bg-card shadow-card",
551
+ className
552
+ ),
553
+ children: [
554
+ /* @__PURE__ */ jsxs("div", { className: "relative h-[184px] w-full shrink-0 overflow-clip", children: [
555
+ /* @__PURE__ */ jsx(
556
+ "img",
557
+ {
558
+ alt: "news banner",
559
+ className: "pointer-events-none absolute inset-0 size-full object-cover",
560
+ src: bannerSrc
561
+ }
562
+ ),
563
+ locked && /* @__PURE__ */ jsx(LockBadge, {})
564
+ ] }),
565
+ /* @__PURE__ */ jsx(
566
+ NewsContent,
567
+ {
568
+ padding: "px-4 py-3",
569
+ category: category ?? "Category",
570
+ title: title ?? "Great design begins with understanding user needs and creating memorable",
571
+ date: date ?? "01 มกราคม 2025",
572
+ bookmarked,
573
+ onBookmarkToggle,
574
+ tone: "desktop"
575
+ }
576
+ )
577
+ ]
578
+ }
579
+ );
580
+ }
581
+ if (variant === "news" && size === "mobile") {
582
+ return /* @__PURE__ */ jsxs(
583
+ "div",
584
+ {
585
+ ref,
586
+ className: cn(
587
+ "flex h-[114px] w-[343px] flex-row overflow-clip rounded-[8px] bg-card shadow-card",
588
+ className
589
+ ),
590
+ children: [
591
+ /* @__PURE__ */ jsxs("div", { className: "relative h-[114px] w-[171px] shrink-0 overflow-clip", children: [
592
+ /* @__PURE__ */ jsx(
593
+ "img",
594
+ {
595
+ alt: "news banner",
596
+ className: "pointer-events-none absolute inset-0 size-full object-cover",
597
+ src: bannerSrc
598
+ }
599
+ ),
600
+ locked && /* @__PURE__ */ jsx(LockBadge, {})
601
+ ] }),
602
+ /* @__PURE__ */ jsx(
603
+ NewsContent,
604
+ {
605
+ padding: "p-3",
606
+ category: category ?? "Category",
607
+ title: title ?? "Great design begins with understanding user needs and creating memorable",
608
+ date: date ?? "01 มกราคม 2025",
609
+ bookmarked,
610
+ onBookmarkToggle,
611
+ tone: "mobile"
612
+ }
613
+ )
614
+ ]
615
+ }
616
+ );
617
+ }
618
+ const widthClass = size === "desktop" ? "w-[308px]" : size === "tablet" ? "w-[224px]" : "w-[163px]";
619
+ const padding = size === "desktop" ? "p-4" : size === "tablet" ? "p-3" : "p-2.5";
620
+ const bannerClass = size === "desktop" ? "h-[173px]" : "aspect-video w-full";
621
+ return /* @__PURE__ */ jsxs(
622
+ "div",
623
+ {
624
+ ref,
625
+ className: cn(
626
+ "flex min-h-[120px] flex-col items-start overflow-clip rounded-[8px] shadow-card",
627
+ widthClass,
628
+ className
629
+ ),
630
+ children: [
631
+ /* @__PURE__ */ jsxs(
632
+ "div",
633
+ {
634
+ className: cn("relative w-full shrink-0 overflow-clip", bannerClass),
635
+ children: [
636
+ /* @__PURE__ */ jsx(
637
+ "img",
638
+ {
639
+ alt: variant === "news" ? "news banner" : "event banner",
640
+ className: "pointer-events-none absolute inset-0 size-full object-cover",
641
+ src: bannerSrc
642
+ }
643
+ ),
644
+ locked && /* @__PURE__ */ jsx(LockBadge, { size })
645
+ ]
646
+ }
647
+ ),
648
+ variant === "news" ? /* @__PURE__ */ jsx(
649
+ NewsContent,
650
+ {
651
+ padding,
652
+ category: category ?? "Category",
653
+ title: title ?? "Great design begins with understanding user needs and creating memorable",
654
+ date: date ?? "01 มกราคม 2025",
655
+ bookmarked,
656
+ onBookmarkToggle,
657
+ tone: "default"
658
+ }
659
+ ) : /* @__PURE__ */ jsx(
660
+ EventContent,
661
+ {
662
+ size,
663
+ padding,
664
+ title: title ?? "Lorem ipsum dolor sit amet consectetur. Lectus viverraasdasd",
665
+ date: date ?? "23 มิ.ย. 2567",
666
+ time: time ?? "08.30 - 12.00",
667
+ location: location ?? "ณ หอประชุมศาสตราจารย์สังเวียน อินทรวิชัย ชั้น 7 ตลาดหลักทรัพย์แห่งประเทศไทย",
668
+ showLocation,
669
+ showAudience,
670
+ count,
671
+ tagStatus
672
+ }
673
+ )
674
+ ]
675
+ }
676
+ );
677
+ });
678
+ Card.displayName = "Card";
679
+ function EventContent({
680
+ size,
681
+ padding,
682
+ title,
683
+ date,
684
+ time,
685
+ location,
686
+ showLocation,
687
+ showAudience,
688
+ count,
689
+ tagStatus
690
+ }) {
691
+ const titleGap = size === "desktop" ? "gap-1.5" : "gap-1";
692
+ const tag = tagConfig[tagStatus];
693
+ return /* @__PURE__ */ jsx("div", { className: cn("w-full shrink-0 bg-card", padding), children: /* @__PURE__ */ jsxs("div", { className: cn("flex w-full flex-col items-start", titleGap), children: [
694
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col items-start gap-1", children: [
695
+ /* @__PURE__ */ jsx("p", { className: "line-clamp-2 w-full overflow-hidden text-ellipsis text-sm font-bold leading-5 text-foreground", children: title }),
696
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-2", children: [
697
+ /* @__PURE__ */ jsxs("div", { className: "flex h-[22px] shrink-0 items-center gap-1", children: [
698
+ /* @__PURE__ */ jsx(
699
+ CalendarBlank,
700
+ {
701
+ size: 16,
702
+ weight: "regular",
703
+ color: "var(--accent-orange)"
704
+ }
705
+ ),
706
+ /* @__PURE__ */ jsx("p", { className: "whitespace-nowrap text-xs font-semibold leading-4 text-accent-orange", children: date })
707
+ ] }),
708
+ /* @__PURE__ */ jsx("div", { className: "h-4 w-px shrink-0 bg-border" }),
709
+ /* @__PURE__ */ jsx("p", { className: "min-w-0 flex-1 overflow-hidden text-ellipsis whitespace-nowrap text-xs leading-4 text-subtle-text", children: time })
710
+ ] }),
711
+ showLocation && /* @__PURE__ */ jsxs("div", { className: "flex h-[22px] w-full items-center gap-1", children: [
712
+ /* @__PURE__ */ jsx(MapPin, { size: 16, weight: "regular", color: "var(--subtle-text)" }),
713
+ /* @__PURE__ */ jsx("p", { className: "min-w-0 flex-1 overflow-hidden text-ellipsis whitespace-nowrap text-xs leading-4 text-subtle-text", children: location })
714
+ ] }),
715
+ showAudience && /* @__PURE__ */ jsxs("div", { className: "flex h-[22px] w-full items-center gap-1", children: [
716
+ /* @__PURE__ */ jsx(Users, { size: 16, weight: "regular", color: "var(--subtle-text)" }),
717
+ /* @__PURE__ */ jsx("p", { className: "shrink-0 whitespace-nowrap text-xs leading-4 text-subtle-text", children: "ผู้เข้าร่วม" }),
718
+ /* @__PURE__ */ jsx("p", { className: "shrink-0 whitespace-nowrap text-xs leading-4 text-primary-action", children: count })
719
+ ] })
720
+ ] }),
721
+ /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-start", children: /* @__PURE__ */ jsxs(
722
+ "div",
723
+ {
724
+ className: "flex items-center justify-center gap-1 overflow-clip rounded-[4px] px-[8px] py-[4px]",
725
+ style: { backgroundColor: tag.bg },
726
+ children: [
727
+ tag.Icon && /* @__PURE__ */ jsx(tag.Icon, { size: 14, weight: "fill", color: tag.text }),
728
+ /* @__PURE__ */ jsx(
729
+ "p",
730
+ {
731
+ className: "whitespace-nowrap text-[12px] leading-[16px]",
732
+ style: { color: tag.text },
733
+ children: tag.label
734
+ }
735
+ )
736
+ ]
737
+ }
738
+ ) })
739
+ ] }) });
740
+ }
741
+ function NewsContent({
742
+ padding,
743
+ category,
744
+ title,
745
+ date,
746
+ bookmarked,
747
+ onBookmarkToggle,
748
+ tone = "default"
749
+ }) {
750
+ const isDesktopTone = tone === "desktop";
751
+ const isMobileTone = tone === "mobile";
752
+ return /* @__PURE__ */ jsxs(
753
+ "div",
754
+ {
755
+ className: cn(
756
+ "flex w-full flex-1 shrink-0 flex-col bg-card",
757
+ isDesktopTone || isMobileTone ? "gap-[10px]" : "gap-2",
758
+ padding
759
+ ),
760
+ children: [
761
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
762
+ /* @__PURE__ */ jsx(
763
+ "p",
764
+ {
765
+ className: cn(
766
+ "text-primary-action",
767
+ isMobileTone ? "text-[9px] font-semibold leading-[14px]" : isDesktopTone ? "text-xs font-semibold leading-4" : "text-xs leading-4"
768
+ ),
769
+ children: category
770
+ }
771
+ ),
772
+ /* @__PURE__ */ jsx(
773
+ "p",
774
+ {
775
+ className: cn(
776
+ "line-clamp-2 text-foreground",
777
+ isMobileTone ? "text-xs font-semibold leading-4" : isDesktopTone ? "text-sm font-bold leading-5" : "text-sm font-semibold leading-5"
778
+ ),
779
+ children: title
780
+ }
781
+ )
782
+ ] }),
783
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center justify-between", children: [
784
+ /* @__PURE__ */ jsx(
785
+ "p",
786
+ {
787
+ className: cn(
788
+ "text-xs leading-4",
789
+ isDesktopTone ? "text-muted-foreground" : "text-subtle-text"
790
+ ),
791
+ children: date
792
+ }
793
+ ),
794
+ /* @__PURE__ */ jsx(
795
+ "button",
796
+ {
797
+ "aria-label": bookmarked ? "Remove bookmark" : "Add bookmark",
798
+ className: cn(
799
+ "flex shrink-0 items-center justify-center rounded transition-colors hover:bg-hover-bg cursor-pointer",
800
+ isMobileTone ? "size-5" : isDesktopTone ? "size-6" : "p-0.5"
801
+ ),
802
+ onClick: onBookmarkToggle,
803
+ type: "button",
804
+ children: /* @__PURE__ */ jsx(
805
+ BookmarkSimpleIcon,
806
+ {
807
+ size: isMobileTone ? 20 : 23.65,
808
+ weight: bookmarked ? "fill" : "regular",
809
+ color: bookmarked ? "var(--primary-action)" : "var(--subtle-text)"
810
+ }
811
+ )
812
+ }
813
+ )
814
+ ] })
815
+ ]
816
+ }
817
+ );
818
+ }
819
+ function CheckboxVisual({
820
+ state,
821
+ disabled
822
+ }) {
823
+ if (state === "default") {
824
+ return /* @__PURE__ */ jsx(
825
+ "span",
826
+ {
827
+ "aria-hidden": "true",
828
+ className: cn(
829
+ "block w-4 h-4 rounded-[2px] border-[1.5px]",
830
+ disabled ? "bg-disabled-bg border-[var(--fill-black-100)]" : "bg-background border-[var(--fill-black-200)]"
831
+ )
832
+ }
833
+ );
834
+ }
835
+ const containerFill = disabled ? "var(--fill-gray-300)" : "var(--fill-p1-600)";
836
+ const iconFill = disabled ? "var(--fill-gray-400)" : "var(--fill-white-1000)";
837
+ if (state === "checked") {
838
+ return /* @__PURE__ */ jsxs(
839
+ "svg",
840
+ {
841
+ "aria-hidden": "true",
842
+ width: "16",
843
+ height: "16",
844
+ viewBox: "0 0 16 16",
845
+ fill: "none",
846
+ xmlns: "http://www.w3.org/2000/svg",
847
+ children: [
848
+ /* @__PURE__ */ jsx(
849
+ "path",
850
+ {
851
+ d: "M14.2222 0H1.77778C0.8 0 0 0.8 0 1.77778V14.2222C0 15.2 0.8 16 1.77778 16H14.2222C15.2 16 16 15.2 16 14.2222V8V1.77778C16 0.8 15.2 0 14.2222 0ZM6.85333 11.8133C6.50667 12.16 5.94667 12.16 5.6 11.8133L2.40889 8.62222C2.06222 8.27556 2.06222 7.71556 2.40889 7.36889C2.75556 7.02222 3.31556 7.02222 3.66222 7.36889L6.22222 9.92889L12.3378 3.81333C12.6844 3.46667 13.2444 3.46667 13.5911 3.81333C13.9378 4.16 13.9378 4.72 13.5911 5.06667L6.85333 11.8133Z",
852
+ fill: containerFill
853
+ }
854
+ ),
855
+ /* @__PURE__ */ jsx(
856
+ "path",
857
+ {
858
+ d: "M5.6 11.8133C5.94667 12.16 6.50667 12.16 6.85333 11.8133L13.5911 5.06667C13.9378 4.72 13.9378 4.16 13.5911 3.81333C13.2444 3.46667 12.6844 3.46667 12.3378 3.81333L6.22222 9.92889L3.66222 7.36889C3.31556 7.02222 2.75556 7.02222 2.40889 7.36889C2.06222 7.71556 2.06222 8.27556 2.40889 8.62222L5.6 11.8133Z",
859
+ fill: iconFill
860
+ }
861
+ )
862
+ ]
863
+ }
864
+ );
865
+ }
866
+ return /* @__PURE__ */ jsxs(
867
+ "svg",
868
+ {
869
+ "aria-hidden": "true",
870
+ width: "16",
871
+ height: "16",
872
+ viewBox: "0 0 16 16",
873
+ fill: "none",
874
+ xmlns: "http://www.w3.org/2000/svg",
875
+ children: [
876
+ /* @__PURE__ */ jsx(
877
+ "path",
878
+ {
879
+ d: "M14.2222 0H1.77778C0.8 0 0 0.8 0 1.77778V14.2222C0 15.2 0.8 16 1.77778 16H14.2222C15.2 16 16 15.2 16 14.2222V1.77778C16 0.8 15.2 0 14.2222 0ZM11.5556 8.88889H4.44444C3.95556 8.88889 3.55556 8.48889 3.55556 8C3.55556 7.51111 3.95556 7.11111 4.44444 7.11111H11.5556C12.0444 7.11111 12.4444 7.51111 12.4444 8C12.4444 8.48889 12.0444 8.88889 11.5556 8.88889Z",
880
+ fill: containerFill
881
+ }
882
+ ),
883
+ /* @__PURE__ */ jsx(
884
+ "path",
885
+ {
886
+ d: "M4.44444 8.88889H11.5556C12.0444 8.88889 12.4444 8.48889 12.4444 8C12.4444 7.51111 12.0444 7.11111 11.5556 7.11111H4.44444C3.95556 7.11111 3.55556 7.51111 3.55556 8C3.55556 8.48889 3.95556 8.88889 4.44444 8.88889Z",
887
+ fill: iconFill
888
+ }
889
+ )
890
+ ]
891
+ }
892
+ );
893
+ }
894
+ const Checkbox = forwardRef(function Checkbox2({
895
+ checked = false,
896
+ disabled = false,
897
+ label,
898
+ description,
899
+ variant = "text",
900
+ onChange,
901
+ name,
902
+ value,
903
+ id,
904
+ ariaLabel,
905
+ className
906
+ }, ref) {
907
+ const localRef = useRef(null);
908
+ const state = checked === "indeterminate" ? "indeterminate" : checked ? "checked" : "default";
909
+ useEffect(() => {
910
+ if (localRef.current) {
911
+ localRef.current.indeterminate = checked === "indeterminate";
912
+ }
913
+ }, [checked]);
914
+ const setRefs = useCallback(
915
+ (node) => {
916
+ localRef.current = node;
917
+ if (typeof ref === "function") ref(node);
918
+ else if (ref) ref.current = node;
919
+ },
920
+ [ref]
921
+ );
922
+ const handleChange = (e) => {
923
+ onChange == null ? void 0 : onChange(e.target.checked);
924
+ };
925
+ const hasText = label !== void 0 || description !== void 0;
926
+ const hasActiveBorder = state === "checked" || state === "indeterminate";
927
+ const isButton = variant === "button";
928
+ const buttonBorder = disabled ? "border-[var(--fill-black-100)]" : hasActiveBorder ? "border-primary-action" : "border-[var(--fill-black-200)]";
281
929
  return /* @__PURE__ */ jsxs(
282
- "div",
930
+ "label",
283
931
  {
284
- ref,
285
932
  className: cn(
286
- "flex min-h-[120px] flex-col items-start overflow-clip rounded-[8px]",
287
- "shadow-card",
288
- widthClass,
933
+ "inline-flex gap-1 select-none",
934
+ description ? "items-start" : "items-center",
935
+ disabled ? "cursor-not-allowed" : "cursor-pointer",
936
+ isButton && cn("bg-background rounded-lg border py-2.5 pl-3 pr-4", buttonBorder),
289
937
  className
290
938
  ),
291
939
  children: [
292
- /* @__PURE__ */ jsxs("div", { className: cn("relative w-full shrink-0 overflow-clip", bannerClass), children: [
940
+ /* @__PURE__ */ jsxs("span", { className: "relative inline-flex items-center justify-center w-6 h-6 shrink-0", children: [
293
941
  /* @__PURE__ */ jsx(
294
- "img",
942
+ "input",
295
943
  {
296
- alt: "event banner",
297
- className: "pointer-events-none absolute inset-0 size-full object-cover",
298
- src: bannerSrc
944
+ ref: setRefs,
945
+ id,
946
+ name,
947
+ value,
948
+ type: "checkbox",
949
+ checked: checked === true,
950
+ disabled,
951
+ onChange: handleChange,
952
+ "aria-label": ariaLabel,
953
+ "aria-checked": checked === "indeterminate" ? "mixed" : checked,
954
+ className: "absolute inset-0 w-full h-full opacity-0 m-0 cursor-[inherit] disabled:cursor-[inherit]"
299
955
  }
300
956
  ),
301
- locked && /* @__PURE__ */ jsxs(
302
- "div",
957
+ /* @__PURE__ */ jsx(CheckboxVisual, { state, disabled })
958
+ ] }),
959
+ hasText && /* @__PURE__ */ jsxs("span", { className: "flex flex-col", children: [
960
+ label !== void 0 && /* @__PURE__ */ jsx(
961
+ "span",
303
962
  {
304
963
  className: cn(
305
- "absolute left-[8px] top-[8px] flex items-center gap-[4px] rounded-[4px] bg-hover-bg px-[6px] py-[4px]"
964
+ "text-base leading-6",
965
+ disabled ? "text-disabled" : "text-foreground"
306
966
  ),
307
- children: [
308
- /* @__PURE__ */ jsx(
309
- "div",
310
- {
311
- "aria-hidden": "true",
312
- className: "pointer-events-none absolute inset-0 rounded-[4px] border border-solid border-border"
313
- }
314
- ),
315
- /* @__PURE__ */ jsx(LockIcon, {}),
316
- /* @__PURE__ */ jsx("p", { className: "whitespace-nowrap text-[12px] leading-[18px] text-subtle-text", children: "Lock" })
317
- ]
967
+ children: label
318
968
  }
319
- )
320
- ] }),
321
- /* @__PURE__ */ jsx("div", { className: cn("w-full shrink-0 bg-card", padding), children: /* @__PURE__ */ jsxs("div", { className: cn("flex w-full flex-col items-start", titleGap), children: [
322
- /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col items-start gap-1", children: [
323
- /* @__PURE__ */ jsx(
324
- "p",
325
- {
326
- className: cn(
327
- "line-clamp-2 w-full overflow-hidden text-ellipsis text-sm leading-5 text-foreground"
328
- ),
329
- children: title
330
- }
331
- ),
332
- /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-2", children: [
333
- /* @__PURE__ */ jsxs("div", { className: "flex h-[22px] shrink-0 items-center gap-1", children: [
334
- /* @__PURE__ */ jsx(CalendarIcon, {}),
335
- /* @__PURE__ */ jsx("p", { className: "whitespace-nowrap text-xs leading-4 text-accent-orange", children: date })
336
- ] }),
337
- /* @__PURE__ */ jsx("div", { className: "h-[14px] w-px shrink-0 bg-border" }),
338
- /* @__PURE__ */ jsx(
339
- "p",
340
- {
341
- className: cn(
342
- "min-w-0 flex-1 overflow-hidden text-ellipsis whitespace-nowrap text-xs leading-4 text-subtle-text"
343
- ),
344
- children: time
345
- }
346
- )
347
- ] }),
348
- showLocation && /* @__PURE__ */ jsxs("div", { className: "flex h-[22px] w-full items-center gap-1", children: [
349
- /* @__PURE__ */ jsx(LocationIcon, {}),
350
- /* @__PURE__ */ jsx(
351
- "p",
352
- {
353
- className: cn(
354
- "min-w-0 flex-1 overflow-hidden text-ellipsis whitespace-nowrap text-xs leading-4 text-subtle-text"
355
- ),
356
- children: location
357
- }
358
- )
359
- ] }),
360
- showAudience && /* @__PURE__ */ jsxs("div", { className: "flex h-[22px] w-full items-center gap-1", children: [
361
- /* @__PURE__ */ jsx(AudienceIcon, {}),
362
- /* @__PURE__ */ jsx("p", { className: "shrink-0 whitespace-nowrap text-xs leading-4 text-subtle-text", children: "ผู้เข้าร่วม" }),
363
- /* @__PURE__ */ jsx("p", { className: "shrink-0 whitespace-nowrap text-xs leading-4 text-primary-action", children: count })
364
- ] })
365
- ] }),
366
- /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-start", children: /* @__PURE__ */ jsx(
367
- "div",
969
+ ),
970
+ description !== void 0 && /* @__PURE__ */ jsx(
971
+ "span",
368
972
  {
369
- className: "flex items-center justify-center gap-[2px] overflow-clip rounded-[4px] px-[8px] py-[4px]",
370
- style: { backgroundColor: tag.bg },
371
- children: /* @__PURE__ */ jsx("p", { className: "whitespace-nowrap text-[12px] leading-[16px]", style: { color: tag.text }, children: tag.label })
973
+ className: cn(
974
+ "text-xs leading-4",
975
+ disabled ? "text-disabled" : "text-subtle-text"
976
+ ),
977
+ children: description
372
978
  }
373
- ) })
374
- ] }) })
979
+ )
980
+ ] })
375
981
  ]
376
982
  }
377
983
  );
378
984
  });
379
- Card.displayName = "Card";
380
- const pageWidthClass = {
381
- sm: "max-w-[640px]",
382
- md: "max-w-[960px]",
383
- lg: "max-w-[1200px]",
384
- xl: "max-w-[1440px]",
385
- full: "max-w-none"
386
- };
387
- const Page = forwardRef(function Page2({ width = "lg", className, children, ...rest }, ref) {
985
+ Checkbox.displayName = "Checkbox";
986
+ function RadioVisual({ checked, disabled }) {
388
987
  return /* @__PURE__ */ jsx(
389
- "main",
988
+ "span",
390
989
  {
391
- ref,
990
+ "aria-hidden": "true",
392
991
  className: cn(
393
- "mx-auto w-full px-6 md:px-8 py-10 flex flex-col gap-12",
394
- pageWidthClass[width],
395
- className
992
+ "w-[18px] h-[18px] rounded-full border-[1.5px] flex items-center justify-center",
993
+ disabled ? "bg-disabled-bg border-[var(--fill-black-100)]" : checked ? "bg-background border-primary-action" : "bg-background border-[var(--fill-black-200)]"
396
994
  ),
397
- ...rest,
398
- children
399
- }
400
- );
401
- });
402
- const PageHeader = forwardRef(
403
- function PageHeader2({ title, description, actions, eyebrow, className, ...rest }, ref) {
404
- return /* @__PURE__ */ jsxs(
405
- "header",
406
- {
407
- ref,
408
- className: cn(
409
- "flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between",
410
- className
411
- ),
412
- ...rest,
413
- children: [
414
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 min-w-0", children: [
415
- eyebrow && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-2", children: eyebrow }),
416
- /* @__PURE__ */ jsx("h1", { children: title }),
417
- description && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground max-w-[720px]", children: description })
418
- ] }),
419
- actions && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-3 shrink-0", children: actions })
420
- ]
421
- }
422
- );
423
- }
424
- );
425
- const Section = forwardRef(function Section2({ title, description, actions, className, children, ...rest }, ref) {
426
- const hasHeader = Boolean(title || description || actions);
427
- return /* @__PURE__ */ jsxs(
428
- "section",
429
- {
430
- ref,
431
- className: cn("flex flex-col gap-6", className),
432
- ...rest,
433
- children: [
434
- hasHeader && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between", children: [
435
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 min-w-0", children: [
436
- title && /* @__PURE__ */ jsx("h2", { children: title }),
437
- description && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground max-w-[720px]", children: description })
438
- ] }),
439
- actions && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-3 shrink-0", children: actions })
440
- ] }),
441
- children
442
- ]
995
+ children: checked && /* @__PURE__ */ jsx(
996
+ "span",
997
+ {
998
+ className: cn(
999
+ "w-2 h-2 rounded-full",
1000
+ disabled ? "bg-[var(--fill-gray-400)]" : "bg-primary-action"
1001
+ )
1002
+ }
1003
+ )
443
1004
  }
444
1005
  );
445
- });
446
- const Toolbar = forwardRef(
447
- function Toolbar2({ end, className, children, ...rest }, ref) {
448
- return /* @__PURE__ */ jsxs(
449
- "div",
450
- {
451
- ref,
452
- className: cn(
453
- "flex flex-wrap items-center gap-3",
454
- className
455
- ),
456
- ...rest,
457
- children: [
458
- children,
459
- end && /* @__PURE__ */ jsx("div", { className: "ml-auto flex items-center gap-3", children: end })
460
- ]
461
- }
462
- );
463
- }
464
- );
465
- const cardGridColsClass = {
466
- 2: "grid-cols-1 sm:grid-cols-2",
467
- 3: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3",
468
- 4: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"
469
- };
470
- const CardGrid = forwardRef(
471
- function CardGrid2({ cols = 3, className, children, ...rest }, ref) {
472
- return /* @__PURE__ */ jsx(
473
- "div",
474
- {
475
- ref,
476
- className: cn("grid gap-6", cardGridColsClass[cols], className),
477
- ...rest,
478
- children
479
- }
480
- );
481
- }
482
- );
483
- const stackGapClass = {
484
- 1: "gap-1",
485
- 2: "gap-2",
486
- 3: "gap-3",
487
- 4: "gap-4",
488
- 6: "gap-6",
489
- 8: "gap-8",
490
- 10: "gap-10",
491
- 12: "gap-12"
492
- };
493
- const stackAlignClass = {
494
- start: "items-start",
495
- center: "items-center",
496
- end: "items-end",
497
- stretch: "items-stretch"
498
- };
499
- const stackJustifyClass = {
500
- start: "justify-start",
501
- center: "justify-center",
502
- end: "justify-end",
503
- between: "justify-between",
504
- around: "justify-around"
505
- };
506
- const Stack = forwardRef(function Stack2({
507
- direction = "col",
508
- gap = 4,
509
- align,
510
- justify,
511
- wrap,
512
- className,
513
- children,
514
- ...rest
1006
+ }
1007
+ const Radio = forwardRef(function Radio2({
1008
+ checked = false,
1009
+ disabled = false,
1010
+ label,
1011
+ description,
1012
+ variant = "text",
1013
+ onChange,
1014
+ name,
1015
+ value,
1016
+ id,
1017
+ ariaLabel,
1018
+ className
515
1019
  }, ref) {
516
- return /* @__PURE__ */ jsx(
517
- "div",
1020
+ const hasText = label !== void 0 || description !== void 0;
1021
+ const isButton = variant === "button";
1022
+ const handleChange = (e) => {
1023
+ onChange == null ? void 0 : onChange(e.target.checked);
1024
+ };
1025
+ const buttonBorder = disabled ? "border-[var(--fill-black-100)]" : checked ? "border-primary-action" : "border-[var(--fill-black-200)]";
1026
+ const buttonBackground = disabled && !checked ? "bg-disabled-bg" : "bg-background";
1027
+ return /* @__PURE__ */ jsxs(
1028
+ "label",
518
1029
  {
519
- ref,
520
1030
  className: cn(
521
- "flex",
522
- direction === "col" ? "flex-col" : "flex-row",
523
- stackGapClass[gap],
524
- align && stackAlignClass[align],
525
- justify && stackJustifyClass[justify],
526
- wrap && "flex-wrap",
1031
+ "inline-flex gap-1 select-none",
1032
+ description ? "items-start" : "items-center",
1033
+ disabled ? "cursor-not-allowed" : "cursor-pointer",
1034
+ isButton && cn(buttonBackground, "rounded-lg border py-2.5 pl-3 pr-4", buttonBorder),
527
1035
  className
528
1036
  ),
529
- ...rest,
530
- children
1037
+ children: [
1038
+ /* @__PURE__ */ jsxs("span", { className: "relative inline-flex items-center justify-center w-6 h-6 shrink-0", children: [
1039
+ /* @__PURE__ */ jsx(
1040
+ "input",
1041
+ {
1042
+ ref,
1043
+ id,
1044
+ name,
1045
+ value,
1046
+ type: "radio",
1047
+ checked,
1048
+ disabled,
1049
+ onChange: handleChange,
1050
+ "aria-label": ariaLabel,
1051
+ className: "absolute inset-0 w-full h-full opacity-0 m-0 cursor-[inherit] disabled:cursor-[inherit]"
1052
+ }
1053
+ ),
1054
+ /* @__PURE__ */ jsx(RadioVisual, { checked, disabled })
1055
+ ] }),
1056
+ hasText && /* @__PURE__ */ jsxs("span", { className: "flex flex-col", children: [
1057
+ label !== void 0 && /* @__PURE__ */ jsx(
1058
+ "span",
1059
+ {
1060
+ className: cn(
1061
+ "text-sm leading-5",
1062
+ disabled ? "text-disabled" : "text-foreground"
1063
+ ),
1064
+ children: label
1065
+ }
1066
+ ),
1067
+ description !== void 0 && /* @__PURE__ */ jsx(
1068
+ "span",
1069
+ {
1070
+ className: cn(
1071
+ "text-xs leading-4",
1072
+ disabled ? "text-disabled" : "text-subtle-text"
1073
+ ),
1074
+ children: description
1075
+ }
1076
+ )
1077
+ ] })
1078
+ ]
531
1079
  }
532
1080
  );
533
1081
  });
1082
+ Radio.displayName = "Radio";
534
1083
  const sizeStyles$1 = {
535
1084
  large: {
536
1085
  container: "h-9 px-3 gap-1",
@@ -3211,6 +3760,308 @@ function StatusTag({ type = "stop", text, className }) {
3211
3760
  }
3212
3761
  );
3213
3762
  }
3763
+ const TableScrollShadowContext = createContext({
3764
+ hasLeftOverflow: false,
3765
+ hasRightOverflow: false
3766
+ });
3767
+ const TableRowStateContext = createContext({
3768
+ selected: false,
3769
+ hovered: false
3770
+ });
3771
+ function getSurface(selected, hovered) {
3772
+ if (selected) return "bg-[var(--bg-brand-primary-light,#f3f8fe)]";
3773
+ if (hovered) return "bg-[var(--bg-default-secondary,#f9fafb)]";
3774
+ return "bg-[var(--bg-default-primary-medium,white)]";
3775
+ }
3776
+ function getTextClass(textStyle) {
3777
+ return textStyle === "bold" || textStyle === "bold-description" ? "font-bold text-foreground" : "font-normal text-foreground";
3778
+ }
3779
+ function resolveStickyShadowDirection(fixed, fixedShadow) {
3780
+ if (fixedShadow) return fixedShadow;
3781
+ if (fixed === "left") return "right";
3782
+ if (fixed === "right") return "left";
3783
+ return void 0;
3784
+ }
3785
+ function StickyShadowEdge({ direction }) {
3786
+ if (direction === "left") {
3787
+ return /* @__PURE__ */ jsx(
3788
+ "span",
3789
+ {
3790
+ "aria-hidden": "true",
3791
+ className: "pointer-events-none absolute inset-y-0 left-[-10px] w-2.5",
3792
+ style: {
3793
+ background: "linear-gradient(90deg, rgba(16,24,40,0.00) 0%, rgba(16,24,40,0.03) 55%, rgba(16,24,40,0.08) 100%)"
3794
+ }
3795
+ }
3796
+ );
3797
+ }
3798
+ return /* @__PURE__ */ jsx(
3799
+ "span",
3800
+ {
3801
+ "aria-hidden": "true",
3802
+ className: "pointer-events-none absolute inset-y-0 right-[-10px] w-2.5",
3803
+ style: {
3804
+ background: "linear-gradient(90deg, rgba(16,24,40,0.08) 0%, rgba(16,24,40,0.03) 45%, rgba(16,24,40,0.00) 100%)"
3805
+ }
3806
+ }
3807
+ );
3808
+ }
3809
+ const Table = forwardRef(function Table2({ className, responsive = true, ...props }, ref) {
3810
+ const scrollRef = useRef(null);
3811
+ const [shadowState, setShadowState] = useState({
3812
+ hasLeftOverflow: false,
3813
+ hasRightOverflow: false
3814
+ });
3815
+ useEffect(() => {
3816
+ if (!responsive) return;
3817
+ const el = scrollRef.current;
3818
+ if (!el) return;
3819
+ const updateShadowState = () => {
3820
+ const maxScrollLeft = Math.max(0, el.scrollWidth - el.clientWidth);
3821
+ setShadowState({
3822
+ hasLeftOverflow: el.scrollLeft > 0,
3823
+ hasRightOverflow: el.scrollLeft < maxScrollLeft - 1
3824
+ });
3825
+ };
3826
+ updateShadowState();
3827
+ el.addEventListener("scroll", updateShadowState, { passive: true });
3828
+ window.addEventListener("resize", updateShadowState);
3829
+ const observer = new ResizeObserver(updateShadowState);
3830
+ observer.observe(el);
3831
+ if (el.firstElementChild instanceof HTMLElement) {
3832
+ observer.observe(el.firstElementChild);
3833
+ }
3834
+ return () => {
3835
+ el.removeEventListener("scroll", updateShadowState);
3836
+ window.removeEventListener("resize", updateShadowState);
3837
+ observer.disconnect();
3838
+ };
3839
+ }, [responsive]);
3840
+ const contextValue = useMemo(() => shadowState, [shadowState]);
3841
+ const table = /* @__PURE__ */ jsx(
3842
+ "table",
3843
+ {
3844
+ ref,
3845
+ className: cn("w-full border-collapse border-spacing-0 text-sm", className),
3846
+ ...props
3847
+ }
3848
+ );
3849
+ if (!responsive) return table;
3850
+ return /* @__PURE__ */ jsx(TableScrollShadowContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx("div", { ref: scrollRef, className: "w-full overflow-x-auto", children: table }) });
3851
+ });
3852
+ const TableRow = forwardRef(
3853
+ function TableRow2({ className, selected = false, hoverable = false, onMouseEnter, onMouseLeave, ...props }, ref) {
3854
+ const [hovered, setHovered] = useState(false);
3855
+ const handleMouseEnter = (e) => {
3856
+ if (hoverable) setHovered(true);
3857
+ onMouseEnter == null ? void 0 : onMouseEnter(e);
3858
+ };
3859
+ const handleMouseLeave = (e) => {
3860
+ if (hoverable) setHovered(false);
3861
+ onMouseLeave == null ? void 0 : onMouseLeave(e);
3862
+ };
3863
+ const rowState = useMemo(
3864
+ () => ({ selected, hovered: hoverable ? hovered : false }),
3865
+ [hoverable, hovered, selected]
3866
+ );
3867
+ return /* @__PURE__ */ jsx(TableRowStateContext.Provider, { value: rowState, children: /* @__PURE__ */ jsx(
3868
+ "tr",
3869
+ {
3870
+ ref,
3871
+ className: cn("align-middle", className),
3872
+ onMouseEnter: handleMouseEnter,
3873
+ onMouseLeave: handleMouseLeave,
3874
+ ...props
3875
+ }
3876
+ ) });
3877
+ }
3878
+ );
3879
+ const TableHeaderCell = forwardRef(
3880
+ function TableHeaderCell2({
3881
+ className,
3882
+ type = "text",
3883
+ state = "default",
3884
+ sortable = true,
3885
+ icon,
3886
+ sortDirection = "none",
3887
+ onSortChange,
3888
+ checkState = false,
3889
+ onCheckChange,
3890
+ fixed,
3891
+ fixedOffset = 0,
3892
+ fixedShadow,
3893
+ children = "Title text",
3894
+ style: styleProp,
3895
+ ...props
3896
+ }, ref) {
3897
+ const { hasLeftOverflow, hasRightOverflow } = useContext(TableScrollShadowContext);
3898
+ const stateClass = state === "disabled" ? "bg-[var(--bg-default-tertiary,#f3f4f6)] text-[var(--text-default-tertiary,#6a7282)]" : state === "hover" ? "bg-[var(--bg-default-secondary,#f9fafb)] text-[var(--text-default-tertiary,#6a7282)]" : "bg-[var(--bg-default-primary,white)] text-[var(--text-default-tertiary,#6a7282)]";
3899
+ const interactiveHoverClass = state === "default" ? "hover:bg-[var(--bg-default-secondary,#f9fafb)]" : "";
3900
+ const sortIcon = sortDirection === "asc" ? /* @__PURE__ */ jsx(ArrowUp, { size: 16, weight: "fill", className: "shrink-0" }) : sortDirection === "desc" ? /* @__PURE__ */ jsx(ArrowDown, { size: 16, weight: "fill", className: "shrink-0" }) : /* @__PURE__ */ jsx(ArrowsDownUp, { size: 16, weight: "fill", className: "shrink-0" });
3901
+ const handleSortClick = () => {
3902
+ if (!sortable || !onSortChange) return;
3903
+ const nextDirection = sortDirection === "none" ? "asc" : sortDirection === "asc" ? "desc" : "none";
3904
+ onSortChange(nextDirection);
3905
+ };
3906
+ const content = type === "text" ? /* @__PURE__ */ jsxs(Fragment, { children: [
3907
+ /* @__PURE__ */ jsx("span", { className: "text-sm leading-5 font-normal", children }),
3908
+ sortable && sortIcon
3909
+ ] }) : type === "icon" ? icon ?? /* @__PURE__ */ jsx(Circle, { size: 20, weight: "regular", className: "shrink-0" }) : /* @__PURE__ */ jsx(
3910
+ Checkbox,
3911
+ {
3912
+ checked: checkState,
3913
+ disabled: state === "disabled",
3914
+ onChange: onCheckChange,
3915
+ ariaLabel: "Select all rows"
3916
+ }
3917
+ );
3918
+ const fixedStyle = fixed === "left" ? { left: fixedOffset } : fixed === "right" ? { right: fixedOffset } : void 0;
3919
+ const shadowDirection = resolveStickyShadowDirection(fixed, fixedShadow);
3920
+ const shouldShowShadow = shadowDirection === "right" ? hasLeftOverflow : shadowDirection === "left" ? hasRightOverflow : false;
3921
+ return /* @__PURE__ */ jsxs(
3922
+ "th",
3923
+ {
3924
+ ref,
3925
+ className: cn(
3926
+ "relative h-12 border-b border-border px-4 py-3",
3927
+ type === "text" ? "min-w-[284px] text-left" : "w-[56px] text-center",
3928
+ stateClass,
3929
+ interactiveHoverClass,
3930
+ fixed && "sticky z-20",
3931
+ sortable && type === "text" && onSortChange && "cursor-pointer select-none",
3932
+ className
3933
+ ),
3934
+ style: { ...fixedStyle, ...styleProp },
3935
+ ...props,
3936
+ onClick: type === "text" ? handleSortClick : props.onClick,
3937
+ children: [
3938
+ shadowDirection && shouldShowShadow && /* @__PURE__ */ jsx(StickyShadowEdge, { direction: shadowDirection }),
3939
+ /* @__PURE__ */ jsx(
3940
+ "div",
3941
+ {
3942
+ className: cn(
3943
+ "flex items-center",
3944
+ type === "text" ? "justify-start gap-1" : "justify-center gap-0"
3945
+ ),
3946
+ children: content
3947
+ }
3948
+ )
3949
+ ]
3950
+ }
3951
+ );
3952
+ }
3953
+ );
3954
+ const TableCell = forwardRef(function TableCell2({
3955
+ className,
3956
+ type = "default",
3957
+ textStyle = "default",
3958
+ selected,
3959
+ hovered,
3960
+ label = "Text label",
3961
+ description = "Text Description",
3962
+ imageSrc,
3963
+ tagText = "Tag",
3964
+ tagVariant = "gray",
3965
+ icon,
3966
+ contentAlign = "start",
3967
+ fixed,
3968
+ fixedOffset = 0,
3969
+ fixedShadow,
3970
+ style: styleProp,
3971
+ ...props
3972
+ }, ref) {
3973
+ const { hasLeftOverflow, hasRightOverflow } = useContext(TableScrollShadowContext);
3974
+ const rowState = useContext(TableRowStateContext);
3975
+ const cellSelected = selected ?? rowState.selected;
3976
+ const cellHovered = hovered ?? rowState.hovered;
3977
+ const surfaceClass = getSurface(cellSelected, cellHovered);
3978
+ const primaryTextClass = getTextClass(textStyle);
3979
+ const hasDescription = textStyle === "bold-description";
3980
+ const iconSize = hasDescription ? 24 : 20;
3981
+ const imageSize = hasDescription ? "size-8" : "size-5";
3982
+ const fixedStyle = fixed === "left" ? { left: fixedOffset } : fixed === "right" ? { right: fixedOffset } : void 0;
3983
+ const shadowDirection = resolveStickyShadowDirection(fixed, fixedShadow);
3984
+ const shouldShowShadow = shadowDirection === "right" ? hasLeftOverflow : shadowDirection === "left" ? hasRightOverflow : false;
3985
+ return /* @__PURE__ */ jsxs(
3986
+ "td",
3987
+ {
3988
+ ref,
3989
+ className: cn(
3990
+ "relative border-b border-border px-4",
3991
+ hasDescription ? "py-3 align-top" : "py-3.5 align-middle",
3992
+ surfaceClass,
3993
+ type === "default" || type === "text-icon" || type === "text-image" || type === "tag" ? "min-w-[284px]" : "w-[56px]",
3994
+ fixed && "sticky z-10",
3995
+ className
3996
+ ),
3997
+ style: { ...fixedStyle, ...styleProp },
3998
+ ...props,
3999
+ children: [
4000
+ shadowDirection && shouldShowShadow && /* @__PURE__ */ jsx(StickyShadowEdge, { direction: shadowDirection }),
4001
+ type === "default" && /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col", children: [
4002
+ /* @__PURE__ */ jsx("span", { className: cn("text-sm leading-5", primaryTextClass), children: label }),
4003
+ hasDescription && /* @__PURE__ */ jsx("span", { className: "text-xs leading-4 font-normal text-subtle-text", children: description })
4004
+ ] }),
4005
+ type === "text-icon" && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
4006
+ icon ?? /* @__PURE__ */ jsx(Circle, { size: iconSize, weight: "regular", className: "shrink-0 text-subtle-text" }),
4007
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col", children: [
4008
+ /* @__PURE__ */ jsx("span", { className: cn("text-sm leading-5", primaryTextClass), children: label }),
4009
+ hasDescription && /* @__PURE__ */ jsx("span", { className: "text-xs leading-4 font-normal text-subtle-text", children: description })
4010
+ ] })
4011
+ ] }),
4012
+ type === "text-image" && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
4013
+ /* @__PURE__ */ jsx("div", { className: cn("shrink-0 overflow-hidden rounded", imageSize), children: imageSrc ? /* @__PURE__ */ jsx(
4014
+ "img",
4015
+ {
4016
+ alt: "",
4017
+ className: "pointer-events-none size-full object-cover",
4018
+ src: imageSrc
4019
+ }
4020
+ ) : /* @__PURE__ */ jsx("div", { className: "size-full bg-hover-bg" }) }),
4021
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col", children: [
4022
+ /* @__PURE__ */ jsx("span", { className: cn("text-sm leading-5", primaryTextClass), children: label }),
4023
+ hasDescription && /* @__PURE__ */ jsx("span", { className: "text-xs leading-4 font-normal text-subtle-text", children: description })
4024
+ ] })
4025
+ ] }),
4026
+ type === "tag" && /* @__PURE__ */ jsx("div", { className: "flex items-center", children: /* @__PURE__ */ jsx(Tag, { text: tagText, size: "large", variant: tagVariant }) }),
4027
+ type === "icon" && /* @__PURE__ */ jsx(
4028
+ "div",
4029
+ {
4030
+ className: cn(
4031
+ "flex items-center",
4032
+ contentAlign === "start" ? "justify-start" : "justify-center"
4033
+ ),
4034
+ children: icon ?? /* @__PURE__ */ jsx(Circle, { size: 24, weight: "regular", className: "text-subtle-text" })
4035
+ }
4036
+ ),
4037
+ type === "button" && /* @__PURE__ */ jsx(
4038
+ "div",
4039
+ {
4040
+ className: cn(
4041
+ "flex items-center",
4042
+ contentAlign === "start" ? "justify-start" : "justify-center"
4043
+ ),
4044
+ children: /* @__PURE__ */ jsx(Button, { size: "xs", variant: "outline-black", children: "Button" })
4045
+ }
4046
+ ),
4047
+ type === "checkbox" && /* @__PURE__ */ jsx(
4048
+ "div",
4049
+ {
4050
+ className: cn(
4051
+ "flex items-center",
4052
+ contentAlign === "start" ? "justify-start" : "justify-center"
4053
+ ),
4054
+ children: /* @__PURE__ */ jsx(Checkbox, { checked: cellSelected })
4055
+ }
4056
+ )
4057
+ ]
4058
+ }
4059
+ );
4060
+ });
4061
+ Table.displayName = "Table";
4062
+ TableRow.displayName = "TableRow";
4063
+ TableHeaderCell.displayName = "TableHeaderCell";
4064
+ TableCell.displayName = "TableCell";
3214
4065
  const TextArea = forwardRef(
3215
4066
  function TextArea2({
3216
4067
  placeholder = "Text label",
@@ -4030,25 +4881,25 @@ TimeInput.displayName = "TimeInput";
4030
4881
  export {
4031
4882
  Button,
4032
4883
  Card,
4033
- CardGrid,
4884
+ Checkbox,
4034
4885
  Chip,
4035
4886
  DateInput,
4036
4887
  Dropdown,
4037
4888
  DropdownMultiple,
4038
4889
  Input,
4039
4890
  OptionList,
4040
- Page,
4041
- PageHeader,
4891
+ Radio,
4042
4892
  SearchInput,
4043
- Section,
4044
- Stack,
4045
4893
  StatusTag,
4046
4894
  Tab,
4047
4895
  TabGroup,
4896
+ Table,
4897
+ TableCell,
4898
+ TableHeaderCell,
4899
+ TableRow,
4048
4900
  Tag,
4049
4901
  TextArea,
4050
4902
  TimeInput,
4051
- Toolbar,
4052
4903
  cn
4053
4904
  };
4054
4905
  //# sourceMappingURL=index.js.map