@keboola/design 11.4.0 → 11.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/AGENTS.md +191 -1
  2. package/CHANGELOG.md +358 -0
  3. package/COMPONENT-API.md +68 -47
  4. package/dist/{AIKit-DDg5DBCG.js → AIKit-CNX6aiKm.js} +208 -62
  5. package/dist/AIKit-CNX6aiKm.js.map +1 -0
  6. package/dist/{Alert-DHJFrWnS.js → Alert-Ba5b2YPq.js} +2 -2
  7. package/dist/{Alert-DHJFrWnS.js.map → Alert-Ba5b2YPq.js.map} +1 -1
  8. package/dist/{Badge-Ch26CXoP.js → Badge-D0pXdekt.js} +2 -2
  9. package/dist/Badge-D0pXdekt.js.map +1 -0
  10. package/dist/{BrandEditor-Go7w8Zj2.js → BrandEditor-CSANsxUz.js} +6 -6
  11. package/dist/{BrandEditor-Go7w8Zj2.js.map → BrandEditor-CSANsxUz.js.map} +1 -1
  12. package/dist/{BrandLogo-Dmi7jo21.js → BrandLogo-CoKBk4MI.js} +4 -4
  13. package/dist/BrandLogo-CoKBk4MI.js.map +1 -0
  14. package/dist/{Breadcrumb-uEkM6adI.js → Breadcrumb-g_xn_-Nf.js} +2 -2
  15. package/dist/{Breadcrumb-uEkM6adI.js.map → Breadcrumb-g_xn_-Nf.js.map} +1 -1
  16. package/dist/{Checkbox-fC0BuO2B.js → Checkbox-CUIn2jap.js} +2 -2
  17. package/dist/{Checkbox-fC0BuO2B.js.map → Checkbox-CUIn2jap.js.map} +1 -1
  18. package/dist/{Clipboard-ChPdiUy3.js → Clipboard-BTW6C-b_.js} +2 -2
  19. package/dist/{Clipboard-ChPdiUy3.js.map → Clipboard-BTW6C-b_.js.map} +1 -1
  20. package/dist/{ClipboardButton-D9pDjgkB.js → ClipboardButton-CwZJdRaz.js} +2 -2
  21. package/dist/{ClipboardButton-D9pDjgkB.js.map → ClipboardButton-CwZJdRaz.js.map} +1 -1
  22. package/dist/{CodeEditor-Cxy3HnKH.js → CodeEditor-C9zy7PxK.js} +6 -6
  23. package/dist/{CodeEditor-Cxy3HnKH.js.map → CodeEditor-C9zy7PxK.js.map} +1 -1
  24. package/dist/{ColorInput-Bxj-1eLT.js → ColorInput-BZV-u_94.js} +3 -3
  25. package/dist/{ColorInput-Bxj-1eLT.js.map → ColorInput-BZV-u_94.js.map} +1 -1
  26. package/dist/{Combobox-Cs_1pj2q.js → Combobox-BfIfaVMA.js} +273 -104
  27. package/dist/Combobox-BfIfaVMA.js.map +1 -0
  28. package/dist/{Command-B7ML9YMv.js → Command-Bfa1kpbt.js} +2 -2
  29. package/dist/{Command-B7ML9YMv.js.map → Command-Bfa1kpbt.js.map} +1 -1
  30. package/dist/{CopyField-BO_sh-HO.js → CopyField-DpT0Ngz1.js} +2 -2
  31. package/dist/{CopyField-BO_sh-HO.js.map → CopyField-DpT0Ngz1.js.map} +1 -1
  32. package/dist/{DateInput-ZdaMQo5i.js → DateInput-DiEd5uCL.js} +3 -3
  33. package/dist/{DateInput-ZdaMQo5i.js.map → DateInput-DiEd5uCL.js.map} +1 -1
  34. package/dist/{DateRangeInput-DkvNh_sT.js → DateRangeInput-DPfVYchl.js} +3 -3
  35. package/dist/{DateRangeInput-DkvNh_sT.js.map → DateRangeInput-DPfVYchl.js.map} +1 -1
  36. package/dist/{FieldItem-CCd9-xnp.js → FieldItem-B7XMmZSz.js} +3 -3
  37. package/dist/{FieldItem-CCd9-xnp.js.map → FieldItem-B7XMmZSz.js.map} +1 -1
  38. package/dist/{Form-k6PH-em3.js → Form-CsttTHn4.js} +7 -7
  39. package/dist/Form-CsttTHn4.js.map +1 -0
  40. package/dist/{FormGroup-DbcDtrgU.js → FormGroup-DHvTFdno.js} +3 -3
  41. package/dist/{FormGroup-DbcDtrgU.js.map → FormGroup-DHvTFdno.js.map} +1 -1
  42. package/dist/{InputGroup-BnLHY0eq.js → InputGroup-DcZRlVnN.js} +22 -14
  43. package/dist/InputGroup-DcZRlVnN.js.map +1 -0
  44. package/dist/{Kbd-CvSM3D3-.js → Kbd-Cvvt91Q8.js} +14 -4
  45. package/dist/Kbd-Cvvt91Q8.js.map +1 -0
  46. package/dist/{MermaidDiagram-WkonYErO.js → MermaidDiagram-CXG5tC6J.js} +19 -18
  47. package/dist/MermaidDiagram-CXG5tC6J.js.map +1 -0
  48. package/dist/{MultiActionButtonGroup-CxWH7yWK.js → MultiActionButtonGroup-DokHbPgM.js} +2 -2
  49. package/dist/{MultiActionButtonGroup-CxWH7yWK.js.map → MultiActionButtonGroup-DokHbPgM.js.map} +1 -1
  50. package/dist/{Navbar-B2UsolVU.js → Navbar-Liy1TPI7.js} +6 -6
  51. package/dist/{Navbar-B2UsolVU.js.map → Navbar-Liy1TPI7.js.map} +1 -1
  52. package/dist/PageHeader-Q3IpCnQd.js.map +1 -1
  53. package/dist/{PageToolbar-DnbFt14Q.js → PageToolbar-DExqEYGl.js} +2 -2
  54. package/dist/{PageToolbar-DnbFt14Q.js.map → PageToolbar-DExqEYGl.js.map} +1 -1
  55. package/dist/{Popconfirm-CILjmzKI.js → Popconfirm-5pBzT_HQ.js} +10 -11
  56. package/dist/{Popconfirm-CILjmzKI.js.map → Popconfirm-5pBzT_HQ.js.map} +1 -1
  57. package/dist/{RadioGroup-XFzFd1ti.js → RadioGroup-DXPbSj8P.js} +2 -2
  58. package/dist/{RadioGroup-XFzFd1ti.js.map → RadioGroup-DXPbSj8P.js.map} +1 -1
  59. package/dist/{Search-4Bxtt8hS.js → Search-5uQAiNIP.js} +2 -2
  60. package/dist/{Search-4Bxtt8hS.js.map → Search-5uQAiNIP.js.map} +1 -1
  61. package/dist/{SearchInput-f_oY9T4Z.js → SearchInput-D4UgAXJK.js} +3 -3
  62. package/dist/{SearchInput-f_oY9T4Z.js.map → SearchInput-D4UgAXJK.js.map} +1 -1
  63. package/dist/{SectionNav-BpJlisbT.js → SectionNav-OkKCjSA-.js} +3 -3
  64. package/dist/{SectionNav-BpJlisbT.js.map → SectionNav-OkKCjSA-.js.map} +1 -1
  65. package/dist/{Select-DpcgKqKB.js → Select-DV3Hak_l.js} +3 -4
  66. package/dist/Select-DV3Hak_l.js.map +1 -0
  67. package/dist/{Sidebar-Cm6I4dE1.js → Sidebar-D3cY1kha.js} +44 -20
  68. package/dist/Sidebar-D3cY1kha.js.map +1 -0
  69. package/dist/{Slider-pPC_3gz9.js → Slider-CRf-bB4y.js} +2 -2
  70. package/dist/{Slider-pPC_3gz9.js.map → Slider-CRf-bB4y.js.map} +1 -1
  71. package/dist/{Switch-ChfPKcTE.js → Switch-B0WdGSjz.js} +7 -7
  72. package/dist/{Switch-ChfPKcTE.js.map → Switch-B0WdGSjz.js.map} +1 -1
  73. package/dist/{TextInput-DHM6dHmn.js → TextInput-DH5SkbsE.js} +3 -3
  74. package/dist/{TextInput-DHM6dHmn.js.map → TextInput-DH5SkbsE.js.map} +1 -1
  75. package/dist/{ThemeProvider-DrQJtzpd.js → ThemeProvider-2RMdVGxO.js} +17 -12
  76. package/dist/{ThemeProvider-DrQJtzpd.js.map → ThemeProvider-2RMdVGxO.js.map} +1 -1
  77. package/dist/{Timeline-6btyJl4D.js → Timeline-BG5Xogxh.js} +11 -11
  78. package/dist/{Timeline-6btyJl4D.js.map → Timeline-BG5Xogxh.js.map} +1 -1
  79. package/dist/{Workbench-BzE-Vvd9.js → Workbench-UR2FBC7I.js} +3 -1
  80. package/dist/Workbench-UR2FBC7I.js.map +1 -0
  81. package/dist/{ZoomableSvg-BWnDkR61.js → ZoomableSvg-pooPb1Cu.js} +3 -3
  82. package/dist/{ZoomableSvg-BWnDkR61.js.map → ZoomableSvg-pooPb1Cu.js.map} +1 -1
  83. package/dist/editors.js +4 -4
  84. package/dist/flint.js +134 -8
  85. package/dist/flint.js.map +1 -1
  86. package/dist/index.d.ts +537 -135
  87. package/dist/index.js +40 -39
  88. package/dist/internal/blocks/AIKit.js +2 -2
  89. package/dist/internal/blocks/AuthLayout.js +118 -0
  90. package/dist/internal/blocks/AuthLayout.js.map +1 -0
  91. package/dist/internal/blocks/BrandEditor.js +1 -1
  92. package/dist/internal/blocks/ClipboardButton.js +1 -1
  93. package/dist/internal/blocks/ColorInput.js +1 -1
  94. package/dist/internal/blocks/Command.js +1 -1
  95. package/dist/internal/blocks/CopyField.js +1 -1
  96. package/dist/internal/blocks/DateInput.js +1 -1
  97. package/dist/internal/blocks/DateRangeInput.js +1 -1
  98. package/dist/internal/blocks/ExportMenu.js +1 -1
  99. package/dist/internal/blocks/Form/connectors/MultiComboboxField.js +1 -1
  100. package/dist/internal/blocks/Form.js +1 -1
  101. package/dist/internal/blocks/FormGroup.js +1 -1
  102. package/dist/internal/blocks/MultiActionButtonGroup.js +1 -1
  103. package/dist/internal/blocks/MultiCombobox.js +107 -48
  104. package/dist/internal/blocks/MultiCombobox.js.map +1 -1
  105. package/dist/internal/blocks/NumberInput.js +1 -1
  106. package/dist/internal/blocks/PageToolbar.js +1 -1
  107. package/dist/internal/blocks/PasswordInput.js +2 -2
  108. package/dist/internal/blocks/SearchInput.js +1 -1
  109. package/dist/internal/blocks/SearchInputWithNavigation.js +2 -2
  110. package/dist/internal/blocks/SectionNav.js +1 -1
  111. package/dist/internal/blocks/TextInput.js +1 -1
  112. package/dist/internal/blocks/Textarea.js +1 -1
  113. package/dist/internal/blocks/TimeInput.js +2 -2
  114. package/dist/internal/components/Alert.js +1 -1
  115. package/dist/internal/components/Avatar.js +1 -1
  116. package/dist/internal/components/Badge.js +1 -1
  117. package/dist/internal/components/BrandLogo.js +1 -1
  118. package/dist/internal/components/Breadcrumb.js +1 -1
  119. package/dist/internal/components/Checkbox.js +1 -1
  120. package/dist/internal/components/Clipboard.js +1 -1
  121. package/dist/internal/components/CollapsiblePanel.js +1 -1
  122. package/dist/internal/components/Combobox.js +2 -2
  123. package/dist/internal/components/InputGroup.js +1 -1
  124. package/dist/internal/components/Kbd.js +1 -1
  125. package/dist/internal/components/Navbar.js +1 -1
  126. package/dist/internal/components/Popconfirm.js +1 -1
  127. package/dist/internal/components/RadioGroup.js +1 -1
  128. package/dist/internal/components/Search.js +1 -1
  129. package/dist/internal/components/Select.js +1 -1
  130. package/dist/internal/components/Sidebar.js +1 -1
  131. package/dist/internal/components/Slider.js +1 -1
  132. package/dist/internal/components/Switch.js +1 -1
  133. package/dist/internal/components/ThemeProvider.js +1 -1
  134. package/dist/internal/components/Timeline.js +1 -1
  135. package/dist/internal/components/Tooltip.js +1 -1
  136. package/dist/internal/components/Truncated.js +1 -1
  137. package/dist/internal/components/Workbench.js +1 -1
  138. package/dist/internal/components/ZoomableSvg.js +1 -1
  139. package/dist/internal/utils.js +2 -2
  140. package/dist/markdown-editor.js +29 -23
  141. package/dist/markdown-editor.js.map +1 -1
  142. package/dist/mermaid.js +1 -1
  143. package/dist/rjsf.js +22 -23
  144. package/dist/rjsf.js.map +1 -1
  145. package/dist/styles.css +1 -1
  146. package/dist/testing.js +1 -1
  147. package/dist/{useColorSchemeState-klihG9-i.js → themeScopeContext-D7fSyb06.js} +16 -3
  148. package/dist/themeScopeContext-D7fSyb06.js.map +1 -0
  149. package/dist/{themeTokens-D70HeNVF.js → themeTokens-qP1-55O7.js} +37 -10
  150. package/dist/themeTokens-qP1-55O7.js.map +1 -0
  151. package/dist/{utils-B5Z52hYs.js → utils-DSvrhU8E.js} +6 -2
  152. package/dist/{utils-B5Z52hYs.js.map → utils-DSvrhU8E.js.map} +1 -1
  153. package/dist/vega.d.ts +1 -1
  154. package/dist/vega.js +3 -3
  155. package/dist/vega.js.map +1 -1
  156. package/dist/{vegaTheme-DfoEQhOy.js → vegaTheme-CSvFEMBl.js} +6 -6
  157. package/dist/vegaTheme-CSvFEMBl.js.map +1 -0
  158. package/package.json +12 -10
  159. package/src/styles.css +3 -0
  160. package/dist/AIKit-DDg5DBCG.js.map +0 -1
  161. package/dist/Badge-Ch26CXoP.js.map +0 -1
  162. package/dist/BrandLogo-Dmi7jo21.js.map +0 -1
  163. package/dist/Combobox-Cs_1pj2q.js.map +0 -1
  164. package/dist/Form-k6PH-em3.js.map +0 -1
  165. package/dist/InputGroup-BnLHY0eq.js.map +0 -1
  166. package/dist/Kbd-CvSM3D3-.js.map +0 -1
  167. package/dist/MermaidDiagram-WkonYErO.js.map +0 -1
  168. package/dist/Select-DpcgKqKB.js.map +0 -1
  169. package/dist/Sidebar-Cm6I4dE1.js.map +0 -1
  170. package/dist/Workbench-BzE-Vvd9.js.map +0 -1
  171. package/dist/themeTokens-D70HeNVF.js.map +0 -1
  172. package/dist/useColorSchemeState-klihG9-i.js.map +0 -1
  173. package/dist/vegaTheme-DfoEQhOy.js.map +0 -1
