@bysages/react 0.2.1 → 0.2.3

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 (263) hide show
  1. package/dist/ai-response-jZy-0Tvv.mjs +127 -0
  2. package/dist/chevron-BeHvt46K.mjs +17 -0
  3. package/dist/components/accordion/index.d.mts +7 -0
  4. package/dist/components/accordion/index.mjs +10 -0
  5. package/dist/components/affix/index.d.mts +20 -0
  6. package/dist/components/affix/index.mjs +18 -0
  7. package/dist/components/ai/index.d.mts +2 -0
  8. package/dist/components/ai/index.mjs +65 -0
  9. package/dist/components/ai-action/index.d.mts +14 -0
  10. package/dist/components/ai-action/index.mjs +18 -0
  11. package/dist/components/ai-attachments/index.d.mts +19 -0
  12. package/dist/components/ai-attachments/index.mjs +106 -0
  13. package/dist/components/ai-message/index.d.mts +11 -0
  14. package/dist/components/ai-message/index.mjs +15 -0
  15. package/dist/components/ai-prompt-input/index.d.mts +47 -0
  16. package/dist/components/ai-prompt-input/index.mjs +135 -0
  17. package/dist/components/ai-reasoning/index.d.mts +13 -0
  18. package/dist/components/ai-reasoning/index.mjs +19 -0
  19. package/dist/components/ai-response/index.d.mts +22 -0
  20. package/dist/components/ai-response/index.mjs +2 -0
  21. package/dist/components/ai-source/index.d.mts +17 -0
  22. package/dist/components/ai-source/index.mjs +27 -0
  23. package/dist/components/ai-suggestion/index.d.mts +13 -0
  24. package/dist/components/ai-suggestion/index.mjs +16 -0
  25. package/dist/components/ai-tool/index.d.mts +21 -0
  26. package/dist/components/ai-tool/index.mjs +36 -0
  27. package/dist/components/alert/index.d.mts +23 -0
  28. package/dist/components/alert/index.mjs +80 -0
  29. package/dist/components/angle-slider/index.d.mts +16 -0
  30. package/dist/components/angle-slider/index.mjs +21 -0
  31. package/dist/components/aspect-ratio/index.d.mts +10 -0
  32. package/dist/components/aspect-ratio/index.mjs +17 -0
  33. package/dist/components/autocomplete/index.d.mts +21 -0
  34. package/dist/components/autocomplete/index.mjs +35 -0
  35. package/dist/components/avatar/index.d.mts +20 -0
  36. package/dist/components/avatar/index.mjs +14 -0
  37. package/dist/components/avatar-group/index.d.mts +11 -0
  38. package/dist/components/avatar-group/index.mjs +15 -0
  39. package/dist/components/back-top/index.d.mts +29 -0
  40. package/dist/components/back-top/index.mjs +82 -0
  41. package/dist/components/badge/index.d.mts +10 -0
  42. package/dist/components/badge/index.mjs +15 -0
  43. package/dist/components/banner/index.d.mts +31 -0
  44. package/dist/components/banner/index.mjs +63 -0
  45. package/dist/components/breadcrumb/index.d.mts +32 -0
  46. package/dist/components/breadcrumb/index.mjs +35 -0
  47. package/dist/components/button/index.d.mts +19 -0
  48. package/dist/components/button/index.mjs +29 -0
  49. package/dist/components/button-group/index.d.mts +24 -0
  50. package/dist/components/button-group/index.mjs +25 -0
  51. package/dist/components/calendar/index.d.mts +17 -0
  52. package/dist/components/calendar/index.mjs +96 -0
  53. package/dist/components/card/index.d.mts +46 -0
  54. package/dist/components/card/index.mjs +44 -0
  55. package/dist/components/carousel/index.d.mts +9 -0
  56. package/dist/components/carousel/index.mjs +12 -0
  57. package/dist/components/cascade-select/index.d.mts +31 -0
  58. package/dist/components/cascade-select/index.mjs +223 -0
  59. package/dist/components/checkbox/index.d.mts +16 -0
  60. package/dist/components/checkbox/index.mjs +21 -0
  61. package/dist/components/checkbox-group/index.d.mts +28 -0
  62. package/dist/components/checkbox-group/index.mjs +65 -0
  63. package/dist/components/chip/index.d.mts +12 -0
  64. package/dist/components/chip/index.mjs +17 -0
  65. package/dist/components/client-only/index.d.mts +2 -0
  66. package/dist/components/client-only/index.mjs +2 -0
  67. package/dist/components/clipboard/index.d.mts +17 -0
  68. package/dist/components/clipboard/index.mjs +17 -0
  69. package/dist/components/collapsible/index.d.mts +7 -0
  70. package/dist/components/collapsible/index.mjs +10 -0
  71. package/dist/components/collection/index.d.mts +2 -0
  72. package/dist/components/collection/index.mjs +2 -0
  73. package/dist/components/color-picker/index.d.mts +20 -0
  74. package/dist/components/color-picker/index.mjs +25 -0
  75. package/dist/components/combobox/index.d.mts +17 -0
  76. package/dist/components/combobox/index.mjs +18 -0
  77. package/dist/components/command/index.d.mts +43 -0
  78. package/dist/components/command/index.mjs +137 -0
  79. package/dist/components/comment/index.d.mts +17 -0
  80. package/dist/components/comment/index.mjs +47 -0
  81. package/dist/components/config-provider/index.d.mts +46 -0
  82. package/dist/components/config-provider/index.mjs +41 -0
  83. package/dist/components/container/index.d.mts +13 -0
  84. package/dist/components/container/index.mjs +15 -0
  85. package/dist/components/date-input/index.d.mts +17 -0
  86. package/dist/components/date-input/index.mjs +21 -0
  87. package/dist/components/date-picker/index.d.mts +19 -0
  88. package/dist/components/date-picker/index.mjs +23 -0
  89. package/dist/components/descriptions/index.d.mts +25 -0
  90. package/dist/components/descriptions/index.mjs +32 -0
  91. package/dist/components/dialog/index.d.mts +9 -0
  92. package/dist/components/dialog/index.mjs +11 -0
  93. package/dist/components/download-trigger/index.d.mts +2 -0
  94. package/dist/components/download-trigger/index.mjs +2 -0
  95. package/dist/components/drawer/index.d.mts +9 -0
  96. package/dist/components/drawer/index.mjs +12 -0
  97. package/dist/components/dynamic-input/index.d.mts +28 -0
  98. package/dist/components/dynamic-input/index.mjs +83 -0
  99. package/dist/components/editable/index.d.mts +16 -0
  100. package/dist/components/editable/index.mjs +17 -0
  101. package/dist/components/ellipsis/index.d.mts +10 -0
  102. package/dist/components/ellipsis/index.mjs +19 -0
  103. package/dist/components/empty/index.d.mts +28 -0
  104. package/dist/components/empty/index.mjs +32 -0
  105. package/dist/components/field/index.d.mts +8 -0
  106. package/dist/components/field/index.mjs +11 -0
  107. package/dist/components/fieldset/index.d.mts +7 -0
  108. package/dist/components/fieldset/index.mjs +10 -0
  109. package/dist/components/file-upload/index.d.mts +18 -0
  110. package/dist/components/file-upload/index.mjs +23 -0
  111. package/dist/components/float-button/index.d.mts +59 -0
  112. package/dist/components/float-button/index.mjs +90 -0
  113. package/dist/components/floating-panel/index.d.mts +9 -0
  114. package/dist/components/floating-panel/index.mjs +12 -0
  115. package/dist/components/focus-trap/index.d.mts +2 -0
  116. package/dist/components/focus-trap/index.mjs +2 -0
  117. package/dist/components/form/index.d.mts +2 -0
  118. package/dist/components/form/index.mjs +67 -0
  119. package/dist/components/format/index.d.mts +9 -0
  120. package/dist/components/format/index.mjs +10 -0
  121. package/dist/components/frame/index.d.mts +10 -0
  122. package/dist/components/frame/index.mjs +12 -0
  123. package/dist/components/grid/index.d.mts +13 -0
  124. package/dist/components/grid/index.mjs +31 -0
  125. package/dist/components/highlight/index.d.mts +7 -0
  126. package/dist/components/highlight/index.mjs +11 -0
  127. package/dist/components/hover-card/index.d.mts +7 -0
  128. package/dist/components/hover-card/index.mjs +10 -0
  129. package/dist/components/icon/index.d.mts +19 -0
  130. package/dist/components/icon/index.mjs +26 -0
  131. package/dist/components/image/index.d.mts +17 -0
  132. package/dist/components/image/index.mjs +57 -0
  133. package/dist/components/image-cropper/index.d.mts +8 -0
  134. package/dist/components/image-cropper/index.mjs +11 -0
  135. package/dist/components/image-viewer/index.d.mts +18 -0
  136. package/dist/components/image-viewer/index.mjs +110 -0
  137. package/dist/components/input/index.d.mts +16 -0
  138. package/dist/components/input/index.mjs +21 -0
  139. package/dist/components/input-group/index.d.mts +17 -0
  140. package/dist/components/input-group/index.mjs +31 -0
  141. package/dist/components/json-tree-view/index.d.mts +7 -0
  142. package/dist/components/json-tree-view/index.mjs +10 -0
  143. package/dist/components/kbd/index.d.mts +6 -0
  144. package/dist/components/kbd/index.mjs +14 -0
  145. package/dist/components/layout/index.d.mts +63 -0
  146. package/dist/components/layout/index.mjs +133 -0
  147. package/dist/components/link/index.d.mts +10 -0
  148. package/dist/components/link/index.mjs +18 -0
  149. package/dist/components/list/index.d.mts +39 -0
  150. package/dist/components/list/index.mjs +66 -0
  151. package/dist/components/listbox/index.d.mts +18 -0
  152. package/dist/components/listbox/index.mjs +18 -0
  153. package/dist/components/marquee/index.d.mts +7 -0
  154. package/dist/components/marquee/index.mjs +10 -0
  155. package/dist/components/masonry/index.d.mts +11 -0
  156. package/dist/components/masonry/index.mjs +29 -0
  157. package/dist/components/mentions/index.d.mts +2 -0
  158. package/dist/components/mentions/index.mjs +2 -0
  159. package/dist/components/menu/index.d.mts +20 -0
  160. package/dist/components/menu/index.mjs +37 -0
  161. package/dist/components/menubar/index.d.mts +32 -0
  162. package/dist/components/menubar/index.mjs +35 -0
  163. package/dist/components/meter/index.d.mts +26 -0
  164. package/dist/components/meter/index.mjs +59 -0
  165. package/dist/components/navigation-menu/index.d.mts +8 -0
  166. package/dist/components/navigation-menu/index.mjs +11 -0
  167. package/dist/components/number-input/index.d.mts +16 -0
  168. package/dist/components/number-input/index.mjs +21 -0
  169. package/dist/components/page-header/index.d.mts +32 -0
  170. package/dist/components/page-header/index.mjs +34 -0
  171. package/dist/components/pagination/index.d.mts +18 -0
  172. package/dist/components/pagination/index.mjs +23 -0
  173. package/dist/components/password-input/index.d.mts +16 -0
  174. package/dist/components/password-input/index.mjs +21 -0
  175. package/dist/components/pin-input/index.d.mts +15 -0
  176. package/dist/components/pin-input/index.mjs +20 -0
  177. package/dist/components/popconfirm/index.d.mts +20 -0
  178. package/dist/components/popconfirm/index.mjs +44 -0
  179. package/dist/components/popover/index.d.mts +8 -0
  180. package/dist/components/popover/index.mjs +11 -0
  181. package/dist/components/presence/index.d.mts +2 -0
  182. package/dist/components/presence/index.mjs +2 -0
  183. package/dist/components/progress/index.d.mts +16 -0
  184. package/dist/components/progress/index.mjs +21 -0
  185. package/dist/components/progress-group/index.d.mts +22 -0
  186. package/dist/components/progress-group/index.mjs +56 -0
  187. package/dist/components/qr-code/index.d.mts +8 -0
  188. package/dist/components/qr-code/index.mjs +11 -0
  189. package/dist/components/radio-group/index.d.mts +16 -0
  190. package/dist/components/radio-group/index.mjs +21 -0
  191. package/dist/components/rating-group/index.d.mts +16 -0
  192. package/dist/components/rating-group/index.mjs +21 -0
  193. package/dist/components/scroll-area/index.d.mts +7 -0
  194. package/dist/components/scroll-area/index.mjs +10 -0
  195. package/dist/components/segment-group/index.d.mts +18 -0
  196. package/dist/components/segment-group/index.mjs +20 -0
  197. package/dist/components/select/index.d.mts +17 -0
  198. package/dist/components/select/index.mjs +18 -0
  199. package/dist/components/separator/index.d.mts +11 -0
  200. package/dist/components/separator/index.mjs +16 -0
  201. package/dist/components/signature-pad/index.d.mts +8 -0
  202. package/dist/components/signature-pad/index.mjs +11 -0
  203. package/dist/components/skeleton/index.d.mts +7 -0
  204. package/dist/components/skeleton/index.mjs +13 -0
  205. package/dist/components/slider/index.d.mts +16 -0
  206. package/dist/components/slider/index.mjs +21 -0
  207. package/dist/components/spinner/index.d.mts +9 -0
  208. package/dist/components/spinner/index.mjs +36 -0
  209. package/dist/components/split-button/index.d.mts +36 -0
  210. package/dist/components/split-button/index.mjs +71 -0
  211. package/dist/components/splitter/index.d.mts +7 -0
  212. package/dist/components/splitter/index.mjs +10 -0
  213. package/dist/components/stack/index.d.mts +11 -0
  214. package/dist/components/stack/index.mjs +32 -0
  215. package/dist/components/stat/index.d.mts +29 -0
  216. package/dist/components/stat/index.mjs +37 -0
  217. package/dist/components/steps/index.d.mts +19 -0
  218. package/dist/components/steps/index.mjs +24 -0
  219. package/dist/components/swap/index.d.mts +8 -0
  220. package/dist/components/swap/index.mjs +11 -0
  221. package/dist/components/switch/index.d.mts +16 -0
  222. package/dist/components/switch/index.mjs +21 -0
  223. package/dist/components/table/index.d.mts +79 -0
  224. package/dist/components/table/index.mjs +688 -0
  225. package/dist/components/tabs/index.d.mts +18 -0
  226. package/dist/components/tabs/index.mjs +23 -0
  227. package/dist/components/tags-input/index.d.mts +17 -0
  228. package/dist/components/tags-input/index.mjs +22 -0
  229. package/dist/components/textarea/index.d.mts +14 -0
  230. package/dist/components/textarea/index.mjs +20 -0
  231. package/dist/components/timeline/index.d.mts +24 -0
  232. package/dist/components/timeline/index.mjs +30 -0
  233. package/dist/components/timer/index.d.mts +8 -0
  234. package/dist/components/timer/index.mjs +11 -0
  235. package/dist/components/toast/index.d.mts +11 -0
  236. package/dist/components/toast/index.mjs +13 -0
  237. package/dist/components/toc/index.d.mts +7 -0
  238. package/dist/components/toc/index.mjs +10 -0
  239. package/dist/components/toggle/index.d.mts +7 -0
  240. package/dist/components/toggle/index.mjs +10 -0
  241. package/dist/components/toggle-group/index.d.mts +15 -0
  242. package/dist/components/toggle-group/index.mjs +20 -0
  243. package/dist/components/tooltip/index.d.mts +7 -0
  244. package/dist/components/tooltip/index.mjs +10 -0
  245. package/dist/components/tour/index.d.mts +11 -0
  246. package/dist/components/tour/index.mjs +13 -0
  247. package/dist/components/transfer/index.d.mts +23 -0
  248. package/dist/components/transfer/index.mjs +154 -0
  249. package/dist/components/tree-select/index.d.mts +28 -0
  250. package/dist/components/tree-select/index.mjs +157 -0
  251. package/dist/components/tree-view/index.d.mts +19 -0
  252. package/dist/components/tree-view/index.mjs +18 -0
  253. package/dist/components/typography/index.d.mts +32 -0
  254. package/dist/components/typography/index.mjs +34 -0
  255. package/dist/components/watermark/index.d.mts +16 -0
  256. package/dist/components/watermark/index.mjs +80 -0
  257. package/dist/index-DaAbbSz9.d.mts +13416 -0
  258. package/dist/index-Uefyw7Im.d.mts +108 -0
  259. package/dist/index-uPyYiWaL.d.mts +1813 -0
  260. package/dist/index.d.mts +128 -15218
  261. package/dist/index.mjs +128 -4556
  262. package/dist/mentions-DMIBCBOd.mjs +181 -0
  263. package/package.json +77 -3
