@sybilion/uilib 1.3.47 → 1.3.48

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.
@@ -4,7 +4,7 @@ import { Button } from '../../Button/Button.js';
4
4
  import { ChatChrome } from '../ChatChrome/ChatChrome.js';
5
5
  import { useChatPanelChromeModel } from './useChatPanelChromeModel.js';
6
6
 
7
- function ChatSheet({ triggerLabel = 'Open Chat', triggerAriaLabel, actionsRef, renderTrigger, presets, scopeId, onMessage, onScriptComplete, renderMessageChart, emptyState, allowedAttachments, allowPdfAttachments, onAttachmentsDropped, slashCommandItems, onSlashItemCommand, inline = false, }) {
7
+ function ChatSheet({ triggerLabel = 'Open Chat', triggerAriaLabel, actionsRef, renderTrigger, presets, scopeId, onMessage, onScriptComplete, renderMessageChart, emptyState, allowedAttachments, allowPdfAttachments, onAttachmentsDropped, slashCommandItems, onSlashItemCommand, transformSendPayload, inline = false, }) {
8
8
  const model = useChatPanelChromeModel({
9
9
  embedAsPage: inline,
10
10
  presets,
@@ -18,6 +18,7 @@ function ChatSheet({ triggerLabel = 'Open Chat', triggerAriaLabel, actionsRef, r
18
18
  onAttachmentsDropped,
19
19
  slashCommandItems,
20
20
  onSlashItemCommand,
21
+ transformSendPayload,
21
22
  });
22
23
  if (actionsRef) {
23
24
  actionsRef.current = {
@@ -22,7 +22,7 @@ const CHAT_NAV_COLLAPSE_BREAKPOINT_PX = 1400;
22
22
  const CHAT_QUERY_PARAM = 'chat';
23
23
  const CHAT_OPEN_VALUE = 'open';
24
24
  const PROMPT_QUERY_PARAM = 'prompt';
25
- function useChatPanelChromeModel({ embedAsPage, presets, scopeId, onMessage, onScriptComplete, renderMessageChart, emptyState, allowedAttachments, allowPdfAttachments, onAttachmentsDropped, slashCommandItems, onSlashItemCommand, }) {
25
+ function useChatPanelChromeModel({ embedAsPage, presets, scopeId, onMessage, onScriptComplete, renderMessageChart, emptyState, allowedAttachments, allowPdfAttachments, onAttachmentsDropped, slashCommandItems, onSlashItemCommand, transformSendPayload, }) {
26
26
  const effectiveScopeId = scopeId ?? NO_SCOPE_FALLBACK;
27
27
  const isMobile = useIsMobile();
28
28
  const { chatPanelContainer, isOpen: sidebarNavOpen, setOpen: setSidebarNavOpen, chatWidthPx, setChatWidthPx, getShellWidth, setChatPanelOpen, } = useSidebar();
@@ -404,9 +404,12 @@ function useChatPanelChromeModel({ embedAsPage, presets, scopeId, onMessage, onS
404
404
  try {
405
405
  if (chatId)
406
406
  endLocalDemoFlow(chatId);
407
- const payload = buildChatSendMessagePayload(message, stagedAttachments);
408
- await sendMessage(payload);
409
- onMessage?.(displayTextFromSendPayload(payload));
407
+ let payload = buildChatSendMessagePayload(message, stagedAttachments);
408
+ if (transformSendPayload) {
409
+ payload = await transformSendPayload(message, stagedAttachments, payload);
410
+ }
411
+ const assistantResponse = await sendMessage(payload);
412
+ onMessage?.(displayTextFromSendPayload(payload), assistantResponse);
410
413
  }
411
414
  catch (error) {
412
415
  logger.error('Error sending chat message:', error);
@@ -423,6 +426,7 @@ function useChatPanelChromeModel({ embedAsPage, presets, scopeId, onMessage, onS
423
426
  sendMessage,
424
427
  onMessage,
425
428
  onScriptComplete,
429
+ transformSendPayload,
426
430
  ]);
427
431
  const submitPreset = useCallback(async (preset) => {
428
432
  const script = preset.script;
@@ -55,7 +55,13 @@ function Renamer({ value = '', onInput, onChange, children, className, placehold
55
55
  md: 'md',
56
56
  lg: 'lg',
57
57
  };
58
- return (jsx("div", { className: cn(S.root, !value && S.empty, className), onKeyDown: onKeyDown, children: isRenaming ? (jsx(Input, { className: S.input, autoFocus: !isMobile, variant: "clean", size: sizeMap[size], placeholder: placeholder, value: name, onChange: handleInputChange, onBlur: handleBlur, onKeyDown: onKeyDown })) : (jsxs(Fragment, { children: [jsx("span", { className: S.value, children: children }), jsxs(Tooltip, { children: [jsx(TooltipTrigger, { asChild: true, children: jsx(Button, { className: S.button, variant: "ghost", onClick: handleEditClick, size: buttonSizeMap[size], type: "button", children: jsx(PencilSimpleIcon, { size: 16 }) }) }), jsx(TooltipContent, { side: "bottom", children: "Rename" })] })] })) }));
58
+ return (jsx("div", { className: cn(S.root, !value && S.empty, className), onKeyDown: onKeyDown, children: isRenaming ? (jsx(Input, { className: S.input, autoFocus: !isMobile, variant: "clean", size: sizeMap[size], placeholder: placeholder, value: name, onChange: handleInputChange, onBlur: handleBlur, onKeyDown: onKeyDown })) : (jsxs(Fragment, { children: [jsx("span", { className: S.value, children: children }), jsxs(Tooltip, { children: [jsx(TooltipTrigger, { asChild: true, children: jsx(Button, { className: S.button, variant: "ghost", onPointerDown: e => {
59
+ e.preventDefault();
60
+ e.stopPropagation();
61
+ }, onClick: e => {
62
+ e.stopPropagation();
63
+ handleEditClick();
64
+ }, size: buttonSizeMap[size], type: "button", children: jsx(PencilSimpleIcon, { size: 16 }) }) }), jsx(TooltipContent, { side: "bottom", children: "Rename" })] })] })) }));
59
65
  }
60
66
 
61
67
  export { Renamer };
@@ -19,4 +19,4 @@ export interface ChatSheetProps extends Omit<UseChatPanelChromeModelInput, 'embe
19
19
  */
20
20
  inline?: boolean;
21
21
  }
22
- export declare function ChatSheet({ triggerLabel, triggerAriaLabel, actionsRef, renderTrigger, presets, scopeId, onMessage, onScriptComplete, renderMessageChart, emptyState, allowedAttachments, allowPdfAttachments, onAttachmentsDropped, slashCommandItems, onSlashItemCommand, inline, }: ChatSheetProps): import("react/jsx-runtime").JSX.Element;
22
+ export declare function ChatSheet({ triggerLabel, triggerAriaLabel, actionsRef, renderTrigger, presets, scopeId, onMessage, onScriptComplete, renderMessageChart, emptyState, allowedAttachments, allowPdfAttachments, onAttachmentsDropped, slashCommandItems, onSlashItemCommand, transformSendPayload, inline, }: ChatSheetProps): import("react/jsx-runtime").JSX.Element;
@@ -1,4 +1,4 @@
1
- import { ChatPreset, type ScriptCompletePayload } from '#uilib/components/ui/Chat/Chat.types';
1
+ import { ChatPreset, type ChatSendMessagePayload, type ScriptCompletePayload } from '#uilib/components/ui/Chat/Chat.types';
2
2
  import type { SlashCommandItem, SlashOnItemCommand } from '#uilib/tiptap/slash-mention/types';
3
3
  import type { ChatChromeProps } from '../ChatChrome';
4
4
  import type { ChatAttachmentDropItem } from '../ChatChrome/ChatChrome.types';
@@ -9,7 +9,8 @@ export type UseChatPanelChromeModelInput = {
9
9
  presets?: ChatPreset[];
10
10
  /** Composite chat scope (e.g. `${userId}-${datasetId}`, `${userId}-dashboard`, `${userId}-report-${reportId}`). */
11
11
  scopeId?: string | null;
12
- onMessage?: (message: string) => void;
12
+ /** Fires after send; second arg is the assistant reply when the API call succeeded. */
13
+ onMessage?: (displayText: string, assistantResponse?: string) => void;
13
14
  /** Fires when a preset script has no further `[Label|branchKey]` steps (graph leaf or linear script end). */
14
15
  onScriptComplete?: (payload: ScriptCompletePayload) => void;
15
16
  /** Renders `[CHART]` tokens in assistant messages. */
@@ -25,6 +26,8 @@ export type UseChatPanelChromeModelInput = {
25
26
  slashCommandItems?: SlashCommandItem[];
26
27
  /** Custom slash command handler (palette pick or Enter on `/id`). */
27
28
  onSlashItemCommand?: SlashOnItemCommand;
29
+ /** Override or extend the default send payload (e.g. api vs display text split). */
30
+ transformSendPayload?: (message: string, attachments: ChatAttachmentDropItem[] | undefined, defaultPayload: string | ChatSendMessagePayload) => string | ChatSendMessagePayload | Promise<string | ChatSendMessagePayload>;
28
31
  };
29
32
  export type UseChatPanelChromeModelResult = {
30
33
  chromeProps: ChatChromeProps;
@@ -34,4 +37,4 @@ export type UseChatPanelChromeModelResult = {
34
37
  newChat: () => void;
35
38
  chatPanelContainer: HTMLElement | null;
36
39
  };
37
- export declare function useChatPanelChromeModel({ embedAsPage, presets, scopeId, onMessage, onScriptComplete, renderMessageChart, emptyState, allowedAttachments, allowPdfAttachments, onAttachmentsDropped, slashCommandItems, onSlashItemCommand, }: UseChatPanelChromeModelInput): UseChatPanelChromeModelResult;
40
+ export declare function useChatPanelChromeModel({ embedAsPage, presets, scopeId, onMessage, onScriptComplete, renderMessageChart, emptyState, allowedAttachments, allowPdfAttachments, onAttachmentsDropped, slashCommandItems, onSlashItemCommand, transformSendPayload, }: UseChatPanelChromeModelInput): UseChatPanelChromeModelResult;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sybilion/uilib",
3
- "version": "1.3.47",
3
+ "version": "1.3.48",
4
4
  "description": "Sybilion Design System — React UI components (Webpack + Stylus)",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -48,6 +48,7 @@ export function ChatSheet({
48
48
  onAttachmentsDropped,
49
49
  slashCommandItems,
50
50
  onSlashItemCommand,
51
+ transformSendPayload,
51
52
  inline = false,
52
53
  }: ChatSheetProps) {
53
54
  const model = useChatPanelChromeModel({
@@ -63,6 +64,7 @@ export function ChatSheet({
63
64
  onAttachmentsDropped,
64
65
  slashCommandItems,
65
66
  onSlashItemCommand,
67
+ transformSendPayload,
66
68
  });
67
69
 
68
70
  if (actionsRef) {
@@ -2,6 +2,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
2
 
3
3
  import {
4
4
  ChatPreset,
5
+ type ChatSendMessagePayload,
5
6
  MessageRole,
6
7
  type ScriptCompletePayload,
7
8
  } from '#uilib/components/ui/Chat/Chat.types';
@@ -54,7 +55,8 @@ export type UseChatPanelChromeModelInput = {
54
55
  presets?: ChatPreset[];
55
56
  /** Composite chat scope (e.g. `${userId}-${datasetId}`, `${userId}-dashboard`, `${userId}-report-${reportId}`). */
56
57
  scopeId?: string | null;
57
- onMessage?: (message: string) => void;
58
+ /** Fires after send; second arg is the assistant reply when the API call succeeded. */
59
+ onMessage?: (displayText: string, assistantResponse?: string) => void;
58
60
  /** Fires when a preset script has no further `[Label|branchKey]` steps (graph leaf or linear script end). */
59
61
  onScriptComplete?: (payload: ScriptCompletePayload) => void;
60
62
  /** Renders `[CHART]` tokens in assistant messages. */
@@ -72,6 +74,15 @@ export type UseChatPanelChromeModelInput = {
72
74
  slashCommandItems?: SlashCommandItem[];
73
75
  /** Custom slash command handler (palette pick or Enter on `/id`). */
74
76
  onSlashItemCommand?: SlashOnItemCommand;
77
+ /** Override or extend the default send payload (e.g. api vs display text split). */
78
+ transformSendPayload?: (
79
+ message: string,
80
+ attachments: ChatAttachmentDropItem[] | undefined,
81
+ defaultPayload: string | ChatSendMessagePayload,
82
+ ) =>
83
+ | string
84
+ | ChatSendMessagePayload
85
+ | Promise<string | ChatSendMessagePayload>;
75
86
  };
76
87
 
77
88
  export type UseChatPanelChromeModelResult = {
@@ -121,6 +132,7 @@ export function useChatPanelChromeModel({
121
132
  onAttachmentsDropped,
122
133
  slashCommandItems,
123
134
  onSlashItemCommand,
135
+ transformSendPayload,
124
136
  }: UseChatPanelChromeModelInput): UseChatPanelChromeModelResult {
125
137
  const effectiveScopeId = scopeId ?? NO_SCOPE_FALLBACK;
126
138
  const isMobile = useIsMobile();
@@ -596,9 +608,16 @@ export function useChatPanelChromeModel({
596
608
 
597
609
  try {
598
610
  if (chatId) endLocalDemoFlow(chatId);
599
- const payload = buildChatSendMessagePayload(message, stagedAttachments);
600
- await sendMessage(payload);
601
- onMessage?.(displayTextFromSendPayload(payload));
611
+ let payload = buildChatSendMessagePayload(message, stagedAttachments);
612
+ if (transformSendPayload) {
613
+ payload = await transformSendPayload(
614
+ message,
615
+ stagedAttachments,
616
+ payload,
617
+ );
618
+ }
619
+ const assistantResponse = await sendMessage(payload);
620
+ onMessage?.(displayTextFromSendPayload(payload), assistantResponse);
602
621
  } catch (error) {
603
622
  logger.error('Error sending chat message:', error);
604
623
  }
@@ -615,6 +634,7 @@ export function useChatPanelChromeModel({
615
634
  sendMessage,
616
635
  onMessage,
617
636
  onScriptComplete,
637
+ transformSendPayload,
618
638
  ],
619
639
  );
620
640
 
@@ -111,7 +111,14 @@ export function Renamer({
111
111
  <Button
112
112
  className={S.button}
113
113
  variant="ghost"
114
- onClick={handleEditClick}
114
+ onPointerDown={e => {
115
+ e.preventDefault();
116
+ e.stopPropagation();
117
+ }}
118
+ onClick={e => {
119
+ e.stopPropagation();
120
+ handleEditClick();
121
+ }}
115
122
  size={buttonSizeMap[size]}
116
123
  type="button"
117
124
  >
@@ -11,7 +11,7 @@ Host provides:
11
11
  - Optional `datasetHistorical` overlay
12
12
  - `seriesInitKey` when selected analysis changes
13
13
 
14
- Report tile: Not used in report tiles.
14
+ Report tile: `drivers_comparison_chart` host loads normalized backtests payload + dataset historical; built-in analysis selector.
15
15
 
16
16
  Requires: `payload` — target + driver normalized_series; `loading` / `chartLoading` — spinners; `seriesInitKey` — reset visible series on analysis change; `runAnalysisHint` / `statusHint` — empty/error text.
17
17
 
@@ -11,7 +11,7 @@ Host provides:
11
11
  - Analysis selection and fetch outside widget
12
12
  - Optional `forecastData`, `customPerformanceMatrix`, `userSeries` for spaghetti
13
13
 
14
- Report tile: Not used in report tiles.
14
+ Report tile: `performance_chart` host loads performance payload + dataset series; built-in analysis selector.
15
15
 
16
16
  Requires: `performanceData` — model/drift forecasts and metrics; `historicalData` — baseline series; `loading` / `chartLoading` / `performanceDataLoading` — spinners; `runAnalysisHint` / `statusHint` — empty states.
17
17
 
@@ -20,7 +20,7 @@ const FaviconWebpackPlugin = require('favicons-webpack-plugin');
20
20
  const pkg = require('../../../package.json');
21
21
 
22
22
  const themeStyl = pathResolve(paths.src, 'theme.styl');
23
- const logoSvgPath = pathResolve(paths.src, 'components/ui/Logo/logo.svg');
23
+ const logoSvgPath = pathResolve(paths.assets, 'logo.svg');
24
24
 
25
25
  /** GitHub Pages project sites live at /<repo>/; set PUBLIC_PATH=/repo-name/ for production deploy. */
26
26
  function normalizePublicPath(raw) {