dishui 0.0.91 → 0.0.101

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 (156) hide show
  1. package/dist/.release-verified.json +6 -0
  2. package/dist/ai.js +24 -0
  3. package/dist/components/Card/Metric2.js +11 -11
  4. package/dist/components/Card/Metric2.js.map +1 -1
  5. package/dist/components/Card/Ticket.d.ts +52 -0
  6. package/dist/components/Card/Ticket2.js +218 -0
  7. package/dist/components/Card/Ticket2.js.map +1 -0
  8. package/dist/components/Card/index.d.ts +32 -0
  9. package/dist/components/Card/index.js +211 -203
  10. package/dist/components/Card/index.js.map +1 -1
  11. package/dist/components/GroupButton/index.js +4 -4
  12. package/dist/components/GroupButton/index.js.map +1 -1
  13. package/dist/components/GroupedTable/index.js +10 -10
  14. package/dist/components/GroupedTable/index.js.map +1 -1
  15. package/dist/components/NavigationList/index.js +9 -9
  16. package/dist/components/NavigationList/index.js.map +1 -1
  17. package/dist/components/Section/index.js +11 -11
  18. package/dist/components/Section/index.js.map +1 -1
  19. package/dist/components/Skeleton/index.js +1 -1
  20. package/dist/components/Skeleton/index.js.map +1 -1
  21. package/dist/components/Table/index.js +6 -6
  22. package/dist/components/Table/index.js.map +1 -1
  23. package/dist/components/ai/AgentChat/index.d.ts +54 -0
  24. package/dist/components/ai/AgentChat/index.js +176 -0
  25. package/dist/components/ai/AgentChat/index.js.map +1 -0
  26. package/dist/components/ai/AgentRunCard/index.d.ts +38 -0
  27. package/dist/components/ai/AgentRunCard/index.js +100 -0
  28. package/dist/components/ai/AgentRunCard/index.js.map +1 -0
  29. package/dist/components/ai/AgentScreen/index.d.ts +50 -0
  30. package/dist/components/ai/AgentScreen/index.js +233 -0
  31. package/dist/components/ai/AgentScreen/index.js.map +1 -0
  32. package/dist/components/ai/ApprovalCard/index.d.ts +26 -0
  33. package/dist/components/ai/ApprovalCard/index.js +89 -0
  34. package/dist/components/ai/ApprovalCard/index.js.map +1 -0
  35. package/dist/components/ai/CodeView/index.d.ts +30 -0
  36. package/dist/components/ai/CodeView/index.js +149 -0
  37. package/dist/components/ai/CodeView/index.js.map +1 -0
  38. package/dist/components/ai/CommandSearch/index.d.ts +39 -0
  39. package/dist/components/ai/CommandSearch/index.js +217 -0
  40. package/dist/components/ai/CommandSearch/index.js.map +1 -0
  41. package/dist/components/ai/ContextCards/index.d.ts +42 -0
  42. package/dist/components/ai/ContextCards/index.js +106 -0
  43. package/dist/components/ai/ContextCards/index.js.map +1 -0
  44. package/dist/components/ai/DiffTable/index.d.ts +70 -0
  45. package/dist/components/ai/DiffTable/index.js +235 -0
  46. package/dist/components/ai/DiffTable/index.js.map +1 -0
  47. package/dist/components/ai/FilterTable/index.d.ts +35 -0
  48. package/dist/components/ai/FilterTable/index.js +86 -0
  49. package/dist/components/ai/FilterTable/index.js.map +1 -0
  50. package/dist/components/ai/FineTuneCard/index.d.ts +24 -0
  51. package/dist/components/ai/FineTuneCard/index.js +75 -0
  52. package/dist/components/ai/FineTuneCard/index.js.map +1 -0
  53. package/dist/components/ai/InsightCards/index.d.ts +23 -0
  54. package/dist/components/ai/InsightCards/index.js +64 -0
  55. package/dist/components/ai/InsightCards/index.js.map +1 -0
  56. package/dist/components/ai/IssueCard/index.d.ts +39 -0
  57. package/dist/components/ai/IssueCard/index.js +78 -0
  58. package/dist/components/ai/IssueCard/index.js.map +1 -0
  59. package/dist/components/ai/LoadingState/index.d.ts +22 -0
  60. package/dist/components/ai/LoadingState/index.js +80 -0
  61. package/dist/components/ai/LoadingState/index.js.map +1 -0
  62. package/dist/components/ai/PromptBar/index.d.ts +26 -0
  63. package/dist/components/ai/PromptBar/index.js +117 -0
  64. package/dist/components/ai/PromptBar/index.js.map +1 -0
  65. package/dist/components/ai/RecommendationCard/index.d.ts +44 -0
  66. package/dist/components/ai/RecommendationCard/index.js +142 -0
  67. package/dist/components/ai/RecommendationCard/index.js.map +1 -0
  68. package/dist/components/ai/RecordsTable/index.d.ts +65 -0
  69. package/dist/components/ai/RecordsTable/index.js +334 -0
  70. package/dist/components/ai/RecordsTable/index.js.map +1 -0
  71. package/dist/components/ai/SelectionActions/index.d.ts +19 -0
  72. package/dist/components/ai/SelectionActions/index.js +40 -0
  73. package/dist/components/ai/SelectionActions/index.js.map +1 -0
  74. package/dist/components/ai/StateFlow/index.d.ts +24 -0
  75. package/dist/components/ai/StateFlow/index.js +50 -0
  76. package/dist/components/ai/StateFlow/index.js.map +1 -0
  77. package/dist/components/ai/StreamingText/index.d.ts +44 -0
  78. package/dist/components/ai/StreamingText/index.js +211 -0
  79. package/dist/components/ai/StreamingText/index.js.map +1 -0
  80. package/dist/components/ai/TaskRows/index.d.ts +53 -0
  81. package/dist/components/ai/TaskRows/index.js +186 -0
  82. package/dist/components/ai/TaskRows/index.js.map +1 -0
  83. package/dist/components/ai/Thinking/index.d.ts +47 -0
  84. package/dist/components/ai/Thinking/index.js +197 -0
  85. package/dist/components/ai/Thinking/index.js.map +1 -0
  86. package/dist/components/ai/ToolChips/index.d.ts +21 -0
  87. package/dist/components/ai/ToolChips/index.js +63 -0
  88. package/dist/components/ai/ToolChips/index.js.map +1 -0
  89. package/dist/components/ai/index.d.ts +54 -0
  90. package/dist/components/ai/shared.d.ts +13 -0
  91. package/dist/components/ai/shared.js +25 -0
  92. package/dist/components/ai/shared.js.map +1 -0
  93. package/dist/components/pro/DataTable/rowDetailExtension.js +1 -1
  94. package/dist/components/pro/DataTable/rowDetailExtension.js.map +1 -1
  95. package/dist/components/pro/Flow/constants.js +3 -3
  96. package/dist/components/pro/Flow/constants.js.map +1 -1
  97. package/dist/components/pro/Flow/nodes/shapes.js +3 -3
  98. package/dist/components/pro/Flow/nodes/shapes.js.map +1 -1
  99. package/dist/components/pro/Flow/utils/themeColor.d.ts +2 -2
  100. package/dist/components/pro/Flow/utils/themeColor.js +2 -2
  101. package/dist/components/pro/Flow/utils/themeColor.js.map +1 -1
  102. package/dist/components/pro/Kanban/Kanban.d.ts +3 -0
  103. package/dist/components/pro/Kanban/Kanban.js +339 -0
  104. package/dist/components/pro/Kanban/Kanban.js.map +1 -0
  105. package/dist/components/pro/Kanban/Swimlanes.d.ts +3 -0
  106. package/dist/components/pro/Kanban/Swimlanes.js +60 -0
  107. package/dist/components/pro/Kanban/Swimlanes.js.map +1 -0
  108. package/dist/components/pro/Kanban/index.d.ts +5 -0
  109. package/dist/components/pro/Kanban/types.d.ts +103 -0
  110. package/dist/components/pro/Kanban/useKanbanDrag.d.ts +17 -0
  111. package/dist/components/pro/Kanban/useKanbanDrag.js +69 -0
  112. package/dist/components/pro/Kanban/useKanbanDrag.js.map +1 -0
  113. package/dist/components/pro/Kanban/utils.d.ts +13 -0
  114. package/dist/components/pro/Kanban/utils.js +48 -0
  115. package/dist/components/pro/Kanban/utils.js.map +1 -0
  116. package/dist/components/pro/RichTextEditor/AIRewrite.js +158 -127
  117. package/dist/components/pro/RichTextEditor/AIRewrite.js.map +1 -1
  118. package/dist/components/pro/RichTextEditor/BlockHandle.d.ts +2 -0
  119. package/dist/components/pro/RichTextEditor/BlockHandle.js +156 -115
  120. package/dist/components/pro/RichTextEditor/BlockHandle.js.map +1 -1
  121. package/dist/components/pro/RichTextEditor/RichTextEditor.js +136 -159
  122. package/dist/components/pro/RichTextEditor/RichTextEditor.js.map +1 -1
  123. package/dist/components/pro/RichTextEditor/Toolbar/ColorPicker.js +44 -41
  124. package/dist/components/pro/RichTextEditor/Toolbar/ColorPicker.js.map +1 -1
  125. package/dist/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.js +59 -53
  126. package/dist/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.js.map +1 -1
  127. package/dist/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.js +48 -44
  128. package/dist/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.js.map +1 -1
  129. package/dist/components/pro/RichTextEditor/Toolbar/TableOpsMenu.js +67 -63
  130. package/dist/components/pro/RichTextEditor/Toolbar/TableOpsMenu.js.map +1 -1
  131. package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.d.ts +1 -0
  132. package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.js +182 -129
  133. package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.js.map +1 -1
  134. package/dist/components/pro/RichTextEditor/Toolbar/ToolbarButton.d.ts +1 -0
  135. package/dist/components/pro/RichTextEditor/Toolbar/ToolbarButton.js +3 -3
  136. package/dist/components/pro/RichTextEditor/Toolbar/ToolbarButton.js.map +1 -1
  137. package/dist/components/pro/RichTextEditor/Toolbar/useAnchoredDropdown.d.ts +3 -0
  138. package/dist/components/pro/RichTextEditor/Toolbar/useAnchoredDropdown.js +31 -0
  139. package/dist/components/pro/RichTextEditor/Toolbar/useAnchoredDropdown.js.map +1 -0
  140. package/dist/components/pro/RichTextEditor/index.d.ts +1 -1
  141. package/dist/components/pro/RichTextEditor/types.d.ts +78 -11
  142. package/dist/components/pro/RichTextEditor/types.js +11 -0
  143. package/dist/components/pro/RichTextEditor/types.js.map +1 -1
  144. package/dist/dishui.css +1 -1
  145. package/dist/index-nostyled.d.ts +1 -1
  146. package/dist/index.d.ts +6 -3
  147. package/dist/index.js +134 -107
  148. package/dist/kanban.js +5 -0
  149. package/dist/layouts/Sidebar.d.ts +16 -0
  150. package/dist/layouts/Sidebar.js +85 -52
  151. package/dist/layouts/Sidebar.js.map +1 -1
  152. package/dist/utils/i18n.js +20 -0
  153. package/dist/utils/i18n.js.map +1 -1
  154. package/dist/utils/menu.js +1 -1
  155. package/dist/utils/menu.js.map +1 -1
  156. package/package.json +14 -3
