@duskmoon-dev/components 0.3.3 → 0.4.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.
Files changed (82) hide show
  1. package/README.md +61 -2
  2. package/dist/classes/chat.d.ts +9 -1
  3. package/dist/classes/console-page.d.ts +16 -0
  4. package/dist/classes/dropdown.d.ts +5 -5
  5. package/dist/classes/fab.d.ts +11 -0
  6. package/dist/classes/index.d.ts +5 -0
  7. package/dist/classes/index.js +180 -34
  8. package/dist/classes/megamenu.d.ts +10 -0
  9. package/dist/classes/otp-input.d.ts +12 -0
  10. package/dist/classes/popover.d.ts +1 -3
  11. package/dist/classes/swap.d.ts +12 -0
  12. package/dist/classes/tree-select.d.ts +6 -6
  13. package/dist/components/app/index.js +128 -68
  14. package/dist/components/avatar/Avatar.types.d.ts +1 -1
  15. package/dist/components/avatar/index.js +2 -1
  16. package/dist/components/badge/index.js +1 -1
  17. package/dist/components/button/Button.d.ts +1 -1
  18. package/dist/components/button/Button.types.d.ts +8 -0
  19. package/dist/components/button/index.js +253 -24
  20. package/dist/components/calendar/index.js +44 -19
  21. package/dist/components/chat/Chat.d.ts +9 -1
  22. package/dist/components/chat/Chat.types.d.ts +26 -0
  23. package/dist/components/chat/index.js +92 -3
  24. package/dist/components/color-picker/ColorPicker.types.d.ts +2 -1
  25. package/dist/components/color-picker/index.js +206 -9
  26. package/dist/components/console-page/ConsolePage.d.ts +2 -0
  27. package/dist/components/console-page/ConsolePage.types.d.ts +29 -0
  28. package/dist/components/console-page/index.d.ts +2 -0
  29. package/dist/components/console-page/index.js +205 -0
  30. package/dist/components/date-picker/DatePicker.types.d.ts +1 -0
  31. package/dist/components/date-picker/index.js +537 -35
  32. package/dist/components/date-picker/usePickerDropdown.d.ts +17 -0
  33. package/dist/components/dm-date-picker/index.js +545 -43
  34. package/dist/components/dm-drawer/index.js +253 -24
  35. package/dist/components/dm-layout/index.js +391 -24
  36. package/dist/components/dm-menu/index.js +380 -13
  37. package/dist/components/dm-page-header/index.js +404 -114
  38. package/dist/components/dm-pro-table/index.js +1183 -368
  39. package/dist/components/dm-query/DmQuery.types.d.ts +1 -1
  40. package/dist/components/dm-query/index.js +931 -188
  41. package/dist/components/dm-search/DmSearch.types.d.ts +4 -0
  42. package/dist/components/dm-search/index.js +917 -163
  43. package/dist/components/dm-table/index.js +1001 -247
  44. package/dist/components/dm-toolbar/index.js +400 -110
  45. package/dist/components/dm-truncate/index.js +115 -35
  46. package/dist/components/dropdown/Dropdown.types.d.ts +1 -1
  47. package/dist/components/dropdown/index.js +400 -110
  48. package/dist/components/fab/Fab.d.ts +4 -0
  49. package/dist/components/fab/Fab.types.d.ts +25 -0
  50. package/dist/components/fab/index.d.ts +2 -0
  51. package/dist/components/fab/index.js +480 -0
  52. package/dist/components/form/Form.types.d.ts +1 -0
  53. package/dist/components/form/index.js +14 -3
  54. package/dist/components/megamenu/Megamenu.d.ts +2 -0
  55. package/dist/components/megamenu/Megamenu.types.d.ts +32 -0
  56. package/dist/components/megamenu/index.d.ts +2 -0
  57. package/dist/components/megamenu/index.js +214 -0
  58. package/dist/components/modal/index.js +128 -68
  59. package/dist/components/otp-input/OtpInput.d.ts +2 -0
  60. package/dist/components/otp-input/OtpInput.types.d.ts +16 -0
  61. package/dist/components/otp-input/index.d.ts +2 -0
  62. package/dist/components/otp-input/index.js +112 -0
  63. package/dist/components/popconfirm/index.js +255 -26
  64. package/dist/components/popover/index.js +24 -4
  65. package/dist/components/swap/Swap.d.ts +3 -0
  66. package/dist/components/swap/Swap.types.d.ts +22 -0
  67. package/dist/components/swap/index.d.ts +2 -0
  68. package/dist/components/swap/index.js +109 -0
  69. package/dist/components/time-picker/TimePicker.types.d.ts +1 -0
  70. package/dist/components/time-picker/index.js +167 -29
  71. package/dist/components/tooltip/Tooltip.types.d.ts +4 -0
  72. package/dist/components/tooltip/index.js +107 -27
  73. package/dist/components/tour/index.js +253 -24
  74. package/dist/components/tree-select/index.js +8 -8
  75. package/dist/components/upload/Upload.types.d.ts +1 -0
  76. package/dist/components/upload/index.js +2 -0
  77. package/dist/generated/version.d.ts +1 -1
  78. package/dist/index.d.ts +5 -0
  79. package/dist/index.js +3330 -1632
  80. package/dist/infrastructure.js +1 -1
  81. package/dist/styles.css +1190 -906
  82. package/package.json +23 -3