@@ -1,26 +1,94 @@
1
1
  import { cn } from "./classNames-BzrkDnOD.js";
2
- import { Tooltip, TooltipProvider } from "./utils-B5Z52hYs.js";
3
- import { AlertCircle, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, CircleCheck, CirclePause, CircleX, Loader2, Maximize2, Minimize2, Play, Send, Sparkles, TriangleAlert, X, XCircle } from "./icons-Cek151jC.js";
2
+ import { Tooltip, TooltipProvider } from "./utils-DSvrhU8E.js";
3
+ import { AlertCircle, ChevronDown, ChevronLeft, ChevronRight, CircleCheck, CirclePause, CircleX, Loader2, Maximize2, Minimize2, Play, Send, Sparkles, ThumbsDown, ThumbsUp, TriangleAlert, X, XCircle } from "./icons-Cek151jC.js";
4
4
  import { Button } from "./Button-DsRrU5F1.js";
5
- import { ClipboardButton } from "./ClipboardButton-D9pDjgkB.js";
5
+ import { ButtonGroup } from "./internal/components/ButtonGroup.js";
6
+ import { ClipboardButton } from "./ClipboardButton-CwZJdRaz.js";
6
7
  import { FullScreenModal, FullScreenModalBody, FullScreenModalHeader } from "./FullScreenModal-BvPuYibe.js";
