@almadar/ui 5.9.0 → 5.9.2

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.
@@ -32960,18 +32960,25 @@ function TableView({
32960
32960
  return dnd.enabled ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: dnd.wrapContainer(emptyNode) }) : emptyNode;
32961
32961
  }
32962
32962
  const lk = LOOKS[look];
32963
+ const hasActions = Boolean(itemActions && itemActions.length > 0);
32964
+ const gridTemplateColumns = [
32965
+ selectable ? "auto" : null,
32966
+ ...colDefs.map((c) => c.width ?? "minmax(0, 1fr)"),
32967
+ hasActions ? "auto" : null
32968
+ ].filter(Boolean).join(" ");
32963
32969
  const header = /* @__PURE__ */ jsxRuntime.jsxs(
32964
32970
  Box,
32965
32971
  {
32966
32972
  role: "row",
32973
+ style: { gridTemplateColumns },
32967
32974
  className: cn(
32968
- "flex items-center gap-3 sticky top-0 z-10",
32969
- "bg-[var(--color-surface-subtle)] border-b border-[var(--color-table-border)]",
32975
+ "grid items-center gap-3 sticky top-0 z-10",
32976
+ "bg-[var(--color-surface-subtle)] border-b border-[var(--color-border)]",
32970
32977
  "text-[var(--color-text-muted)] uppercase text-xs font-semibold tracking-wide",
32971
32978
  lk.headPad
32972
32979
  ),
32973
32980
  children: [
32974
- selectable && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-8 flex-shrink-0 flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(Checkbox, { checked: allSelected, onChange: toggleAll, "aria-label": "Select all rows" }) }),
32981
+ selectable && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(Checkbox, { checked: allSelected, onChange: toggleAll, "aria-label": "Select all rows" }) }),
32975
32982
  colDefs.map((col) => {
32976
32983
  const active = sortColumn === (col.field ?? col.key);
32977
32984
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -32981,7 +32988,6 @@ function TableView({
32981
32988
  onClick: () => handleSort(col),
32982
32989
  className: cn(
32983
32990
  "flex items-center gap-1 min-w-0",
32984
- col.width ?? "flex-1",
32985
32991
  alignClass[col.align ?? "left"],
32986
32992
  col.sortable && sortEvent && "cursor-pointer select-none hover:text-foreground"
32987
32993
  ),
@@ -33001,7 +33007,7 @@ function TableView({
33001
33007
  col.key
33002
33008
  );
33003
33009
  }),
33004
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-px flex-shrink-0", "aria-hidden": true })
33010
+ hasActions && /* @__PURE__ */ jsxRuntime.jsx(Box, { "aria-hidden": true })
33005
33011
  ]
33006
33012
  }
33007
33013
  );
@@ -33013,16 +33019,18 @@ function TableView({
33013
33019
  role: "row",
33014
33020
  "data-entity-row": true,
33015
33021
  "data-entity-id": id,
33022
+ style: !hasRenderProp ? { gridTemplateColumns } : void 0,
33016
33023
  className: cn(
33017
- "group flex items-center gap-3 transition-colors duration-fast",
33024
+ "group items-center gap-3 transition-colors duration-fast",
33025
+ hasRenderProp ? "flex" : "grid",
33018
33026
  lk.rowPad,
33019
- lk.divider && "border-b border-[var(--color-table-border)]",
33027
+ lk.divider && "border-b border-[var(--color-border)]",
33020
33028
  lk.striped && index % 2 === 1 && "bg-[var(--color-surface-subtle)]",
33021
33029
  "hover:bg-[var(--color-surface-subtle)]",
33022
- look === "bordered" && "[&>*]:border-r [&>*]:border-[var(--color-table-border)] [&>*:last-child]:border-r-0"
33030
+ look === "bordered" && "[&>*]:border-r [&>*]:border-[var(--color-border)] [&>*:last-child]:border-r-0"
33023
33031
  ),
33024
33032
  children: [
33025
- selectable && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-8 flex-shrink-0 flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(
33033
+ selectable && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(
33026
33034
  Checkbox,
33027
33035
  {
33028
33036
  checked: selected.has(id),
@@ -33034,7 +33042,6 @@ function TableView({
33034
33042
  const raw = getNestedValue(row, col.field ?? col.key);
33035
33043
  const cellBase = cn(
33036
33044
  "flex items-center min-w-0",
33037
- col.width ?? "flex-1",
33038
33045
  alignClass[col.align ?? "left"],
33039
33046
  weightClass[col.weight ?? "normal"],
33040
33047
  col.className
@@ -33042,7 +33049,7 @@ function TableView({
33042
33049
  if (col.format === "badge" && raw != null && raw !== "") {
33043
33050
  return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant4(String(raw)), size: "sm", children: String(raw) }) }, col.key);
33044
33051
  }
33045
- return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cn(cellBase, "truncate block"), children: formatCell(raw, col.format) }, col.key);
33052
+ return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: formatCell(raw, col.format) }) }, col.key);
33046
33053
  }),