@@ -4,7 +4,7 @@ import t from "react";
4
4
  import { jsx as n, jsxs as r } from "react/jsx-runtime";
5
5
  //#region src/components/Table/index.tsx
6
6
  var i = t.createContext(null), a = t.createContext(!1), o = {}, s = ({ children: t, className: r = "", card: s = !1, cardOptions: c = o, onClick: l, onMouseEnter: u, onMouseLeave: d, ...f }) => {
7
- let p = e("table", s && "blade-table-card", r);
7
+ let p = e("table", s && "dishui-table-card", r);
8
8
  return /* @__PURE__ */ n(i.Provider, {
9
9
  value: s ? c : null,
10
10
  children: /* @__PURE__ */ n(a.Provider, {
@@ -39,7 +39,7 @@ var i = t.createContext(null), a = t.createContext(!1), o = {}, s = ({ children:
39
39
  });
40
40
  },
41
41
  Body: ({ children: r, className: o = "", style: s, ...c }) => {
42
- let l = t.useContext(i), u = e("table-row-group", l && "blade-table-card__grid", l?.gridClassName, o);
42
+ let l = t.useContext(i), u = e("table-row-group", l && "dishui-table-card__grid", l?.gridClassName, o);
43
43
  return /* @__PURE__ */ n(a.Provider, {
44
44
  value: !0,
45
45
  children: /* @__PURE__ */ n("tbody", {
@@ -55,7 +55,7 @@ var i = t.createContext(null), a = t.createContext(!1), o = {}, s = ({ children:
55
55
  });
56
56
  },
57
57
  Row: ({ children: r, className: o = "", selected: s = !1, style: c, onClick: l, onDoubleClick: u, onMouseEnter: d, onMouseLeave: f, ...p }) => {
58
- let m = t.useContext(i), h = t.useContext(a) ? m : null, g = e("table-row", s && "bg-base-200", "hover:bg-base-100", h && "blade-table-card__row", h?.className, o);
58
+ let m = t.useContext(i), h = t.useContext(a) ? m : null, g = e("table-row", s && "bg-base-200", "hover:bg-base-100", h && "dishui-table-card__row", h?.className, o);
59
59
  return /* @__PURE__ */ n("tr", {
60
60
  role: m ? "row" : void 0,
61
61
  "data-card-selected": h && s ? "true" : void 0,
@@ -73,7 +73,7 @@ var i = t.createContext(null), a = t.createContext(!1), o = {}, s = ({ children:
73
73
  });
74
74
  },
75
75
  Cell: ({ children: o, label: s, className: c = "", onClick: l, colSpan: u, style: d, onDoubleClick: f, onMouseEnter: p, onMouseLeave: m, ...h }) => {
76
- let g = t.useContext(i), _ = t.useContext(a) ? g : null, v = e("table-cell", _ && "blade-table-card__field", _?.fieldClassName, c);
76
+ let g = t.useContext(i), _ = t.useContext(a) ? g : null, v = e("table-cell", _ && "dishui-table-card__field", _?.fieldClassName, c);
77
77
  return /* @__PURE__ */ r("td", {
78
78
  role: g ? "cell" : void 0,
79
79
  ...h,
@@ -88,14 +88,14 @@ var i = t.createContext(null), a = t.createContext(!1), o = {}, s = ({ children:
88
88
  onMouseEnter: p,
89
89
  onMouseLeave: m,
90
90
  children: [_ && s != null ? /* @__PURE__ */ n("div", {
91
- className: e("blade-table-card__label", _.labelClassName),
91
+ className: e("dishui-table-card__label", _.labelClassName),
92
92
  style: _.labelStyle,
93
93
  children: s
94
94
  }) : null, o]
95
95
  });
96
96
  },
97
97
  HeaderCell: ({ children: o, className: s = "", style: c, onClick: l, sortable: u = !1, sortDirection: d = null, draggable: f, onDragStart: p, onDragOver: m, onDrop: h, onMouseEnter: g, onMouseLeave: _, ...v }) => {
98
- let y = t.useContext(i), b = t.useContext(a), x = b ? y : null, S = e("table-cell font-medium", u && "cursor-pointer", x && "blade-table-card__field", x?.fieldClassName, s);
98
+ let y = t.useContext(i), b = t.useContext(a), x = b ? y : null, S = e("table-cell font-medium", u && "cursor-pointer", x && "dishui-table-card__field", x?.fieldClassName, s);
99
99
  return /* @__PURE__ */ n("th", {
100
100
  role: y ? v.scope === "row" || v.scope === "rowgroup" || b && !v.scope ? "rowheader" : "columnheader" : void 0,
101
101
  ...v,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/Table/index.tsx"],"sourcesContent":["import React from 'react';\nimport { cn } from '../../utils/cn';\nimport './Table.css';\n\nexport type TableCardOptions = {\n /** Applied to each Table.Body grid. */\n gridClassName?: string;\n gridStyle?: React.CSSProperties;\n /** Applied to each body row card. */\n className?: string;\n style?: React.CSSProperties;\n fieldClassName?: string;\n fieldStyle?: React.CSSProperties;\n labelClassName?: string;\n labelStyle?: React.CSSProperties;\n};\n\nconst CardContext = React.createContext<TableCardOptions | null>(null);\nconst BodyContext = React.createContext(false);\nconst defaultCardOptions: TableCardOptions = {};\n\nexport type TableProps = {\n children: React.ReactNode;\n card?: boolean;\n cardOptions?: TableCardOptions;\n className?: string;\n onClick?: (e: React.MouseEvent) => void;\n onMouseEnter?: (e: React.MouseEvent) => void;\n onMouseLeave?: (e: React.MouseEvent) => void;\n} & React.TableHTMLAttributes<HTMLTableElement>;\n\nconst Table = ({\n children,\n className = '',\n card = false,\n cardOptions = defaultCardOptions,\n onClick,\n onMouseEnter,\n onMouseLeave,\n ...rest\n}: TableProps) => {\n const baseClass = 'table';\n \n const tableClasses = cn(baseClass, card && 'blade-table-card', className);\n\n return (\n <CardContext.Provider value={card ? cardOptions : null}>\n <BodyContext.Provider value={false}>\n <table\n role={card ? 'table' : undefined}\n {...rest}\n className={tableClasses}\n onClick={onClick}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n {children}\n </table>\n </BodyContext.Provider>\n </CardContext.Provider>\n );\n};\n\n// Table.Head 组件\nexport type TableHeadProps = React.HTMLAttributes<HTMLTableSectionElement>;\n\nconst TableHead = ({\n children,\n className = '',\n ...rest\n}: TableHeadProps) => {\n const options = React.useContext(CardContext);\n const baseClass = 'table-header-group';\n \n const headClasses = cn(baseClass, className);\n\n return (\n <thead role={options ? 'rowgroup' : undefined} {...rest} className={headClasses}>\n {children}\n </thead>\n );\n};\n\n// Table.Body 组件\nexport type TableBodyProps = React.HTMLAttributes<HTMLTableSectionElement>;\n\nconst TableBody = ({\n children,\n className = '',\n style,\n ...rest\n}: TableBodyProps) => {\n const options = React.useContext(CardContext);\n const bodyClasses = cn('table-row-group', options && 'blade-table-card__grid', options?.gridClassName, className);\n\n return (\n <BodyContext.Provider value={true}>\n <tbody\n role={options ? 'rowgroup' : undefined}\n {...rest}\n className={bodyClasses}\n style={options ? { ...options.gridStyle, ...style } : style}\n >\n {children}\n </tbody>\n </BodyContext.Provider>\n );\n};\n\n// Table.Row 组件\nexport type TableRowProps = {\n children: React.ReactNode;\n className?: string;\n selected?: boolean;\n onClick?: (e: React.MouseEvent) => void;\n onDoubleClick?: (e: React.MouseEvent) => void;\n onMouseEnter?: (e: React.MouseEvent) => void;\n onMouseLeave?: (e: React.MouseEvent) => void;\n} & Omit<\n React.HTMLAttributes<HTMLTableRowElement>,\n 'className' | 'onClick' | 'onDoubleClick' | 'onMouseEnter' | 'onMouseLeave'\n>;\n\nconst TableRow = ({\n children,\n className = '',\n selected = false,\n style,\n onClick,\n onDoubleClick,\n onMouseEnter,\n onMouseLeave,\n ...rest\n}: TableRowProps) => {\n const cardOptions = React.useContext(CardContext);\n const inBody = React.useContext(BodyContext);\n const options = inBody ? cardOptions : null;\n const baseClass = 'table-row';\n\n const rowClasses = cn(\n baseClass,\n selected && 'bg-base-200',\n 'hover:bg-base-100',\n options && 'blade-table-card__row',\n options?.className,\n className\n );\n\n return (\n <tr\n role={cardOptions ? 'row' : undefined}\n data-card-selected={options && selected ? 'true' : undefined}\n style={options ? { ...options.style, ...style } : style}\n className={rowClasses}\n onClick={onClick}\n onDoubleClick={onDoubleClick}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n {...rest}\n >\n {children}\n </tr>\n );\n};\n\n// Table.Cell 组件\nexport type TableCellProps = {\n children?: React.ReactNode;\n /** Visible field label in card body cells only. */\n label?: React.ReactNode;\n className?: string;\n onClick?: (e: React.MouseEvent) => void;\n colSpan?: number;\n style?: React.CSSProperties;\n \n // 添加鼠标事件\n onDoubleClick?: (e: React.MouseEvent) => void;\n onMouseEnter?: (e: React.MouseEvent) => void;\n onMouseLeave?: (e: React.MouseEvent) => void;\n} & React.TdHTMLAttributes<HTMLTableCellElement>;\n\nconst TableCell = ({\n children,\n label,\n className = '',\n onClick,\n colSpan,\n style,\n onDoubleClick,\n onMouseEnter,\n onMouseLeave,\n ...rest\n}: TableCellProps) => {\n const cardOptions = React.useContext(CardContext);\n const inBody = React.useContext(BodyContext);\n const options = inBody ? cardOptions : null;\n const cellClasses = cn('table-cell', options && 'blade-table-card__field', options?.fieldClassName, className);\n\n return (\n <td\n role={cardOptions ? 'cell' : undefined}\n {...rest}\n className={cellClasses}\n onClick={onClick}\n colSpan={colSpan}\n style={options ? { ...options.fieldStyle, ...style } : style}\n onDoubleClick={onDoubleClick}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n {/* Keep children in a fixed slot so mode/label changes preserve local state. */}\n {options && label !== null && label !== undefined ? <div className={cn('blade-table-card__label', options.labelClassName)} style={options.labelStyle}>{label}</div> : null}\n {children}\n </td>\n );\n};\n\n// Table.HeaderCell 组件\nexport type TableHeaderCellProps = {\n children: React.ReactNode;\n className?: string;\n onClick?: (e: React.MouseEvent) => void;\n sortable?: boolean;\n sortDirection?: 'asc' | 'desc' | null;\n \n // 拖拽相关属性\n draggable?: boolean;\n onDragStart?: (e: React.DragEvent) => void;\n onDragOver?: (e: React.DragEvent) => void;\n onDrop?: (e: React.DragEvent) => void;\n \n // 鼠标事件\n onMouseEnter?: (e: React.MouseEvent) => void;\n onMouseLeave?: (e: React.MouseEvent) => void;\n} & React.ThHTMLAttributes<HTMLTableCellElement>;\n\nconst TableHeaderCell = ({\n children,\n className = '',\n style,\n onClick,\n sortable = false,\n sortDirection = null,\n \n // 拖拽相关属性\n draggable,\n onDragStart,\n onDragOver,\n onDrop,\n \n // 鼠标事件\n onMouseEnter,\n onMouseLeave,\n ...rest\n}: TableHeaderCellProps) => {\n const cardOptions = React.useContext(CardContext);\n const inBody = React.useContext(BodyContext);\n const options = inBody ? cardOptions : null;\n const baseClass = 'table-cell font-medium';\n \n const headerCellClasses = cn(\n baseClass,\n sortable && 'cursor-pointer',\n options && 'blade-table-card__field',\n options?.fieldClassName,\n className\n );\n\n return (\n <th\n role={cardOptions ? (rest.scope === 'row' || rest.scope === 'rowgroup' || (inBody && !rest.scope) ? 'rowheader' : 'columnheader') : undefined}\n {...rest}\n style={options ? { ...options.fieldStyle, ...style } : style}\n className={headerCellClasses}\n onClick={onClick}\n draggable={draggable}\n onDragStart={onDragStart}\n onDragOver={onDragOver}\n onDrop={onDrop}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n {sortable ? <div className=\"flex items-center gap-2\">\n {children}\n {sortable && (\n <div className=\"flex flex-col\">\n {sortDirection === 'asc' ? (\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"2\" d=\"M5 15l7-7 7 7\" />\n </svg>\n ) : sortDirection === 'desc' ? (\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"2\" d=\"M19 9l-7 7-7-7\" />\n </svg>\n ) : (\n <div className=\"h-4 w-4 opacity-30\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"2\" d=\"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4\" />\n </svg>\n </div>\n )}\n </div>\n )}\n </div> : children}\n </th>\n );\n};\n\nexport type TableCaptionProps = React.HTMLAttributes<HTMLTableCaptionElement>;\nexport type TableFooterProps = React.HTMLAttributes<HTMLTableSectionElement>;\nconst TableCaption = (props: TableCaptionProps) => <caption {...props} />;\nconst TableFooter = (props: TableFooterProps) => {\n const options = React.useContext(CardContext);\n return <tfoot role={options ? 'rowgroup' : undefined} {...props} />;\n};\n\n// 扩展Table组件,添加子组件\nexport type TableCardProps = Omit<TableProps, 'card'>;\n\ninterface TableSubcomponents {\n Caption: React.FC<TableCaptionProps>;\n Footer: React.FC<TableFooterProps>;\n Head: React.FC<TableHeadProps>;\n Body: React.FC<TableBodyProps>;\n Row: React.FC<TableRowProps>;\n Cell: React.FC<TableCellProps>;\n HeaderCell: React.FC<TableHeaderCellProps>;\n}\n\nconst subcomponents: TableSubcomponents = {\n Caption: TableCaption,\n Footer: TableFooter,\n Head: TableHead,\n Body: TableBody,\n Row: TableRow,\n Cell: TableCell,\n HeaderCell: TableHeaderCell,\n};\n\nconst TableCard = (props: TableCardProps) => <Table {...props} card />;\nconst TableWithCompounds = Object.assign(Table, subcomponents, {\n Card: Object.assign(TableCard, subcomponents),\n});\n\nexport default TableWithCompounds; "],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/Table/index.tsx"],"sourcesContent":["import React from 'react';\nimport { cn } from '../../utils/cn';\nimport './Table.css';\n\nexport type TableCardOptions = {\n /** Applied to each Table.Body grid. */\n gridClassName?: string;\n gridStyle?: React.CSSProperties;\n /** Applied to each body row card. */\n className?: string;\n style?: React.CSSProperties;\n fieldClassName?: string;\n fieldStyle?: React.CSSProperties;\n labelClassName?: string;\n labelStyle?: React.CSSProperties;\n};\n\nconst CardContext = React.createContext<TableCardOptions | null>(null);\nconst BodyContext = React.createContext(false);\nconst defaultCardOptions: TableCardOptions = {};\n\nexport type TableProps = {\n children: React.ReactNode;\n card?: boolean;\n cardOptions?: TableCardOptions;\n className?: string;\n onClick?: (e: React.MouseEvent) => void;\n onMouseEnter?: (e: React.MouseEvent) => void;\n onMouseLeave?: (e: React.MouseEvent) => void;\n} & React.TableHTMLAttributes<HTMLTableElement>;\n\nconst Table = ({\n children,\n className = '',\n card = false,\n cardOptions = defaultCardOptions,\n onClick,\n onMouseEnter,\n onMouseLeave,\n ...rest\n}: TableProps) => {\n const baseClass = 'table';\n \n const tableClasses = cn(baseClass, card && 'dishui-table-card', className);\n\n return (\n <CardContext.Provider value={card ? cardOptions : null}>\n <BodyContext.Provider value={false}>\n <table\n role={card ? 'table' : undefined}\n {...rest}\n className={tableClasses}\n onClick={onClick}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n {children}\n </table>\n </BodyContext.Provider>\n </CardContext.Provider>\n );\n};\n\n// Table.Head 组件\nexport type TableHeadProps = React.HTMLAttributes<HTMLTableSectionElement>;\n\nconst TableHead = ({\n children,\n className = '',\n ...rest\n}: TableHeadProps) => {\n const options = React.useContext(CardContext);\n const baseClass = 'table-header-group';\n \n const headClasses = cn(baseClass, className);\n\n return (\n <thead role={options ? 'rowgroup' : undefined} {...rest} className={headClasses}>\n {children}\n </thead>\n );\n};\n\n// Table.Body 组件\nexport type TableBodyProps = React.HTMLAttributes<HTMLTableSectionElement>;\n\nconst TableBody = ({\n children,\n className = '',\n style,\n ...rest\n}: TableBodyProps) => {\n const options = React.useContext(CardContext);\n const bodyClasses = cn('table-row-group', options && 'dishui-table-card__grid', options?.gridClassName, className);\n\n return (\n <BodyContext.Provider value={true}>\n <tbody\n role={options ? 'rowgroup' : undefined}\n {...rest}\n className={bodyClasses}\n style={options ? { ...options.gridStyle, ...style } : style}\n >\n {children}\n </tbody>\n </BodyContext.Provider>\n );\n};\n\n// Table.Row 组件\nexport type TableRowProps = {\n children: React.ReactNode;\n className?: string;\n selected?: boolean;\n onClick?: (e: React.MouseEvent) => void;\n onDoubleClick?: (e: React.MouseEvent) => void;\n onMouseEnter?: (e: React.MouseEvent) => void;\n onMouseLeave?: (e: React.MouseEvent) => void;\n} & Omit<\n React.HTMLAttributes<HTMLTableRowElement>,\n 'className' | 'onClick' | 'onDoubleClick' | 'onMouseEnter' | 'onMouseLeave'\n>;\n\nconst TableRow = ({\n children,\n className = '',\n selected = false,\n style,\n onClick,\n onDoubleClick,\n onMouseEnter,\n onMouseLeave,\n ...rest\n}: TableRowProps) => {\n const cardOptions = React.useContext(CardContext);\n const inBody = React.useContext(BodyContext);\n const options = inBody ? cardOptions : null;\n const baseClass = 'table-row';\n\n const rowClasses = cn(\n baseClass,\n selected && 'bg-base-200',\n 'hover:bg-base-100',\n options && 'dishui-table-card__row',\n options?.className,\n className\n );\n\n return (\n <tr\n role={cardOptions ? 'row' : undefined}\n data-card-selected={options && selected ? 'true' : undefined}\n style={options ? { ...options.style, ...style } : style}\n className={rowClasses}\n onClick={onClick}\n onDoubleClick={onDoubleClick}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n {...rest}\n >\n {children}\n </tr>\n );\n};\n\n// Table.Cell 组件\nexport type TableCellProps = {\n children?: React.ReactNode;\n /** Visible field label in card body cells only. */\n label?: React.ReactNode;\n className?: string;\n onClick?: (e: React.MouseEvent) => void;\n colSpan?: number;\n style?: React.CSSProperties;\n \n // 添加鼠标事件\n onDoubleClick?: (e: React.MouseEvent) => void;\n onMouseEnter?: (e: React.MouseEvent) => void;\n onMouseLeave?: (e: React.MouseEvent) => void;\n} & React.TdHTMLAttributes<HTMLTableCellElement>;\n\nconst TableCell = ({\n children,\n label,\n className = '',\n onClick,\n colSpan,\n style,\n onDoubleClick,\n onMouseEnter,\n onMouseLeave,\n ...rest\n}: TableCellProps) => {\n const cardOptions = React.useContext(CardContext);\n const inBody = React.useContext(BodyContext);\n const options = inBody ? cardOptions : null;\n const cellClasses = cn('table-cell', options && 'dishui-table-card__field', options?.fieldClassName, className);\n\n return (\n <td\n role={cardOptions ? 'cell' : undefined}\n {...rest}\n className={cellClasses}\n onClick={onClick}\n colSpan={colSpan}\n style={options ? { ...options.fieldStyle, ...style } : style}\n onDoubleClick={onDoubleClick}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n {/* Keep children in a fixed slot so mode/label changes preserve local state. */}\n {options && label !== null && label !== undefined ? <div className={cn('dishui-table-card__label', options.labelClassName)} style={options.labelStyle}>{label}</div> : null}\n {children}\n </td>\n );\n};\n\n// Table.HeaderCell 组件\nexport type TableHeaderCellProps = {\n children: React.ReactNode;\n className?: string;\n onClick?: (e: React.MouseEvent) => void;\n sortable?: boolean;\n sortDirection?: 'asc' | 'desc' | null;\n \n // 拖拽相关属性\n draggable?: boolean;\n onDragStart?: (e: React.DragEvent) => void;\n onDragOver?: (e: React.DragEvent) => void;\n onDrop?: (e: React.DragEvent) => void;\n \n // 鼠标事件\n onMouseEnter?: (e: React.MouseEvent) => void;\n onMouseLeave?: (e: React.MouseEvent) => void;\n} & React.ThHTMLAttributes<HTMLTableCellElement>;\n\nconst TableHeaderCell = ({\n children,\n className = '',\n style,\n onClick,\n sortable = false,\n sortDirection = null,\n \n // 拖拽相关属性\n draggable,\n onDragStart,\n onDragOver,\n onDrop,\n \n // 鼠标事件\n onMouseEnter,\n onMouseLeave,\n ...rest\n}: TableHeaderCellProps) => {\n const cardOptions = React.useContext(CardContext);\n const inBody = React.useContext(BodyContext);\n const options = inBody ? cardOptions : null;\n const baseClass = 'table-cell font-medium';\n \n const headerCellClasses = cn(\n baseClass,\n sortable && 'cursor-pointer',\n options && 'dishui-table-card__field',\n options?.fieldClassName,\n className\n );\n\n return (\n <th\n role={cardOptions ? (rest.scope === 'row' || rest.scope === 'rowgroup' || (inBody && !rest.scope) ? 'rowheader' : 'columnheader') : undefined}\n {...rest}\n style={options ? { ...options.fieldStyle, ...style } : style}\n className={headerCellClasses}\n onClick={onClick}\n draggable={draggable}\n onDragStart={onDragStart}\n onDragOver={onDragOver}\n onDrop={onDrop}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n {sortable ? <div className=\"flex items-center gap-2\">\n {children}\n {sortable && (\n <div className=\"flex flex-col\">\n {sortDirection === 'asc' ? (\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"2\" d=\"M5 15l7-7 7 7\" />\n </svg>\n ) : sortDirection === 'desc' ? (\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"2\" d=\"M19 9l-7 7-7-7\" />\n </svg>\n ) : (\n <div className=\"h-4 w-4 opacity-30\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"2\" d=\"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4\" />\n </svg>\n </div>\n )}\n </div>\n )}\n </div> : children}\n </th>\n );\n};\n\nexport type TableCaptionProps = React.HTMLAttributes<HTMLTableCaptionElement>;\nexport type TableFooterProps = React.HTMLAttributes<HTMLTableSectionElement>;\nconst TableCaption = (props: TableCaptionProps) => <caption {...props} />;\nconst TableFooter = (props: TableFooterProps) => {\n const options = React.useContext(CardContext);\n return <tfoot role={options ? 'rowgroup' : undefined} {...props} />;\n};\n\n// 扩展Table组件,添加子组件\nexport type TableCardProps = Omit<TableProps, 'card'>;\n\ninterface TableSubcomponents {\n Caption: React.FC<TableCaptionProps>;\n Footer: React.FC<TableFooterProps>;\n Head: React.FC<TableHeadProps>;\n Body: React.FC<TableBodyProps>;\n Row: React.FC<TableRowProps>;\n Cell: React.FC<TableCellProps>;\n HeaderCell: React.FC<TableHeaderCellProps>;\n}\n\nconst subcomponents: TableSubcomponents = {\n Caption: TableCaption,\n Footer: TableFooter,\n Head: TableHead,\n Body: TableBody,\n Row: TableRow,\n Cell: TableCell,\n HeaderCell: TableHeaderCell,\n};\n\nconst TableCard = (props: TableCardProps) => <Table {...props} card />;\nconst TableWithCompounds = Object.assign(Table, subcomponents, {\n Card: Object.assign(TableCard, subcomponents),\n});\n\nexport default TableWithCompounds; "],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import React from 'react';
2
+ export type AgentChatReasoningStep = {
3
+ /** Tools used in this step, rendered as chips: `Sales History · Flavor Data`. */
4
+ tools?: string[];
5
+ /** Rendered as `for 4s` after the chips. */
6
+ durationMs?: number;
7
+ /** Plain-language result of the step. */
8
+ summary?: React.ReactNode;
9
+ };
10
+ export type AgentChatMessage = {
11
+ id: string;
12
+ role: 'user' | 'assistant';
13
+ content?: React.ReactNode | string;
14
+ /** Assistant-only: each step renders as a chips-and-duration line followed by its summary. */
15
+ reasoning?: AgentChatReasoningStep[];
16
+ /** Epoch milliseconds. */
17
+ createdAt?: number;
18
+ };
19
+ export type ChatThread = {
20
+ id: string;
21
+ label: string;
22
+ messages: AgentChatMessage[];
23
+ };
24
+ export type AgentChatLabels = {
25
+ send?: string;
26
+ thinking?: string;
27
+ threads?: string;
28
+ messages?: string;
29
+ };
30
+ export type AgentChatProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> & {
31
+ threads: ChatThread[];
32
+ /** Controlled active thread id. */
33
+ activeThread?: string;
34
+ defaultActiveThread?: string;
35
+ onActiveThreadChange?: (threadId: string) => void;
36
+ /** Called with the trimmed composer text and the active thread id. */
37
+ onSend?: (text: string, threadId: string) => void;
38
+ /** Shows a thinking indicator under the last message and disables sending. */
39
+ busy?: boolean;
40
+ placeholder?: string;
41
+ /** Total panel height; number = px. */
42
+ height?: string | number;
43
+ /** Replace the default message renderer. */
44
+ renderMessage?: (message: AgentChatMessage) => React.ReactNode;
45
+ /** Shown when the active thread has no messages. */
46
+ emptyState?: React.ReactNode;
47
+ labels?: AgentChatLabels;
48
+ };
49
+ /**
50
+ * Tabbed chat panel: a `tablist` of threads, a scrollable log where user
51
+ * turns sit right in a muted bubble and assistant turns sit left as plain
52
+ * text with their reasoning lines, and a composer that auto-grows.
53
+ */
54
+ export default function AgentChat({ threads, activeThread: activeProp, defaultActiveThread, onActiveThreadChange, onSend, busy, placeholder, height, renderMessage, emptyState, labels, className, style, ...rest }: AgentChatProps): React.JSX.Element;
@@ -0,0 +1,176 @@
1
+ import { cn as e } from "../../../utils/cn.js";
2
+ import { formatDuration as t } from "../shared.js";
3
+ import n from "../LoadingState/index.js";
4
+ /* empty css */
5
+ import r, { useCallback as i, useEffect as a, useId as o, useRef as s, useState as c } from "react";
6
+ import { Fragment as l, jsx as u, jsxs as d } from "react/jsx-runtime";
7
+ //#region src/components/ai/AgentChat/index.tsx
8
+ var f = {
9
+ send: "Send",
10
+ thinking: "Thinking",
11
+ threads: "Threads",
12
+ messages: "Messages"
13
+ }, p = (e) => {
14
+ e.style.height = "auto", e.style.height = `${Math.min(e.scrollHeight, 160)}px`;
15
+ }, m = () => /* @__PURE__ */ d("svg", {
16
+ width: "16",
17
+ height: "16",
18
+ viewBox: "0 0 24 24",
19
+ fill: "none",
20
+ stroke: "currentColor",
21
+ strokeWidth: "2",
22
+ strokeLinecap: "round",
23
+ strokeLinejoin: "round",
24
+ "aria-hidden": "true",
25
+ children: [/* @__PURE__ */ u("path", { d: "m5 12 7-7 7 7" }), /* @__PURE__ */ u("path", { d: "M12 19V5" })]
26
+ }), h = ({ steps: e }) => /* @__PURE__ */ u("ol", {
27
+ className: "dishui-ai-agent-chat__reasoning",
28
+ children: e.map((e) => /* @__PURE__ */ d("li", {
29
+ className: "dishui-ai-agent-chat__step",
30
+ children: [(e.tools?.length || e.durationMs !== void 0) && /* @__PURE__ */ d("div", {
31
+ className: "dishui-ai-agent-chat__tools",
32
+ children: [e.tools?.map((e, t) => /* @__PURE__ */ d(r.Fragment, { children: [t > 0 && /* @__PURE__ */ u("span", {
33
+ className: "dishui-ai-agent-chat__sep",
34
+ "aria-hidden": "true",
35
+ children: "·"
36
+ }), /* @__PURE__ */ u("span", {
37
+ className: "dishui-ai-agent-chat__chip",
38
+ children: e
39
+ })] }, e)), e.durationMs !== void 0 && /* @__PURE__ */ d(l, { children: [!!e.tools?.length && /* @__PURE__ */ u("span", {
40
+ className: "dishui-ai-agent-chat__sep",
41
+ "aria-hidden": "true",
42
+ children: "·"
43
+ }), /* @__PURE__ */ d("span", {
44
+ className: "dishui-ai-agent-chat__duration",
45
+ children: ["for ", t(e.durationMs)]
46
+ })] })]
47
+ }), e.summary !== void 0 && /* @__PURE__ */ u("div", {
48
+ className: "dishui-ai-agent-chat__summary",
49
+ children: e.summary
50
+ })]
51
+ }, `${e.durationMs ?? ""}-${e.tools?.join("-") ?? ""}-${String(e.summary ?? "")}`))
52
+ }), g = ({ message: t }) => /* @__PURE__ */ d("div", {
53
+ className: e("dishui-ai-agent-chat__message", `dishui-ai-agent-chat__message--${t.role}`),
54
+ children: [t.role === "assistant" && t.reasoning?.length ? /* @__PURE__ */ u(h, { steps: t.reasoning }) : null, t.content !== void 0 && t.content !== null && /* @__PURE__ */ u("div", {
55
+ className: "dishui-ai-agent-chat__content",
56
+ children: t.content
57
+ })]
58
+ });
59
+ function _({ threads: t, activeThread: l, defaultActiveThread: h, onActiveThreadChange: _, onSend: v, busy: y = !1, placeholder: b = "Ask the agent…", height: x = 480, renderMessage: S, emptyState: C, labels: w, className: T, style: E, ...D }) {
60
+ let O = o(), k = {
61
+ ...f,
62
+ ...w
63
+ }, [A, j] = c(h ?? t[0]?.id), M = l ?? A, N = t.find((e) => e.id === M) ?? t[0], P = i((e) => {
64
+ j(e), _?.(e);
65
+ }, [_]), F = s({}), I = (e, n) => {
66
+ let r;
67
+ if (e.key === "ArrowRight" ? r = (n + 1) % t.length : e.key === "ArrowLeft" ? r = (n - 1 + t.length) % t.length : e.key === "Home" ? r = 0 : e.key === "End" && (r = t.length - 1), r === void 0) return;
68
+ e.preventDefault();
69
+ let i = t[r];
70
+ P(i.id), F.current[i.id]?.focus();
71
+ }, L = s(null), R = N?.messages.length ?? 0;
72
+ a(() => {
73
+ let e = L.current;
74
+ e && (e.scrollTop = e.scrollHeight);
75
+ }, [R, y]);
76
+ let [z, B] = c(""), V = s(null), H = !y && z.trim().length > 0 && !!N, U = () => {
77
+ if (!H || !N) return;
78
+ v?.(z.trim(), N.id), B("");
79
+ let e = V.current;
80
+ e && (e.style.height = "auto");
81
+ }, W = (e) => {
82
+ e.key === "Enter" && !e.shiftKey && !e.nativeEvent.isComposing && (e.preventDefault(), U());
83
+ }, G = `${O}-panel`, K = (e) => `${O}-tab-${e}`;
84
+ return /* @__PURE__ */ d("div", {
85
+ ...D,
86
+ className: e("dishui-ai-agent-chat", T),
87
+ style: {
88
+ ...E,
89
+ height: typeof x == "number" ? `${x}px` : x
90
+ },
91
+ children: [
92
+ t.length > 1 && /* @__PURE__ */ u("div", {
93
+ className: "dishui-ai-agent-chat__tabs",
94
+ role: "tablist",
95
+ "aria-label": k.threads,
96
+ children: t.map((t, n) => {
97
+ let r = t.id === N?.id;
98
+ return /* @__PURE__ */ u("button", {
99
+ ref: (e) => {
100
+ F.current[t.id] = e;
101
+ },
102
+ id: K(t.id),
103
+ type: "button",
104
+ role: "tab",
105
+ "aria-selected": r,
106
+ "aria-controls": G,
107
+ tabIndex: r ? 0 : -1,
108
+ className: e("dishui-ai-agent-chat__tab", r && "dishui-ai-agent-chat__tab--active"),
109
+ onClick: () => P(t.id),
110
+ onKeyDown: (e) => I(e, n),
111
+ children: t.label
112
+ }, t.id);
113
+ })
114
+ }),
115
+ /* @__PURE__ */ u("div", {
116
+ ref: L,
117
+ id: G,
118
+ role: "tabpanel",
119
+ "aria-labelledby": N && t.length > 1 ? K(N.id) : void 0,
120
+ className: "dishui-ai-agent-chat__log",
121
+ children: /* @__PURE__ */ d("div", {
122
+ role: "log",
123
+ "aria-live": "polite",
124
+ "aria-label": k.messages,
125
+ className: "dishui-ai-agent-chat__messages",
126
+ children: [
127
+ R === 0 && !y && C !== void 0 && /* @__PURE__ */ u("div", {
128
+ className: "dishui-ai-agent-chat__empty",
129
+ children: C
130
+ }),
131
+ N?.messages.map((e) => /* @__PURE__ */ u(r.Fragment, { children: S ? S(e) : /* @__PURE__ */ u(g, { message: e }) }, e.id)),
132
+ y && /* @__PURE__ */ u("div", {
133
+ className: "dishui-ai-agent-chat__message dishui-ai-agent-chat__message--assistant",
134
+ children: /* @__PURE__ */ u(n, {
135
+ variant: "dots",
136
+ size: "sm",
137
+ label: k.thinking,
138
+ showElapsed: !1
139
+ })
140
+ })
141
+ ]
142
+ })
143
+ }),
144
+ /* @__PURE__ */ d("form", {
145
+ className: "dishui-ai-agent-chat__composer",
146
+ onSubmit: (e) => {
147
+ e.preventDefault(), U();
148
+ },
149
+ children: [/* @__PURE__ */ u("textarea", {
150
+ ref: V,
151
+ className: "dishui-ai-agent-chat__input",
152
+ rows: 1,
153
+ value: z,
154
+ placeholder: b,
155
+ "aria-label": b,
156
+ disabled: !N,
157
+ onChange: (e) => {
158
+ B(e.target.value), p(e.target);
159
+ },
160
+ onKeyDown: W
161
+ }), /* @__PURE__ */ u("button", {
162
+ type: "submit",
163
+ className: "dishui-ai-agent-chat__send",
164
+ disabled: !H,
165
+ "aria-label": k.send,
166
+ title: k.send,
167
+ children: /* @__PURE__ */ u(m, {})
168
+ })]
169
+ })
170
+ ]
171
+ });
172
+ }
173
+ //#endregion
174
+ export { _ as default };
175
+
176
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/ai/AgentChat/index.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useId, useRef, useState } from 'react';\nimport { cn } from '../../../utils/cn';\nimport { formatDuration } from '../shared';\nimport LoadingState from '../LoadingState';\nimport './AgentChat.css';\n\nexport type AgentChatReasoningStep = {\n /** Tools used in this step, rendered as chips: `Sales History · Flavor Data`. */\n tools?: string[];\n /** Rendered as `for 4s` after the chips. */\n durationMs?: number;\n /** Plain-language result of the step. */\n summary?: React.ReactNode;\n};\n\nexport type AgentChatMessage = {\n id: string;\n role: 'user' | 'assistant';\n content?: React.ReactNode | string;\n /** Assistant-only: each step renders as a chips-and-duration line followed by its summary. */\n reasoning?: AgentChatReasoningStep[];\n /** Epoch milliseconds. */\n createdAt?: number;\n};\n\nexport type ChatThread = {\n id: string;\n label: string;\n messages: AgentChatMessage[];\n};\n\nexport type AgentChatLabels = {\n send?: string;\n thinking?: string;\n threads?: string;\n messages?: string;\n};\n\nexport type AgentChatProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> & {\n threads: ChatThread[];\n /** Controlled active thread id. */\n activeThread?: string;\n defaultActiveThread?: string;\n onActiveThreadChange?: (threadId: string) => void;\n /** Called with the trimmed composer text and the active thread id. */\n onSend?: (text: string, threadId: string) => void;\n /** Shows a thinking indicator under the last message and disables sending. */\n busy?: boolean;\n placeholder?: string;\n /** Total panel height; number = px. */\n height?: string | number;\n /** Replace the default message renderer. */\n renderMessage?: (message: AgentChatMessage) => React.ReactNode;\n /** Shown when the active thread has no messages. */\n emptyState?: React.ReactNode;\n labels?: AgentChatLabels;\n};\n\nconst DEFAULT_LABELS: Required<AgentChatLabels> = {\n send: 'Send',\n thinking: 'Thinking',\n threads: 'Threads',\n messages: 'Messages',\n};\n\nconst resizeComposer = (el: HTMLTextAreaElement) => {\n el.style.height = 'auto';\n el.style.height = `${Math.min(el.scrollHeight, 160)}px`;\n};\n\nconst SendIcon: React.FC = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"m5 12 7-7 7 7\" />\n <path d=\"M12 19V5\" />\n </svg>\n);\n\nconst Reasoning: React.FC<{ steps: AgentChatReasoningStep[] }> = ({ steps }) => (\n <ol className=\"dishui-ai-agent-chat__reasoning\">\n {steps.map(step => (\n <li key={`${step.durationMs ?? ''}-${step.tools?.join('-') ?? ''}-${String(step.summary ?? '')}`} className=\"dishui-ai-agent-chat__step\">\n {(step.tools?.length || step.durationMs !== undefined) && (\n <div className=\"dishui-ai-agent-chat__tools\">\n {step.tools?.map((tool, j) => (\n <React.Fragment key={tool}>\n {j > 0 && <span className=\"dishui-ai-agent-chat__sep\" aria-hidden=\"true\">·</span>}\n <span className=\"dishui-ai-agent-chat__chip\">{tool}</span>\n </React.Fragment>\n ))}\n {step.durationMs !== undefined && (\n <>\n {!!step.tools?.length && <span className=\"dishui-ai-agent-chat__sep\" aria-hidden=\"true\">·</span>}\n <span className=\"dishui-ai-agent-chat__duration\">for {formatDuration(step.durationMs)}</span>\n </>\n )}\n </div>\n )}\n {step.summary !== undefined && <div className=\"dishui-ai-agent-chat__summary\">{step.summary}</div>}\n </li>\n ))}\n </ol>\n);\n\nconst DefaultMessage: React.FC<{ message: AgentChatMessage }> = ({ message }) => (\n <div className={cn('dishui-ai-agent-chat__message', `dishui-ai-agent-chat__message--${message.role}`)}>\n {message.role === 'assistant' && message.reasoning?.length ? <Reasoning steps={message.reasoning} /> : null}\n {message.content !== undefined && message.content !== null && (\n <div className=\"dishui-ai-agent-chat__content\">{message.content}</div>\n )}\n </div>\n);\n\n/**\n * Tabbed chat panel: a `tablist` of threads, a scrollable log where user\n * turns sit right in a muted bubble and assistant turns sit left as plain\n * text with their reasoning lines, and a composer that auto-grows.\n */\nexport default function AgentChat({\n threads,\n activeThread: activeProp,\n defaultActiveThread,\n onActiveThreadChange,\n onSend,\n busy = false,\n placeholder = 'Ask the agent…',\n height = 480,\n renderMessage,\n emptyState,\n labels,\n className,\n style,\n ...rest\n}: AgentChatProps) {\n const baseId = useId();\n const text = { ...DEFAULT_LABELS, ...labels };\n\n const [internalActive, setInternalActive] = useState<string | undefined>(defaultActiveThread ?? threads[0]?.id);\n const activeId = activeProp ?? internalActive;\n const thread = threads.find(t => t.id === activeId) ?? threads[0];\n const activate = useCallback((id: string) => {\n setInternalActive(id);\n onActiveThreadChange?.(id);\n }, [onActiveThreadChange]);\n\n const tabRefs = useRef<Record<string, HTMLButtonElement | null>>({});\n const onTabKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>, index: number) => {\n let next: number | undefined;\n if (event.key === 'ArrowRight') next = (index + 1) % threads.length;\n else if (event.key === 'ArrowLeft') next = (index - 1 + threads.length) % threads.length;\n else if (event.key === 'Home') next = 0;\n else if (event.key === 'End') next = threads.length - 1;\n if (next === undefined) return;\n event.preventDefault();\n const target = threads[next];\n activate(target.id);\n tabRefs.current[target.id]?.focus();\n };\n\n const logRef = useRef<HTMLDivElement>(null);\n const messageCount = thread?.messages.length ?? 0;\n // The effect intentionally follows message/busy transitions to keep the log pinned.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useEffect(() => {\n const el = logRef.current;\n if (el) el.scrollTop = el.scrollHeight;\n // Message count and busy state intentionally retrigger the imperative scroll.\n void messageCount;\n void busy;\n }, [messageCount, busy]);\n\n const [draft, setDraft] = useState('');\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n const canSend = !busy && draft.trim().length > 0 && !!thread;\n const send = () => {\n if (!canSend || !thread) return;\n onSend?.(draft.trim(), thread.id);\n setDraft('');\n const el = textareaRef.current;\n if (el) el.style.height = 'auto';\n };\n const onComposerKeyDown = (event: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (event.key === 'Enter' && !event.shiftKey && !event.nativeEvent.isComposing) {\n event.preventDefault();\n send();\n }\n };\n\n const panelId = `${baseId}-panel`;\n const tabId = (id: string) => `${baseId}-tab-${id}`;\n\n return (\n <div\n {...rest}\n className={cn('dishui-ai-agent-chat', className)}\n style={{ ...style, height: typeof height === 'number' ? `${height}px` : height }}\n >\n {threads.length > 1 && (\n <div className=\"dishui-ai-agent-chat__tabs\" role=\"tablist\" aria-label={text.threads}>\n {threads.map((t, i) => {\n const selected = t.id === thread?.id;\n return (\n <button\n key={t.id}\n ref={el => { tabRefs.current[t.id] = el; }}\n id={tabId(t.id)}\n type=\"button\"\n role=\"tab\"\n aria-selected={selected}\n aria-controls={panelId}\n tabIndex={selected ? 0 : -1}\n className={cn('dishui-ai-agent-chat__tab', selected && 'dishui-ai-agent-chat__tab--active')}\n onClick={() => activate(t.id)}\n onKeyDown={e => onTabKeyDown(e, i)}\n >\n {t.label}\n </button>\n );\n })}\n </div>\n )}\n\n <div\n ref={logRef}\n id={panelId}\n role=\"tabpanel\"\n aria-labelledby={thread && threads.length > 1 ? tabId(thread.id) : undefined}\n className=\"dishui-ai-agent-chat__log\"\n >\n <div role=\"log\" aria-live=\"polite\" aria-label={text.messages} className=\"dishui-ai-agent-chat__messages\">\n {messageCount === 0 && !busy && emptyState !== undefined && (\n <div className=\"dishui-ai-agent-chat__empty\">{emptyState}</div>\n )}\n {thread?.messages.map(message => (\n <React.Fragment key={message.id}>\n {renderMessage ? renderMessage(message) : <DefaultMessage message={message} />}\n </React.Fragment>\n ))}\n {busy && (\n <div className=\"dishui-ai-agent-chat__message dishui-ai-agent-chat__message--assistant\">\n <LoadingState variant=\"dots\" size=\"sm\" label={text.thinking} showElapsed={false} />\n </div>\n )}\n </div>\n </div>\n\n <form\n className=\"dishui-ai-agent-chat__composer\"\n onSubmit={e => { e.preventDefault(); send(); }}\n >\n <textarea\n ref={textareaRef}\n className=\"dishui-ai-agent-chat__input\"\n rows={1}\n value={draft}\n placeholder={placeholder}\n aria-label={placeholder}\n disabled={!thread}\n onChange={e => { setDraft(e.target.value); resizeComposer(e.target); }}\n onKeyDown={onComposerKeyDown}\n />\n <button\n type=\"submit\"\n className=\"dishui-ai-agent-chat__send\"\n disabled={!canSend}\n aria-label={text.send}\n title={text.send}\n >\n <SendIcon />\n </button>\n </form>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import React from 'react';
2
+ export type AgentRunStatus = 'queued' | 'running' | 'waiting' | 'done' | 'failed';
3
+ export type AgentRunMeta = {
4
+ label?: React.ReactNode;
5
+ value: React.ReactNode;
6
+ };
7
+ export type AgentRunCardProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'title' | 'onSelect'> & {
8
+ /** Agent name (e.g. `Sol`). */
9
+ name: React.ReactNode;
10
+ /** Model or engine label shown beside the name (e.g. `Opus 5`). */
11
+ model?: React.ReactNode;
12
+ /** Avatar slot, typically an `Avatar` with the agent's initials. */
13
+ avatar?: React.ReactNode;
14
+ /** Run status; drives the trailing badge tone and progress colour. */
15
+ status?: AgentRunStatus;
16
+ /** Explicit status label; defaults to a capitalised form of `status`. */
17
+ statusLabel?: React.ReactNode;
18
+ /** The task the agent is working on (single truncating line). */
19
+ task?: React.ReactNode;
20
+ /** Current activity line, prefixed by a status dot. */
21
+ activity?: React.ReactNode;
22
+ /** Progress from 0 to 1. When omitted, the progress row is hidden. */
23
+ progress?: number;
24
+ /** Compact meta values shown in a row (e.g. steps, elapsed, tokens). */
25
+ meta?: AgentRunMeta[];
26
+ /** Monospace footer, typically a branch or path. */
27
+ footer?: React.ReactNode;
28
+ /** Selected state (raised border). */
29
+ selected?: boolean;
30
+ /** Click handler turns the card into a button for keyboard users. */
31
+ onSelect?: () => void;
32
+ };
33
+ /**
34
+ * Agent run card: avatar + name + model, a status badge, the task, a current
35
+ * activity line, an optional progress bar with percentage, a compact meta row
36
+ * (steps / elapsed / tokens) and a monospace footer (branch or path).
37
+ */
38
+ export default function AgentRunCard({ name, model, avatar, status, statusLabel, task, activity, progress, meta, footer, selected, onSelect, className, ...rest }: AgentRunCardProps): React.JSX.Element;
@@ -0,0 +1,100 @@
1
+ import { cn as e } from "../../../utils/cn.js";
2
+ import { clamp as t } from "../shared.js";
3
+ /* empty css */
4
+ import "react";
5
+ import { jsx as n, jsxs as r } from "react/jsx-runtime";
6
+ //#region src/components/ai/AgentRunCard/index.tsx
7
+ var i = {
8
+ queued: "Queued",
9
+ running: "Running",
10
+ waiting: "Waiting",
11
+ done: "Done",
12
+ failed: "Failed"
13
+ }, a = [];
14
+ function o({ name: o, model: s, avatar: c, status: l = "queued", statusLabel: u, task: d, activity: f, progress: p, meta: m = a, footer: h, selected: g = !1, onSelect: _, className: v, ...y }) {
15
+ let b = !!_, x = typeof p == "number" && Number.isFinite(p), S = x ? Math.round(t(p, 0, 1) * 100) : 0, C = l === "running", w = u ?? i[l];
16
+ return /* @__PURE__ */ r("div", {
17
+ ...y,
18
+ className: e("dishui-ai-run-card", `dishui-ai-run-card--${l}`, g && "dishui-ai-run-card--selected", b && "dishui-ai-run-card--interactive", v),
19
+ role: b ? "button" : void 0,
20
+ tabIndex: b ? 0 : void 0,
21
+ "aria-pressed": b ? g : void 0,
22
+ onClick: b ? _ : y.onClick,
23
+ onKeyDown: b ? (e) => {
24
+ e.target === e.currentTarget && (e.key === "Enter" || e.key === " ") && (e.preventDefault(), e.repeat || _?.());
25
+ } : void 0,
26
+ children: [
27
+ /* @__PURE__ */ r("header", {
28
+ className: "dishui-ai-run-card__header",
29
+ children: [
30
+ c != null && /* @__PURE__ */ n("span", {
31
+ className: "dishui-ai-run-card__avatar",
32
+ children: c
33
+ }),
34
+ /* @__PURE__ */ r("span", {
35
+ className: "dishui-ai-run-card__identity",
36
+ children: [/* @__PURE__ */ n("span", {
37
+ className: "dishui-ai-run-card__name",
38
+ children: o
39
+ }), s != null && /* @__PURE__ */ n("span", {
40
+ className: "dishui-ai-run-card__model",
41
+ children: s
42
+ })]
43
+ }),
44
+ /* @__PURE__ */ r("span", {
45
+ className: e("dishui-ai-run-card__status", `dishui-ai-run-card__status--${l}`),
46
+ role: "status",
47
+ "aria-live": "polite",
48
+ children: [/* @__PURE__ */ n("span", {
49
+ className: e("dishui-ai-run-card__dot", C && "dishui-ai-run-card__dot--live"),
50
+ "aria-hidden": "true"
51
+ }), w]
52
+ })
53
+ ]
54
+ }),
55
+ d != null && /* @__PURE__ */ n("div", {
56
+ className: "dishui-ai-run-card__task",
57
+ children: d
58
+ }),
59
+ f != null && /* @__PURE__ */ r("div", {
60
+ className: "dishui-ai-run-card__activity",
61
+ children: [/* @__PURE__ */ n("span", {
62
+ className: "dishui-ai-run-card__activity-dot",
63
+ "aria-hidden": "true"
64
+ }), /* @__PURE__ */ n("span", {
65
+ className: "dishui-ai-run-card__activity-text",
66
+ children: f
67
+ })]
68
+ }),
69
+ x && /* @__PURE__ */ r("div", {
70
+ className: "dishui-ai-run-card__progress",
71
+ children: [/* @__PURE__ */ n("span", {
72
+ className: "dishui-ai-run-card__track",
73
+ role: "progressbar",
74
+ "aria-valuemin": 0,
75
+ "aria-valuemax": 100,
76
+ "aria-valuenow": S,
77
+ children: /* @__PURE__ */ n("span", {
78
+ className: "dishui-ai-run-card__fill",
79
+ style: { width: `${S}%` }
80
+ })
81
+ }), /* @__PURE__ */ r("span", {
82
+ className: "dishui-ai-run-card__pct",
83
+ children: [S, "%"]
84
+ })]
85
+ }),
86
+ m.length > 0 && /* @__PURE__ */ n("dl", {
87
+ className: "dishui-ai-run-card__meta",
88
+ children: m.map((e, t) => /* @__PURE__ */ r("div", { children: [e.label !== null && e.label !== void 0 && /* @__PURE__ */ n("dt", { children: e.label }), /* @__PURE__ */ n("dd", { children: e.value })] }, e.label !== null && e.label !== void 0 ? `${String(e.label)}-${t}` : `meta-${t}`))
89
+ }),
90
+ h != null && /* @__PURE__ */ n("div", {
91
+ className: "dishui-ai-run-card__footer",
92
+ children: h
93
+ })
94
+ ]
95
+ });
96
+ }
97
+ //#endregion
98
+ export { o as default };
99
+
100
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/ai/AgentRunCard/index.tsx"],"sourcesContent":["import React from 'react';\nimport { cn } from '../../../utils/cn';\nimport { clamp } from '../shared';\nimport './AgentRunCard.css';\n\nexport type AgentRunStatus = 'queued' | 'running' | 'waiting' | 'done' | 'failed';\n\nexport type AgentRunMeta = {\n label?: React.ReactNode;\n value: React.ReactNode;\n};\n\nexport type AgentRunCardProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'title' | 'onSelect'> & {\n /** Agent name (e.g. `Sol`). */\n name: React.ReactNode;\n /** Model or engine label shown beside the name (e.g. `Opus 5`). */\n model?: React.ReactNode;\n /** Avatar slot, typically an `Avatar` with the agent's initials. */\n avatar?: React.ReactNode;\n /** Run status; drives the trailing badge tone and progress colour. */\n status?: AgentRunStatus;\n /** Explicit status label; defaults to a capitalised form of `status`. */\n statusLabel?: React.ReactNode;\n /** The task the agent is working on (single truncating line). */\n task?: React.ReactNode;\n /** Current activity line, prefixed by a status dot. */\n activity?: React.ReactNode;\n /** Progress from 0 to 1. When omitted, the progress row is hidden. */\n progress?: number;\n /** Compact meta values shown in a row (e.g. steps, elapsed, tokens). */\n meta?: AgentRunMeta[];\n /** Monospace footer, typically a branch or path. */\n footer?: React.ReactNode;\n /** Selected state (raised border). */\n selected?: boolean;\n /** Click handler turns the card into a button for keyboard users. */\n onSelect?: () => void;\n};\n\nconst STATUS_LABEL: Record<AgentRunStatus, string> = {\n queued: 'Queued',\n running: 'Running',\n waiting: 'Waiting',\n done: 'Done',\n failed: 'Failed',\n};\n\nconst EMPTY_META: AgentRunMeta[] = [];\n\n/**\n * Agent run card: avatar + name + model, a status badge, the task, a current\n * activity line, an optional progress bar with percentage, a compact meta row\n * (steps / elapsed / tokens) and a monospace footer (branch or path).\n */\nexport default function AgentRunCard({\n name,\n model,\n avatar,\n status = 'queued',\n statusLabel,\n task,\n activity,\n progress,\n meta = EMPTY_META,\n footer,\n selected = false,\n onSelect,\n className,\n ...rest\n}: AgentRunCardProps) {\n const interactive = !!onSelect;\n const hasProgress = typeof progress === 'number' && Number.isFinite(progress);\n const pct = hasProgress ? Math.round(clamp(progress as number, 0, 1) * 100) : 0;\n const live = status === 'running';\n const label = statusLabel ?? STATUS_LABEL[status];\n\n return (\n <div\n {...rest}\n className={cn(\n 'dishui-ai-run-card',\n `dishui-ai-run-card--${status}`,\n selected && 'dishui-ai-run-card--selected',\n interactive && 'dishui-ai-run-card--interactive',\n className,\n )}\n role={interactive ? 'button' : undefined}\n tabIndex={interactive ? 0 : undefined}\n aria-pressed={interactive ? selected : undefined}\n onClick={interactive ? onSelect : rest.onClick}\n onKeyDown={interactive ? (event) => {\n if (event.target !== event.currentTarget) return;\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n if (!event.repeat) onSelect?.();\n }\n } : undefined}\n >\n <header className=\"dishui-ai-run-card__header\">\n {avatar !== null && avatar !== undefined && <span className=\"dishui-ai-run-card__avatar\">{avatar}</span>}\n <span className=\"dishui-ai-run-card__identity\">\n <span className=\"dishui-ai-run-card__name\">{name}</span>\n {model !== null && model !== undefined && <span className=\"dishui-ai-run-card__model\">{model}</span>}\n </span>\n <span\n className={cn('dishui-ai-run-card__status', `dishui-ai-run-card__status--${status}`)}\n role=\"status\"\n aria-live=\"polite\"\n >\n <span className={cn('dishui-ai-run-card__dot', live && 'dishui-ai-run-card__dot--live')} aria-hidden=\"true\" />\n {label}\n </span>\n </header>\n\n {task !== null && task !== undefined && <div className=\"dishui-ai-run-card__task\">{task}</div>}\n\n {activity !== null && activity !== undefined && (\n <div className=\"dishui-ai-run-card__activity\">\n <span className=\"dishui-ai-run-card__activity-dot\" aria-hidden=\"true\" />\n <span className=\"dishui-ai-run-card__activity-text\">{activity}</span>\n </div>\n )}\n\n {hasProgress && (\n <div className=\"dishui-ai-run-card__progress\">\n <span\n className=\"dishui-ai-run-card__track\"\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={pct}\n >\n <span className=\"dishui-ai-run-card__fill\" style={{ width: `${pct}%` }} />\n </span>\n <span className=\"dishui-ai-run-card__pct\">{pct}%</span>\n </div>\n )}\n\n {meta.length > 0 && (\n <dl className=\"dishui-ai-run-card__meta\">\n {meta.map((item, index) => (\n <div key={item.label !== null && item.label !== undefined ? `${String(item.label)}-${index}` : `meta-${index}`}>\n {item.label !== null && item.label !== undefined && <dt>{item.label}</dt>}\n <dd>{item.value}</dd>\n </div>\n ))}\n </dl>\n )}\n\n {footer !== null && footer !== undefined && <div className=\"dishui-ai-run-card__footer\">{footer}</div>}\n </div>\n );\n}\n"],"mappings":";;;;;;AAuCA,IAAM,IAA+C;CACnD,QAAQ;CACR,SAAS;CACT,SAAS;CACT,MAAM;CACN,QAAQ;AACV,GAEM,IAA6B,CAAC;AAOpC,SAAwB,EAAa,EACnC,SACA,UACA,WACA,YAAS,UACT,gBACA,SACA,aACA,aACA,UAAO,GACP,WACA,cAAW,IACX,aACA,cACA,GAAG,KACiB;CACpB,IAAM,IAAc,CAAC,CAAC,GAChB,IAAc,OAAO,KAAa,YAAY,OAAO,SAAS,CAAQ,GACtE,IAAM,IAAc,KAAK,MAAM,EAAM,GAAoB,GAAG,CAAC,IAAI,GAAG,IAAI,GACxE,IAAO,MAAW,WAClB,IAAQ,KAAe,EAAa;CAE1C,OACE,kBAAC,OAAD;EACE,GAAI;EACJ,WAAW,EACT,sBACA,uBAAuB,KACvB,KAAY,gCACZ,KAAe,mCACf,CACF;EACA,MAAM,IAAc,WAAW,KAAA;EAC/B,UAAU,IAAc,IAAI,KAAA;EAC5B,gBAAc,IAAc,IAAW,KAAA;EACvC,SAAS,IAAc,IAAW,EAAK;EACvC,WAAW,KAAe,MAAU;GAC9B,EAAM,WAAW,EAAM,kBACvB,EAAM,QAAQ,WAAW,EAAM,QAAQ,SACzC,EAAM,eAAe,GAChB,EAAM,UAAQ,IAAW;EAElC,IAAI,KAAA;EAnBN,UAAA;GAqBE,kBAAC,UAAD;IAAQ,WAAU;IAAlB,UAAA;KACG,KAAW,QAAgC,kBAAC,QAAD;MAAM,WAAU;MAA8B,UAAA;KAAa,CAAA;KACvG,kBAAC,QAAD;MAAM,WAAU;MAAhB,UAAA,CACE,kBAAC,QAAD;OAAM,WAAU;OAA4B,UAAA;MAAW,CAAA,GACtD,KAAU,QAA+B,kBAAC,QAAD;OAAM,WAAU;OAA6B,UAAA;MAAY,CAAA,CAC/F;;KACN,kBAAC,QAAD;MACE,WAAW,EAAG,8BAA8B,+BAA+B,GAAQ;MACnF,MAAK;MACL,aAAU;MAHZ,UAAA,CAKE,kBAAC,QAAD;OAAM,WAAW,EAAG,2BAA2B,KAAQ,+BAA+B;OAAG,eAAY;MAAQ,CAAA,GAC5G,CACG;;IACA;;GAEP,KAAS,QAA8B,kBAAC,OAAD;IAAK,WAAU;IAA4B,UAAA;GAAU,CAAA;GAE5F,KAAa,QACZ,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,kBAAC,QAAD;KAAM,WAAU;KAAmC,eAAY;IAAQ,CAAA,GACvE,kBAAC,QAAD;KAAM,WAAU;KAAqC,UAAA;IAAe,CAAA,CACjE;;GAGN,KACC,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,kBAAC,QAAD;KACE,WAAU;KACV,MAAK;KACL,iBAAe;KACf,iBAAe;KACf,iBAAe;KAEf,UAAA,kBAAC,QAAD;MAAM,WAAU;MAA2B,OAAO,EAAE,OAAO,GAAG,EAAI,GAAG;KAAI,CAAA;IACrE,CAAA,GACN,kBAAC,QAAD;KAAM,WAAU;KAAhB,UAAA,CAA2C,GAAI,GAAO;IACnD,CAAA,CAAA;;GAGN,EAAK,SAAS,KACb,kBAAC,MAAD;IAAI,WAAU;IACX,UAAA,EAAK,KAAK,GAAM,MACf,kBAAC,OAAD,EAAA,UAAA,CACG,EAAK,UAAU,QAAQ,EAAK,UAAU,KAAA,KAAa,kBAAC,MAAD,EAAA,UAAK,EAAK,MAAU,CAAA,GACxE,kBAAC,MAAD,EAAA,UAAK,EAAK,MAAU,CAAA,CACjB,EAAA,GAHK,EAAK,UAAU,QAAQ,EAAK,UAAU,KAAA,IAAY,GAAG,OAAO,EAAK,KAAK,EAAE,GAAG,MAAU,QAAQ,GAGlG,CACN;GACC,CAAA;GAGL,KAAW,QAAgC,kBAAC,OAAD;IAAK,WAAU;IAA8B,UAAA;GAAY,CAAA;EAClG;;AAET"}
@@ -0,0 +1,50 @@
1
+ import React from 'react';
2
+ export type AgentScreenStatus = 'idle' | 'loading' | 'working' | 'paused' | 'recording';
3
+ export type AgentScreenLabels = {
4
+ open?: string;
5
+ teach?: string;
6
+ record?: string;
7
+ stopRecording?: string;
8
+ pause?: string;
9
+ resume?: string;
10
+ status?: Partial<Record<AgentScreenStatus, string>>;
11
+ };
12
+ export type AgentScreenProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'children' | 'title'> & {
13
+ status: AgentScreenStatus;
14
+ title?: React.ReactNode;
15
+ /** Shown in a faux address bar and opened by the default Open action. */
16
+ url?: string;
17
+ /** Screen content (`<img>`, `<iframe>`, any node). Absent → skeleton blocks. */
18
+ children?: React.ReactNode;
19
+ /** Defaults to opening `url` in a new tab when `url` is given. */
20
+ onOpen?: () => void;
21
+ onTeach?: () => void;
22
+ /** Toggles recording; the label flips to Stop while `status === 'recording'`. */
23
+ onRecord?: () => void;
24
+ onPause?: () => void;
25
+ onResume?: () => void;
26
+ elapsedMs?: number;
27
+ /** CSS `aspect-ratio` of the screen area. */
28
+ aspectRatio?: string;
29
+ /** Optional secondary panel shown beside or below the screen. */
30
+ secondary?: React.ReactNode;
31
+ /** Split direction when `secondary` is present. */
32
+ split?: 'horizontal' | 'vertical';
33
+ /** Initial panel percentages; must sum to 100. */
34
+ defaultSplitSizes?: [number, number];
35
+ /** Controlled panel percentages; must sum to 100. */
36
+ splitSizes?: [number, number];
37
+ onSplitSizesChange?: (sizes: number[]) => void;
38
+ onSplitSizesCommit?: (sizes: number[]) => void;
39
+ /** Minimum percentage for the primary screen and secondary panel. */
40
+ minPanelSizes?: [number, number];
41
+ /** Resize handle presentation from the shared Resizable component. */
42
+ resizeHandleVariant?: 'line' | 'pill';
43
+ labels?: AgentScreenLabels;
44
+ };
45
+ /**
46
+ * Window chrome around an agent's screen: title, text + dot status badge,
47
+ * elapsed time, optional address bar, the screen surface and a footer
48
+ * toolbar with Open / Teach a task / Record / Pause.
49
+ */
50
+ export default function AgentScreen({ status, title, url, children, onOpen, onTeach, onRecord, onPause, onResume, elapsedMs, aspectRatio, secondary, split, defaultSplitSizes, splitSizes, onSplitSizesChange, onSplitSizesCommit, minPanelSizes, resizeHandleVariant, labels, className, ...rest }: AgentScreenProps): React.JSX.Element;