7
8
  import { Truncated } from "./internal/components/Truncated.js";
8
9
  import { HoverCard } from "./HoverCard-B9ZMJxjn.js";
9
- import { Command } from "./Command-B7ML9YMv.js";
10
- import { TextInput } from "./TextInput-DHM6dHmn.js";
11
- import { Checkbox } from "./Checkbox-fC0BuO2B.js";
12
- import { Badge } from "./Badge-Ch26CXoP.js";
10
+ import { Command } from "./Command-Bfa1kpbt.js";
11
+ import { TextInput } from "./TextInput-DH5SkbsE.js";
12
+ import { Checkbox } from "./Checkbox-CUIn2jap.js";
13
+ import { Badge } from "./Badge-D0pXdekt.js";
13
14
  import { Textarea } from "./internal/blocks/Textarea.js";
14
15
  import { Table } from "./Table-CvYuTuNU.js";
15
16
  import { DiagramSkeleton } from "./internal/blocks/DiagramShared/DiagramSkeleton.js";
16
17
  import { Progress } from "./internal/components/Progress.js";
17
18
  import { Slot } from "@radix-ui/react-slot";
18
- import { Suspense, isValidElement, lazy, useEffect, useId, useRef, useState } from "react";
19
+ import { Suspense, isValidElement, lazy, useCallback, useEffect, useId, useRef, useState } from "react";
19
20
  import { cva } from "class-variance-authority";