33047
33054
  itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", className: "flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: itemActions.map((action, i) => /* @__PURE__ */ jsxRuntime.jsxs(
33048
33055
  Button,
@@ -37081,6 +37088,8 @@ var init_ReplyTree = __esm({
37081
37088
  const hasReplies = !!node.replies && node.replies.length > 0;
37082
37089
  const isCollapsed = collapsedSet.has(node.id);
37083
37090
  const atMaxDepth = depth >= maxDepth;
37091
+ const [replyOpen, setReplyOpen] = React98.useState(false);
37092
+ const [draft, setDraft] = React98.useState("");
37084
37093
  const handleVote = React98.useCallback(
37085
37094
  (next) => {
37086
37095
  onVote?.(node.id, next);
@@ -37090,8 +37099,19 @@ var init_ReplyTree = __esm({
37090
37099
  );
37091
37100
  const handleReply = React98.useCallback(() => {
37092
37101
  onReply?.(node.id);
37093
- if (replyEvent) eventBus.emit(`UI:${replyEvent}`, { parentNodeId: node.id });
37094
- }, [node.id, onReply, replyEvent, eventBus]);
37102
+ setReplyOpen((open) => !open);
37103
+ }, [node.id, onReply]);
37104
+ const handleSubmitReply = React98.useCallback(() => {
37105
+ const content = draft.trim();
37106
+ if (!content) return;
37107
+ if (replyEvent) eventBus.emit(`UI:${replyEvent}`, { parentNodeId: node.id, content });
37108
+ setDraft("");
37109
+ setReplyOpen(false);
37110
+ }, [node.id, draft, replyEvent, eventBus]);
37111
+ const handleCancelReply = React98.useCallback(() => {
37112
+ setDraft("");
37113
+ setReplyOpen(false);
37114
+ }, []);
37095
37115
  const handleFlag = React98.useCallback(() => {
37096
37116
  onFlag?.(node.id);
37097
37117
  if (flagEvent) eventBus.emit(`UI:${flagEvent}`, { nodeId: node.id });
@@ -37178,6 +37198,33 @@ var init_ReplyTree = __esm({
37178
37198
  }
37179
37199
  )
37180
37200
  ] }),
37201
+ replyOpen && /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "flex flex-col gap-2 mt-1", children: [
37202
+ /* @__PURE__ */ jsxRuntime.jsx(
37203
+ Input,
37204
+ {
37205
+ inputType: "textarea",
37206
+ rows: 2,
37207
+ value: draft,
37208
+ placeholder: `Reply to ${node.authorName}\u2026`,
37209
+ onChange: (e) => setDraft(e.target.value),
37210
+ "aria-label": `Reply to ${node.authorName}`
37211
+ }
37212
+ ),
37213
+ /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "flex flex-row gap-2 items-center", children: [
37214
+ /* @__PURE__ */ jsxRuntime.jsx(
37215
+ Button,
37216
+ {
37217
+ variant: "primary",
37218
+ size: "sm",
37219
+ leftIcon: "send",
37220
+ onClick: handleSubmitReply,
37221
+ disabled: !draft.trim(),
37222
+ children: "Send"
37223
+ }
37224
+ ),
37225
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", onClick: handleCancelReply, children: "Cancel" })
37226
+ ] })
37227
+ ] }),
37181
37228
  hasReplies && !isCollapsed && (atMaxDepth ? /* @__PURE__ */ jsxRuntime.jsx(
37182
37229
  Button,
37183
37230
  {
package/dist/avl/index.js CHANGED
@@ -32911,18 +32911,25 @@ function TableView({
32911
32911
  return dnd.enabled ? /* @__PURE__ */ jsx(Fragment, { children: dnd.wrapContainer(emptyNode) }) : emptyNode;
32912
32912
  }
32913
32913
  const lk = LOOKS[look];
32914
+ const hasActions = Boolean(itemActions && itemActions.length > 0);
32915
+ const gridTemplateColumns = [
32916
+ selectable ? "auto" : null,
32917
+ ...colDefs.map((c) => c.width ?? "minmax(0, 1fr)"),
32918
+ hasActions ? "auto" : null
32919
+ ].filter(Boolean).join(" ");
32914
32920
  const header = /* @__PURE__ */ jsxs(
32915
32921
  Box,
32916
32922
  {
32917
32923
  role: "row",
32924
+ style: { gridTemplateColumns },
32918
32925
  className: cn(
32919
- "flex items-center gap-3 sticky top-0 z-10",
32920
- "bg-[var(--color-surface-subtle)] border-b border-[var(--color-table-border)]",
32926
+ "grid items-center gap-3 sticky top-0 z-10",
32927
+ "bg-[var(--color-surface-subtle)] border-b border-[var(--color-border)]",
32921
32928
  "text-[var(--color-text-muted)] uppercase text-xs font-semibold tracking-wide",
32922
32929
  lk.headPad
32923
32930
  ),
32924
32931
  children: [
32925
- selectable && /* @__PURE__ */ jsx(Box, { className: "w-8 flex-shrink-0 flex items-center", children: /* @__PURE__ */ jsx(Checkbox, { checked: allSelected, onChange: toggleAll, "aria-label": "Select all rows" }) }),
32932
+ selectable && /* @__PURE__ */ jsx(Box, { className: "flex items-center", children: /* @__PURE__ */ jsx(Checkbox, { checked: allSelected, onChange: toggleAll, "aria-label": "Select all rows" }) }),
32926
32933
  colDefs.map((col) => {
32927
32934
  const active = sortColumn === (col.field ?? col.key);
32928
32935
  return /* @__PURE__ */ jsxs(
@@ -32932,7 +32939,6 @@ function TableView({
32932
32939
  onClick: () => handleSort(col),
32933
32940
  className: cn(
32934
32941
  "flex items-center gap-1 min-w-0",
32935
- col.width ?? "flex-1",
32936
32942
  alignClass[col.align ?? "left"],
32937
32943
  col.sortable && sortEvent && "cursor-pointer select-none hover:text-foreground"
32938
32944
  ),
@@ -32952,7 +32958,7 @@ function TableView({
32952
32958
  col.key
32953
32959
  );
32954
32960
  }),
32955
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(Box, { className: "w-px flex-shrink-0", "aria-hidden": true })
32961
+ hasActions && /* @__PURE__ */ jsx(Box, { "aria-hidden": true })
32956
32962
  ]
32957
32963
  }
32958
32964
  );
@@ -32964,16 +32970,18 @@ function TableView({
32964
32970
  role: "row",
32965
32971
  "data-entity-row": true,
32966
32972
  "data-entity-id": id,
32973
+ style: !hasRenderProp ? { gridTemplateColumns } : void 0,
32967
32974
  className: cn(
32968
- "group flex items-center gap-3 transition-colors duration-fast",
32975
+ "group items-center gap-3 transition-colors duration-fast",
32976
+ hasRenderProp ? "flex" : "grid",
32969
32977
  lk.rowPad,
32970
- lk.divider && "border-b border-[var(--color-table-border)]",
32978
+ lk.divider && "border-b border-[var(--color-border)]",
32971
32979
  lk.striped && index % 2 === 1 && "bg-[var(--color-surface-subtle)]",
32972
32980
  "hover:bg-[var(--color-surface-subtle)]",
32973
- look === "bordered" && "[&>*]:border-r [&>*]:border-[var(--color-table-border)] [&>*:last-child]:border-r-0"
32981
+ look === "bordered" && "[&>*]:border-r [&>*]:border-[var(--color-border)] [&>*:last-child]:border-r-0"
32974
32982
  ),
32975
32983
  children: [
32976
- selectable && /* @__PURE__ */ jsx(Box, { className: "w-8 flex-shrink-0 flex items-center", children: /* @__PURE__ */ jsx(
32984
+ selectable && /* @__PURE__ */ jsx(Box, { className: "flex items-center", children: /* @__PURE__ */ jsx(
32977
32985
  Checkbox,
32978
32986
  {
32979
32987
  checked: selected.has(id),
@@ -32985,7 +32993,6 @@ function TableView({
32985
32993
  const raw = getNestedValue(row, col.field ?? col.key);
32986
32994
  const cellBase = cn(
32987
32995
  "flex items-center min-w-0",
32988
- col.width ?? "flex-1",
32989
32996
  alignClass[col.align ?? "left"],
32990
32997
  weightClass[col.weight ?? "normal"],
32991
32998
  col.className
@@ -32993,7 +33000,7 @@ function TableView({
32993
33000
  if (col.format === "badge" && raw != null && raw !== "") {
32994
33001
  return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx(Badge, { variant: statusVariant4(String(raw)), size: "sm", children: String(raw) }) }, col.key);
32995
33002
  }
32996
- return /* @__PURE__ */ jsx(Box, { role: "cell", className: cn(cellBase, "truncate block"), children: formatCell(raw, col.format) }, col.key);
33003
+ return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx("span", { className: "truncate", children: formatCell(raw, col.format) }) }, col.key);
32997
33004
  }),
32998
33005
  itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: itemActions.map((action, i) => /* @__PURE__ */ jsxs(
32999
33006
  Button,
@@ -37032,6 +37039,8 @@ var init_ReplyTree = __esm({
37032
37039
  const hasReplies = !!node.replies && node.replies.length > 0;
37033
37040
  const isCollapsed = collapsedSet.has(node.id);
37034
37041
  const atMaxDepth = depth >= maxDepth;
37042
+ const [replyOpen, setReplyOpen] = useState(false);
37043
+ const [draft, setDraft] = useState("");
37035
37044
  const handleVote = useCallback(
37036
37045
  (next) => {
37037
37046
  onVote?.(node.id, next);
@@ -37041,8 +37050,19 @@ var init_ReplyTree = __esm({
37041
37050
  );
37042
37051
  const handleReply = useCallback(() => {
37043
37052
  onReply?.(node.id);
37044
- if (replyEvent) eventBus.emit(`UI:${replyEvent}`, { parentNodeId: node.id });
37045
- }, [node.id, onReply, replyEvent, eventBus]);
37053
+ setReplyOpen((open) => !open);
37054
+ }, [node.id, onReply]);
37055
+ const handleSubmitReply = useCallback(() => {
37056
+ const content = draft.trim();
37057
+ if (!content) return;
37058
+ if (replyEvent) eventBus.emit(`UI:${replyEvent}`, { parentNodeId: node.id, content });
37059
+ setDraft("");
37060
+ setReplyOpen(false);
37061
+ }, [node.id, draft, replyEvent, eventBus]);
37062
+ const handleCancelReply = useCallback(() => {
37063
+ setDraft("");
37064
+ setReplyOpen(false);
37065
+ }, []);
37046
37066
  const handleFlag = useCallback(() => {
37047
37067
  onFlag?.(node.id);
37048
37068
  if (flagEvent) eventBus.emit(`UI:${flagEvent}`, { nodeId: node.id });
@@ -37129,6 +37149,33 @@ var init_ReplyTree = __esm({
37129
37149
  }
37130
37150
  )
37131
37151
  ] }),
37152
+ replyOpen && /* @__PURE__ */ jsxs(Box, { className: "flex flex-col gap-2 mt-1", children: [
37153
+ /* @__PURE__ */ jsx(
37154
+ Input,
37155
+ {
37156
+ inputType: "textarea",
37157
+ rows: 2,
37158
+ value: draft,
37159
+ placeholder: `Reply to ${node.authorName}\u2026`,
37160
+ onChange: (e) => setDraft(e.target.value),
37161
+ "aria-label": `Reply to ${node.authorName}`
37162
+ }
37163
+ ),
37164
+ /* @__PURE__ */ jsxs(Box, { className: "flex flex-row gap-2 items-center", children: [
37165
+ /* @__PURE__ */ jsx(
37166
+ Button,
37167
+ {
37168
+ variant: "primary",
37169
+ size: "sm",
37170
+ leftIcon: "send",
37171
+ onClick: handleSubmitReply,
37172
+ disabled: !draft.trim(),
37173
+ children: "Send"
37174
+ }
37175
+ ),
37176
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: handleCancelReply, children: "Cancel" })
37177
+ ] })
37178
+ ] }),
37132
37179
  hasReplies && !isCollapsed && (atMaxDepth ? /* @__PURE__ */ jsx(
37133
37180
  Button,
37134
37181
  {
@@ -28419,18 +28419,25 @@ function TableView({
28419
28419
  return dnd.enabled ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: dnd.wrapContainer(emptyNode) }) : emptyNode;
28420
28420
  }
28421
28421
  const lk = LOOKS[look];
28422
+ const hasActions = Boolean(itemActions && itemActions.length > 0);
28423
+ const gridTemplateColumns = [
28424
+ selectable ? "auto" : null,
28425
+ ...colDefs.map((c) => c.width ?? "minmax(0, 1fr)"),
28426
+ hasActions ? "auto" : null
28427
+ ].filter(Boolean).join(" ");
28422
28428
  const header = /* @__PURE__ */ jsxRuntime.jsxs(
28423
28429
  exports.Box,
28424
28430
  {
28425
28431
  role: "row",
28432
+ style: { gridTemplateColumns },
28426
28433
  className: cn(
28427
- "flex items-center gap-3 sticky top-0 z-10",
28428
- "bg-[var(--color-surface-subtle)] border-b border-[var(--color-table-border)]",
28434
+ "grid items-center gap-3 sticky top-0 z-10",
28435
+ "bg-[var(--color-surface-subtle)] border-b border-[var(--color-border)]",
28429
28436
  "text-[var(--color-text-muted)] uppercase text-xs font-semibold tracking-wide",
28430
28437
  lk.headPad
28431
28438
  ),
28432
28439
  children: [
28433
- selectable && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "w-8 flex-shrink-0 flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Checkbox, { checked: allSelected, onChange: toggleAll, "aria-label": "Select all rows" }) }),
28440
+ selectable && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Checkbox, { checked: allSelected, onChange: toggleAll, "aria-label": "Select all rows" }) }),
28434
28441
  colDefs.map((col) => {
28435
28442
  const active = sortColumn === (col.field ?? col.key);
28436
28443
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -28440,7 +28447,6 @@ function TableView({
28440
28447
  onClick: () => handleSort(col),
28441
28448
  className: cn(
28442
28449
  "flex items-center gap-1 min-w-0",
28443
- col.width ?? "flex-1",
28444
28450
  alignClass[col.align ?? "left"],
28445
28451
  col.sortable && sortEvent && "cursor-pointer select-none hover:text-foreground"
28446
28452
  ),
@@ -28460,7 +28466,7 @@ function TableView({
28460
28466
  col.key
28461
28467
  );
28462
28468
  }),
28463
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "w-px flex-shrink-0", "aria-hidden": true })
28469
+ hasActions && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { "aria-hidden": true })
28464
28470
  ]
28465
28471
  }
28466
28472
  );
@@ -28472,16 +28478,18 @@ function TableView({
28472
28478
  role: "row",
28473
28479
  "data-entity-row": true,
28474
28480
  "data-entity-id": id,
28481
+ style: !hasRenderProp ? { gridTemplateColumns } : void 0,
28475
28482
  className: cn(
28476
- "group flex items-center gap-3 transition-colors duration-fast",
28483
+ "group items-center gap-3 transition-colors duration-fast",
28484
+ hasRenderProp ? "flex" : "grid",
28477
28485
  lk.rowPad,
28478
- lk.divider && "border-b border-[var(--color-table-border)]",
28486
+ lk.divider && "border-b border-[var(--color-border)]",
28479
28487
  lk.striped && index % 2 === 1 && "bg-[var(--color-surface-subtle)]",
28480
28488
  "hover:bg-[var(--color-surface-subtle)]",
28481
- look === "bordered" && "[&>*]:border-r [&>*]:border-[var(--color-table-border)] [&>*:last-child]:border-r-0"
28489
+ look === "bordered" && "[&>*]:border-r [&>*]:border-[var(--color-border)] [&>*:last-child]:border-r-0"
28482
28490
  ),
28483
28491
  children: [
28484
- selectable && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "w-8 flex-shrink-0 flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(
28492
+ selectable && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(
28485
28493
  exports.Checkbox,
28486
28494
  {
28487
28495
  checked: selected.has(id),
@@ -28493,7 +28501,6 @@ function TableView({
28493
28501
  const raw = getNestedValue(row, col.field ?? col.key);
28494
28502
  const cellBase = cn(
28495
28503
  "flex items-center min-w-0",
28496
- col.width ?? "flex-1",
28497
28504
  alignClass[col.align ?? "left"],
28498
28505
  weightClass[col.weight ?? "normal"],
28499
28506
  col.className
@@ -28501,7 +28508,7 @@ function TableView({
28501
28508
  if (col.format === "badge" && raw != null && raw !== "") {
28502
28509
  return /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx(exports.Badge, { variant: statusVariant4(String(raw)), size: "sm", children: String(raw) }) }, col.key);
28503
28510
  }
28504
- return /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { role: "cell", className: cn(cellBase, "truncate block"), children: formatCell(raw, col.format) }, col.key);
28511
+ return /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: formatCell(raw, col.format) }) }, col.key);
28505
28512
  }),
28506
28513
  itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(exports.HStack, { gap: "xs", className: "flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: itemActions.map((action, i) => /* @__PURE__ */ jsxRuntime.jsxs(
28507
28514
  exports.Button,
@@ -32540,6 +32547,8 @@ var init_ReplyTree = __esm({
32540
32547
  const hasReplies = !!node.replies && node.replies.length > 0;
32541
32548
  const isCollapsed = collapsedSet.has(node.id);
32542
32549
  const atMaxDepth = depth >= maxDepth;
32550
+ const [replyOpen, setReplyOpen] = React80.useState(false);
32551
+ const [draft, setDraft] = React80.useState("");
32543
32552
  const handleVote = React80.useCallback(
32544
32553
  (next) => {
32545
32554
  onVote?.(node.id, next);
@@ -32549,8 +32558,19 @@ var init_ReplyTree = __esm({
32549
32558
  );
32550
32559
  const handleReply = React80.useCallback(() => {
32551
32560
  onReply?.(node.id);
32552
- if (replyEvent) eventBus.emit(`UI:${replyEvent}`, { parentNodeId: node.id });
32553
- }, [node.id, onReply, replyEvent, eventBus]);
32561
+ setReplyOpen((open) => !open);
32562
+ }, [node.id, onReply]);
32563
+ const handleSubmitReply = React80.useCallback(() => {
32564
+ const content = draft.trim();
32565
+ if (!content) return;
32566
+ if (replyEvent) eventBus.emit(`UI:${replyEvent}`, { parentNodeId: node.id, content });
32567
+ setDraft("");
32568
+ setReplyOpen(false);
32569
+ }, [node.id, draft, replyEvent, eventBus]);
32570
+ const handleCancelReply = React80.useCallback(() => {
32571
+ setDraft("");
32572
+ setReplyOpen(false);
32573
+ }, []);
32554
32574
  const handleFlag = React80.useCallback(() => {
32555
32575
  onFlag?.(node.id);
32556
32576
  if (flagEvent) eventBus.emit(`UI:${flagEvent}`, { nodeId: node.id });
@@ -32637,6 +32657,33 @@ var init_ReplyTree = __esm({
32637
32657
  }
32638
32658
  )
32639
32659
  ] }),
32660
+ replyOpen && /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: "flex flex-col gap-2 mt-1", children: [
32661
+ /* @__PURE__ */ jsxRuntime.jsx(
32662
+ exports.Input,
32663
+ {
32664
+ inputType: "textarea",
32665
+ rows: 2,
32666
+ value: draft,
32667
+ placeholder: `Reply to ${node.authorName}\u2026`,
32668
+ onChange: (e) => setDraft(e.target.value),
32669
+ "aria-label": `Reply to ${node.authorName}`
32670
+ }
32671
+ ),
32672
+ /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: "flex flex-row gap-2 items-center", children: [
32673
+ /* @__PURE__ */ jsxRuntime.jsx(
32674
+ exports.Button,
32675
+ {
32676
+ variant: "primary",
32677
+ size: "sm",
32678
+ leftIcon: "send",
32679
+ onClick: handleSubmitReply,
32680
+ disabled: !draft.trim(),
32681
+ children: "Send"
32682
+ }
32683
+ ),
32684
+ /* @__PURE__ */ jsxRuntime.jsx(exports.Button, { variant: "ghost", size: "sm", onClick: handleCancelReply, children: "Cancel" })
32685
+ ] })
32686
+ ] }),
32640
32687
  hasReplies && !isCollapsed && (atMaxDepth ? /* @__PURE__ */ jsxRuntime.jsx(
32641
32688
  exports.Button,
32642
32689
  {
@@ -28370,18 +28370,25 @@ function TableView({
28370
28370
  return dnd.enabled ? /* @__PURE__ */ jsx(Fragment, { children: dnd.wrapContainer(emptyNode) }) : emptyNode;
28371
28371
  }
28372
28372
  const lk = LOOKS[look];
28373
+ const hasActions = Boolean(itemActions && itemActions.length > 0);
28374
+ const gridTemplateColumns = [
28375
+ selectable ? "auto" : null,
28376
+ ...colDefs.map((c) => c.width ?? "minmax(0, 1fr)"),
28377
+ hasActions ? "auto" : null
28378
+ ].filter(Boolean).join(" ");
28373
28379
  const header = /* @__PURE__ */ jsxs(
28374
28380
  Box,
28375
28381
  {
28376
28382
  role: "row",
28383
+ style: { gridTemplateColumns },
28377
28384
  className: cn(
28378
- "flex items-center gap-3 sticky top-0 z-10",
28379
- "bg-[var(--color-surface-subtle)] border-b border-[var(--color-table-border)]",
28385
+ "grid items-center gap-3 sticky top-0 z-10",
28386
+ "bg-[var(--color-surface-subtle)] border-b border-[var(--color-border)]",
28380
28387
  "text-[var(--color-text-muted)] uppercase text-xs font-semibold tracking-wide",
28381
28388
  lk.headPad
28382
28389
  ),
28383
28390
  children: [
28384
- selectable && /* @__PURE__ */ jsx(Box, { className: "w-8 flex-shrink-0 flex items-center", children: /* @__PURE__ */ jsx(Checkbox, { checked: allSelected, onChange: toggleAll, "aria-label": "Select all rows" }) }),
28391
+ selectable && /* @__PURE__ */ jsx(Box, { className: "flex items-center", children: /* @__PURE__ */ jsx(Checkbox, { checked: allSelected, onChange: toggleAll, "aria-label": "Select all rows" }) }),
28385
28392
  colDefs.map((col) => {
28386
28393
  const active = sortColumn === (col.field ?? col.key);
28387
28394
  return /* @__PURE__ */ jsxs(
@@ -28391,7 +28398,6 @@ function TableView({
28391
28398
  onClick: () => handleSort(col),
28392
28399
  className: cn(
28393
28400
  "flex items-center gap-1 min-w-0",
28394
- col.width ?? "flex-1",
28395
28401
  alignClass[col.align ?? "left"],
28396
28402
  col.sortable && sortEvent && "cursor-pointer select-none hover:text-foreground"
28397
28403
  ),
@@ -28411,7 +28417,7 @@ function TableView({
28411
28417
  col.key
28412
28418
  );
28413
28419
  }),
28414
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(Box, { className: "w-px flex-shrink-0", "aria-hidden": true })
28420
+ hasActions && /* @__PURE__ */ jsx(Box, { "aria-hidden": true })
28415
28421
  ]
28416
28422
  }
28417
28423
  );
@@ -28423,16 +28429,18 @@ function TableView({
28423
28429
  role: "row",
28424
28430
  "data-entity-row": true,
28425
28431
  "data-entity-id": id,
28432
+ style: !hasRenderProp ? { gridTemplateColumns } : void 0,
28426
28433
  className: cn(
28427
- "group flex items-center gap-3 transition-colors duration-fast",
28434
+ "group items-center gap-3 transition-colors duration-fast",
28435
+ hasRenderProp ? "flex" : "grid",
28428
28436
  lk.rowPad,
28429
- lk.divider && "border-b border-[var(--color-table-border)]",
28437
+ lk.divider && "border-b border-[var(--color-border)]",
28430
28438
  lk.striped && index % 2 === 1 && "bg-[var(--color-surface-subtle)]",
28431
28439
  "hover:bg-[var(--color-surface-subtle)]",
28432
- look === "bordered" && "[&>*]:border-r [&>*]:border-[var(--color-table-border)] [&>*:last-child]:border-r-0"
28440
+ look === "bordered" && "[&>*]:border-r [&>*]:border-[var(--color-border)] [&>*:last-child]:border-r-0"
28433
28441
  ),
28434
28442
  children: [
28435
- selectable && /* @__PURE__ */ jsx(Box, { className: "w-8 flex-shrink-0 flex items-center", children: /* @__PURE__ */ jsx(
28443
+ selectable && /* @__PURE__ */ jsx(Box, { className: "flex items-center", children: /* @__PURE__ */ jsx(
28436
28444
  Checkbox,
28437
28445
  {
28438
28446
  checked: selected.has(id),
@@ -28444,7 +28452,6 @@ function TableView({
28444
28452
  const raw = getNestedValue(row, col.field ?? col.key);
28445
28453
  const cellBase = cn(
28446
28454
  "flex items-center min-w-0",
28447
- col.width ?? "flex-1",
28448
28455
  alignClass[col.align ?? "left"],
28449
28456
  weightClass[col.weight ?? "normal"],
28450
28457
  col.className
@@ -28452,7 +28459,7 @@ function TableView({
28452
28459
  if (col.format === "badge" && raw != null && raw !== "") {
28453
28460
  return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx(Badge, { variant: statusVariant4(String(raw)), size: "sm", children: String(raw) }) }, col.key);
28454
28461
  }
28455
- return /* @__PURE__ */ jsx(Box, { role: "cell", className: cn(cellBase, "truncate block"), children: formatCell(raw, col.format) }, col.key);
28462
+ return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx("span", { className: "truncate", children: formatCell(raw, col.format) }) }, col.key);
28456
28463
  }),
28457
28464
  itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: itemActions.map((action, i) => /* @__PURE__ */ jsxs(
28458
28465
  Button,
@@ -32491,6 +32498,8 @@ var init_ReplyTree = __esm({
32491
32498
  const hasReplies = !!node.replies && node.replies.length > 0;
32492
32499
  const isCollapsed = collapsedSet.has(node.id);
32493
32500
  const atMaxDepth = depth >= maxDepth;
32501
+ const [replyOpen, setReplyOpen] = useState(false);
32502
+ const [draft, setDraft] = useState("");
32494
32503
  const handleVote = useCallback(
32495
32504
  (next) => {
32496
32505
  onVote?.(node.id, next);
@@ -32500,8 +32509,19 @@ var init_ReplyTree = __esm({
32500
32509
  );
32501
32510
  const handleReply = useCallback(() => {
32502
32511
  onReply?.(node.id);
32503
- if (replyEvent) eventBus.emit(`UI:${replyEvent}`, { parentNodeId: node.id });
32504
- }, [node.id, onReply, replyEvent, eventBus]);
32512
+ setReplyOpen((open) => !open);
32513
+ }, [node.id, onReply]);
32514
+ const handleSubmitReply = useCallback(() => {
32515
+ const content = draft.trim();
32516
+ if (!content) return;
32517
+ if (replyEvent) eventBus.emit(`UI:${replyEvent}`, { parentNodeId: node.id, content });
32518
+ setDraft("");
32519
+ setReplyOpen(false);
32520
+ }, [node.id, draft, replyEvent, eventBus]);
32521
+ const handleCancelReply = useCallback(() => {
32522
+ setDraft("");
32523
+ setReplyOpen(false);
32524
+ }, []);
32505
32525
  const handleFlag = useCallback(() => {
32506
32526
  onFlag?.(node.id);
32507
32527
  if (flagEvent) eventBus.emit(`UI:${flagEvent}`, { nodeId: node.id });
@@ -32588,6 +32608,33 @@ var init_ReplyTree = __esm({
32588
32608
  }
32589
32609
  )
32590
32610
  ] }),
32611
+ replyOpen && /* @__PURE__ */ jsxs(Box, { className: "flex flex-col gap-2 mt-1", children: [
32612
+ /* @__PURE__ */ jsx(
32613
+ Input,
32614
+ {
32615
+ inputType: "textarea",
32616
+ rows: 2,
32617
+ value: draft,
32618
+ placeholder: `Reply to ${node.authorName}\u2026`,
32619
+ onChange: (e) => setDraft(e.target.value),
32620
+ "aria-label": `Reply to ${node.authorName}`
32621
+ }
32622
+ ),
32623
+ /* @__PURE__ */ jsxs(Box, { className: "flex flex-row gap-2 items-center", children: [
32624
+ /* @__PURE__ */ jsx(
32625
+ Button,
32626
+ {
32627
+ variant: "primary",
32628
+ size: "sm",
32629
+ leftIcon: "send",
32630
+ onClick: handleSubmitReply,
32631
+ disabled: !draft.trim(),
32632
+ children: "Send"
32633
+ }
32634
+ ),
32635
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: handleCancelReply, children: "Cancel" })
32636
+ ] })
32637
+ ] }),
32591
32638
  hasReplies && !isCollapsed && (atMaxDepth ? /* @__PURE__ */ jsx(
32592
32639
  Button,
32593
32640
  {
@@ -31,6 +31,7 @@ export interface ReplyTreeProps {
31
31
  }>;
32
32
  replyEvent?: EventEmit<{
33
33
  parentNodeId: string;
34
+ content: string;
34
35
  }>;
35
36
  flagEvent?: EventEmit<{
36
37
  nodeId: string;
@@ -23,7 +23,9 @@ export interface TableViewColumn {
23
23
  header?: string;
24
24
  /** Accessibility / fallback label. */
25
25
  label?: string;
26
- /** Width utility class applied to header + body cells (e.g. "w-28", "flex-1", "min-w-[10rem]"). */
26
+ /** CSS grid track size for this column (e.g. "7rem", "minmax(10rem, 1.5fr)",
27
+ * "1fr"). Shared across header + body so columns align. Defaults to
28
+ * "minmax(0, 1fr)" (equal flexible share). */
27
29
  width?: string;
28
30
  /** Horizontal alignment of the column's cells. */
29
31
  align?: 'left' | 'center' | 'right';
@@ -29372,18 +29372,25 @@ function TableView({
29372
29372
  return dnd.enabled ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: dnd.wrapContainer(emptyNode) }) : emptyNode;
29373
29373
  }
29374
29374
  const lk = LOOKS[look];
29375
+ const hasActions = Boolean(itemActions && itemActions.length > 0);
29376
+ const gridTemplateColumns = [
29377
+ selectable ? "auto" : null,
29378
+ ...colDefs.map((c) => c.width ?? "minmax(0, 1fr)"),
29379
+ hasActions ? "auto" : null
29380
+ ].filter(Boolean).join(" ");
29375
29381
  const header = /* @__PURE__ */ jsxRuntime.jsxs(
29376
29382
  Box,
29377
29383
  {
29378
29384
  role: "row",
29385
+ style: { gridTemplateColumns },
29379
29386
  className: cn(
29380
- "flex items-center gap-3 sticky top-0 z-10",
29381
- "bg-[var(--color-surface-subtle)] border-b border-[var(--color-table-border)]",
29387
+ "grid items-center gap-3 sticky top-0 z-10",
29388
+ "bg-[var(--color-surface-subtle)] border-b border-[var(--color-border)]",
29382
29389
  "text-[var(--color-text-muted)] uppercase text-xs font-semibold tracking-wide",
29383
29390
  lk.headPad
29384
29391
  ),
29385
29392
  children: [
29386
- selectable && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-8 flex-shrink-0 flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(Checkbox, { checked: allSelected, onChange: toggleAll, "aria-label": "Select all rows" }) }),
29393
+ selectable && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(Checkbox, { checked: allSelected, onChange: toggleAll, "aria-label": "Select all rows" }) }),
29387
29394
  colDefs.map((col) => {
29388
29395
  const active = sortColumn === (col.field ?? col.key);
29389
29396
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -29393,7 +29400,6 @@ function TableView({
29393
29400
  onClick: () => handleSort(col),
29394
29401
  className: cn(
29395
29402
  "flex items-center gap-1 min-w-0",
29396
- col.width ?? "flex-1",
29397
29403
  alignClass[col.align ?? "left"],
29398
29404
  col.sortable && sortEvent && "cursor-pointer select-none hover:text-foreground"
29399
29405
  ),
@@ -29413,7 +29419,7 @@ function TableView({
29413
29419
  col.key
29414
29420
  );
29415
29421
  }),
29416
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-px flex-shrink-0", "aria-hidden": true })
29422
+ hasActions && /* @__PURE__ */ jsxRuntime.jsx(Box, { "aria-hidden": true })
29417
29423
  ]
29418
29424
  }
29419
29425
  );
@@ -29425,16 +29431,18 @@ function TableView({
29425
29431
  role: "row",
29426
29432
  "data-entity-row": true,
29427
29433
  "data-entity-id": id,
29434
+ style: !hasRenderProp ? { gridTemplateColumns } : void 0,
29428
29435
  className: cn(
29429
- "group flex items-center gap-3 transition-colors duration-fast",
29436
+ "group items-center gap-3 transition-colors duration-fast",
29437
+ hasRenderProp ? "flex" : "grid",
29430
29438
  lk.rowPad,
29431
- lk.divider && "border-b border-[var(--color-table-border)]",
29439
+ lk.divider && "border-b border-[var(--color-border)]",
29432
29440
  lk.striped && index % 2 === 1 && "bg-[var(--color-surface-subtle)]",
29433
29441
  "hover:bg-[var(--color-surface-subtle)]",
29434
- look === "bordered" && "[&>*]:border-r [&>*]:border-[var(--color-table-border)] [&>*:last-child]:border-r-0"
29442
+ look === "bordered" && "[&>*]:border-r [&>*]:border-[var(--color-border)] [&>*:last-child]:border-r-0"
29435
29443
  ),
29436
29444
  children: [
29437
- selectable && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-8 flex-shrink-0 flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(
29445
+ selectable && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(
29438
29446
  Checkbox,
29439
29447
  {
29440
29448
  checked: selected.has(id),
@@ -29446,7 +29454,6 @@ function TableView({
29446
29454
  const raw = getNestedValue(row, col.field ?? col.key);
29447
29455
  const cellBase = cn(
29448
29456
  "flex items-center min-w-0",
29449
- col.width ?? "flex-1",
29450
29457
  alignClass[col.align ?? "left"],
29451
29458
  weightClass[col.weight ?? "normal"],
29452
29459
  col.className
@@ -29454,7 +29461,7 @@ function TableView({
29454
29461
  if (col.format === "badge" && raw != null && raw !== "") {
29455
29462
  return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant4(String(raw)), size: "sm", children: String(raw) }) }, col.key);
29456
29463
  }
29457
- return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cn(cellBase, "truncate block"), children: formatCell(raw, col.format) }, col.key);
29464
+ return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: formatCell(raw, col.format) }) }, col.key);
29458
29465
  }),
29459
29466
  itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", className: "flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: itemActions.map((action, i) => /* @__PURE__ */ jsxRuntime.jsxs(
29460
29467
  Button,
@@ -33493,6 +33500,8 @@ var init_ReplyTree = __esm({
33493
33500
  const hasReplies = !!node.replies && node.replies.length > 0;
33494
33501
  const isCollapsed = collapsedSet.has(node.id);
33495
33502
  const atMaxDepth = depth >= maxDepth;
33503
+ const [replyOpen, setReplyOpen] = React86.useState(false);
33504
+ const [draft, setDraft] = React86.useState("");
33496
33505
  const handleVote = React86.useCallback(
33497
33506
  (next) => {
33498
33507
  onVote?.(node.id, next);
@@ -33502,8 +33511,19 @@ var init_ReplyTree = __esm({
33502
33511
  );
33503
33512
  const handleReply = React86.useCallback(() => {
33504
33513
  onReply?.(node.id);
33505
- if (replyEvent) eventBus.emit(`UI:${replyEvent}`, { parentNodeId: node.id });
33506
- }, [node.id, onReply, replyEvent, eventBus]);
33514
+ setReplyOpen((open) => !open);
33515
+ }, [node.id, onReply]);
33516
+ const handleSubmitReply = React86.useCallback(() => {
33517
+ const content = draft.trim();
33518
+ if (!content) return;
33519
+ if (replyEvent) eventBus.emit(`UI:${replyEvent}`, { parentNodeId: node.id, content });
33520
+ setDraft("");
33521
+ setReplyOpen(false);
33522
+ }, [node.id, draft, replyEvent, eventBus]);
33523
+ const handleCancelReply = React86.useCallback(() => {
33524
+ setDraft("");
33525
+ setReplyOpen(false);
33526
+ }, []);
33507
33527
  const handleFlag = React86.useCallback(() => {
33508
33528
  onFlag?.(node.id);
33509
33529
  if (flagEvent) eventBus.emit(`UI:${flagEvent}`, { nodeId: node.id });
@@ -33590,6 +33610,33 @@ var init_ReplyTree = __esm({
33590
33610
  }
33591
33611
  )
33592
33612
  ] }),
33613
+ replyOpen && /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "flex flex-col gap-2 mt-1", children: [
33614
+ /* @__PURE__ */ jsxRuntime.jsx(
33615
+ Input,
33616
+ {
33617
+ inputType: "textarea",
33618
+ rows: 2,
33619
+ value: draft,
33620
+ placeholder: `Reply to ${node.authorName}\u2026`,
33621
+ onChange: (e) => setDraft(e.target.value),
33622
+ "aria-label": `Reply to ${node.authorName}`
33623
+ }
33624
+ ),
33625
+ /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "flex flex-row gap-2 items-center", children: [
33626
+ /* @__PURE__ */ jsxRuntime.jsx(
33627
+ Button,
33628
+ {
33629
+ variant: "primary",
33630
+ size: "sm",
33631
+ leftIcon: "send",
33632
+ onClick: handleSubmitReply,
33633
+ disabled: !draft.trim(),
33634
+ children: "Send"
33635
+ }
33636
+ ),
33637
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", onClick: handleCancelReply, children: "Cancel" })
33638
+ ] })
33639
+ ] }),
33593
33640
  hasReplies && !isCollapsed && (atMaxDepth ? /* @__PURE__ */ jsxRuntime.jsx(
33594
33641
  Button,
33595
33642
  {
@@ -29323,18 +29323,25 @@ function TableView({
29323
29323
  return dnd.enabled ? /* @__PURE__ */ jsx(Fragment, { children: dnd.wrapContainer(emptyNode) }) : emptyNode;
29324
29324
  }
29325
29325
  const lk = LOOKS[look];
29326
+ const hasActions = Boolean(itemActions && itemActions.length > 0);
29327
+ const gridTemplateColumns = [
29328
+ selectable ? "auto" : null,
29329
+ ...colDefs.map((c) => c.width ?? "minmax(0, 1fr)"),
29330
+ hasActions ? "auto" : null
29331
+ ].filter(Boolean).join(" ");
29326
29332
  const header = /* @__PURE__ */ jsxs(
29327
29333
  Box,
29328
29334
  {
29329
29335
  role: "row",
29336
+ style: { gridTemplateColumns },
29330
29337
  className: cn(
29331
- "flex items-center gap-3 sticky top-0 z-10",
29332
- "bg-[var(--color-surface-subtle)] border-b border-[var(--color-table-border)]",
29338
+ "grid items-center gap-3 sticky top-0 z-10",
29339
+ "bg-[var(--color-surface-subtle)] border-b border-[var(--color-border)]",
29333
29340
  "text-[var(--color-text-muted)] uppercase text-xs font-semibold tracking-wide",
29334
29341
  lk.headPad
29335
29342
  ),
29336
29343
  children: [
29337
- selectable && /* @__PURE__ */ jsx(Box, { className: "w-8 flex-shrink-0 flex items-center", children: /* @__PURE__ */ jsx(Checkbox, { checked: allSelected, onChange: toggleAll, "aria-label": "Select all rows" }) }),
29344
+ selectable && /* @__PURE__ */ jsx(Box, { className: "flex items-center", children: /* @__PURE__ */ jsx(Checkbox, { checked: allSelected, onChange: toggleAll, "aria-label": "Select all rows" }) }),
29338
29345
  colDefs.map((col) => {
29339
29346
  const active = sortColumn === (col.field ?? col.key);
29340
29347
  return /* @__PURE__ */ jsxs(
@@ -29344,7 +29351,6 @@ function TableView({
29344
29351
  onClick: () => handleSort(col),
29345
29352
  className: cn(
29346
29353
  "flex items-center gap-1 min-w-0",
29347
- col.width ?? "flex-1",
29348
29354
  alignClass[col.align ?? "left"],
29349
29355
  col.sortable && sortEvent && "cursor-pointer select-none hover:text-foreground"
29350
29356
  ),
@@ -29364,7 +29370,7 @@ function TableView({
29364
29370
  col.key
29365
29371
  );
29366
29372
  }),
29367
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(Box, { className: "w-px flex-shrink-0", "aria-hidden": true })
29373
+ hasActions && /* @__PURE__ */ jsx(Box, { "aria-hidden": true })
29368
29374
  ]
29369
29375
  }
29370
29376
  );
@@ -29376,16 +29382,18 @@ function TableView({
29376
29382
  role: "row",
29377
29383
  "data-entity-row": true,
29378
29384
  "data-entity-id": id,
29385
+ style: !hasRenderProp ? { gridTemplateColumns } : void 0,
29379
29386
  className: cn(
29380
- "group flex items-center gap-3 transition-colors duration-fast",
29387
+ "group items-center gap-3 transition-colors duration-fast",
29388
+ hasRenderProp ? "flex" : "grid",
29381
29389
  lk.rowPad,
29382
- lk.divider && "border-b border-[var(--color-table-border)]",
29390
+ lk.divider && "border-b border-[var(--color-border)]",
29383
29391
  lk.striped && index % 2 === 1 && "bg-[var(--color-surface-subtle)]",
29384
29392
  "hover:bg-[var(--color-surface-subtle)]",
29385
- look === "bordered" && "[&>*]:border-r [&>*]:border-[var(--color-table-border)] [&>*:last-child]:border-r-0"
29393
+ look === "bordered" && "[&>*]:border-r [&>*]:border-[var(--color-border)] [&>*:last-child]:border-r-0"
29386
29394
  ),
29387
29395
  children: [
29388
- selectable && /* @__PURE__ */ jsx(Box, { className: "w-8 flex-shrink-0 flex items-center", children: /* @__PURE__ */ jsx(
29396
+ selectable && /* @__PURE__ */ jsx(Box, { className: "flex items-center", children: /* @__PURE__ */ jsx(
29389
29397
  Checkbox,
29390
29398
  {
29391
29399
  checked: selected.has(id),
@@ -29397,7 +29405,6 @@ function TableView({
29397
29405
  const raw = getNestedValue(row, col.field ?? col.key);
29398
29406
  const cellBase = cn(
29399
29407
  "flex items-center min-w-0",
29400
- col.width ?? "flex-1",
29401
29408
  alignClass[col.align ?? "left"],
29402
29409
  weightClass[col.weight ?? "normal"],
29403
29410
  col.className
@@ -29405,7 +29412,7 @@ function TableView({
29405
29412
  if (col.format === "badge" && raw != null && raw !== "") {
29406
29413
  return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx(Badge, { variant: statusVariant4(String(raw)), size: "sm", children: String(raw) }) }, col.key);
29407
29414
  }
29408
- return /* @__PURE__ */ jsx(Box, { role: "cell", className: cn(cellBase, "truncate block"), children: formatCell(raw, col.format) }, col.key);
29415
+ return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx("span", { className: "truncate", children: formatCell(raw, col.format) }) }, col.key);
29409
29416
  }),
29410
29417
  itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: itemActions.map((action, i) => /* @__PURE__ */ jsxs(
29411
29418
  Button,
@@ -33444,6 +33451,8 @@ var init_ReplyTree = __esm({
33444
33451
  const hasReplies = !!node.replies && node.replies.length > 0;
33445
33452
  const isCollapsed = collapsedSet.has(node.id);
33446
33453
  const atMaxDepth = depth >= maxDepth;
33454
+ const [replyOpen, setReplyOpen] = useState(false);
33455
+ const [draft, setDraft] = useState("");
33447
33456
  const handleVote = useCallback(
33448
33457
  (next) => {
33449
33458
  onVote?.(node.id, next);
@@ -33453,8 +33462,19 @@ var init_ReplyTree = __esm({
33453
33462
  );
33454
33463
  const handleReply = useCallback(() => {
33455
33464
  onReply?.(node.id);
33456
- if (replyEvent) eventBus.emit(`UI:${replyEvent}`, { parentNodeId: node.id });
33457
- }, [node.id, onReply, replyEvent, eventBus]);
33465
+ setReplyOpen((open) => !open);
33466
+ }, [node.id, onReply]);
33467
+ const handleSubmitReply = useCallback(() => {
33468
+ const content = draft.trim();
33469
+ if (!content) return;
33470
+ if (replyEvent) eventBus.emit(`UI:${replyEvent}`, { parentNodeId: node.id, content });
33471
+ setDraft("");
33472
+ setReplyOpen(false);
33473
+ }, [node.id, draft, replyEvent, eventBus]);
33474
+ const handleCancelReply = useCallback(() => {
33475
+ setDraft("");
33476
+ setReplyOpen(false);
33477
+ }, []);
33458
33478
  const handleFlag = useCallback(() => {
33459
33479
  onFlag?.(node.id);
33460
33480
  if (flagEvent) eventBus.emit(`UI:${flagEvent}`, { nodeId: node.id });
@@ -33541,6 +33561,33 @@ var init_ReplyTree = __esm({
33541
33561
  }
33542
33562
  )
33543
33563
  ] }),
33564
+ replyOpen && /* @__PURE__ */ jsxs(Box, { className: "flex flex-col gap-2 mt-1", children: [
33565
+ /* @__PURE__ */ jsx(
33566
+ Input,
33567
+ {
33568
+ inputType: "textarea",
33569
+ rows: 2,
33570
+ value: draft,
33571
+ placeholder: `Reply to ${node.authorName}\u2026`,
33572
+ onChange: (e) => setDraft(e.target.value),
33573
+ "aria-label": `Reply to ${node.authorName}`
33574
+ }
33575
+ ),
33576
+ /* @__PURE__ */ jsxs(Box, { className: "flex flex-row gap-2 items-center", children: [
33577
+ /* @__PURE__ */ jsx(
33578
+ Button,
33579
+ {
33580
+ variant: "primary",
33581
+ size: "sm",
33582
+ leftIcon: "send",
33583
+ onClick: handleSubmitReply,
33584
+ disabled: !draft.trim(),
33585
+ children: "Send"
33586
+ }
33587
+ ),
33588
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: handleCancelReply, children: "Cancel" })
33589
+ ] })
33590
+ ] }),
33544
33591
  hasReplies && !isCollapsed && (atMaxDepth ? /* @__PURE__ */ jsx(
33545
33592
  Button,
33546
33593
  {
@@ -29077,18 +29077,25 @@ function TableView({
29077
29077
  return dnd.enabled ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: dnd.wrapContainer(emptyNode) }) : emptyNode;
29078
29078
  }
29079
29079
  const lk = LOOKS[look];
29080
+ const hasActions = Boolean(itemActions && itemActions.length > 0);
29081
+ const gridTemplateColumns = [
29082
+ selectable ? "auto" : null,
29083
+ ...colDefs.map((c) => c.width ?? "minmax(0, 1fr)"),
29084
+ hasActions ? "auto" : null
29085
+ ].filter(Boolean).join(" ");
29080
29086
  const header = /* @__PURE__ */ jsxRuntime.jsxs(
29081
29087
  Box,
29082
29088
  {
29083
29089
  role: "row",
29090
+ style: { gridTemplateColumns },
29084
29091
  className: cn(
29085
- "flex items-center gap-3 sticky top-0 z-10",
29086
- "bg-[var(--color-surface-subtle)] border-b border-[var(--color-table-border)]",
29092
+ "grid items-center gap-3 sticky top-0 z-10",
29093
+ "bg-[var(--color-surface-subtle)] border-b border-[var(--color-border)]",
29087
29094
  "text-[var(--color-text-muted)] uppercase text-xs font-semibold tracking-wide",
29088
29095
  lk.headPad
29089
29096
  ),
29090
29097
  children: [
29091
- selectable && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-8 flex-shrink-0 flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(Checkbox, { checked: allSelected, onChange: toggleAll, "aria-label": "Select all rows" }) }),
29098
+ selectable && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(Checkbox, { checked: allSelected, onChange: toggleAll, "aria-label": "Select all rows" }) }),
29092
29099
  colDefs.map((col) => {
29093
29100
  const active = sortColumn === (col.field ?? col.key);
29094
29101
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -29098,7 +29105,6 @@ function TableView({
29098
29105
  onClick: () => handleSort(col),
29099
29106
  className: cn(
29100
29107
  "flex items-center gap-1 min-w-0",
29101
- col.width ?? "flex-1",
29102
29108
  alignClass[col.align ?? "left"],
29103
29109
  col.sortable && sortEvent && "cursor-pointer select-none hover:text-foreground"
29104
29110
  ),
@@ -29118,7 +29124,7 @@ function TableView({
29118
29124
  col.key
29119
29125
  );
29120
29126
  }),
29121
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-px flex-shrink-0", "aria-hidden": true })
29127
+ hasActions && /* @__PURE__ */ jsxRuntime.jsx(Box, { "aria-hidden": true })
29122
29128
  ]
29123
29129
  }
29124
29130
  );
@@ -29130,16 +29136,18 @@ function TableView({
29130
29136
  role: "row",
29131
29137
  "data-entity-row": true,
29132
29138
  "data-entity-id": id,
29139
+ style: !hasRenderProp ? { gridTemplateColumns } : void 0,
29133
29140
  className: cn(
29134
- "group flex items-center gap-3 transition-colors duration-fast",
29141
+ "group items-center gap-3 transition-colors duration-fast",
29142
+ hasRenderProp ? "flex" : "grid",
29135
29143
  lk.rowPad,
29136
- lk.divider && "border-b border-[var(--color-table-border)]",
29144
+ lk.divider && "border-b border-[var(--color-border)]",
29137
29145
  lk.striped && index % 2 === 1 && "bg-[var(--color-surface-subtle)]",
29138
29146
  "hover:bg-[var(--color-surface-subtle)]",
29139
- look === "bordered" && "[&>*]:border-r [&>*]:border-[var(--color-table-border)] [&>*:last-child]:border-r-0"
29147
+ look === "bordered" && "[&>*]:border-r [&>*]:border-[var(--color-border)] [&>*:last-child]:border-r-0"
29140
29148
  ),
29141
29149
  children: [
29142
- selectable && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-8 flex-shrink-0 flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(
29150
+ selectable && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(
29143
29151
  Checkbox,
29144
29152
  {
29145
29153
  checked: selected.has(id),
@@ -29151,7 +29159,6 @@ function TableView({
29151
29159
  const raw = getNestedValue(row, col.field ?? col.key);
29152
29160
  const cellBase = cn(
29153
29161
  "flex items-center min-w-0",
29154
- col.width ?? "flex-1",
29155
29162
  alignClass[col.align ?? "left"],
29156
29163
  weightClass[col.weight ?? "normal"],
29157
29164
  col.className
@@ -29159,7 +29166,7 @@ function TableView({
29159
29166
  if (col.format === "badge" && raw != null && raw !== "") {
29160
29167
  return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant4(String(raw)), size: "sm", children: String(raw) }) }, col.key);
29161
29168
  }
29162
- return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cn(cellBase, "truncate block"), children: formatCell(raw, col.format) }, col.key);
29169
+ return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: formatCell(raw, col.format) }) }, col.key);
29163
29170
  }),
29164
29171
  itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", className: "flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: itemActions.map((action, i) => /* @__PURE__ */ jsxRuntime.jsxs(
29165
29172
  Button,
@@ -33060,6 +33067,8 @@ var init_ReplyTree = __esm({
33060
33067
  const hasReplies = !!node.replies && node.replies.length > 0;
33061
33068
  const isCollapsed = collapsedSet.has(node.id);
33062
33069
  const atMaxDepth = depth >= maxDepth;
33070
+ const [replyOpen, setReplyOpen] = React85.useState(false);
33071
+ const [draft, setDraft] = React85.useState("");
33063
33072
  const handleVote = React85.useCallback(
33064
33073
  (next) => {
33065
33074
  onVote?.(node.id, next);
@@ -33069,8 +33078,19 @@ var init_ReplyTree = __esm({
33069
33078
  );
33070
33079
  const handleReply = React85.useCallback(() => {
33071
33080
  onReply?.(node.id);
33072
- if (replyEvent) eventBus.emit(`UI:${replyEvent}`, { parentNodeId: node.id });
33073
- }, [node.id, onReply, replyEvent, eventBus]);
33081
+ setReplyOpen((open) => !open);
33082
+ }, [node.id, onReply]);
33083
+ const handleSubmitReply = React85.useCallback(() => {
33084
+ const content = draft.trim();
33085
+ if (!content) return;
33086
+ if (replyEvent) eventBus.emit(`UI:${replyEvent}`, { parentNodeId: node.id, content });
33087
+ setDraft("");
33088
+ setReplyOpen(false);
33089
+ }, [node.id, draft, replyEvent, eventBus]);
33090
+ const handleCancelReply = React85.useCallback(() => {
33091
+ setDraft("");
33092
+ setReplyOpen(false);
33093
+ }, []);
33074
33094
  const handleFlag = React85.useCallback(() => {
33075
33095
  onFlag?.(node.id);
33076
33096
  if (flagEvent) eventBus.emit(`UI:${flagEvent}`, { nodeId: node.id });
@@ -33157,6 +33177,33 @@ var init_ReplyTree = __esm({
33157
33177
  }
33158
33178
  )
33159
33179
  ] }),
33180
+ replyOpen && /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "flex flex-col gap-2 mt-1", children: [
33181
+ /* @__PURE__ */ jsxRuntime.jsx(
33182
+ Input,
33183
+ {
33184
+ inputType: "textarea",
33185
+ rows: 2,
33186
+ value: draft,
33187
+ placeholder: `Reply to ${node.authorName}\u2026`,
33188
+ onChange: (e) => setDraft(e.target.value),
33189
+ "aria-label": `Reply to ${node.authorName}`
33190
+ }
33191
+ ),
33192
+ /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "flex flex-row gap-2 items-center", children: [
33193
+ /* @__PURE__ */ jsxRuntime.jsx(
33194
+ Button,
33195
+ {
33196
+ variant: "primary",
33197
+ size: "sm",
33198
+ leftIcon: "send",
33199
+ onClick: handleSubmitReply,
33200
+ disabled: !draft.trim(),
33201
+ children: "Send"
33202
+ }
33203
+ ),
33204
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", onClick: handleCancelReply, children: "Cancel" })
33205
+ ] })
33206
+ ] }),
33160
33207
  hasReplies && !isCollapsed && (atMaxDepth ? /* @__PURE__ */ jsxRuntime.jsx(
33161
33208
  Button,
33162
33209
  {
@@ -29028,18 +29028,25 @@ function TableView({
29028
29028
  return dnd.enabled ? /* @__PURE__ */ jsx(Fragment, { children: dnd.wrapContainer(emptyNode) }) : emptyNode;
29029
29029
  }
29030
29030
  const lk = LOOKS[look];
29031
+ const hasActions = Boolean(itemActions && itemActions.length > 0);
29032
+ const gridTemplateColumns = [
29033
+ selectable ? "auto" : null,
29034
+ ...colDefs.map((c) => c.width ?? "minmax(0, 1fr)"),
29035
+ hasActions ? "auto" : null
29036
+ ].filter(Boolean).join(" ");
29031
29037
  const header = /* @__PURE__ */ jsxs(
29032
29038
  Box,
29033
29039
  {
29034
29040
  role: "row",
29041
+ style: { gridTemplateColumns },
29035
29042
  className: cn(
29036
- "flex items-center gap-3 sticky top-0 z-10",
29037
- "bg-[var(--color-surface-subtle)] border-b border-[var(--color-table-border)]",
29043
+ "grid items-center gap-3 sticky top-0 z-10",
29044
+ "bg-[var(--color-surface-subtle)] border-b border-[var(--color-border)]",
29038
29045
  "text-[var(--color-text-muted)] uppercase text-xs font-semibold tracking-wide",
29039
29046
  lk.headPad
29040
29047
  ),
29041
29048
  children: [
29042
- selectable && /* @__PURE__ */ jsx(Box, { className: "w-8 flex-shrink-0 flex items-center", children: /* @__PURE__ */ jsx(Checkbox, { checked: allSelected, onChange: toggleAll, "aria-label": "Select all rows" }) }),
29049
+ selectable && /* @__PURE__ */ jsx(Box, { className: "flex items-center", children: /* @__PURE__ */ jsx(Checkbox, { checked: allSelected, onChange: toggleAll, "aria-label": "Select all rows" }) }),
29043
29050
  colDefs.map((col) => {
29044
29051
  const active = sortColumn === (col.field ?? col.key);
29045
29052
  return /* @__PURE__ */ jsxs(
@@ -29049,7 +29056,6 @@ function TableView({
29049
29056
  onClick: () => handleSort(col),
29050
29057
  className: cn(
29051
29058
  "flex items-center gap-1 min-w-0",
29052
- col.width ?? "flex-1",
29053
29059
  alignClass[col.align ?? "left"],
29054
29060
  col.sortable && sortEvent && "cursor-pointer select-none hover:text-foreground"
29055
29061
  ),
@@ -29069,7 +29075,7 @@ function TableView({
29069
29075
  col.key
29070
29076
  );
29071
29077
  }),
29072
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(Box, { className: "w-px flex-shrink-0", "aria-hidden": true })
29078
+ hasActions && /* @__PURE__ */ jsx(Box, { "aria-hidden": true })
29073
29079
  ]
29074
29080
  }
29075
29081
  );
@@ -29081,16 +29087,18 @@ function TableView({
29081
29087
  role: "row",
29082
29088
  "data-entity-row": true,
29083
29089
  "data-entity-id": id,
29090
+ style: !hasRenderProp ? { gridTemplateColumns } : void 0,
29084
29091
  className: cn(
29085
- "group flex items-center gap-3 transition-colors duration-fast",
29092
+ "group items-center gap-3 transition-colors duration-fast",
29093
+ hasRenderProp ? "flex" : "grid",
29086
29094
  lk.rowPad,
29087
- lk.divider && "border-b border-[var(--color-table-border)]",
29095
+ lk.divider && "border-b border-[var(--color-border)]",
29088
29096
  lk.striped && index % 2 === 1 && "bg-[var(--color-surface-subtle)]",
29089
29097
  "hover:bg-[var(--color-surface-subtle)]",
29090
- look === "bordered" && "[&>*]:border-r [&>*]:border-[var(--color-table-border)] [&>*:last-child]:border-r-0"
29098
+ look === "bordered" && "[&>*]:border-r [&>*]:border-[var(--color-border)] [&>*:last-child]:border-r-0"
29091
29099
  ),
29092
29100
  children: [
29093
- selectable && /* @__PURE__ */ jsx(Box, { className: "w-8 flex-shrink-0 flex items-center", children: /* @__PURE__ */ jsx(
29101
+ selectable && /* @__PURE__ */ jsx(Box, { className: "flex items-center", children: /* @__PURE__ */ jsx(
29094
29102
  Checkbox,
29095
29103
  {
29096
29104
  checked: selected.has(id),
@@ -29102,7 +29110,6 @@ function TableView({
29102
29110
  const raw = getNestedValue(row, col.field ?? col.key);
29103
29111
  const cellBase = cn(
29104
29112
  "flex items-center min-w-0",
29105
- col.width ?? "flex-1",
29106
29113
  alignClass[col.align ?? "left"],
29107
29114
  weightClass[col.weight ?? "normal"],
29108
29115
  col.className
@@ -29110,7 +29117,7 @@ function TableView({
29110
29117
  if (col.format === "badge" && raw != null && raw !== "") {
29111
29118
  return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx(Badge, { variant: statusVariant4(String(raw)), size: "sm", children: String(raw) }) }, col.key);
29112
29119
  }
29113
- return /* @__PURE__ */ jsx(Box, { role: "cell", className: cn(cellBase, "truncate block"), children: formatCell(raw, col.format) }, col.key);
29120
+ return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx("span", { className: "truncate", children: formatCell(raw, col.format) }) }, col.key);
29114
29121
  }),
29115
29122
  itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: itemActions.map((action, i) => /* @__PURE__ */ jsxs(
29116
29123
  Button,
@@ -33011,6 +33018,8 @@ var init_ReplyTree = __esm({
33011
33018
  const hasReplies = !!node.replies && node.replies.length > 0;
33012
33019
  const isCollapsed = collapsedSet.has(node.id);
33013
33020
  const atMaxDepth = depth >= maxDepth;
33021
+ const [replyOpen, setReplyOpen] = useState(false);
33022
+ const [draft, setDraft] = useState("");
33014
33023
  const handleVote = useCallback(
33015
33024
  (next) => {
33016
33025
  onVote?.(node.id, next);
@@ -33020,8 +33029,19 @@ var init_ReplyTree = __esm({
33020
33029
  );
33021
33030
  const handleReply = useCallback(() => {
33022
33031
  onReply?.(node.id);
33023
- if (replyEvent) eventBus.emit(`UI:${replyEvent}`, { parentNodeId: node.id });
33024
- }, [node.id, onReply, replyEvent, eventBus]);
33032
+ setReplyOpen((open) => !open);
33033
+ }, [node.id, onReply]);
33034
+ const handleSubmitReply = useCallback(() => {
33035
+ const content = draft.trim();
33036
+ if (!content) return;
33037
+ if (replyEvent) eventBus.emit(`UI:${replyEvent}`, { parentNodeId: node.id, content });
33038
+ setDraft("");
33039
+ setReplyOpen(false);
33040
+ }, [node.id, draft, replyEvent, eventBus]);
33041
+ const handleCancelReply = useCallback(() => {
33042
+ setDraft("");
33043
+ setReplyOpen(false);
33044
+ }, []);
33025
33045
  const handleFlag = useCallback(() => {
33026
33046
  onFlag?.(node.id);
33027
33047
  if (flagEvent) eventBus.emit(`UI:${flagEvent}`, { nodeId: node.id });
@@ -33108,6 +33128,33 @@ var init_ReplyTree = __esm({
33108
33128
  }
33109
33129
  )
33110
33130
  ] }),
33131
+ replyOpen && /* @__PURE__ */ jsxs(Box, { className: "flex flex-col gap-2 mt-1", children: [
33132
+ /* @__PURE__ */ jsx(
33133
+ Input,
33134
+ {
33135
+ inputType: "textarea",
33136
+ rows: 2,
33137
+ value: draft,
33138
+ placeholder: `Reply to ${node.authorName}\u2026`,
33139
+ onChange: (e) => setDraft(e.target.value),
33140
+ "aria-label": `Reply to ${node.authorName}`
33141
+ }
33142
+ ),
33143
+ /* @__PURE__ */ jsxs(Box, { className: "flex flex-row gap-2 items-center", children: [
33144
+ /* @__PURE__ */ jsx(
33145
+ Button,
33146
+ {
33147
+ variant: "primary",
33148
+ size: "sm",
33149
+ leftIcon: "send",
33150
+ onClick: handleSubmitReply,
33151
+ disabled: !draft.trim(),
33152
+ children: "Send"
33153
+ }
33154
+ ),
33155
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: handleCancelReply, children: "Cancel" })
33156
+ ] })
33157
+ ] }),
33111
33158
  hasReplies && !isCollapsed && (atMaxDepth ? /* @__PURE__ */ jsx(
33112
33159
  Button,
33113
33160
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "5.9.0",
3
+ "version": "5.9.2",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "sideEffects": [