@@ -332,15 +332,342 @@ MenuRoot.Item = MenuItem;
332
332
  MenuRoot.Divider = MenuDivider;
333
333
  MenuRoot.ItemGroup = MenuItemGroup;
334
334
  var Menu = MenuRoot;
335
+ // src/components/button/Button.tsx
336
+ import React2 from "react";
337
+ import { createPortal } from "react-dom";
338
+
339
+ // src/classes/button.ts
340
+ var buttonBaseClass = "btn";
341
+ var buttonColorClasses = {
342
+ primary: "btn-primary",
343
+ secondary: "btn-secondary",
344
+ tertiary: "btn-tertiary",
345
+ accent: "btn-accent",
346
+ neutral: "btn-neutral",
347
+ base: "btn-base",
348
+ info: "btn-info",
349
+ success: "btn-success",
350
+ warning: "btn-warning",
351
+ error: "btn-error"
352
+ };
353
+ var buttonAppearanceClasses = {
354
+ filled: "",
355
+ outline: "btn-outline",
356
+ tonal: "btn-tonal",
357
+ ghost: "btn-ghost",
358
+ text: "btn-text"
359
+ };
360
+ var buttonShapeClasses = {
361
+ rect: "",
362
+ circle: "btn-circle btn-icon",
363
+ square: "btn-square"
364
+ };
365
+ var buttonSizeClasses = {
366
+ xs: "btn-xs",
367
+ sm: "btn-sm",
368
+ md: "btn-md",
369
+ lg: "btn-lg"
370
+ };
371
+ var buttonBlockClass = "btn-block";
372
+ var buttonIsLoadingClass = "btn-loading";
373
+ function getButtonClasses({
374
+ color = "primary",
375
+ appearance = "filled",
376
+ shape = "rect",
377
+ size = "md",
378
+ block,
379
+ isLoading,
380
+ className
381
+ }) {
382
+ return cn(buttonBaseClass, buttonColorClasses[color], buttonAppearanceClasses[appearance], buttonShapeClasses[shape], buttonSizeClasses[size], shape === "circle" && size === "xs" && "btn-icon-sm", shape === "circle" && size === "sm" && "btn-icon-sm", shape === "circle" && size === "lg" && "btn-icon-lg", block && buttonBlockClass, isLoading && buttonIsLoadingClass, className);
383
+ }
384
+
385
+ // src/components/button/Button.tsx
386
+ import { jsx as jsx2, jsxs as jsxs2, Fragment } from "react/jsx-runtime";
387
+ function isPromiseLike(value) {
388
+ return value !== null && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
389
+ }
390
+ function Button({
391
+ color = "primary",
392
+ appearance = "filled",
393
+ shape = "rect",
394
+ size = "md",
395
+ block,
396
+ isLoading,
397
+ leftIcon,
398
+ rightIcon,
399
+ className,
400
+ children,
401
+ disabled,
402
+ ref,
403
+ confirm,
404
+ onClick,
405
+ ...props
406
+ }) {
407
+ const buttonRef = React2.useRef(null);
408
+ const popoverRef = React2.useRef(null);
409
+ const cancelRef = React2.useRef(null);
410
+ const approvalRef = React2.useRef("idle");
411
+ const pendingRef = React2.useRef(false);
412
+ const actionRef = React2.useRef(0);
413
+ const operationRef = React2.useRef(0);
414
+ const mountedRef = React2.useRef(false);
415
+ const [portalTarget, setPortalTarget] = React2.useState(null);
416
+ const [confirmLoading, setConfirmLoading] = React2.useState(false);
417
+ const [confirmError, setConfirmError] = React2.useState(false);
418
+ const generatedId = React2.useId().replace(/:/g, "");
419
+ const popoverId = `button-confirm-${generatedId}`;
420
+ const titleId = `${popoverId}-title`;
421
+ const descriptionId = `${popoverId}-description`;
422
+ const anchor = `--${popoverId}-anchor`;
423
+ const hasConfirm = Boolean(confirm);
424
+ const confirmation = confirm && typeof confirm === "object" ? confirm : undefined;
425
+ const title = confirmation ? confirmation.title : "Confirm action";
426
+ const hasTitle = title !== undefined && title !== null && title !== false && title !== "";
427
+ const content = confirmation?.component ?? confirmation?.message ?? confirmation?.description;
428
+ const hasContent = content !== undefined && content !== null && content !== false && content !== "";
429
+ const mergedRef = React2.useCallback((node) => {
430
+ buttonRef.current = node;
431
+ if (!node) {
432
+ if (typeof ref === "function")
433
+ ref(null);
434
+ else if (ref)
435
+ ref.current = null;
436
+ return;
437
+ }
438
+ const cleanup = typeof ref === "function" ? ref(node) : undefined;
439
+ if (ref && typeof ref !== "function")
440
+ ref.current = node;
441
+ return () => {
442
+ buttonRef.current = null;
443
+ if (typeof cleanup === "function")
444
+ cleanup();
445
+ else if (typeof ref === "function")
446
+ ref(null);
447
+ else if (ref)
448
+ ref.current = null;
449
+ };
450
+ }, [ref]);
451
+ React2.useEffect(() => {
452
+ mountedRef.current = true;
453
+ return () => {
454
+ mountedRef.current = false;
455
+ operationRef.current += 1;
456
+ };
457
+ }, []);
458
+ React2.useEffect(() => {
459
+ operationRef.current += 1;
460
+ approvalRef.current = "idle";
461
+ setConfirmError(false);
462
+ setPortalTarget(hasConfirm ? document.body : null);
463
+ }, [hasConfirm]);
464
+ function closePopover() {
465
+ if (popoverRef.current?.matches(":popover-open")) {
466
+ popoverRef.current.hidePopover();
467
+ }
468
+ buttonRef.current?.focus();
469
+ }
470
+ function handleClick(event) {
471
+ if (!confirm) {
472
+ onClick?.(event);
473
+ return;
474
+ }
475
+ if (approvalRef.current === "native") {
476
+ approvalRef.current = "idle";
477
+ return;
478
+ }
479
+ if (approvalRef.current === "action") {
480
+ approvalRef.current = "idle";
481
+ let result;
482
+ try {
483
+ result = onClick?.(event);
484
+ } catch {
485
+ event.preventDefault();
486
+ pendingRef.current = false;
487
+ setConfirmError(true);
488
+ return;
489
+ }
490
+ if (!isPromiseLike(result)) {
491
+ pendingRef.current = false;
492
+ closePopover();
493
+ return;
494
+ }
495
+ const userPreventedDefault = event.defaultPrevented;
496
+ event.preventDefault();
497
+ setConfirmLoading(true);
498
+ const action = actionRef.current;
499
+ const operation = operationRef.current;
500
+ Promise.resolve(result).then(() => {
501
+ if (!mountedRef.current || action !== actionRef.current)
502
+ return;
503
+ pendingRef.current = false;
504
+ setConfirmLoading(false);
505
+ if (operation !== operationRef.current)
506
+ return;
507
+ closePopover();
508
+ if (!userPreventedDefault && !buttonRef.current?.disabled) {
509
+ approvalRef.current = "native";
510
+ buttonRef.current?.click();
511
+ approvalRef.current = "idle";
512
+ }
513
+ }, () => {
514
+ if (!mountedRef.current || action !== actionRef.current)
515
+ return;
516
+ pendingRef.current = false;
517
+ setConfirmLoading(false);
518
+ if (operation !== operationRef.current)
519
+ return;
520
+ setConfirmError(true);
521
+ cancelRef.current?.focus();
522
+ });
523
+ return;
524
+ }
525
+ event.preventDefault();
526
+ if (disabled || isLoading || pendingRef.current)
527
+ return;
528
+ if (popoverRef.current?.matches(":popover-open")) {
529
+ closePopover();
530
+ return;
531
+ }
532
+ setConfirmError(false);
533
+ popoverRef.current?.showPopover();
534
+ cancelRef.current?.focus();
535
+ }
536
+ function handleConfirm(event) {
537
+ event.preventDefault();
538
+ event.stopPropagation();
539
+ const trigger = buttonRef.current;
540
+ if (disabled || isLoading || pendingRef.current || !trigger || trigger.disabled || !event.currentTarget.matches(":popover-open"))
541
+ return;
542
+ setConfirmError(false);
543
+ pendingRef.current = true;
544
+ actionRef.current += 1;
545
+ approvalRef.current = "action";
546
+ trigger.click();
547
+ if (approvalRef.current === "action") {
548
+ approvalRef.current = "idle";
549
+ pendingRef.current = false;
550
+ }
551
+ }
552
+ const classes = getButtonClasses({
553
+ color,
554
+ appearance,
555
+ shape,
556
+ size,
557
+ block,
558
+ isLoading,
559
+ className
560
+ });
561
+ const confirmClasses = getButtonClasses({
562
+ color,
563
+ size: "sm",
564
+ isLoading: confirmLoading
565
+ });
566
+ return /* @__PURE__ */ jsxs2(Fragment, {
567
+ children: [
568
+ /* @__PURE__ */ jsxs2("button", {
569
+ ref: confirm ? mergedRef : ref,
570
+ className: classes,
571
+ disabled: disabled || isLoading,
572
+ "aria-busy": isLoading,
573
+ "aria-disabled": disabled || isLoading,
574
+ ...props,
575
+ style: confirm ? { ...props.style, anchorName: anchor } : props.style,
576
+ "aria-haspopup": confirm ? "dialog" : props["aria-haspopup"],
577
+ "aria-controls": confirm ? popoverId : props["aria-controls"],
578
+ onClick: confirm ? handleClick : onClick,
579
+ children: [
580
+ isLoading && /* @__PURE__ */ jsx2("span", {
581
+ className: "btn-spinner"
582
+ }),
583
+ !isLoading && leftIcon && /* @__PURE__ */ jsx2("span", {
584
+ className: "btn-icon-left",
585
+ children: leftIcon
586
+ }),
587
+ /* @__PURE__ */ jsx2("span", {
588
+ className: "btn-content",
589
+ children
590
+ }),
591
+ !isLoading && rightIcon && /* @__PURE__ */ jsx2("span", {
592
+ className: "btn-icon-right",
593
+ children: rightIcon
594
+ })
595
+ ]
596
+ }),
597
+ confirm && portalTarget && createPortal(/* @__PURE__ */ jsxs2("form", {
598
+ id: popoverId,
599
+ ref: popoverRef,
600
+ popover: "auto",
601
+ role: "dialog",
602
+ "aria-labelledby": hasTitle ? titleId : undefined,
603
+ "aria-label": hasTitle ? undefined : "Confirm action",
604
+ "aria-describedby": hasContent ? descriptionId : undefined,
605
+ className: "popover popover-confirm popover-bottom",
606
+ style: { positionAnchor: anchor },
607
+ onSubmit: handleConfirm,
608
+ onClick: (event) => event.stopPropagation(),
609
+ onToggle: (event) => {
610
+ if (!event.currentTarget.matches(":popover-open")) {
611
+ operationRef.current += 1;
612
+ if (event.currentTarget.contains(document.activeElement) || document.activeElement === document.body) {
613
+ buttonRef.current?.focus();
614
+ }
615
+ }
616
+ },
617
+ children: [
618
+ hasTitle && /* @__PURE__ */ jsx2("div", {
619
+ className: "popover-header",
620
+ children: /* @__PURE__ */ jsx2("h3", {
621
+ id: titleId,
622
+ className: "popover-title",
623
+ children: title
624
+ })
625
+ }),
626
+ hasContent && /* @__PURE__ */ jsx2("div", {
627
+ id: descriptionId,
628
+ className: "popover-body",
629
+ children: content
630
+ }),
631
+ confirmError && /* @__PURE__ */ jsx2("div", {
632
+ role: "alert",
633
+ className: "popover-body",
634
+ children: "The action failed. Please try again."
635
+ }),
636
+ /* @__PURE__ */ jsxs2("div", {
637
+ className: "popover-footer",
638
+ children: [
639
+ /* @__PURE__ */ jsx2("button", {
640
+ ref: cancelRef,
641
+ type: "button",
642
+ className: "btn btn-text btn-sm",
643
+ popoverTarget: popoverId,
644
+ popoverTargetAction: "hide",
645
+ disabled: confirmLoading,
646
+ children: confirmation?.cancelText ?? "Cancel"
647
+ }),
648
+ /* @__PURE__ */ jsx2("button", {
649
+ type: "submit",
650
+ className: confirmClasses,
651
+ disabled: disabled || isLoading || confirmLoading,
652
+ "aria-busy": confirmLoading,
653
+ children: confirmation?.confirmText ?? "Confirm"
654
+ })
655
+ ]
656
+ })
657
+ ]
658
+ }), portalTarget)
659
+ ]
660
+ });
661
+ }
335
662
  // src/components/dm-menu/DmMenu.tsx