20
21
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
21
22
  import TextareaAutosize from "react-textarea-autosize";
22
23
  import ReactMarkdown from "react-markdown";
23
24
  import remarkGfm from "remark-gfm";
25
+ //#region src/blocks/AIKit/AnswerActions.tsx
26
+ const VOTE_BUTTONS = [{
27
+ vote: "up",
28
+ label: "Good answer",
29
+ icon: /* @__PURE__ */ jsx(ThumbsUp, { className: "tw:size-4" })
30
+ }, {
31
+ vote: "down",
32
+ label: "Bad answer",
33
+ icon: /* @__PURE__ */ jsx(ThumbsDown, { className: "tw:size-4" })
34
+ }];
35
+ /**
36
+ * What a reader can do with a finished answer: take it away, and say whether it was any good.
37
+ *
38
+ * - **Always rendered, never hover-only.** A reveal-on-hover row does not exist for anyone
39
+ * reaching it without a pointer. The buttons are quiet (`invisible`) rather than hidden.
40
+ * - Copy sits first: it is the one action with no round trip.
41
+ * - **A vote can be changed but not withdrawn.** `aria-pressed` says which one is recorded, and
42
+ * both buttons stay focusable so a reader can switch. Pressing the pressed one re-sends the
43
+ * same vote.
44
+ * - The recorded vote and the write are the caller's: the two chats vote against different
45
+ * endpoints, and only the caller knows whether a turn is finished enough to rate.
46
+ */
47
+ const AnswerActions = ({ copyText, vote, onVote }) => {
48
+ return /* @__PURE__ */ jsxs(ButtonGroup, {
49
+ space: "extra-small",
50
+ "aria-label": "Answer actions",
51
+ children: [copyText ? /* @__PURE__ */ jsx(ClipboardButton, {
52
+ text: copyText,
53
+ tooltip: "Copy answer",
54
+ size: "icon-xs",
55
+ variant: "invisible"
56
+ }) : null, VOTE_BUTTONS.map(({ vote: candidate, label, icon }) => {
57
+ const isRecorded = vote === candidate;
58
+ return /* @__PURE__ */ jsx(Tooltip, {
59
+ tooltip: label,
60
+ placement: "top",
61
+ triggerAsChild: true,
62
+ children: /* @__PURE__ */ jsx(Button, {
63
+ size: "icon-xs",
64
+ variant: isRecorded ? "secondary" : "invisible",
65
+ "aria-label": label,
66
+ "aria-pressed": isRecorded,
67
+ onClick: () => onVote(candidate),
68
+ children: icon
69
+ })
70
+ }, candidate);
71
+ })]
72
+ });
73
+ };
74
+ //#endregion
75
+ //#region src/blocks/AIKit/CollapsibleBody.tsx
76
+ const CollapsibleBody = ({ isExpanded, isClosing, onClosed, children }) => {
77
+ const handleTransitionEnd = (event) => {
78
+ if (event.target !== event.currentTarget) return;
79
+ if (event.propertyName !== "grid-template-rows") return;
80
+ if (!isExpanded) onClosed();
81
+ };
82
+ return /* @__PURE__ */ jsx("div", {
83
+ className: cn("tw:grid tw:transition-[grid-template-rows] tw:duration-300 tw:ease-out tw:motion-reduce:transition-none", isExpanded ? "tw:grid-rows-[1fr]" : "tw:grid-rows-[0fr]"),
84
+ onTransitionEnd: handleTransitionEnd,
85
+ children: /* @__PURE__ */ jsx("div", {
86
+ className: "tw:min-h-0 tw:overflow-hidden",
87
+ children: (isExpanded || isClosing) && children
88
+ })
89
+ });
90
+ };
91
+ //#endregion
24
92
  //#region src/blocks/AIKit/CollapsibleStepHeader.tsx
