elseware-ui 2.31.0 → 2.31.1

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
@@ -24,6 +24,7 @@ var reactBeautifulDnd = require('react-beautiful-dnd');
24
24
  var md = require('react-icons/md');
25
25
  require('@mdxeditor/editor/style.css');
26
26
  var editor = require('@mdxeditor/editor');
27
+ var bi = require('react-icons/bi');
27
28
 
28
29
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
29
30
 
@@ -3131,7 +3132,7 @@ var ShapeSwitch = () => {
3131
3132
  {
3132
3133
  value: currentShape,
3133
3134
  onChange: handleChange,
3134
- className: "\n px-3 py-2 rounded-md border border-gray-300\n bg-white dark:bg-gray-800\n text-sm shadow-sm\n focus:outline-none\n ",
3135
+ className: "\r\n px-3 py-2 rounded-md border border-gray-300\r\n bg-white dark:bg-gray-800\r\n text-sm shadow-sm\r\n focus:outline-none\r\n ",
3135
3136
  children: Object.keys(Shape).map((shape) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: shape, children: shape }, shape))
3136
3137
  }
3137
3138
  ) });
@@ -15741,7 +15742,7 @@ function Tags({
15741
15742
  var Tags_default = Tags;
15742
15743
  function TextArea({
15743
15744
  placeholder,
15744
- limit,
15745
+ limit = 1e3,
15745
15746
  styles,
15746
15747
  shape,
15747
15748
  ...props
@@ -16125,7 +16126,7 @@ function MarkdownTOC({ title = "Table of Contents" }) {
16125
16126
  /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
16126
16127
  "h2",
16127
16128
  {
16128
- className: "\n text-sm\n font-semibold\n uppercase\n tracking-wide\n text-gray-900\n dark:text-gray-100\n ",
16129
+ className: "\r\n text-sm\r\n font-semibold\r\n uppercase\r\n tracking-wide\r\n text-gray-900\r\n dark:text-gray-100\r\n ",
16129
16130
  children: title
16130
16131
  }
16131
16132
  ) }),
@@ -17454,7 +17455,7 @@ var GlowWrapper = ({
17454
17455
  /* @__PURE__ */ jsxRuntime.jsx(
17455
17456
  "span",
17456
17457
  {
17457
- className: "\n pointer-events-none absolute inset-0 opacity-0 \n group-hover:opacity-100 transition-opacity duration-300\n ",
17458
+ className: "\r\n pointer-events-none absolute inset-0 opacity-0 \r\n group-hover:opacity-100 transition-opacity duration-300\r\n ",
17458
17459
  style: { background: "var(--glow-bg)" }
17459
17460
  }
17460
17461
  ),
@@ -17485,6 +17486,436 @@ function ShowMore({ text, limit }) {
17485
17486
  ] });
17486
17487
  }
17487
17488
  var ShowMore_default = ShowMore;
17489
+ function CommentComposer({
17490
+ placeholder = "Add a comment...",
17491
+ submitLabel = "Comment",
17492
+ onSubmit
17493
+ }) {
17494
+ const [value, setValue] = React4.useState("");
17495
+ const [focused, setFocused] = React4.useState(false);
17496
+ async function handleSubmit() {
17497
+ if (!value.trim()) return;
17498
+ await onSubmit?.(value);
17499
+ setValue("");
17500
+ setFocused(false);
17501
+ }
17502
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-4", children: [
17503
+ /* @__PURE__ */ jsxRuntime.jsx(Avatar, { size: "md" }),
17504
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 flex flex-col gap-3", children: [
17505
+ /* @__PURE__ */ jsxRuntime.jsx(
17506
+ "textarea",
17507
+ {
17508
+ value,
17509
+ placeholder,
17510
+ onFocus: () => setFocused(true),
17511
+ onChange: (e) => setValue(e.target.value),
17512
+ className: "w-full min-h-[48px] bg-transparent border-b border-gray-300 dark:border-neutral-700 outline-none resize-none pb-2 text-sm"
17513
+ }
17514
+ ),
17515
+ (focused || value.length > 0) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
17516
+ /* @__PURE__ */ jsxRuntime.jsx(
17517
+ Button_default,
17518
+ {
17519
+ variant: "secondary",
17520
+ appearance: "ghost",
17521
+ text: "Cancel",
17522
+ onClick: () => {
17523
+ setValue("");
17524
+ setFocused(false);
17525
+ }
17526
+ }
17527
+ ),
17528
+ /* @__PURE__ */ jsxRuntime.jsx(
17529
+ Button_default,
17530
+ {
17531
+ variant: "primary",
17532
+ text: submitLabel,
17533
+ onClick: handleSubmit
17534
+ }
17535
+ )
17536
+ ] })
17537
+ ] })
17538
+ ] });
17539
+ }
17540
+ var CommentComposer_default = CommentComposer;
17541
+
17542
+ // src/compositions/comment-thread/utils/formatCommentDate.ts
17543
+ function formatCommentDate(date) {
17544
+ const now = /* @__PURE__ */ new Date();
17545
+ const target = new Date(date);
17546
+ const seconds = Math.floor((now.getTime() - target.getTime()) / 1e3);
17547
+ const intervals = [
17548
+ { label: "year", seconds: 31536e3 },
17549
+ { label: "month", seconds: 2592e3 },
17550
+ { label: "day", seconds: 86400 },
17551
+ { label: "hour", seconds: 3600 },
17552
+ { label: "minute", seconds: 60 }
17553
+ ];
17554
+ for (const interval of intervals) {
17555
+ const count = Math.floor(seconds / interval.seconds);
17556
+ if (count >= 1) {
17557
+ return `${count} ${interval.label}${count > 1 ? "s" : ""} ago`;
17558
+ }
17559
+ }
17560
+ return "Just now";
17561
+ }
17562
+ function CommentHeader({
17563
+ avatar,
17564
+ username,
17565
+ createdAt,
17566
+ edited
17567
+ }) {
17568
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [
17569
+ /* @__PURE__ */ jsxRuntime.jsx(Avatar, { src: avatar, size: "sm" }),
17570
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm flex-wrap", children: [
17571
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-semibold text-gray-900 dark:text-gray-100", children: [
17572
+ "@",
17573
+ username
17574
+ ] }),
17575
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-500 dark:text-gray-400", children: formatCommentDate(createdAt) }),
17576
+ edited && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-gray-400", children: "edited" })
17577
+ ] })
17578
+ ] });
17579
+ }
17580
+ var CommentHeader_default = CommentHeader;
17581
+ function CommentContent({ content }) {
17582
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm leading-relaxed whitespace-pre-wrap text-gray-700 dark:text-gray-300", children: content });
17583
+ }
17584
+ var CommentContent_default = CommentContent;
17585
+ function CommentActions({
17586
+ likes = 0,
17587
+ dislikes = 0,
17588
+ onLike,
17589
+ onDislike,
17590
+ onReply
17591
+ }) {
17592
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-5 text-sm text-gray-500 dark:text-gray-400", children: [
17593
+ /* @__PURE__ */ jsxRuntime.jsxs(
17594
+ "button",
17595
+ {
17596
+ onClick: onLike,
17597
+ className: "inline-flex items-center gap-1 hover:text-gray-900 dark:hover:text-gray-100 transition-colors",
17598
+ children: [
17599
+ /* @__PURE__ */ jsxRuntime.jsx(bi.BiLike, { size: 18 }),
17600
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: likes })
17601
+ ]
17602
+ }
17603
+ ),
17604
+ /* @__PURE__ */ jsxRuntime.jsxs(
17605
+ "button",
17606
+ {
17607
+ onClick: onDislike,
17608
+ className: "inline-flex items-center gap-1 hover:text-gray-900 dark:hover:text-gray-100 transition-colors",
17609
+ children: [
17610
+ /* @__PURE__ */ jsxRuntime.jsx(bi.BiDislike, { size: 18 }),
17611
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: dislikes })
17612
+ ]
17613
+ }
17614
+ ),
17615
+ /* @__PURE__ */ jsxRuntime.jsx(
17616
+ "button",
17617
+ {
17618
+ onClick: onReply,
17619
+ className: "font-medium hover:text-gray-900 dark:hover:text-gray-100 transition-colors",
17620
+ children: "Reply"
17621
+ }
17622
+ )
17623
+ ] });
17624
+ }
17625
+ var CommentActions_default = CommentActions;
17626
+ function CommentMenu({
17627
+ canEdit,
17628
+ canDelete,
17629
+ canReport,
17630
+ onEdit,
17631
+ onDelete,
17632
+ onReport
17633
+ }) {
17634
+ const [open, setOpen] = React4.useState(false);
17635
+ const ref = React4.useRef(null);
17636
+ React4.useEffect(() => {
17637
+ function handleOutsideClick(event) {
17638
+ if (ref.current && !ref.current.contains(event.target)) {
17639
+ setOpen(false);
17640
+ }
17641
+ }
17642
+ document.addEventListener("mousedown", handleOutsideClick);
17643
+ return () => document.removeEventListener("mousedown", handleOutsideClick);
17644
+ }, []);
17645
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: "relative", children: [
17646
+ /* @__PURE__ */ jsxRuntime.jsx(
17647
+ "button",
17648
+ {
17649
+ onClick: () => setOpen((prev) => !prev),
17650
+ className: "text-gray-500 hover:text-gray-900 dark:hover:text-gray-100 transition-colors",
17651
+ children: /* @__PURE__ */ jsxRuntime.jsx(bi.BiDotsVerticalRounded, { size: 18 })
17652
+ }
17653
+ ),
17654
+ open && /* @__PURE__ */ jsxRuntime.jsxs(
17655
+ "div",
17656
+ {
17657
+ className: "\r\n absolute\r\n right-0\r\n top-full\r\n mt-2\r\n min-w-[160px]\r\n overflow-hidden\r\n rounded-xl\r\n border\r\n border-gray-200\r\n dark:border-neutral-800\r\n bg-white\r\n dark:bg-neutral-900\r\n shadow-xl\r\n z-50\r\n ",
17658
+ children: [
17659
+ canEdit && /* @__PURE__ */ jsxRuntime.jsxs(
17660
+ "button",
17661
+ {
17662
+ onClick: () => {
17663
+ setOpen(false);
17664
+ onEdit?.();
17665
+ },
17666
+ className: "w-full flex items-center gap-2 px-4 py-3 text-sm hover:bg-gray-100 dark:hover:bg-neutral-800",
17667
+ children: [
17668
+ /* @__PURE__ */ jsxRuntime.jsx(bi.BiEdit, {}),
17669
+ "Edit"
17670
+ ]
17671
+ }
17672
+ ),
17673
+ canDelete && /* @__PURE__ */ jsxRuntime.jsxs(
17674
+ "button",
17675
+ {
17676
+ onClick: () => {
17677
+ setOpen(false);
17678
+ onDelete?.();
17679
+ },
17680
+ className: "w-full flex items-center gap-2 px-4 py-3 text-sm hover:bg-gray-100 dark:hover:bg-neutral-800",
17681
+ children: [
17682
+ /* @__PURE__ */ jsxRuntime.jsx(bi.BiTrash, {}),
17683
+ "Delete"
17684
+ ]
17685
+ }
17686
+ ),
17687
+ canReport && /* @__PURE__ */ jsxRuntime.jsxs(
17688
+ "button",
17689
+ {
17690
+ onClick: () => {
17691
+ setOpen(false);
17692
+ onReport?.();
17693
+ },
17694
+ className: "w-full flex items-center gap-2 px-4 py-3 text-sm hover:bg-gray-100 dark:hover:bg-neutral-800",
17695
+ children: [
17696
+ /* @__PURE__ */ jsxRuntime.jsx(bi.BiFlag, {}),
17697
+ "Report"
17698
+ ]
17699
+ }
17700
+ )
17701
+ ]
17702
+ }
17703
+ )
17704
+ ] });
17705
+ }
17706
+ var CommentMenu_default = CommentMenu;
17707
+ function CommentRepliesToggle({
17708
+ repliesCount,
17709
+ collapsed,
17710
+ onToggle
17711
+ }) {
17712
+ return /* @__PURE__ */ jsxRuntime.jsxs(
17713
+ "button",
17714
+ {
17715
+ onClick: onToggle,
17716
+ className: "inline-flex items-center gap-1 text-sm font-medium text-blue-500 hover:text-blue-400 transition-colors w-fit",
17717
+ children: [
17718
+ collapsed ? /* @__PURE__ */ jsxRuntime.jsx(bi.BiChevronDown, { size: 18 }) : /* @__PURE__ */ jsxRuntime.jsx(bi.BiChevronUp, { size: 18 }),
17719
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: collapsed ? `View ${repliesCount} repl${repliesCount > 1 ? "ies" : "y"}` : "Hide replies" })
17720
+ ]
17721
+ }
17722
+ );
17723
+ }
17724
+ var CommentRepliesToggle_default = CommentRepliesToggle;
17725
+ function ReplyComposer({ username, onSubmit }) {
17726
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-2", children: /* @__PURE__ */ jsxRuntime.jsx(
17727
+ CommentComposer_default,
17728
+ {
17729
+ placeholder: `Reply to @${username}`,
17730
+ submitLabel: "Reply",
17731
+ onSubmit
17732
+ }
17733
+ ) });
17734
+ }
17735
+ var ReplyComposer_default = ReplyComposer;
17736
+
17737
+ // src/compositions/comment-thread/constants/comment.constants.ts
17738
+ var MAX_COMMENT_DEPTH = 5;
17739
+ var COMMENT_INDENTATION = 0;
17740
+ function CommentItem({
17741
+ comment,
17742
+ depth = 0,
17743
+ onLike,
17744
+ onDislike,
17745
+ onReply,
17746
+ onEdit,
17747
+ onDelete,
17748
+ onReport
17749
+ }) {
17750
+ const [collapsed, setCollapsed] = React4.useState(false);
17751
+ const [isReplying, setIsReplying] = React4.useState(false);
17752
+ const resolvedDepth = Math.min(depth, MAX_COMMENT_DEPTH);
17753
+ async function handleReply(content) {
17754
+ console.log(content);
17755
+ setIsReplying(false);
17756
+ }
17757
+ return /* @__PURE__ */ jsxRuntime.jsxs(
17758
+ "div",
17759
+ {
17760
+ className: "flex flex-col gap-4",
17761
+ style: {
17762
+ paddingLeft: `${resolvedDepth * COMMENT_INDENTATION}px`
17763
+ },
17764
+ children: [
17765
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 flex flex-col gap-3 min-w-0", children: [
17766
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
17767
+ /* @__PURE__ */ jsxRuntime.jsx(
17768
+ CommentHeader_default,
17769
+ {
17770
+ avatar: comment.author.avatar,
17771
+ username: comment.author.username,
17772
+ createdAt: comment.createdAt,
17773
+ edited: comment.edited
17774
+ }
17775
+ ),
17776
+ /* @__PURE__ */ jsxRuntime.jsx(
17777
+ CommentMenu_default,
17778
+ {
17779
+ canEdit: comment.permissions?.canEdit,
17780
+ canDelete: comment.permissions?.canDelete,
17781
+ canReport: comment.permissions?.canReport,
17782
+ onEdit: () => onEdit?.(comment),
17783
+ onDelete: () => onDelete?.(comment),
17784
+ onReport: () => onReport?.(comment)
17785
+ }
17786
+ )
17787
+ ] }),
17788
+ /* @__PURE__ */ jsxRuntime.jsx(CommentContent_default, { content: comment.content }),
17789
+ /* @__PURE__ */ jsxRuntime.jsx(
17790
+ CommentActions_default,
17791
+ {
17792
+ likes: comment.likes,
17793
+ dislikes: comment.dislikes,
17794
+ onLike: () => onLike?.(comment),
17795
+ onDislike: () => onDislike?.(comment),
17796
+ onReply: () => {
17797
+ setIsReplying((prev) => !prev);
17798
+ onReply?.(comment);
17799
+ }
17800
+ }
17801
+ ),
17802
+ isReplying && /* @__PURE__ */ jsxRuntime.jsx(
17803
+ ReplyComposer_default,
17804
+ {
17805
+ username: comment.author.username,
17806
+ onSubmit: handleReply
17807
+ }
17808
+ ),
17809
+ !!comment.replies?.length && /* @__PURE__ */ jsxRuntime.jsx(
17810
+ CommentRepliesToggle_default,
17811
+ {
17812
+ collapsed,
17813
+ repliesCount: comment.replies.length,
17814
+ onToggle: () => setCollapsed((prev) => !prev)
17815
+ }
17816
+ )
17817
+ ] }) }),
17818
+ !collapsed && !!comment.replies?.length && /* @__PURE__ */ jsxRuntime.jsx(
17819
+ "div",
17820
+ {
17821
+ className: cn(
17822
+ "border-l border-gray-200 dark:border-neutral-800",
17823
+ "pl-4 ml-5"
17824
+ ),
17825
+ children: /* @__PURE__ */ jsxRuntime.jsx(
17826
+ CommentList_default,
17827
+ {
17828
+ comments: comment.replies,
17829
+ depth: depth + 1,
17830
+ onLike,
17831
+ onDislike,
17832
+ onReply,
17833
+ onEdit,
17834
+ onDelete,
17835
+ onReport
17836
+ }
17837
+ )
17838
+ }
17839
+ )
17840
+ ]
17841
+ }
17842
+ );
17843
+ }
17844
+ var CommentItem_default = CommentItem;
17845
+ function CommentList({
17846
+ comments,
17847
+ depth = 0,
17848
+ onLike,
17849
+ onDislike,
17850
+ onReply,
17851
+ onEdit,
17852
+ onDelete,
17853
+ onReport
17854
+ }) {
17855
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-8", children: comments.map((comment) => /* @__PURE__ */ jsxRuntime.jsx(
17856
+ CommentItem_default,
17857
+ {
17858
+ comment,
17859
+ depth,
17860
+ onLike,
17861
+ onDislike,
17862
+ onReply,
17863
+ onEdit,
17864
+ onDelete,
17865
+ onReport
17866
+ },
17867
+ comment.id
17868
+ )) });
17869
+ }
17870
+ var CommentList_default = CommentList;
17871
+ var CommentThreadContext = React4.createContext(null);
17872
+ function useCommentThread(initialComments) {
17873
+ const [comments, setComments] = React4.useState(initialComments);
17874
+ return {
17875
+ comments,
17876
+ setComments
17877
+ };
17878
+ }
17879
+ function CommentThread({
17880
+ comments: initialComments = [],
17881
+ onCommentCreate,
17882
+ onLike,
17883
+ onDislike,
17884
+ onReply,
17885
+ onEdit,
17886
+ onDelete,
17887
+ onReport
17888
+ }) {
17889
+ const { comments, setComments } = useCommentThread(initialComments);
17890
+ async function handleCreateComment(content) {
17891
+ await onCommentCreate?.(content);
17892
+ }
17893
+ return /* @__PURE__ */ jsxRuntime.jsx(
17894
+ CommentThreadContext.Provider,
17895
+ {
17896
+ value: {
17897
+ comments,
17898
+ setComments
17899
+ },
17900
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-8 w-full", children: [
17901
+ /* @__PURE__ */ jsxRuntime.jsx(CommentComposer_default, { onSubmit: handleCreateComment }),
17902
+ /* @__PURE__ */ jsxRuntime.jsx(
17903
+ CommentList_default,
17904
+ {
17905
+ comments,
17906
+ onLike,
17907
+ onDislike,
17908
+ onReply,
17909
+ onEdit,
17910
+ onDelete,
17911
+ onReport
17912
+ }
17913
+ )
17914
+ ] })
17915
+ }
17916
+ );
17917
+ }
17918
+ var CommentThread_default = CommentThread;
17488
17919
  function DataViewTable({
17489
17920
  title,
17490
17921
  columns,
@@ -18322,6 +18753,7 @@ exports.CloudinaryImage = CloudinaryImage_default;
18322
18753
  exports.CloudinaryProvider = CloudinaryProvider;
18323
18754
  exports.CloudinaryVideo = CloudinaryVideo_default;
18324
18755
  exports.Code = Code;
18756
+ exports.CommentThread = CommentThread_default;
18325
18757
  exports.Content = Content;
18326
18758
  exports.ContentArea = ContentArea_default;
18327
18759
  exports.DataView = DataView;