@sarunyu/system-one 4.1.0 → 4.2.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
@@ -4,7 +4,7 @@ import * as React from "react";
4
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 { 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";
7
+ import { BookmarkSimpleIcon, BroadcastIcon, CalendarBlank, MapPin, Users, XCircle, CheckCircle, Lock, Check, Plus, Circle, Minus, CaretLeft, CaretRight, CaretDoubleLeft, CaretDoubleRight, CaretUp, CaretDown, X, MagnifyingGlass, 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";
@@ -1173,6 +1173,11 @@ function DrawerPortal({
1173
1173
  }) {
1174
1174
  return /* @__PURE__ */ jsx(Drawer$1.Portal, { "data-slot": "drawer-portal", ...props });
1175
1175
  }
1176
+ function DrawerClose({
1177
+ ...props
1178
+ }) {
1179
+ return /* @__PURE__ */ jsx(Drawer$1.Close, { "data-slot": "drawer-close", ...props });
1180
+ }
1176
1181
  function DrawerOverlay({
1177
1182
  className,
1178
1183
  ...props
@@ -1230,6 +1235,126 @@ function DrawerTitle({
1230
1235
  }
1231
1236
  );
1232
1237
  }
1238
+ function BottomSheet({
1239
+ open,
1240
+ onOpenChange,
1241
+ trigger,
1242
+ headerType = "text",
1243
+ showHeader = true,
1244
+ rightSide = "icon",
1245
+ title = "Title",
1246
+ actionLabel = "Action",
1247
+ imageSrc,
1248
+ leftIcon,
1249
+ rightIcon,
1250
+ onActionClick,
1251
+ showHandle = true,
1252
+ children,
1253
+ className,
1254
+ contentClassName
1255
+ }) {
1256
+ return /* @__PURE__ */ jsxs(Drawer, { direction: "bottom", open, onOpenChange, children: [
1257
+ trigger ? /* @__PURE__ */ jsx(DrawerTrigger, { asChild: true, children: trigger }) : null,
1258
+ /* @__PURE__ */ jsxs(
1259
+ DrawerContent,
1260
+ {
1261
+ className: cn(
1262
+ "[&>div:first-child]:hidden rounded-t-[24px] border-t-0 px-4 pb-6 pt-2",
1263
+ className
1264
+ ),
1265
+ children: [
1266
+ /* @__PURE__ */ jsx(DrawerTitle, { className: "sr-only", children: title }),
1267
+ showHandle ? /* @__PURE__ */ jsx("div", { className: "mb-2 flex justify-center", children: /* @__PURE__ */ jsx("div", { className: "h-1 w-10 rounded-full bg-muted" }) }) : null,
1268
+ showHeader ? /* @__PURE__ */ jsx(
1269
+ Header,
1270
+ {
1271
+ headerType,
1272
+ rightSide,
1273
+ title,
1274
+ actionLabel,
1275
+ imageSrc,
1276
+ leftIcon,
1277
+ rightIcon,
1278
+ onActionClick
1279
+ }
1280
+ ) : null,
1281
+ children ? /* @__PURE__ */ jsx("div", { className: cn("pt-2", contentClassName), children }) : null
1282
+ ]
1283
+ }
1284
+ )
1285
+ ] });
1286
+ }
1287
+ function Header({
1288
+ headerType,
1289
+ rightSide,
1290
+ title,
1291
+ actionLabel,
1292
+ imageSrc,
1293
+ leftIcon,
1294
+ rightIcon,
1295
+ onActionClick
1296
+ }) {
1297
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-3", rightSide === "action" ? "pr-2" : void 0), children: [
1298
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
1299
+ /* @__PURE__ */ jsx(Leading, { headerType, imageSrc, leftIcon }),
1300
+ /* @__PURE__ */ jsx("p", { className: "truncate text-base leading-6 font-bold text-foreground", children: title })
1301
+ ] }),
1302
+ /* @__PURE__ */ jsx(
1303
+ Trailing,
1304
+ {
1305
+ rightSide,
1306
+ actionLabel,
1307
+ rightIcon,
1308
+ onActionClick
1309
+ }
1310
+ )
1311
+ ] });
1312
+ }
1313
+ function Leading({
1314
+ headerType,
1315
+ imageSrc,
1316
+ leftIcon
1317
+ }) {
1318
+ if (headerType === "image") {
1319
+ return imageSrc ? /* @__PURE__ */ jsx("img", { alt: "", className: "size-8 shrink-0 rounded-md object-cover", src: imageSrc }) : /* @__PURE__ */ jsx("div", { className: "size-8 shrink-0 rounded-md bg-muted" });
1320
+ }
1321
+ if (headerType === "icon") {
1322
+ return /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "text-foreground", children: leftIcon ?? /* @__PURE__ */ jsx(Circle, { size: 22 }) });
1323
+ }
1324
+ return null;
1325
+ }
1326
+ function Trailing({
1327
+ rightSide,
1328
+ actionLabel,
1329
+ rightIcon,
1330
+ onActionClick
1331
+ }) {
1332
+ if (rightSide === "action") {
1333
+ return /* @__PURE__ */ jsx(
1334
+ Button,
1335
+ {
1336
+ className: "px-0 py-0 text-base leading-6 font-bold",
1337
+ onClick: onActionClick,
1338
+ size: "md",
1339
+ variant: "plain",
1340
+ children: actionLabel
1341
+ }
1342
+ );
1343
+ }
1344
+ if (rightSide === "icon") {
1345
+ return /* @__PURE__ */ jsx(DrawerClose, { asChild: true, children: /* @__PURE__ */ jsx(
1346
+ Button,
1347
+ {
1348
+ "aria-label": "Close bottom sheet",
1349
+ className: "text-foreground",
1350
+ size: "icon-xs",
1351
+ variant: "plain-black",
1352
+ children: rightIcon ?? /* @__PURE__ */ jsx(Circle, { size: 22 })
1353
+ }
1354
+ ) });
1355
+ }
1356
+ return null;
1357
+ }
1233
1358
  const THAI_MONTHS_SHORT = [
1234
1359
  "ม.ค.",
1235
1360
  "ก.พ.",
@@ -2160,16 +2285,22 @@ const DateInput = forwardRef(
2160
2285
  ref,
2161
2286
  className: cn("flex flex-col gap-[4px] w-full", className),
2162
2287
  children: [
2163
- isMobile ? /* @__PURE__ */ jsxs(Drawer, { open, onOpenChange: handleOpenChange, children: [
2164
- /* @__PURE__ */ jsx(DrawerTrigger, { asChild: true, children: triggerButton }),
2165
- /* @__PURE__ */ jsxs(DrawerContent, { children: [
2166
- /* @__PURE__ */ jsx(DrawerTitle, { className: "sr-only", children: "เลือกวันที่" }),
2167
- /* @__PURE__ */ jsxs("div", { className: "overflow-auto px-4 pt-2 pb-8 w-full", children: [
2288
+ isMobile ? /* @__PURE__ */ jsx(
2289
+ BottomSheet,
2290
+ {
2291
+ open,
2292
+ onOpenChange: handleOpenChange,
2293
+ trigger: triggerButton,
2294
+ title: "เลือกวันที่",
2295
+ showHeader: false,
2296
+ rightSide: "none",
2297
+ contentClassName: "pt-0",
2298
+ children: /* @__PURE__ */ jsxs("div", { className: "overflow-auto px-4 pt-2 pb-8 w-full", children: [
2168
2299
  /* @__PURE__ */ jsx(DrawerRangeCtx.Provider, { value: mode === "range", children: calendarContent }),
2169
2300
  actionButtons
2170
2301
  ] })
2171
- ] })
2172
- ] }) : /* @__PURE__ */ jsxs(
2302
+ }
2303
+ ) : /* @__PURE__ */ jsxs(
2173
2304
  Popover.Root,
2174
2305
  {
2175
2306
  open,
@@ -3275,6 +3406,139 @@ const Input = forwardRef(function Input2({
3275
3406
  ] });
3276
3407
  });
3277
3408
  Input.displayName = "Input";
3409
+ const ALERT_CONFIG = {
3410
+ warning: {
3411
+ titleColor: "var(--accent-orange)",
3412
+ background: "https://www.figma.com/api/mcp/asset/f4ca68ad-5732-4124-9ff4-cfb69330cc02",
3413
+ layers: [
3414
+ { inset: "12.5%", src: "https://www.figma.com/api/mcp/asset/7052a092-a432-4e8c-b559-6b51d28d878f" },
3415
+ { inset: "22.5%", src: "https://www.figma.com/api/mcp/asset/a291a1b2-06c8-455c-8e21-29755aa05c57" },
3416
+ { inset: "28.57% 30.71% 32.86% 30.71%", src: "https://www.figma.com/api/mcp/asset/a22c7520-55fe-4003-ba78-65dab40b9e23" }
3417
+ ]
3418
+ },
3419
+ success: {
3420
+ titleColor: "var(--success)",
3421
+ background: "https://www.figma.com/api/mcp/asset/2a865e6f-8a92-4496-88b5-71ac99e2c385",
3422
+ layers: [
3423
+ { inset: "12.77%", src: "https://www.figma.com/api/mcp/asset/5878ce35-4f9a-4203-97a8-70a2f17b182c" },
3424
+ { inset: "22.55%", src: "https://www.figma.com/api/mcp/asset/cea74180-b261-4db7-8712-6d32c4ccdeaf" }
3425
+ ]
3426
+ },
3427
+ danger: {
3428
+ titleColor: "var(--destructive)",
3429
+ background: "https://www.figma.com/api/mcp/asset/c7a65595-684e-4a04-b7fd-d443951f680a",
3430
+ layers: [
3431
+ { inset: "12.77%", src: "https://www.figma.com/api/mcp/asset/10090345-ae32-4fc4-aff6-cba04ea93700" },
3432
+ { inset: "22.55%", src: "https://www.figma.com/api/mcp/asset/3aa1156e-e48b-411f-ab98-93e1da98ecc1" }
3433
+ ]
3434
+ }
3435
+ };
3436
+ function Modal({
3437
+ variant = "dialog",
3438
+ actionLayout = "none",
3439
+ responsive = "mobile",
3440
+ alertStatus = "warning",
3441
+ showClose = true,
3442
+ title = "Text label",
3443
+ description = "Lorem ipsum dolor sit amet consectetur. Mi id nunc ac tempus turpis. Ipsum consectetur dictum volutpat viverra arcu rhoncus sit arcu.",
3444
+ primaryLabel = "Accept",
3445
+ secondaryLabel = "Cancel",
3446
+ children,
3447
+ className,
3448
+ onClose,
3449
+ onPrimaryClick,
3450
+ onSecondaryClick
3451
+ }) {
3452
+ const isContent = variant === "content";
3453
+ const isAlert = variant === "alert";
3454
+ const isDesktop = responsive === "desktop";
3455
+ const alert = ALERT_CONFIG[alertStatus];
3456
+ return /* @__PURE__ */ jsxs(
3457
+ "div",
3458
+ {
3459
+ className: cn(
3460
+ "max-w-full overflow-hidden border border-border bg-background",
3461
+ isAlert ? "w-[343px] rounded-2xl" : "rounded-xl",
3462
+ isContent ? "w-[343px]" : isAlert ? void 0 : "w-[375px]",
3463
+ className
3464
+ ),
3465
+ children: [
3466
+ /* @__PURE__ */ jsxs("div", { className: cn("flex items-center px-4 pt-4", isAlert ? "justify-end" : "justify-between gap-4"), children: [
3467
+ !isAlert ? /* @__PURE__ */ jsx("p", { className: "text-[18px] leading-7 font-bold text-foreground", children: title }) : null,
3468
+ showClose ? /* @__PURE__ */ jsx(
3469
+ Button,
3470
+ {
3471
+ "aria-label": "Close dialog",
3472
+ className: "h-5 w-5 shrink-0 rounded-none text-subtle-text",
3473
+ onClick: onClose,
3474
+ size: "icon-xs",
3475
+ variant: "plain-black",
3476
+ children: /* @__PURE__ */ jsx(X, { size: 20, weight: "regular" })
3477
+ }
3478
+ ) : null
3479
+ ] }),
3480
+ /* @__PURE__ */ jsx("div", { className: cn("px-4 pb-6", isAlert ? "pt-0" : "pt-4"), children: isAlert ? /* @__PURE__ */ jsx(AlertBody, { config: alert, title, description }) : isContent ? /* @__PURE__ */ jsx("div", { className: "w-full", children: children ?? null }) : children ?? /* @__PURE__ */ jsx("p", { className: "text-sm leading-5 text-muted-foreground", children: description }) }),
3481
+ actionLayout !== "none" ? /* @__PURE__ */ jsx("div", { className: "px-4 pb-4", children: /* @__PURE__ */ jsx(
3482
+ ModalActions,
3483
+ {
3484
+ layout: actionLayout,
3485
+ isContent,
3486
+ isDesktop,
3487
+ primaryLabel,
3488
+ secondaryLabel,
3489
+ onPrimaryClick,
3490
+ onSecondaryClick
3491
+ }
3492
+ ) }) : null
3493
+ ]
3494
+ }
3495
+ );
3496
+ }
3497
+ function AlertBody({
3498
+ config,
3499
+ title,
3500
+ description
3501
+ }) {
3502
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-4 text-center", children: [
3503
+ /* @__PURE__ */ jsxs("div", { className: "relative size-[100px]", children: [
3504
+ /* @__PURE__ */ jsx("img", { alt: "", className: "absolute inset-0 size-full", src: config.background }),
3505
+ config.layers.map((layer) => /* @__PURE__ */ jsx("div", { className: "absolute", style: { inset: layer.inset }, children: /* @__PURE__ */ jsx("img", { alt: "", className: "absolute inset-0 size-full", src: layer.src }) }, layer.src))
3506
+ ] }),
3507
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2", children: [
3508
+ /* @__PURE__ */ jsx("p", { className: "text-[18px] leading-7 font-bold", style: { color: config.titleColor }, children: title }),
3509
+ /* @__PURE__ */ jsx("p", { className: "text-sm leading-5 text-muted-foreground", children: description })
3510
+ ] })
3511
+ ] });
3512
+ }
3513
+ function ModalActions({
3514
+ layout,
3515
+ isContent,
3516
+ isDesktop,
3517
+ primaryLabel,
3518
+ secondaryLabel,
3519
+ onPrimaryClick,
3520
+ onSecondaryClick
3521
+ }) {
3522
+ const desktopInline = isContent && isDesktop;
3523
+ if (layout === "single") {
3524
+ return /* @__PURE__ */ jsx("div", { className: cn(desktopInline ? "flex justify-end" : void 0), children: /* @__PURE__ */ jsx(
3525
+ Button,
3526
+ {
3527
+ className: cn(desktopInline ? void 0 : "w-full"),
3528
+ onClick: onPrimaryClick,
3529
+ size: "xl",
3530
+ variant: "primary",
3531
+ children: primaryLabel
3532
+ }
3533
+ ) });
3534
+ }
3535
+ const containerClass = isContent ? cn("flex gap-4", isDesktop ? "justify-end" : "flex-col") : "flex items-center gap-4";
3536
+ const buttonClass = isContent ? isDesktop ? void 0 : "w-full" : "min-w-0 flex-1";
3537
+ return /* @__PURE__ */ jsxs("div", { className: containerClass, children: [
3538
+ /* @__PURE__ */ jsx(Button, { className: buttonClass, onClick: onSecondaryClick, size: "xl", variant: "outline", children: secondaryLabel }),
3539
+ /* @__PURE__ */ jsx(Button, { className: buttonClass, onClick: onPrimaryClick, size: "xl", variant: "primary", children: primaryLabel })
3540
+ ] });
3541
+ }
3278
3542
  const OptionList = forwardRef(
3279
3543
  function OptionList2({
3280
3544
  options,
@@ -3850,7 +4114,15 @@ const Table = forwardRef(function Table2({ className, responsive = true, ...prop
3850
4114
  return /* @__PURE__ */ jsx(TableScrollShadowContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx("div", { ref: scrollRef, className: "w-full overflow-x-auto", children: table }) });
3851
4115
  });
3852
4116
  const TableRow = forwardRef(
3853
- function TableRow2({ className, selected = false, hoverable = true, onMouseEnter, onMouseLeave, ...props }, ref) {
4117
+ function TableRow2({
4118
+ className,
4119
+ selected = false,
4120
+ onSelectedChange,
4121
+ hoverable = true,
4122
+ onMouseEnter,
4123
+ onMouseLeave,
4124
+ ...props
4125
+ }, ref) {
3854
4126
  const [hovered, setHovered] = useState(false);
3855
4127
  const handleMouseEnter = (e) => {
3856
4128
  if (hoverable) setHovered(true);
@@ -3861,8 +4133,8 @@ const TableRow = forwardRef(
3861
4133
  onMouseLeave == null ? void 0 : onMouseLeave(e);
3862
4134
  };
3863
4135
  const rowState = useMemo(
3864
- () => ({ selected, hovered: hoverable ? hovered : false }),
3865
- [hoverable, hovered, selected]
4136
+ () => ({ selected, hovered: hoverable ? hovered : false, onSelectedChange }),
4137
+ [hoverable, hovered, selected, onSelectedChange]
3866
4138
  );
3867
4139
  return /* @__PURE__ */ jsx(TableRowStateContext.Provider, { value: rowState, children: /* @__PURE__ */ jsx(
3868
4140
  "tr",
@@ -4059,7 +4331,14 @@ const TableCell = forwardRef(function TableCell2({
4059
4331
  "flex items-center",
4060
4332
  contentAlign === "start" ? "justify-start" : "justify-center"
4061
4333
  ),
4062
- children: /* @__PURE__ */ jsx(Checkbox, { checked: cellSelected })
4334
+ children: /* @__PURE__ */ jsx(
4335
+ Checkbox,
4336
+ {
4337
+ checked: cellSelected,
4338
+ onChange: rowState.onSelectedChange,
4339
+ ariaLabel: "Select row"
4340
+ }
4341
+ )
4063
4342
  }
4064
4343
  )
4065
4344
  ]
@@ -4842,16 +5121,22 @@ const TimeInput = forwardRef(
4842
5121
  className
4843
5122
  ),
4844
5123
  children: [
4845
- isMobile ? /* @__PURE__ */ jsxs(Drawer, { open, onOpenChange: handleOpenChange, children: [
4846
- /* @__PURE__ */ jsx(DrawerTrigger, { asChild: true, children: triggerButton }),
4847
- /* @__PURE__ */ jsxs(DrawerContent, { children: [
4848
- /* @__PURE__ */ jsx(DrawerTitle, { className: "sr-only", children: "เลือกเวลา" }),
4849
- /* @__PURE__ */ jsxs("div", { className: "overflow-auto px-4 pt-2 pb-8 w-full", children: [
5124
+ isMobile ? /* @__PURE__ */ jsx(
5125
+ BottomSheet,
5126
+ {
5127
+ open,
5128
+ onOpenChange: handleOpenChange,
5129
+ trigger: triggerButton,
5130
+ title: "เลือกเวลา",
5131
+ showHeader: false,
5132
+ rightSide: "none",
5133
+ contentClassName: "pt-0",
5134
+ children: /* @__PURE__ */ jsxs("div", { className: "overflow-auto px-4 pt-2 pb-8 w-full", children: [
4850
5135
  pickerContent,
4851
5136
  actionButtons
4852
5137
  ] })
4853
- ] })
4854
- ] }) : /* @__PURE__ */ jsxs(
5138
+ }
5139
+ ) : /* @__PURE__ */ jsxs(
4855
5140
  Popover.Root,
4856
5141
  {
4857
5142
  open,
@@ -4887,6 +5172,7 @@ const TimeInput = forwardRef(
4887
5172
  );
4888
5173
  TimeInput.displayName = "TimeInput";
4889
5174
  export {
5175
+ BottomSheet,
4890
5176
  Button,
4891
5177
  Card,
4892
5178
  Checkbox,
@@ -4895,6 +5181,7 @@ export {
4895
5181
  Dropdown,
4896
5182
  DropdownMultiple,
4897
5183
  Input,
5184
+ Modal,
4898
5185
  OptionList,
4899
5186
  Radio,
4900
5187
  SearchInput,
@@ -4908,6 +5195,7 @@ export {
4908
5195
  Tag,
4909
5196
  TextArea,
4910
5197
  TimeInput,
4911
- cn
5198
+ cn,
5199
+ useIsMobile
4912
5200
  };
4913
5201
  //# sourceMappingURL=index.js.map