@@ -0,0 +1,127 @@
1
+ import { injectComponentStyle } from "@bysages/core";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { useEffect, useRef } from "react";
4
+ import { renderHtml } from "@tanstack/markdown/html";
5
+ //#region src/components/ai-response/code-copy.ts
6
+ /** The two glyphs a copy affordance needs: the stamp and its
7
+ * confirmation. Inline SVG keeps the enhancement framework-agnostic —
8
+ * it lives beside the renderer's generated code HTML. */
9
+ const COPY_CODE_ICON = `<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>`;
10
+ const COPIED_CODE_ICON = `<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg>`;
11
+ /** How long the confirmation stays before the stamp returns. */
12
+ const REVERT_MS = 1500;
13
+ /** Make sure every fenced block under `host` carries its copy stamp.
14
+ * The stamp anchors to a wrapper outside the scrolling `pre` — inside,
15
+ * it would fix to the overflow area and travel out of view with the
16
+ * code. The renderer rebuilds the markdown as one HTML string on every
17
+ * stream tick, so this stays idempotent and cheap enough to re-run
18
+ * after each patch. */
19
+ function decorateCodeCopy(host, copyLabel) {
20
+ for (const pre of host.querySelectorAll("pre")) {
21
+ let body = pre.parentElement;
22
+ if (!body || body.getAttribute("data-part") !== "code-body") {
23
+ body = document.createElement("div");
24
+ body.setAttribute("data-scope", "ai");
25
+ body.setAttribute("data-part", "code-body");
26
+ pre.replaceWith(body);
27
+ body.appendChild(pre);
28
+ }
29
+ let button = body.querySelector("[data-part=\"code-copy\"]");
30
+ if (!button) {
31
+ button = document.createElement("button");
32
+ button.type = "button";
33
+ button.setAttribute("data-scope", "ai");
34
+ button.setAttribute("data-part", "code-copy");
35
+ button.innerHTML = COPY_CODE_ICON;
36
+ body.appendChild(button);
37
+ }
38
+ button.title = copyLabel;
39
+ button.setAttribute("aria-label", copyLabel);
40
+ }
41
+ }
42
+ /** The one delegated click for the whole response: copy the block's
43
+ * text and confirm in place, then return the stamp after a beat. */
44
+ async function clickCodeCopy(event, copyLabel, copiedLabel) {
45
+ const button = event.target?.closest("[data-part=\"code-copy\"]");
46
+ const pre = button?.closest("[data-part=\"code-body\"]")?.querySelector("pre");
47
+ if (!button || !pre) return;
48
+ await navigator.clipboard.writeText(pre.textContent ?? "");
49
+ button.innerHTML = COPIED_CODE_ICON;
50
+ button.setAttribute("data-state", "copied");
51
+ button.title = copiedLabel;
52
+ button.setAttribute("aria-label", copiedLabel);
53
+ setTimeout(() => {
54
+ if (!button.isConnected) return;
55
+ button.innerHTML = COPY_CODE_ICON;
56
+ button.removeAttribute("data-state");
57
+ button.title = copyLabel;
58
+ button.setAttribute("aria-label", copyLabel);
59
+ }, REVERT_MS);
60
+ }
61
+ //#endregion
62
+ //#region src/components/ai-response/tables.ts
63
+ /** Wide tables ride a scrolling lane instead of bursting the column.
64
+ * The lane is a plain div: the table-as-scroll-container form is what
65
+ * ate the mouse wheel over plain tables. Idempotent, so it can run
66
+ * after every stream patch. */
67
+ const lanes = /* @__PURE__ */ new Set();
68
+ let laneObserver;
69
+ /** A lane's verdict must follow its box — the panel around it can
70
+ * resize at any moment, so each lane stays observed and re-decided
71
+ * whenever its width changes. */
72
+ function watchLane(lane) {
73
+ if (lanes.has(lane)) return;
74
+ lanes.add(lane);
75
+ laneObserver ??= new ResizeObserver(() => {
76
+ for (const lane of lanes) {
77
+ if (!lane.isConnected) {
78
+ laneObserver.unobserve(lane);
79
+ lanes.delete(lane);
80
+ continue;
81
+ }
82
+ lane.toggleAttribute("data-scrollable", lane.scrollWidth > lane.clientWidth);
83
+ }
84
+ });
85
+ laneObserver.observe(lane);
86
+ }
87
+ function wrapResponseTables(root) {
88
+ for (const table of root.querySelectorAll("table")) {
89
+ if (table.parentElement?.hasAttribute("data-table-scroll")) continue;
90
+ const lane = document.createElement("div");
91
+ lane.setAttribute("data-table-scroll", "");
92
+ table.replaceWith(lane);
93
+ lane.append(table);
94
+ }
95
+ for (const lane of root.querySelectorAll("[data-table-scroll]")) {
96
+ lane.toggleAttribute("data-scrollable", lane.scrollWidth > lane.clientWidth);
97
+ watchLane(lane);
98
+ }
99
+ }
100
+ //#endregion
101
+ //#region src/components/ai-response/index.tsx
102
+ function Response({ content, highlighter, copyLabel = "Copy code", copiedLabel = "Copied", ...rest }) {
103
+ injectComponentStyle("ai");
104
+ const root = useRef(null);
105
+ useEffect(() => {
106
+ const host = root.current;
107
+ if (host) decorateCodeCopy(host, copyLabel);
108
+ if (host) wrapResponseTables(host);
109
+ }, [
110
+ content,
111
+ highlighter,
112
+ copyLabel
113
+ ]);
114
+ const onClick = (event) => {
115
+ clickCodeCopy(event.nativeEvent, copyLabel, copiedLabel);
116
+ };
117
+ return /* @__PURE__ */ jsx("div", {
118
+ ...rest,
119
+ ref: root,
120
+ "data-scope": "ai",
121
+ "data-part": "response",
122
+ onClick,
123
+ dangerouslySetInnerHTML: { __html: renderHtml(content, highlighter ? { highlighter } : void 0) }
124
+ });
125
+ }
126
+ //#endregion
127
+ export { Response as t };
@@ -0,0 +1,17 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ //#region src/components/ai/chevron.tsx
3
+ /** The folding chevron the shared indicator turns. */
4
+ const chevron = /* @__PURE__ */ jsx("svg", {
5
+ viewBox: "0 0 16 16",
6
+ fill: "none",
7
+ "aria-hidden": "true",
8
+ children: /* @__PURE__ */ jsx("path", {
9
+ d: "M6 4l4 4-4 4",
10
+ stroke: "currentColor",
11
+ strokeWidth: 1.5,
12
+ strokeLinecap: "round",
13
+ strokeLinejoin: "round"
14
+ })
15
+ });
16
+ //#endregion
17
+ export { chevron as t };
@@ -0,0 +1,7 @@
1
+ import { Accordion as Accordion$1 } from "@ark-ui/react/accordion";
2
+ //#region src/components/accordion/index.d.ts
3
+ /** Ark's Accordion, dressed in the paper-and-ink system: a ruled sheet
4
+ * folded by quiet rows, unfolding with a spring-chevoned dissolve. The
5
+ * API is Ark's own — Root, Item, ItemTrigger, ItemContent, ItemIndicator. */
6
+ export declare const Accordion: typeof Accordion$1;
7
+ //#endregion
@@ -0,0 +1,10 @@
1
+ import { injectComponentStyle } from "@bysages/core";
2
+ import { Accordion as Accordion$1 } from "@ark-ui/react/accordion";
3
+ //#region src/components/accordion/index.tsx
4
+ /** Ark's Accordion, dressed in the paper-and-ink system: a ruled sheet
5
+ * folded by quiet rows, unfolding with a spring-chevoned dissolve. The
6
+ * API is Ark's own — Root, Item, ItemTrigger, ItemContent, ItemIndicator. */
7
+ const Accordion = Accordion$1;
8
+ injectComponentStyle("accordion");
9
+ //#endregion
10
+ export { Accordion };
@@ -0,0 +1,20 @@
1
+ import { HTMLAttributes } from "react";
2
+ //#region src/components/affix/index.d.ts
3
+ /**
4
+ * A nail: the wrapped content travels with the page until it reaches its
5
+ * offset, then stays put while the page moves on. The semantics are
6
+ * plain `position: sticky` — pinning is relative to the nearest
7
+ * *scrolling* ancestor, so the element works inside a scrollable panel
8
+ * exactly as it does on the page itself, and a parent with
9
+ * `overflow: hidden` clips the pin. Both offsets may be given: the
10
+ * content then holds its place inside that band.
11
+ */
12
+ export interface AffixProps extends HTMLAttributes<HTMLDivElement> {
13
+ /** Where the content pins when it reaches the top of the scrolling
14
+ * ancestor — the height of any fixed header it must clear. */
15
+ offsetTop?: string;
16
+ /** Where it pins from the bottom instead, for footers and action bars. */
17
+ offsetBottom?: string;
18
+ }
19
+ export declare function Affix({ offsetTop, offsetBottom, ...rest }: AffixProps): import("react").JSX.Element;
20
+ //#endregion
@@ -0,0 +1,18 @@
1
+ import { injectComponentStyle } from "@bysages/core";
2
+ import { jsx } from "react/jsx-runtime";
3
+ //#region src/components/affix/index.tsx
4
+ function Affix({ offsetTop = "0px", offsetBottom = "0px", ...rest }) {
5
+ injectComponentStyle("affix");
6
+ return /* @__PURE__ */ jsx("div", {
7
+ ...rest,
8
+ style: {
9
+ ...rest.style,
10
+ top: offsetTop,
11
+ bottom: offsetBottom
12
+ },
13
+ "data-scope": "affix",
14
+ "data-part": "root"
15
+ });
16
+ }
17
+ //#endregion
18
+ export { Affix };
@@ -0,0 +1,2 @@
1
+ import { a as SourceDocumentUIPart, c as TextUIPart, d as UIMessagePart, i as ReasoningUIPart, l as ToolUIPart, n as DataUIPart, o as SourceUrlUIPart, r as FileUIPart, s as StepStartUIPart, t as Ai, u as UIMessage } from "../../index-DaAbbSz9.mjs";
2
+ export { Ai, type DataUIPart, type FileUIPart, type ReasoningUIPart, type SourceDocumentUIPart, type SourceUrlUIPart, type StepStartUIPart, type TextUIPart, type ToolUIPart, type UIMessage, type UIMessagePart };
@@ -0,0 +1,65 @@
1
+ import { Action } from "../ai-action/index.mjs";
2
+ import { AiMessage as Message } from "../ai-message/index.mjs";
3
+ import { AiPromptInput as PromptInput } from "../ai-prompt-input/index.mjs";
4
+ import { AiReasoning as Reasoning } from "../ai-reasoning/index.mjs";
5
+ import { t as Response } from "../../ai-response-jZy-0Tvv.mjs";
6
+ import { AiSource as Source, AiSources as Sources } from "../ai-source/index.mjs";
7
+ import { AiSuggestion as Suggestion } from "../ai-suggestion/index.mjs";
8
+ import { AiTool as Tool } from "../ai-tool/index.mjs";
9
+ import { injectComponentStyle } from "@bysages/core";
10
+ import { jsx } from "react/jsx-runtime";
11
+ //#region src/components/ai/index.tsx
12
+ /** A conversation column: Root is the log, Message carries a role, and
13
+ * the speaking parts — Response, Reasoning, Tool, Sources — part the
14
+ * stream. The interactive folds are the shared Collapsible wearing a
15
+ * `data-ai` marker, so the machine work is never ours. Parts stay
16
+ * agnostic of any client; consumers map their message format (e.g. the
17
+ * `UIMessage` parts re-exported here) onto these primitives. */
18
+ function part(name, tag, extra = {}) {
19
+ const Tag = tag;
20
+ const Component = ({ children, ...rest }) => /* @__PURE__ */ jsx(Tag, {
21
+ ...extra,
22
+ ...rest,
23
+ "data-scope": "ai",
24
+ "data-part": name.toLowerCase(),
25
+ children
26
+ });
27
+ Component.displayName = "Ai" + name;
28
+ return Component;
29
+ }
30
+ /** The log itself: the column every stroke lands in, a landmark to
31
+ * screen readers. */
32
+ const Conversation = part("Conversation", "div", {
33
+ role: "log",
34
+ "aria-label": "Conversation"
35
+ });
36
+ /** The bubble's inner measure — content that belongs to neither side
37
+ * specifically. */
38
+ const MessageContent = part("Content", "div");
39
+ /** The quiet row under a message — copy, retry, feedback. */
40
+ const Actions = part("Actions", "div");
41
+ /** The while-it-works whisper for the in-flight turns. */
42
+ const Loader = part("Loader", "span", {
43
+ role: "status",
44
+ "aria-label": "Loading"
45
+ });
46
+ /** The whole family under one handle — `Ai.Conversation`,
47
+ * `Ai.Message`, and the rest, exactly as before the split. */
48
+ const Ai = Object.assign(Conversation, {
49
+ Conversation,
50
+ MessageContent,
51
+ Actions,
52
+ Loader,
53
+ Message,
54
+ Response,
55
+ Reasoning,
56
+ Tool,
57
+ Sources,
58
+ Source,
59
+ Action,
60
+ Suggestion,
61
+ PromptInput
62
+ });
63
+ injectComponentStyle("ai");
64
+ //#endregion
65
+ export { Ai };
@@ -0,0 +1,14 @@
1
+ import { ButtonHTMLAttributes, ReactNode } from "react";
2
+ //#region src/components/ai-action/index.d.ts
3
+ /** A quiet icon button — copy, retry, thumbs. The label names it to
4
+ * assistive tech and as the hover title. The control itself is the
5
+ * shared Button in its ghost register. */
6
+ export interface ActionProps extends ButtonHTMLAttributes<HTMLButtonElement> {
7
+ /** What the button does, spoken to assistive tech and shown as the
8
+ * hover title — copy, retry, thumbs. */
9
+ label: string;
10
+ children?: ReactNode;
11
+ }
12
+ export declare function Action({ label, children, ...rest }: ActionProps): import("react").JSX.Element;
13
+ //#endregion
14
+ export { Action as AiAction };
@@ -0,0 +1,18 @@
1
+ import { Button } from "../button/index.mjs";
2
+ import { injectComponentStyle } from "@bysages/core";
3
+ import { jsx } from "react/jsx-runtime";
4
+ //#region src/components/ai-action/index.tsx
5
+ function Action({ label, children, ...rest }) {
6
+ injectComponentStyle("ai");
7
+ return /* @__PURE__ */ jsx(Button, {
8
+ variant: "ghost",
9
+ size: "sm",
10
+ square: true,
11
+ "aria-label": label,
12
+ title: label,
13
+ ...rest,
14
+ children
15
+ });
16
+ }
17
+ //#endregion
18
+ export { Action, Action as AiAction };
@@ -0,0 +1,19 @@
1
+ import { HTMLAttributes } from "react";
2
+ //#region src/components/ai-attachments/index.d.ts
3
+ /** One file riding the prompt: its glyph by extension, its name and
4
+ * human size, and a quiet way to take it back off. Uploading reads as
5
+ * a dashed ghost, error as danger ink. */
6
+ export interface AttachmentProps extends HTMLAttributes<HTMLSpanElement> {
7
+ /** The file's name — it picks the glyph by extension. */
8
+ name: string;
9
+ /** The file's size in bytes, when known — rendered human. */
10
+ size?: number;
11
+ /** The upload's state on the wire. */
12
+ status?: "uploading" | "ready" | "error";
13
+ onRemove?: () => void;
14
+ }
15
+ export declare function Attachment({ name, size, status, onRemove, ...rest }: AttachmentProps): import("react").JSX.Element;
16
+ /** The row the files ride in — a wrapping line of chips. */
17
+ export declare function Attachments({ children, ...rest }: HTMLAttributes<HTMLSpanElement>): import("react").JSX.Element;
18
+ //#endregion
19
+ export { Attachment as AiAttachment, Attachments as AiAttachments };
@@ -0,0 +1,106 @@
1
+ import { injectComponentStyle } from "@bysages/core";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ //#region src/components/ai-attachments/index.tsx
4
+ const imageGlyph = /* @__PURE__ */ jsxs("svg", {
5
+ viewBox: "0 0 16 16",
6
+ "aria-hidden": "true",
7
+ fill: "none",
8
+ stroke: "currentColor",
9
+ strokeWidth: 1.5,
10
+ strokeLinecap: "square",
11
+ children: [
12
+ /* @__PURE__ */ jsx("rect", {
13
+ x: 2.5,
14
+ y: 3.5,
15
+ width: 11,
16
+ height: 9
17
+ }),
18
+ /* @__PURE__ */ jsx("path", { d: "M2.5 10.5 6 7l3 3 2-1.5 2.5 2" }),
19
+ /* @__PURE__ */ jsx("circle", {
20
+ cx: 6,
21
+ cy: 6,
22
+ r: .75,
23
+ fill: "currentColor",
24
+ stroke: "none"
25
+ })
26
+ ]
27
+ });
28
+ const fileGlyph = /* @__PURE__ */ jsxs("svg", {
29
+ viewBox: "0 0 16 16",
30
+ "aria-hidden": "true",
31
+ fill: "none",
32
+ stroke: "currentColor",
33
+ strokeWidth: 1.5,
34
+ strokeLinecap: "square",
35
+ children: [/* @__PURE__ */ jsx("path", { d: "M4 2.5h5l3 3V13.5H4z" }), /* @__PURE__ */ jsx("path", { d: "M9 2.5v3h3" })]
36
+ });
37
+ const removeGlyph = /* @__PURE__ */ jsx("svg", {
38
+ viewBox: "0 0 16 16",
39
+ width: 12,
40
+ height: 12,
41
+ "aria-hidden": "true",
42
+ fill: "none",
43
+ stroke: "currentColor",
44
+ strokeWidth: 1.5,
45
+ strokeLinecap: "square",
46
+ children: /* @__PURE__ */ jsx("path", { d: "M4 4l8 8M12 4l-8 8" })
47
+ });
48
+ const IMAGE_EXTS = [
49
+ "png",
50
+ "jpg",
51
+ "jpeg",
52
+ "gif",
53
+ "webp",
54
+ "svg",
55
+ "avif",
56
+ "bmp",
57
+ "ico"
58
+ ];
59
+ const isImage = (name) => IMAGE_EXTS.includes(name.split(".").pop()?.toLowerCase() ?? "");
60
+ const humanSize = (bytes) => {
61
+ if (bytes < 1024) return `${bytes} B`;
62
+ const units = [
63
+ "KB",
64
+ "MB",
65
+ "GB"
66
+ ];
67
+ let value = bytes;
68
+ let unit = -1;
69
+ do {
70
+ value /= 1024;
71
+ unit += 1;
72
+ } while (value >= 1024 && unit < units.length - 1);
73
+ return `${value.toFixed(1)} ${units[unit]}`;
74
+ };
75
+ function Attachment({ name, size, status = "ready", onRemove, ...rest }) {
76
+ injectComponentStyle("ai");
77
+ return /* @__PURE__ */ jsxs("span", {
78
+ ...rest,
79
+ "data-scope": "ai",
80
+ "data-part": "attachment",
81
+ "data-status": status,
82
+ children: [
83
+ isImage(name) ? imageGlyph : fileGlyph,
84
+ /* @__PURE__ */ jsx("span", { children: name }),
85
+ size !== void 0 ? /* @__PURE__ */ jsx("span", { children: humanSize(size) }) : null,
86
+ /* @__PURE__ */ jsx("button", {
87
+ type: "button",
88
+ "data-remove": "",
89
+ "aria-label": `Remove ${name}`,
90
+ onClick: () => onRemove?.(),
91
+ children: removeGlyph
92
+ })
93
+ ]
94
+ });
95
+ }
96
+ /** The row the files ride in — a wrapping line of chips. */
97
+ function Attachments({ children, ...rest }) {
98
+ return /* @__PURE__ */ jsx("span", {
99
+ ...rest,
100
+ "data-scope": "ai",
101
+ "data-part": "attachments",
102
+ children
103
+ });
104
+ }
105
+ //#endregion
106
+ export { Attachment as AiAttachment, Attachment, Attachments as AiAttachments, Attachments };
@@ -0,0 +1,11 @@
1
+ import { HTMLAttributes, ReactNode } from "react";
2
+ //#region src/components/ai-message/index.d.ts
3
+ /** Whose stroke this is — the user's words sit in a recessed bubble,
4
+ * the assistant speaks flat on the paper. */
5
+ export interface MessageProps extends HTMLAttributes<HTMLElement> {
6
+ role?: "user" | "assistant" | "system";
7
+ children?: ReactNode;
8
+ }
9
+ export declare function Message({ role, children, ...rest }: MessageProps): import("react").JSX.Element;
10
+ //#endregion
11
+ export { Message as AiMessage };
@@ -0,0 +1,15 @@
1
+ import { injectComponentStyle } from "@bysages/core";
2
+ import { jsx } from "react/jsx-runtime";
3
+ //#region src/components/ai-message/index.tsx
4
+ function Message({ role = "assistant", children, ...rest }) {
5
+ injectComponentStyle("ai");
6
+ return /* @__PURE__ */ jsx("article", {
7
+ ...rest,
8
+ "data-scope": "ai",
9
+ "data-part": "message",
10
+ "data-role": role,
11
+ children
12
+ });
13
+ }
14
+ //#endregion
15
+ export { Message as AiMessage, Message };
@@ -0,0 +1,47 @@
1
+ import { t as MentionEntry } from "../../index-Uefyw7Im.mjs";
2
+ import { HTMLAttributes, ReactNode } from "react";
3
+ //#region src/components/ai-prompt-input/index.d.ts
4
+ /**
5
+ * The prompt vessel: the shared field textarea — self-growing on the
6
+ * machine's autoresize — with the submit seal riding its last line.
7
+ * Around the body, props answer the composer's anatomy: `header` for
8
+ * attachments riding above, `leading` for the tools at the text's
9
+ * left, `trailing` for the seal itself, `footer` for the tools beneath,
10
+ * and `footerEnd` for the controls that close the footer row — the
11
+ * seal falls there by default, so a model picker dropped in rides the
12
+ * send's shoulder. Controlled — bind `value` and take the text on
13
+ * `submit`. Enter sends; Shift+Enter breaks the line. While `busy`
14
+ * the seal becomes a stop seal and Enter holds its breath.
15
+ */
16
+ export interface PromptInputProps extends Omit<HTMLAttributes<HTMLFormElement>, "onSubmit"> {
17
+ /** The draft in the vessel — bind `value`; it clears itself on a
18
+ * successful submit. */
19
+ value: string;
20
+ onValueChange?: (value: string) => void;
21
+ onSubmit?: (value: string) => void;
22
+ onStop?: () => void;
23
+ /** The quiet invitation before the reader types. */
24
+ placeholder?: string;
25
+ /** Still the words on the canvas, but the submit seal does nothing
26
+ * and Enter stays a line break. */
27
+ disabled?: boolean;
28
+ /** The machine is working — the seal becomes a stop seal and Enter
29
+ * holds its breath. */
30
+ busy?: boolean;
31
+ /** Mention candidates for the field: pass the roster and the summon
32
+ * character (`@` unless told otherwise) and the vessel rides the
33
+ * textarea. While candidates are up, Enter inserts and the send
34
+ * waits. */
35
+ mentions?: {
36
+ items: MentionEntry[];
37
+ trigger?: string;
38
+ };
39
+ header?: ReactNode;
40
+ leading?: ReactNode;
41
+ trailing?: ReactNode;
42
+ footer?: ReactNode;
43
+ footerEnd?: ReactNode;
44
+ }
45
+ export declare function PromptInput({ value, onValueChange, onSubmit, onStop, placeholder, disabled, busy, mentions, header, leading, trailing, footer, footerEnd, ...rest }: PromptInputProps): import("react").JSX.Element;
46
+ //#endregion
47
+ export { PromptInput as AiPromptInput };
@@ -0,0 +1,135 @@
1
+ import { Button } from "../button/index.mjs";
2
+ import { Field } from "../field/index.mjs";
3
+ import { n as MentionsVessel, r as useMentions } from "../../mentions-DMIBCBOd.mjs";
4
+ import { injectComponentStyle } from "@bysages/core";
5
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
+ import { useRef } from "react";
7
+ //#region src/components/ai-prompt-input/index.tsx
8
+ const arrowUpGlyph = /* @__PURE__ */ jsx("svg", {
9
+ viewBox: "0 0 16 16",
10
+ width: 14,
11
+ height: 14,
12
+ "aria-hidden": "true",
13
+ fill: "none",
14
+ stroke: "currentColor",
15
+ strokeWidth: 1.5,
16
+ strokeLinecap: "square",
17
+ children: /* @__PURE__ */ jsx("path", { d: "M8 13V3M3.5 7.5 8 3l4.5 4.5" })
18
+ });
19
+ const stopGlyph = /* @__PURE__ */ jsx("svg", {
20
+ viewBox: "0 0 16 16",
21
+ width: 14,
22
+ height: 14,
23
+ "aria-hidden": "true",
24
+ children: /* @__PURE__ */ jsx("rect", {
25
+ x: 4.5,
26
+ y: 4.5,
27
+ width: 7,
28
+ height: 7,
29
+ fill: "currentColor"
30
+ })
31
+ });
32
+ /** An empty slot leaves no part in the anatomy — the bare vessel keeps
33
+ * its single-line posture. */
34
+ function row(part, content) {
35
+ if (content == null || Array.isArray(content) && content.length === 0) return null;
36
+ return /* @__PURE__ */ jsx("div", {
37
+ "data-scope": "ai",
38
+ "data-part": part,
39
+ children: content
40
+ });
41
+ }
42
+ function PromptInput({ value, onValueChange, onSubmit, onStop, placeholder = "Send a message", disabled = false, busy = false, mentions, header, leading, trailing, footer, footerEnd, ...rest }) {
43
+ injectComponentStyle("ai");
44
+ const fieldRef = useRef(null);
45
+ const mentionState = useMentions(() => ({
46
+ items: mentions?.items ?? [],
47
+ trigger: mentions?.trigger
48
+ }), () => fieldRef.current, {
49
+ getText: () => fieldRef.current?.value ?? value,
50
+ setText: (next) => onValueChange?.(next)
51
+ });
52
+ const mentionsActive = mentions != null;
53
+ const submit = () => {
54
+ const text = value.trim();
55
+ if (!text || disabled || busy) return;
56
+ onSubmit?.(text);
57
+ onValueChange?.("");
58
+ };
59
+ const seal = busy ? /* @__PURE__ */ jsx(Button, {
60
+ variant: "solid",
61
+ size: "sm",
62
+ square: true,
63
+ type: "button",
64
+ "aria-label": "Stop",
65
+ disabled,
66
+ onClick: () => onStop?.(),
67
+ children: stopGlyph
68
+ }) : /* @__PURE__ */ jsx(Button, {
69
+ variant: "solid",
70
+ size: "sm",
71
+ square: true,
72
+ type: "submit",
73
+ "aria-label": "Send",
74
+ disabled: disabled || !value.trim(),
75
+ children: arrowUpGlyph
76
+ });
77
+ const hasFooter = footer != null && (!Array.isArray(footer) || footer.length > 0);
78
+ return /* @__PURE__ */ jsxs("form", {
79
+ ...rest,
80
+ "data-scope": "ai",
81
+ "data-part": "prompt",
82
+ onSubmit: (event) => {
83
+ event.preventDefault();
84
+ submit();
85
+ },
86
+ children: [
87
+ row("prompt-header", header),
88
+ /* @__PURE__ */ jsxs("div", {
89
+ "data-scope": "ai",
90
+ "data-part": "prompt-main",
91
+ children: [
92
+ row("prompt-leading", leading),
93
+ /* @__PURE__ */ jsx(Field.Root, { children: /* @__PURE__ */ jsx(Field.Textarea, {
94
+ ref: fieldRef,
95
+ autoresize: true,
96
+ rows: 1,
97
+ value,
98
+ placeholder,
99
+ disabled,
100
+ onChange: (event) => {
101
+ onValueChange?.(event.target.value);
102
+ mentionState.onInput();
103
+ },
104
+ onKeyDown: (event) => {
105
+ if (mentionState.onKeydown(event)) return;
106
+ if (event.key === "Enter" && !event.shiftKey) {
107
+ event.preventDefault();
108
+ submit();
109
+ }
110
+ }
111
+ }) }),
112
+ mentionsActive ? /* @__PURE__ */ jsx(MentionsVessel, {
113
+ open: mentionState.open,
114
+ matches: mentionState.matches,
115
+ active: mentionState.active,
116
+ anchor: fieldRef.current,
117
+ onInsert: mentionState.insert,
118
+ onActiveChange: mentionState.setActive,
119
+ onOpenChange: (open) => {
120
+ if (!open) mentionState.close();
121
+ }
122
+ }) : null,
123
+ row("prompt-trailing", hasFooter ? trailing : trailing ?? seal)
124
+ ]
125
+ }),
126
+ hasFooter ? /* @__PURE__ */ jsxs("div", {
127
+ "data-scope": "ai",
128
+ "data-part": "prompt-footer",
129
+ children: [footer, row("prompt-end", footerEnd == null ? seal : /* @__PURE__ */ jsxs(Fragment, { children: [footerEnd, seal] }))]
130
+ }) : null
131
+ ]
132
+ });
133
+ }
134
+ //#endregion
135
+ export { PromptInput as AiPromptInput, PromptInput };
@@ -0,0 +1,13 @@
1
+ import { HTMLAttributes, ReactNode } from "react";
2
+ //#region src/components/ai-reasoning/index.d.ts
3
+ /** The model's thought, folded by the shared collapsible in its quiet
4
+ * register: bare ink for a trigger, the thought on one hairline. */
5
+ export interface ReasoningProps extends HTMLAttributes<HTMLDivElement> {
6
+ /** The trigger's words — the fold arrives open under them. */
7
+ label?: string;
8
+ defaultOpen?: boolean;
9
+ children?: ReactNode;
10
+ }
11
+ export declare function Reasoning({ label, children, ...rest }: ReasoningProps): import("react").JSX.Element;
12
+ //#endregion
13
+ export { Reasoning as AiReasoning };