25
93
  const variantClasses = {
26
94
  success: "tw:text-muted-foreground tw:focus-visible:outline-ring tw:not-disabled:hover:text-foreground",
@@ -31,8 +99,7 @@ const variantClasses = {
31
99
  const iconClasses = "tw:size-3.5 tw:shrink-0 tw:basis-3.5 tw:opacity-70";
32
100
  const renderVariantIcon$1 = (variant) => {
33
101
  if (variant === "processing") return /* @__PURE__ */ jsx(Loader2, { className: cn(iconClasses, "tw:animate-spin") });
34
- if (variant === "error") return /* @__PURE__ */ jsx(XCircle, { className: iconClasses });
35
- if (variant === "dismissed") return /* @__PURE__ */ jsx(XCircle, { className: cn(iconClasses, "tw:text-neutral-500") });
102
+ if (variant === "error" || variant === "dismissed") return /* @__PURE__ */ jsx(XCircle, { className: iconClasses });
36
103
  return /* @__PURE__ */ jsx(CircleCheck, { className: iconClasses });
37
104
  };
38
105
  const CollapsibleStepHeader = ({ isExpanded, onToggle, label, variant = "success" }) => {
@@ -51,6 +118,9 @@ const CollapsibleStepHeader = ({ isExpanded, onToggle, label, variant = "success
51
118
  });
52
119
  };
53
120
  //#endregion
121
+ //#region src/blocks/AIKit/hasMotion.ts
122
+ const hasMotion = () => typeof window.matchMedia === "function" && !window.matchMedia("(prefers-reduced-motion: reduce)").matches;
123
+ //#endregion
54
124
  //#region src/blocks/AIKit/InlineStepDetail.tsx
55
125
  const InlineStepDetail = ({ children }) => /* @__PURE__ */ jsx("div", {
56
126
  className: "tw:ml-2.5 tw:whitespace-pre-wrap tw:border-l tw:border-border tw:pl-3 tw:text-xs tw:text-muted-foreground",
@@ -80,29 +150,40 @@ const SECTION_LABELS = {
80
150
  success: "Answered questions",
81
151
  dismissed: "Dismissed questions"
82
152
  };
83
- const AnswerSummary = ({ items, variant = "success", noAnswerLabel = "No answer" }) => {
153
+ const AnswerSummary = ({ items, variant = "success", noAnswerLabel = "No answer", onExpandToggle }) => {
84
154
  const [isExpanded, setIsExpanded] = useState(false);
85
- const toggle = () => setIsExpanded((prev) => !prev);
155
+ const [isClosing, setIsClosing] = useState(false);
156
+ const toggle = () => {
157
+ const next = !isExpanded;
158
+ if (!next) setIsClosing(hasMotion());
159
+ setIsExpanded(next);
160
+ onExpandToggle?.(next);
161
+ };
86
162
  const count = items.length;
87
163
  const [firstItem] = items;
88
164
  const label = count === 1 && firstItem ? firstItem.question : `${count} questions`;
89
165
  return /* @__PURE__ */ jsxs("section", {
90
- className: "tw:mt-4 tw:flex tw:flex-col tw:gap-4",
166
+ className: "tw:mt-4 tw:flex tw:flex-col",
91
167
  "aria-label": SECTION_LABELS[variant],
92
168
  children: [/* @__PURE__ */ jsx(CollapsibleStepHeader, {
93
169
  isExpanded,
94
170
  onToggle: toggle,
95
171
  variant,
96
172
  label
97
- }), isExpanded && /* @__PURE__ */ jsx("div", {
98
- className: "tw:flex tw:flex-col tw:gap-4 tw:pl-5",
99
- children: items.map(({ question, answer }, index) => /* @__PURE__ */ jsxs("div", {
100
- className: "tw:flex tw:flex-col tw:gap-1",
101
- children: [/* @__PURE__ */ jsx(InlineStepLabel, {
102
- variant,
103
- children: question
104
- }), /* @__PURE__ */ jsx(InlineStepDetail, { children: answer && answer.length > 0 ? answer : noAnswerLabel })]
105
- }, `${index}-${question}`))
173
+ }), /* @__PURE__ */ jsx(CollapsibleBody, {
174
+ isExpanded,
175
+ isClosing,
176
+ onClosed: () => setIsClosing(false),
177
+ children: /* @__PURE__ */ jsx("div", {
178
+ className: "tw:flex tw:flex-col tw:gap-4 tw:pt-4 tw:pl-5",
179
+ children: items.map(({ question, answer }, index) => /* @__PURE__ */ jsxs("div", {
180
+ className: "tw:flex tw:flex-col tw:gap-1",
181
+ children: [/* @__PURE__ */ jsx(InlineStepLabel, {
182
+ variant,
183
+ children: question
184
+ }), /* @__PURE__ */ jsx(InlineStepDetail, { children: answer && answer.length > 0 ? answer : noAnswerLabel })]
185
+ }, `${index}-${question}`))
186
+ })
106
187
  })]
107
188
  });
108
189
  };
@@ -112,6 +193,10 @@ const MermaidDiagram = lazy(() => import("@keboola/design/mermaid").then((module
112
193
  console.error("[AIKit] failed to load the MermaidDiagram chunk", error);
113
194
  return { default: ({ code }) => /* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", { children: code }) }) };
114
195
  }));
196
+ const FlintChart = lazy(() => import("@keboola/design/flint").then((module) => ({ default: module.FlintChart }), (error) => {
197
+ console.error("[AIKit] failed to load the FlintChart chunk", error);
198
+ return { default: ({ code }) => /* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", { children: code }) }) };
199
+ }));
115
200
  const proseClass = "tw:prose tw:prose-sm tw:max-w-none tw:break-words tw:[&_pre]:bg-muted tw:[&_pre]:text-foreground tw:[&_:not(pre)>code]:bg-muted tw:[&_:not(pre)>code]:text-foreground tw:[&_:not(pre)>code]:rounded tw:[&_:not(pre)>code]:px-1 tw:[&_:not(pre)>code]:py-0.5 tw:[&_:not(pre)>code]:before:content-none tw:[&_:not(pre)>code]:after:content-none";
116
201
  const getText = (node) => {
117
202
  if (typeof node === "string") return node;
@@ -135,19 +220,48 @@ const getLanguage = (element) => {
135
220
  * - A caller's own plugins are appended to these, never substituted for them.
136
221
  */
137
222
  const baseRemarkPlugins = [remarkGfm];
223
+ /**
224
+ * Fence language → the renderer that draws it.
225
+ *
226
+ * - Both dialects are the agent's, not this package's: kai-agent's prompt tells the model to
227
+ * write ```mermaid for structure and ```flint for quantitative data, so a chat that renders
228
+ * one and not the other drops output the agent was instructed to produce.
229
+ * - `flint-chart` is an alias — it is the fence tag flint's own docs use, so a model emits it
230
+ * unprompted often enough to matter. `markdownComponents.tsx` in kbc-ui carries the same pair.
231
+ * - Read through `Object.hasOwn`, never by plain index: a fence tagged ```constructor or
232
+ * ```valueOf otherwise answers with an `Object.prototype` member, which is truthy, and mounting
233
+ * it as a component throws — taking the whole message subtree down with it.
234
+ */
235
+ const DIAGRAM_RENDERERS = {
236
+ mermaid: MermaidDiagram,
237
+ flint: FlintChart,
238
+ "flint-chart": FlintChart
239
+ };
240
+ /**
241
+ * The fence languages this renderer draws instead of printing.
242
+ *
243
+ * - For a caller that streams: a diagram mounts a lazily loaded chunk, so an answer arriving a
244
+ * token at a time has to keep a fence that is still open an ordinary code block, or every
245
+ * keystroke fetches the chunk. Sharing the list is what keeps that hold-back from missing a
246
+ * dialect this map has and the caller does not.
247
+ * - Frozen, because it is that shared contract: a consumer that pushed onto it would change how
248
+ * every other app in the same bundle holds a fence back.
249
+ */
250
+ const DIAGRAM_LANGUAGES = Object.freeze(Object.keys(DIAGRAM_RENDERERS));
138
251
  const baseComponents = {
139
252
  pre({ children, ...props }) {
140
253
  const child = Array.isArray(children) ? children[0] : children;
141
- if (getLanguage(child) === "mermaid") {
142
- const code = getText(child).replace(/\n$/, "");
254
+ const code = getText(child).replace(/\n$/, "");
255
+ const language = getLanguage(child);
256
+ const Diagram = language !== void 0 && Object.hasOwn(DIAGRAM_RENDERERS, language) ? DIAGRAM_RENDERERS[language] : void 0;
257
+ if (Diagram) {
143
258
  if (!code.trim()) return null;
144
259
  return /* @__PURE__ */ jsx(Suspense, {
145
260
  fallback: /* @__PURE__ */ jsx(DiagramSkeleton, {}),
146
- children: /* @__PURE__ */ jsx(MermaidDiagram, { code })
261
+ children: /* @__PURE__ */ jsx(Diagram, { code })
147
262
  });
148
263
  }
149
264
  const { node: _node, ...rest } = props;
150
- const code = getText(child).replace(/\n$/, "");
151
265
  return /* @__PURE__ */ jsxs("div", {
152
266
  className: "tw:group tw:relative",
153
267
  children: [/* @__PURE__ */ jsx("span", {
@@ -335,7 +449,7 @@ const ExpandToggle = ({ isExpanded, onToggle, showMoreLabel, showLessLabel }) =>
335
449
  });
336
450
  const ChangeRequestForm = ({ value, onValueChange, onSubmit, onKeyDown, placeholder, submitLabel, formLabel, canSubmit, isSubmitting }) => /* @__PURE__ */ jsx("form", {
337
451
  onSubmit,
338
- className: "tw:border-0 tw:border-t tw:border-solid tw:border-neutral-100 tw:bg-white tw:px-4 tw:py-3",
452
+ className: "tw:border-0 tw:border-t tw:border-solid tw:border-border tw:bg-card tw:text-card-foreground tw:px-4 tw:py-3",
339
453
  "aria-label": formLabel,
340
454
  children: /* @__PURE__ */ jsxs("div", {
341
455
  className: "tw:relative",
@@ -415,8 +529,10 @@ const PlanApproval = ({ status, title, summary, stepCount, planBody, defaultExpa
415
529
  const canShowPlanBody = planBody != null;
416
530
  const trimmedChangeRequest = changeRequest.trim();
417
531
  const canSubmitChangeRequest = trimmedChangeRequest.length > 0 && !isSubmitting;
532
+ const [isClosing, setIsClosing] = useState(false);
418
533
  const toggleExpanded = () => {
419
534
  const next = !isExpanded;
535
+ if (!next) setIsClosing(hasMotion());
420
536
  if (isExpandedProp === void 0) setUncontrolledExpanded(next);
421
537
  onExpandToggle?.(next);
422
538
  };
@@ -465,7 +581,7 @@ const PlanApproval = ({ status, title, summary, stepCount, planBody, defaultExpa
465
581
  });
466
582
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("section", {
467
583
  "aria-label": title,
468
- className: cn("tw:flex tw:w-full tw:max-w-[800px] tw:flex-col tw:overflow-hidden tw:rounded-xl tw:border tw:border-solid tw:border-border tw:bg-neutral-50", className),
584
+ className: cn("tw:flex tw:w-full tw:max-w-[800px] tw:flex-col tw:overflow-hidden tw:rounded-xl tw:border tw:border-solid tw:border-border tw:bg-background tw:text-foreground", className),
469
585
  "data-testid": "plan-approval-root",
470
586
  "data-plan-status": status,
471
587
  children: [
@@ -482,11 +598,11 @@ const PlanApproval = ({ status, title, summary, stepCount, planBody, defaultExpa
482
598
  dismissedLabel: dismissedPillLabel,
483
599
  changesRequestedLabel: changesRequestedPillLabel
484
600
  }), stepCount != null && stepCount > 0 && /* @__PURE__ */ jsx("span", {
485
- className: "tw:text-xs tw:leading-4 tw:text-neutral-500",
601
+ className: "tw:text-xs tw:leading-4 tw:text-muted-foreground",
486
602
  children: stepCountLabel(stepCount)
487
603
  })]
488
604
  }), /* @__PURE__ */ jsx("p", {
489
- className: "tw:m-0 tw:text-base tw:font-semibold tw:leading-6 tw:text-neutral-800",
605
+ className: "tw:m-0 tw:text-base tw:font-semibold tw:leading-6",
490
606
  children: title
491
607
  })]
492
608
  }), /* @__PURE__ */ jsxs("div", {
@@ -515,15 +631,20 @@ const PlanApproval = ({ status, title, summary, stepCount, planBody, defaultExpa
515
631
  })]
516
632
  }),
517
633
  summary != null && /* @__PURE__ */ jsx("div", {
518
- className: cn("tw:whitespace-pre-wrap tw:border-0 tw:border-t tw:border-solid tw:border-neutral-100 tw:px-4 tw:pt-4 tw:text-sm tw:text-neutral-700", isExpanded && canShowPlanBody ? "tw:pb-4" : "tw:pb-2"),
634
+ className: cn("tw:whitespace-pre-wrap tw:border-0 tw:border-t tw:border-solid tw:border-border tw:px-4 tw:pt-4 tw:text-sm", isExpanded && canShowPlanBody ? "tw:pb-4" : "tw:pb-2"),
519
635
  children: summary
520
636
  }),
521
- isExpanded && canShowPlanBody && /* @__PURE__ */ jsx("div", {
522
- className: "tw:max-h-[400px] tw:overflow-y-auto tw:border-0 tw:border-t tw:border-solid tw:border-neutral-100 tw:bg-white tw:p-4 tw:text-sm tw:text-neutral-700",
523
- children: planBody
637
+ canShowPlanBody && /* @__PURE__ */ jsx(CollapsibleBody, {
638
+ isExpanded,
639
+ isClosing,
640
+ onClosed: () => setIsClosing(false),
641
+ children: /* @__PURE__ */ jsx("div", {
642
+ className: "tw:max-h-[400px] tw:overflow-y-auto tw:border-0 tw:border-t tw:border-solid tw:border-border tw:bg-card tw:p-4 tw:text-sm tw:text-card-foreground",
643
+ children: planBody
644
+ })
524
645
  }),
525
646
  !isFullScreen && /* @__PURE__ */ jsxs(Fragment$1, { children: [showChangeRequestForm && changeRequestForm, /* @__PURE__ */ jsxs("div", {
526
- className: cn("tw:flex tw:items-center tw:gap-2 tw:overflow-x-auto tw:border-0 tw:border-t tw:border-solid tw:border-neutral-100 tw:bg-white tw:px-4 tw:py-3", canShowPlanBody ? "tw:justify-between" : "tw:justify-end"),
647
+ className: cn("tw:flex tw:items-center tw:gap-2 tw:overflow-x-auto tw:border-0 tw:border-t tw:border-solid tw:border-border tw:bg-card tw:px-4 tw:py-3 tw:text-card-foreground", canShowPlanBody ? "tw:justify-between" : "tw:justify-end"),
527
648
  children: [canShowPlanBody && /* @__PURE__ */ jsx("div", {
528
649
  className: "tw:shrink-0",
529
650
  children: /* @__PURE__ */ jsx(ExpandToggle, {
@@ -585,14 +706,14 @@ const PlanApproval = ({ status, title, summary, stepCount, planBody, defaultExpa
585
706
  })
586
707
  }),
587
708
  /* @__PURE__ */ jsx(FullScreenModalBody, {
588
- className: "tw:bg-white tw:px-6 tw:py-4",
709
+ className: "tw:bg-card tw:px-6 tw:py-4 tw:text-card-foreground",
589
710
  children: /* @__PURE__ */ jsx("div", {
590
- className: "tw:mx-auto tw:w-full tw:max-w-[800px] tw:text-sm tw:text-neutral-700",
711
+ className: "tw:mx-auto tw:w-full tw:max-w-[800px] tw:text-sm",
591
712
  children: planBody
592
713
  })
593
714
  }),
594
715
  (showChangeRequestForm || showActions) && /* @__PURE__ */ jsx("div", {
595
- className: "tw:shrink-0 tw:border-0 tw:border-t tw:border-solid tw:border-neutral-100 tw:bg-white",
716
+ className: "tw:shrink-0 tw:border-0 tw:border-t tw:border-solid tw:border-border tw:bg-card tw:text-card-foreground",
596
717
  children: /* @__PURE__ */ jsxs("div", {
597
718
  className: "tw:mx-auto tw:w-full tw:max-w-[800px]",
598
719
  children: [showChangeRequestForm && changeRequestForm, showActions && /* @__PURE__ */ jsx("div", {
@@ -758,11 +879,15 @@ const wrapperVariants = cva(null, {
758
879
  inline: ""
759
880
  } }
760
881
  });
761
- const PromptInput = ({ onSend, onAbort, onContinue, prefix, variant, suffix, disabled, disableSubmit, value = "", onValueChange, status = "ready", maxRows = 6, minRows, commands, autoFocus, ...textareaProps }) => {
882
+ const PromptInput = ({ onSend, onAbort, onContinue, prefix, variant, suffix, disabled, disableSubmit, value = "", onValueChange, status = "ready", maxRows = 6, minRows, commands, autoFocus, textareaRef: publishedRef, ...textareaProps }) => {
762
883
  const defaultMinRows = variant === "inline" ? 1 : 2;
763
884
  const isDisabled = (disabled || disableSubmit || !value.trim()) && status !== "streaming" && status !== "interrupted";
764
885
  const textareaId = useId();
765
886
  const textareaRef = useRef(null);
887
+ const setTextareaNode = useCallback((node) => {
888
+ textareaRef.current = node;
889
+ if (publishedRef) publishedRef.current = node;
890
+ }, [publishedRef]);
766
891
  const [dismissedValue, setDismissedValue] = useState(null);
767
892
  const autoFocusRef = useRef(autoFocus);
768
893
  useEffect(() => {
@@ -833,7 +958,7 @@ const PromptInput = ({ onSend, onAbort, onContinue, prefix, variant, suffix, dis
833
958
  minRows: minRows ?? defaultMinRows,
834
959
  maxRows,
835
960
  id: textareaId,
836
- ref: textareaRef,
961
+ ref: setTextareaNode,
837
962
  value,
838
963
  onChange: handleOnChange,
839
964
  onKeyDown: handleOnKeyDown,
@@ -1331,14 +1456,31 @@ const ToolCallStatusHeader = ({ icon: IconComponent, iconSpin, status, text, nee
1331
1456
  className: "tw:text-xs tw:font-medium tw:text-warning",
1332
1457
  children: "Confirmation required"
1333
1458
  }), /* @__PURE__ */ jsx(TriangleAlert, { className: "tw:size-3.5 tw:text-warning" })]
1334
- }), isCollapsible && (isCollapsed ? /* @__PURE__ */ jsx(ChevronDown, { className: "tw:size-3.5 tw:shrink-0 tw:text-muted-foreground" }) : /* @__PURE__ */ jsx(ChevronUp, { className: "tw:size-3.5 tw:shrink-0 tw:text-muted-foreground" }))]
1459
+ }), isCollapsible && /* @__PURE__ */ jsx(ChevronDown, { className: cn("tw:size-3.5 tw:shrink-0 tw:text-muted-foreground", "tw:transition-transform tw:duration-300 tw:ease-out tw:motion-reduce:transition-none", !isCollapsed && "tw:rotate-180") })]
1335
1460
  })]
1336
1461
  });
1337
1462
  };
1338
1463
  //#endregion
1339
1464
  //#region src/blocks/AIKit/usageStatsHelpers.ts
1340
- /** Clamp a percentage to 0–100 and normalize non-finite input to 0. */
1465
+ /**
1466
+ * Clamp a percentage to 0–100 and normalize non-finite input to 0.
1467
+ *
1468
+ * - `Progress`'s indicator is unclamped, so a value over 100 slides the bar off-screen.
1469
+ * - `NaN` normalizes to 0 — `Math.min`/`Math.max` propagate it, and it renders as no bar at all.
1470
+ */
1341
1471
  const clampPercentage = (value) => Number.isFinite(value) ? Math.min(100, Math.max(0, value)) : 0;
1472
+ /**
1473
+ * A percentage as text — `72%`, `1.1%`, `99.9%`.
1474
+ *
1475
+ * - One decimal place, trimmed to a whole number, so `11/1000` reads as `1.1%` rather than `1%`.
1476
+ * - Floored, not rounded: rounding `99.96` up to `100%` disagrees with the at-limit state computed
1477
+ * from the raw value, exactly at the boundary everything else turns on.
1478
+ * - The `1e-9` nudge is for floating-point noise — `11 / 1000 * 100` is `1.0999999999999999`.
1479
+ */
1480
+ const formatPercentage = (value) => {
1481
+ const floored = Math.floor(value * 10 + 1e-9) / 10;
1482
+ return `${Number.isInteger(floored) ? floored.toFixed(0) : floored.toFixed(1)}%`;
1483
+ };
1342
1484
  //#endregion
1343
1485
  //#region src/blocks/AIKit/UsageStatsRing.tsx
1344
1486
  const UsageStatsRing = ({ value, size = 16, strokeWidth = 2.5, className }) => {
@@ -1357,7 +1499,7 @@ const UsageStatsRing = ({ value, size = 16, strokeWidth = 2.5, className }) => {
1357
1499
  r: radius,
1358
1500
  fill: "none",
1359
1501
  strokeWidth,
1360
- className: "tw:stroke-neutral-400 tw:opacity-50"
1502
+ className: "tw:stroke-muted-foreground tw:opacity-50"
1361
1503
  }), /* @__PURE__ */ jsx("circle", {
1362
1504
  cx: size / 2,
1363
1505
  cy: size / 2,
@@ -1373,28 +1515,32 @@ const UsageStatsRing = ({ value, size = 16, strokeWidth = 2.5, className }) => {
1373
1515
  };
1374
1516
  //#endregion
1375
1517
  //#region src/blocks/AIKit/UsageStats.tsx
1376
- const UsageStats = ({ value, alert = false, children, className, ariaLabel, align = "end", side = "top", sideOffset = 8 }) => {
1518
+ const UsageStats = ({ value, alert = false, children, className, ariaLabel, align = "end", side = "top", sideOffset = 8, open, onOpenChange }) => {
1377
1519
  const hasAlert = Boolean(alert);
1378
1520
  const isWarning = alert === "warning";
1379
1521
  const defaultLabel = `Usage: ${Math.round(clampPercentage(value))}%${hasAlert ? " (usage alert)" : ""}`;
1380
- return /* @__PURE__ */ jsxs(HoverCard, { children: [/* @__PURE__ */ jsx(HoverCard.Trigger, {
1381
- asChild: true,
1382
- children: /* @__PURE__ */ jsxs("span", {
1383
- "aria-label": ariaLabel ?? defaultLabel,
1384
- className: cn("tw:relative tw:inline-flex tw:size-8 tw:items-center tw:justify-center", className),
1385
- children: [/* @__PURE__ */ jsx(UsageStatsRing, { value }), hasAlert && /* @__PURE__ */ jsx(AlertCircle, {
1386
- "data-testid": "usage-stats-alert",
1387
- className: cn("tw:absolute tw:-right-0.5 tw:-top-0.5 tw:size-3", isWarning ? "tw:text-warning-500" : "tw:text-error-500")
1388
- })]
1389
- })
1390
- }), /* @__PURE__ */ jsx(HoverCard.Content, {
1391
- align,
1392
- side,
1393
- sideOffset,
1394
- children
1395
- })] });
1522
+ return /* @__PURE__ */ jsxs(HoverCard, {
1523
+ open,
1524
+ onOpenChange,
1525
+ children: [/* @__PURE__ */ jsx(HoverCard.Trigger, {
1526
+ asChild: true,
1527
+ children: /* @__PURE__ */ jsxs("span", {
1528
+ "aria-label": ariaLabel ?? defaultLabel,
1529
+ className: cn("tw:relative tw:inline-flex tw:size-8 tw:items-center tw:justify-center", className),
1530
+ children: [/* @__PURE__ */ jsx(UsageStatsRing, { value }), hasAlert && /* @__PURE__ */ jsx(AlertCircle, {
1531
+ "data-testid": "usage-stats-alert",
1532
+ className: cn("tw:absolute tw:-right-0.5 tw:-top-0.5 tw:size-3", isWarning ? "tw:text-warning-500" : "tw:text-error-500")
1533
+ })]
1534
+ })
1535
+ }), /* @__PURE__ */ jsx(HoverCard.Content, {
1536
+ align,
1537
+ side,
1538
+ sideOffset,
1539
+ children
1540
+ })]
1541
+ });
1396
1542
  };
1397
1543
  //#endregion
1398
- export { AnswerSummary, CollapsibleStepHeader, InlineStepDetail, InlineStepLabel, Markdown, MessageBubble, PlanApproval, PlanRewritingIndicator, PromptInput, Question, QuestionBlock, SuggestedPrompt, ThinkingIndicator, ToolCallApproval, ToolCallChip, ToolCallStatusHeader, UsageStats, UsageStatsRing };
1544
+ export { AnswerActions, AnswerSummary, CollapsibleStepHeader, DIAGRAM_LANGUAGES, InlineStepDetail, InlineStepLabel, Markdown, MessageBubble, PlanApproval, PlanRewritingIndicator, PromptInput, Question, QuestionBlock, SuggestedPrompt, ThinkingIndicator, ToolCallApproval, ToolCallChip, ToolCallStatusHeader, UsageStats, UsageStatsRing, clampPercentage, formatPercentage };
1399
1545
 
1400
- //# sourceMappingURL=AIKit-DDg5DBCG.js.map
1546
+ //# sourceMappingURL=AIKit-CNX6aiKm.js.map