336
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
663
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
337
664
  function getMenuLabel(menu, locale) {
338
665
  return locale === "en-US" && menu.menuNameEn ? menu.menuNameEn : menu.menuName;
339
666
  }
340
667
  function renderIcon(icon) {
341
668
  if (!icon)
342
669
  return;
343
- return typeof icon === "string" ? /* @__PURE__ */ jsx2("span", {
670
+ return typeof icon === "string" ? /* @__PURE__ */ jsx3("span", {
344
671
  className: dmMenuProductIconClass,
345
672
  "aria-hidden": "true",
346
673
  children: icon
@@ -365,6 +692,28 @@ function toMenuItems(menus, locale, byKey) {
365
692
  function createDmMenuItems(menus, locale) {
366
693
  return toMenuItems(menus, locale);
367
694
  }
695
+ function presentMenuItem(item, collapsed) {
696
+ if (item.type === "divider")
697
+ return item;
698
+ const label = item.label ?? item.title;
699
+ const initial = typeof label === "string" ? label.trim().slice(0, 1) : "";
700
+ return {
701
+ ...item,
702
+ label: /* @__PURE__ */ jsx3("span", {
703
+ className: "dm-menu-item-label",
704
+ children: label
705
+ }),
706
+ icon: item.icon || collapsed ? /* @__PURE__ */ jsx3("span", {
707
+ "aria-hidden": "true",
708
+ className: "dm-menu-item-symbol",
709
+ children: item.icon || /* @__PURE__ */ jsx3("span", {
710
+ className: "dm-menu-item-initial",
711
+ children: initial || "•"
712
+ })
713
+ }) : undefined,
714
+ children: item.children?.map((child) => presentMenuItem(child, collapsed))
715
+ };
716
+ }
368
717
  var DmMenu = forwardRef2(({
369
718
  menus = [],
370
719
  items,
@@ -383,14 +732,14 @@ var DmMenu = forwardRef2(({
383
732
  menuByKey.clear();
384
733
  return toMenuItems(menus, locale, menuByKey);
385
734
  }, [locale, menuByKey, menus]);
386
- const contentItems = items ?? schemaItems;
735
+ const contentItems = (items ?? schemaItems).map((item) => presentMenuItem(item, inlineCollapsed));
387
736
  function handleClick(info) {
388
737
  onClick?.({
389
738
  ...info,
390
739
  menu: menuByKey.get(info.key)
391
740
  });
392
741
  }
393
- return /* @__PURE__ */ jsxs2("div", {
742
+ return /* @__PURE__ */ jsxs3("div", {
394
743
  ref,
395
744
  className: getDmMenuClasses({
396
745
  hideProductHeader,
@@ -398,25 +747,25 @@ var DmMenu = forwardRef2(({
398
747
  className
399
748
  }),
400
749
  children: [
401
- hideProductHeader ? null : /* @__PURE__ */ jsx2("div", {
750
+ hideProductHeader ? null : /* @__PURE__ */ jsx3("div", {
402
751
  className: dmMenuHeaderClass,
403
- children: /* @__PURE__ */ jsx2(Menu, {
752
+ children: /* @__PURE__ */ jsx3(Menu, {
404
753
  mode: "inline",
405
754
  inlineCollapsed,
406
755
  selectable: false,
407
756
  items: [
408
- {
757
+ presentMenuItem({
409
758
  key: "__product",
410
759
  label: productTitle,
411
760
  title: productTitle,
412
761
  icon: renderIcon(productIcon)
413
- }
762
+ }, inlineCollapsed)
414
763
  ]
415
764
  })
416
765
  }),
417
- /* @__PURE__ */ jsx2("div", {
766
+ /* @__PURE__ */ jsx3("div", {
418
767
  className: dmMenuContentClass,
419
- children: /* @__PURE__ */ jsx2(Menu, {
768
+ children: /* @__PURE__ */ jsx3(Menu, {
420
769
  ...props,
421
770
  mode: props.mode ?? "inline",
422
771
  items: contentItems,
@@ -424,14 +773,32 @@ var DmMenu = forwardRef2(({
424
773
  onClick: handleClick
425
774
  })
426
775
  }),
427
- onCollapsed ? /* @__PURE__ */ jsx2("div", {
776
+ onCollapsed ? /* @__PURE__ */ jsx3("div", {
428
777
  className: dmMenuFooterClass,
429
- children: /* @__PURE__ */ jsx2("button", {
778
+ children: /* @__PURE__ */ jsx3(Button, {
430
779
  type: "button",
780
+ color: "base",
781
+ appearance: "ghost",
782
+ shape: "square",
783
+ size: "sm",
431
784
  className: dmMenuCollapseButtonClass,
432
785
  "aria-label": inlineCollapsed ? "Expand menu" : "Collapse menu",
433
786
  onClick: onCollapsed,
434
- children: inlineCollapsed ? ">" : "<"
787
+ children: /* @__PURE__ */ jsx3("svg", {
788
+ "aria-hidden": "true",
789
+ focusable: "false",
790
+ width: "18",
791
+ height: "18",
792
+ viewBox: "0 0 24 24",
793
+ fill: "none",
794
+ stroke: "currentColor",
795
+ strokeWidth: "2",
796
+ strokeLinecap: "round",
797
+ strokeLinejoin: "round",
798
+ children: /* @__PURE__ */ jsx3("path", {
799
+ d: inlineCollapsed ? "m9 18 6-6-6-6" : "m15 18-6-6 6-6"
800
+ })
801
+ })
435
802
  })
436
803
  }) : null
437
804
  ]