@aganzefelicite/responsekit-react 0.1.0 → 0.2.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.
- package/README.md +28 -10
- package/dist/index.cjs +255 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +79 -1
- package/dist/index.d.ts +79 -1
- package/dist/index.js +250 -1
- package/dist/index.js.map +1 -1
- package/dist/styles.css +97 -0
- package/package.json +13 -3
package/dist/index.d.cts
CHANGED
|
@@ -248,6 +248,84 @@ declare function FallbackBlock({ block }: BlockComponentProps<Block>): react.JSX
|
|
|
248
248
|
/** The built-in block components, keyed by block `type`. */
|
|
249
249
|
declare const defaultBlockComponents: BlockComponents;
|
|
250
250
|
|
|
251
|
+
/**
|
|
252
|
+
* A floating, draggable, resizable panel that hosts any content (typically a chat or an
|
|
253
|
+
* `<AiRenderer/>`). Chrome only — it owns position/size/open state and nothing else, so
|
|
254
|
+
* you keep full control of what renders inside.
|
|
255
|
+
*
|
|
256
|
+
* - Drag by the header to move it (kept inside the viewport).
|
|
257
|
+
* - Drag the bottom-right corner to resize (clamped to `minWidth`/`minHeight`).
|
|
258
|
+
* - A launcher button toggles it open/closed; pass `showLauncher={false}` and drive
|
|
259
|
+
* `open`/`onOpenChange` yourself for a fully controlled widget.
|
|
260
|
+
*/
|
|
261
|
+
interface AiWidgetProps {
|
|
262
|
+
children: ReactNode;
|
|
263
|
+
/** Header title text. */
|
|
264
|
+
title?: string;
|
|
265
|
+
/** Optional extra controls rendered in the header (e.g. a "New chat" button). */
|
|
266
|
+
headerActions?: ReactNode;
|
|
267
|
+
/** Uncontrolled initial open state. Ignored when `open` is provided. */
|
|
268
|
+
defaultOpen?: boolean;
|
|
269
|
+
/** Controlled open state. Provide together with `onOpenChange`. */
|
|
270
|
+
open?: boolean;
|
|
271
|
+
onOpenChange?: (open: boolean) => void;
|
|
272
|
+
/** Initial top-left position in px. Defaults to the bottom-right corner. */
|
|
273
|
+
initialPosition?: {
|
|
274
|
+
x: number;
|
|
275
|
+
y: number;
|
|
276
|
+
};
|
|
277
|
+
/** Initial panel size in px. */
|
|
278
|
+
initialSize?: {
|
|
279
|
+
width: number;
|
|
280
|
+
height: number;
|
|
281
|
+
};
|
|
282
|
+
minWidth?: number;
|
|
283
|
+
minHeight?: number;
|
|
284
|
+
/** Show the floating toggle button. Default `true`. */
|
|
285
|
+
showLauncher?: boolean;
|
|
286
|
+
/** Launcher button contents when the widget is closed. */
|
|
287
|
+
launcher?: ReactNode;
|
|
288
|
+
className?: string;
|
|
289
|
+
}
|
|
290
|
+
declare function AiWidget({ children, title, headerActions, defaultOpen, open: openProp, onOpenChange, initialPosition, initialSize, minWidth, minHeight, showLauncher, launcher, className, }: AiWidgetProps): react.JSX.Element | null;
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Default, browser-side handling for the actions the SDK emits.
|
|
294
|
+
*
|
|
295
|
+
* The SDK never runs business logic — blocks only emit intent via `onAction`. But the two
|
|
296
|
+
* most common actions (`DOWNLOAD` a table/chart's data, `OPEN_LINK`) have an obvious,
|
|
297
|
+
* host-independent implementation. These helpers provide that so downloads "just work"
|
|
298
|
+
* without every consumer re-implementing blob plumbing. Wrap your handler with
|
|
299
|
+
* `withDefaultActions` to opt in, or call `runDefaultAction` yourself.
|
|
300
|
+
*/
|
|
301
|
+
|
|
302
|
+
/** Low-level: trigger a browser "Save as" for a Blob. No-op outside the browser. */
|
|
303
|
+
declare function triggerDownload(blob: Blob, filename: string): void;
|
|
304
|
+
/**
|
|
305
|
+
* Turn a `DOWNLOAD` action's `data` into a file and save it. Handles:
|
|
306
|
+
* - a string → written as-is (CSV/JSON/plain, per `format`)
|
|
307
|
+
* - a Blob → saved directly
|
|
308
|
+
* - anything else → serialized to pretty JSON
|
|
309
|
+
* Returns `true` when a download was started, `false` if there was nothing to save
|
|
310
|
+
* (or we're not in a browser).
|
|
311
|
+
*/
|
|
312
|
+
declare function performDownload(action: DownloadAction): boolean;
|
|
313
|
+
/** Open an `OPEN_LINK` action's href. Returns `true` when handled. */
|
|
314
|
+
declare function performOpenLink(action: OpenLinkAction): boolean;
|
|
315
|
+
/**
|
|
316
|
+
* Apply the SDK's default handling for an action. Currently `DOWNLOAD` and `OPEN_LINK`.
|
|
317
|
+
* Returns `true` if the action was handled here, so callers can decide whether to also
|
|
318
|
+
* run their own logic.
|
|
319
|
+
*/
|
|
320
|
+
declare function runDefaultAction(action: AiAction): boolean;
|
|
321
|
+
/**
|
|
322
|
+
* Wrap an `onAction` handler so `DOWNLOAD`/`OPEN_LINK` work out of the box while your own
|
|
323
|
+
* handler still sees every action (e.g. for analytics or custom actions):
|
|
324
|
+
*
|
|
325
|
+
* <AiRenderer onAction={withDefaultActions((a) => track(a))} />
|
|
326
|
+
*/
|
|
327
|
+
declare function withDefaultActions(onAction?: OnAction): OnAction;
|
|
328
|
+
|
|
251
329
|
interface MarkdownProps {
|
|
252
330
|
children: string;
|
|
253
331
|
className?: string;
|
|
@@ -310,4 +388,4 @@ declare function messageUrl(baseUrl: string, conversationId: string): string;
|
|
|
310
388
|
*/
|
|
311
389
|
declare function streamMessage(options: StreamMessageOptions): AsyncGenerator<SseEvent>;
|
|
312
390
|
|
|
313
|
-
export { type AiAction, AiRenderer, type AiRendererProps, AiStream, type AiStreamProps, type BlockComponent, type BlockComponentProps, type BlockComponents, ChartBlock, type ChatTurn, type ConversationClientOptions, type CustomAction, type DownloadAction, ErrorBoundary, ErrorView, FallbackBlock, FilterBlock, InsightBlock, KpiBlock, Markdown, type MarkdownProps, type OnAction, type OpenLinkAction, RecommendationBlock, type RefreshAction, type RegisterBlockOptions, type StreamMessageOptions, TableBlock, TextBlock, type UseAiStreamOptions, type UseAiStreamResult, type UseChatOptions, type UseChatResult, createConversation, defaultBlockComponents, deleteConversation, getConversation, getMessages, listConversations, messageUrl, noopAction, registerBlock, registeredBlockTypes, renameConversation, resolveBlockComponent, streamMessage, unregisterBlock, useAiStream, useChat };
|
|
391
|
+
export { type AiAction, AiRenderer, type AiRendererProps, AiStream, type AiStreamProps, AiWidget, type AiWidgetProps, type BlockComponent, type BlockComponentProps, type BlockComponents, ChartBlock, type ChatTurn, type ConversationClientOptions, type CustomAction, type DownloadAction, ErrorBoundary, ErrorView, FallbackBlock, FilterBlock, InsightBlock, KpiBlock, Markdown, type MarkdownProps, type OnAction, type OpenLinkAction, RecommendationBlock, type RefreshAction, type RegisterBlockOptions, type StreamMessageOptions, TableBlock, TextBlock, type UseAiStreamOptions, type UseAiStreamResult, type UseChatOptions, type UseChatResult, createConversation, defaultBlockComponents, deleteConversation, getConversation, getMessages, listConversations, messageUrl, noopAction, performDownload, performOpenLink, registerBlock, registeredBlockTypes, renameConversation, resolveBlockComponent, runDefaultAction, streamMessage, triggerDownload, unregisterBlock, useAiStream, useChat, withDefaultActions };
|
package/dist/index.d.ts
CHANGED
|
@@ -248,6 +248,84 @@ declare function FallbackBlock({ block }: BlockComponentProps<Block>): react.JSX
|
|
|
248
248
|
/** The built-in block components, keyed by block `type`. */
|
|
249
249
|
declare const defaultBlockComponents: BlockComponents;
|
|
250
250
|
|
|
251
|
+
/**
|
|
252
|
+
* A floating, draggable, resizable panel that hosts any content (typically a chat or an
|
|
253
|
+
* `<AiRenderer/>`). Chrome only — it owns position/size/open state and nothing else, so
|
|
254
|
+
* you keep full control of what renders inside.
|
|
255
|
+
*
|
|
256
|
+
* - Drag by the header to move it (kept inside the viewport).
|
|
257
|
+
* - Drag the bottom-right corner to resize (clamped to `minWidth`/`minHeight`).
|
|
258
|
+
* - A launcher button toggles it open/closed; pass `showLauncher={false}` and drive
|
|
259
|
+
* `open`/`onOpenChange` yourself for a fully controlled widget.
|
|
260
|
+
*/
|
|
261
|
+
interface AiWidgetProps {
|
|
262
|
+
children: ReactNode;
|
|
263
|
+
/** Header title text. */
|
|
264
|
+
title?: string;
|
|
265
|
+
/** Optional extra controls rendered in the header (e.g. a "New chat" button). */
|
|
266
|
+
headerActions?: ReactNode;
|
|
267
|
+
/** Uncontrolled initial open state. Ignored when `open` is provided. */
|
|
268
|
+
defaultOpen?: boolean;
|
|
269
|
+
/** Controlled open state. Provide together with `onOpenChange`. */
|
|
270
|
+
open?: boolean;
|
|
271
|
+
onOpenChange?: (open: boolean) => void;
|
|
272
|
+
/** Initial top-left position in px. Defaults to the bottom-right corner. */
|
|
273
|
+
initialPosition?: {
|
|
274
|
+
x: number;
|
|
275
|
+
y: number;
|
|
276
|
+
};
|
|
277
|
+
/** Initial panel size in px. */
|
|
278
|
+
initialSize?: {
|
|
279
|
+
width: number;
|
|
280
|
+
height: number;
|
|
281
|
+
};
|
|
282
|
+
minWidth?: number;
|
|
283
|
+
minHeight?: number;
|
|
284
|
+
/** Show the floating toggle button. Default `true`. */
|
|
285
|
+
showLauncher?: boolean;
|
|
286
|
+
/** Launcher button contents when the widget is closed. */
|
|
287
|
+
launcher?: ReactNode;
|
|
288
|
+
className?: string;
|
|
289
|
+
}
|
|
290
|
+
declare function AiWidget({ children, title, headerActions, defaultOpen, open: openProp, onOpenChange, initialPosition, initialSize, minWidth, minHeight, showLauncher, launcher, className, }: AiWidgetProps): react.JSX.Element | null;
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Default, browser-side handling for the actions the SDK emits.
|
|
294
|
+
*
|
|
295
|
+
* The SDK never runs business logic — blocks only emit intent via `onAction`. But the two
|
|
296
|
+
* most common actions (`DOWNLOAD` a table/chart's data, `OPEN_LINK`) have an obvious,
|
|
297
|
+
* host-independent implementation. These helpers provide that so downloads "just work"
|
|
298
|
+
* without every consumer re-implementing blob plumbing. Wrap your handler with
|
|
299
|
+
* `withDefaultActions` to opt in, or call `runDefaultAction` yourself.
|
|
300
|
+
*/
|
|
301
|
+
|
|
302
|
+
/** Low-level: trigger a browser "Save as" for a Blob. No-op outside the browser. */
|
|
303
|
+
declare function triggerDownload(blob: Blob, filename: string): void;
|
|
304
|
+
/**
|
|
305
|
+
* Turn a `DOWNLOAD` action's `data` into a file and save it. Handles:
|
|
306
|
+
* - a string → written as-is (CSV/JSON/plain, per `format`)
|
|
307
|
+
* - a Blob → saved directly
|
|
308
|
+
* - anything else → serialized to pretty JSON
|
|
309
|
+
* Returns `true` when a download was started, `false` if there was nothing to save
|
|
310
|
+
* (or we're not in a browser).
|
|
311
|
+
*/
|
|
312
|
+
declare function performDownload(action: DownloadAction): boolean;
|
|
313
|
+
/** Open an `OPEN_LINK` action's href. Returns `true` when handled. */
|
|
314
|
+
declare function performOpenLink(action: OpenLinkAction): boolean;
|
|
315
|
+
/**
|
|
316
|
+
* Apply the SDK's default handling for an action. Currently `DOWNLOAD` and `OPEN_LINK`.
|
|
317
|
+
* Returns `true` if the action was handled here, so callers can decide whether to also
|
|
318
|
+
* run their own logic.
|
|
319
|
+
*/
|
|
320
|
+
declare function runDefaultAction(action: AiAction): boolean;
|
|
321
|
+
/**
|
|
322
|
+
* Wrap an `onAction` handler so `DOWNLOAD`/`OPEN_LINK` work out of the box while your own
|
|
323
|
+
* handler still sees every action (e.g. for analytics or custom actions):
|
|
324
|
+
*
|
|
325
|
+
* <AiRenderer onAction={withDefaultActions((a) => track(a))} />
|
|
326
|
+
*/
|
|
327
|
+
declare function withDefaultActions(onAction?: OnAction): OnAction;
|
|
328
|
+
|
|
251
329
|
interface MarkdownProps {
|
|
252
330
|
children: string;
|
|
253
331
|
className?: string;
|
|
@@ -310,4 +388,4 @@ declare function messageUrl(baseUrl: string, conversationId: string): string;
|
|
|
310
388
|
*/
|
|
311
389
|
declare function streamMessage(options: StreamMessageOptions): AsyncGenerator<SseEvent>;
|
|
312
390
|
|
|
313
|
-
export { type AiAction, AiRenderer, type AiRendererProps, AiStream, type AiStreamProps, type BlockComponent, type BlockComponentProps, type BlockComponents, ChartBlock, type ChatTurn, type ConversationClientOptions, type CustomAction, type DownloadAction, ErrorBoundary, ErrorView, FallbackBlock, FilterBlock, InsightBlock, KpiBlock, Markdown, type MarkdownProps, type OnAction, type OpenLinkAction, RecommendationBlock, type RefreshAction, type RegisterBlockOptions, type StreamMessageOptions, TableBlock, TextBlock, type UseAiStreamOptions, type UseAiStreamResult, type UseChatOptions, type UseChatResult, createConversation, defaultBlockComponents, deleteConversation, getConversation, getMessages, listConversations, messageUrl, noopAction, registerBlock, registeredBlockTypes, renameConversation, resolveBlockComponent, streamMessage, unregisterBlock, useAiStream, useChat };
|
|
391
|
+
export { type AiAction, AiRenderer, type AiRendererProps, AiStream, type AiStreamProps, AiWidget, type AiWidgetProps, type BlockComponent, type BlockComponentProps, type BlockComponents, ChartBlock, type ChatTurn, type ConversationClientOptions, type CustomAction, type DownloadAction, ErrorBoundary, ErrorView, FallbackBlock, FilterBlock, InsightBlock, KpiBlock, Markdown, type MarkdownProps, type OnAction, type OpenLinkAction, RecommendationBlock, type RefreshAction, type RegisterBlockOptions, type StreamMessageOptions, TableBlock, TextBlock, type UseAiStreamOptions, type UseAiStreamResult, type UseChatOptions, type UseChatResult, createConversation, defaultBlockComponents, deleteConversation, getConversation, getMessages, listConversations, messageUrl, noopAction, performDownload, performOpenLink, registerBlock, registeredBlockTypes, renameConversation, resolveBlockComponent, runDefaultAction, streamMessage, triggerDownload, unregisterBlock, useAiStream, useChat, withDefaultActions };
|
package/dist/index.js
CHANGED
|
@@ -4974,7 +4974,256 @@ function useChat(options) {
|
|
|
4974
4974
|
useEffect(() => () => abortRef.current?.abort(), []);
|
|
4975
4975
|
return { conversationId, turns, isStreaming, error, send, stop, reset, newConversation };
|
|
4976
4976
|
}
|
|
4977
|
+
var MARGIN = 24;
|
|
4978
|
+
var clamp = (v, lo, hi) => Math.min(Math.max(v, lo), hi);
|
|
4979
|
+
var viewport = () => ({
|
|
4980
|
+
w: typeof window === "undefined" ? 1024 : window.innerWidth,
|
|
4981
|
+
h: typeof window === "undefined" ? 768 : window.innerHeight
|
|
4982
|
+
});
|
|
4983
|
+
function AiWidget({
|
|
4984
|
+
children,
|
|
4985
|
+
title = "Assistant",
|
|
4986
|
+
headerActions,
|
|
4987
|
+
defaultOpen = false,
|
|
4988
|
+
open: openProp,
|
|
4989
|
+
onOpenChange,
|
|
4990
|
+
initialPosition,
|
|
4991
|
+
initialSize = { width: 384, height: 560 },
|
|
4992
|
+
minWidth = 300,
|
|
4993
|
+
minHeight = 360,
|
|
4994
|
+
showLauncher = true,
|
|
4995
|
+
launcher,
|
|
4996
|
+
className
|
|
4997
|
+
}) {
|
|
4998
|
+
const isControlled = openProp !== void 0;
|
|
4999
|
+
const [openState, setOpenState] = useState(defaultOpen);
|
|
5000
|
+
const open = isControlled ? openProp : openState;
|
|
5001
|
+
const setOpen = useCallback(
|
|
5002
|
+
(next) => {
|
|
5003
|
+
if (!isControlled) setOpenState(next);
|
|
5004
|
+
onOpenChange?.(next);
|
|
5005
|
+
},
|
|
5006
|
+
[isControlled, onOpenChange]
|
|
5007
|
+
);
|
|
5008
|
+
const [size, setSize] = useState(initialSize);
|
|
5009
|
+
const [pos, setPos] = useState(initialPosition ?? null);
|
|
5010
|
+
useEffect(() => {
|
|
5011
|
+
if (pos) return;
|
|
5012
|
+
const { w, h } = viewport();
|
|
5013
|
+
setPos({
|
|
5014
|
+
x: Math.max(MARGIN, w - size.width - MARGIN),
|
|
5015
|
+
y: Math.max(MARGIN, h - size.height - MARGIN)
|
|
5016
|
+
});
|
|
5017
|
+
}, [pos]);
|
|
5018
|
+
useEffect(() => {
|
|
5019
|
+
if (typeof window === "undefined") return;
|
|
5020
|
+
const onResize = () => {
|
|
5021
|
+
setPos((p) => {
|
|
5022
|
+
if (!p) return p;
|
|
5023
|
+
const { w, h } = viewport();
|
|
5024
|
+
return {
|
|
5025
|
+
x: clamp(p.x, 0, Math.max(0, w - size.width)),
|
|
5026
|
+
y: clamp(p.y, 0, Math.max(0, h - size.height))
|
|
5027
|
+
};
|
|
5028
|
+
});
|
|
5029
|
+
};
|
|
5030
|
+
window.addEventListener("resize", onResize);
|
|
5031
|
+
return () => window.removeEventListener("resize", onResize);
|
|
5032
|
+
}, [size.width, size.height]);
|
|
5033
|
+
const dragRef = useRef(null);
|
|
5034
|
+
const onHeaderPointerDown = (e) => {
|
|
5035
|
+
if (e.button !== 0 || !pos) return;
|
|
5036
|
+
if (e.target.closest("button, a, input, select")) return;
|
|
5037
|
+
dragRef.current = { px: e.clientX, py: e.clientY, ox: pos.x, oy: pos.y };
|
|
5038
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
5039
|
+
};
|
|
5040
|
+
const onHeaderPointerMove = (e) => {
|
|
5041
|
+
const d = dragRef.current;
|
|
5042
|
+
if (!d) return;
|
|
5043
|
+
const { w, h } = viewport();
|
|
5044
|
+
setPos({
|
|
5045
|
+
x: clamp(d.ox + (e.clientX - d.px), 0, Math.max(0, w - size.width)),
|
|
5046
|
+
y: clamp(d.oy + (e.clientY - d.py), 0, Math.max(0, h - size.height))
|
|
5047
|
+
});
|
|
5048
|
+
};
|
|
5049
|
+
const endHeaderPointer = (e) => {
|
|
5050
|
+
dragRef.current = null;
|
|
5051
|
+
if (e.currentTarget.hasPointerCapture?.(e.pointerId)) {
|
|
5052
|
+
e.currentTarget.releasePointerCapture(e.pointerId);
|
|
5053
|
+
}
|
|
5054
|
+
};
|
|
5055
|
+
const resizeRef = useRef(null);
|
|
5056
|
+
const onResizePointerDown = (e) => {
|
|
5057
|
+
if (e.button !== 0) return;
|
|
5058
|
+
e.stopPropagation();
|
|
5059
|
+
resizeRef.current = { px: e.clientX, py: e.clientY, ow: size.width, oh: size.height };
|
|
5060
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
5061
|
+
};
|
|
5062
|
+
const onResizePointerMove = (e) => {
|
|
5063
|
+
const r = resizeRef.current;
|
|
5064
|
+
if (!r || !pos) return;
|
|
5065
|
+
const { w, h } = viewport();
|
|
5066
|
+
setSize({
|
|
5067
|
+
width: clamp(r.ow + (e.clientX - r.px), minWidth, w - pos.x - MARGIN / 2),
|
|
5068
|
+
height: clamp(r.oh + (e.clientY - r.py), minHeight, h - pos.y - MARGIN / 2)
|
|
5069
|
+
});
|
|
5070
|
+
};
|
|
5071
|
+
const endResizePointer = (e) => {
|
|
5072
|
+
resizeRef.current = null;
|
|
5073
|
+
if (e.currentTarget.hasPointerCapture?.(e.pointerId)) {
|
|
5074
|
+
e.currentTarget.releasePointerCapture(e.pointerId);
|
|
5075
|
+
}
|
|
5076
|
+
};
|
|
5077
|
+
if (!open) {
|
|
5078
|
+
if (!showLauncher) return null;
|
|
5079
|
+
return /* @__PURE__ */ jsx(
|
|
5080
|
+
"button",
|
|
5081
|
+
{
|
|
5082
|
+
type: "button",
|
|
5083
|
+
className: "rk-widget-launcher",
|
|
5084
|
+
onClick: () => setOpen(true),
|
|
5085
|
+
"aria-label": `Open ${title}`,
|
|
5086
|
+
children: launcher ?? /* @__PURE__ */ jsx(LauncherIcon, {})
|
|
5087
|
+
}
|
|
5088
|
+
);
|
|
5089
|
+
}
|
|
5090
|
+
const panelStyle = pos ? {
|
|
5091
|
+
left: pos.x,
|
|
5092
|
+
top: pos.y,
|
|
5093
|
+
width: size.width,
|
|
5094
|
+
height: size.height
|
|
5095
|
+
} : { visibility: "hidden" };
|
|
5096
|
+
return /* @__PURE__ */ jsxs(
|
|
5097
|
+
"div",
|
|
5098
|
+
{
|
|
5099
|
+
className: `rk-widget${className ? ` ${className}` : ""}`,
|
|
5100
|
+
style: panelStyle,
|
|
5101
|
+
role: "dialog",
|
|
5102
|
+
"aria-label": title,
|
|
5103
|
+
children: [
|
|
5104
|
+
/* @__PURE__ */ jsxs(
|
|
5105
|
+
"div",
|
|
5106
|
+
{
|
|
5107
|
+
className: "rk-widget-header",
|
|
5108
|
+
onPointerDown: onHeaderPointerDown,
|
|
5109
|
+
onPointerMove: onHeaderPointerMove,
|
|
5110
|
+
onPointerUp: endHeaderPointer,
|
|
5111
|
+
onPointerCancel: endHeaderPointer,
|
|
5112
|
+
children: [
|
|
5113
|
+
/* @__PURE__ */ jsx("span", { className: "rk-widget-title", children: title }),
|
|
5114
|
+
/* @__PURE__ */ jsxs("div", { className: "rk-widget-header-actions", children: [
|
|
5115
|
+
headerActions,
|
|
5116
|
+
/* @__PURE__ */ jsx(
|
|
5117
|
+
"button",
|
|
5118
|
+
{
|
|
5119
|
+
type: "button",
|
|
5120
|
+
className: "rk-widget-close",
|
|
5121
|
+
onClick: () => setOpen(false),
|
|
5122
|
+
"aria-label": `Close ${title}`,
|
|
5123
|
+
children: "\xD7"
|
|
5124
|
+
}
|
|
5125
|
+
)
|
|
5126
|
+
] })
|
|
5127
|
+
]
|
|
5128
|
+
}
|
|
5129
|
+
),
|
|
5130
|
+
/* @__PURE__ */ jsx("div", { className: "rk-widget-body", children }),
|
|
5131
|
+
/* @__PURE__ */ jsx(
|
|
5132
|
+
"div",
|
|
5133
|
+
{
|
|
5134
|
+
className: "rk-widget-resize",
|
|
5135
|
+
onPointerDown: onResizePointerDown,
|
|
5136
|
+
onPointerMove: onResizePointerMove,
|
|
5137
|
+
onPointerUp: endResizePointer,
|
|
5138
|
+
onPointerCancel: endResizePointer,
|
|
5139
|
+
role: "separator",
|
|
5140
|
+
"aria-label": "Resize",
|
|
5141
|
+
"aria-orientation": "horizontal"
|
|
5142
|
+
}
|
|
5143
|
+
)
|
|
5144
|
+
]
|
|
5145
|
+
}
|
|
5146
|
+
);
|
|
5147
|
+
}
|
|
5148
|
+
function LauncherIcon() {
|
|
5149
|
+
return /* @__PURE__ */ jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
|
|
5150
|
+
"path",
|
|
5151
|
+
{
|
|
5152
|
+
d: "M21 11.5a8.38 8.38 0 0 1-8.5 8.5 9.3 9.3 0 0 1-4-.9L3 21l1.9-5.5a8.38 8.38 0 0 1-.9-4A8.5 8.5 0 0 1 12.5 3 8.38 8.38 0 0 1 21 11.5Z",
|
|
5153
|
+
stroke: "currentColor",
|
|
5154
|
+
strokeWidth: "1.8",
|
|
5155
|
+
strokeLinecap: "round",
|
|
5156
|
+
strokeLinejoin: "round"
|
|
5157
|
+
}
|
|
5158
|
+
) });
|
|
5159
|
+
}
|
|
5160
|
+
|
|
5161
|
+
// src/download.ts
|
|
5162
|
+
var MIME = {
|
|
5163
|
+
CSV: "text/csv",
|
|
5164
|
+
JSON: "application/json",
|
|
5165
|
+
TXT: "text/plain"
|
|
5166
|
+
};
|
|
5167
|
+
function inBrowser() {
|
|
5168
|
+
return typeof document !== "undefined" && typeof URL !== "undefined";
|
|
5169
|
+
}
|
|
5170
|
+
function triggerDownload(blob, filename) {
|
|
5171
|
+
if (!inBrowser()) return;
|
|
5172
|
+
const url = URL.createObjectURL(blob);
|
|
5173
|
+
const a = document.createElement("a");
|
|
5174
|
+
a.href = url;
|
|
5175
|
+
a.download = filename;
|
|
5176
|
+
a.rel = "noopener";
|
|
5177
|
+
document.body.appendChild(a);
|
|
5178
|
+
a.click();
|
|
5179
|
+
a.remove();
|
|
5180
|
+
setTimeout(() => URL.revokeObjectURL(url), 0);
|
|
5181
|
+
}
|
|
5182
|
+
function performDownload(action) {
|
|
5183
|
+
if (!inBrowser()) return false;
|
|
5184
|
+
const { data, format, filename } = action;
|
|
5185
|
+
if (data === null || data === void 0) return false;
|
|
5186
|
+
const fmt = typeof format === "string" ? format.toUpperCase() : void 0;
|
|
5187
|
+
let blob;
|
|
5188
|
+
let name = filename;
|
|
5189
|
+
if (data instanceof Blob) {
|
|
5190
|
+
blob = data;
|
|
5191
|
+
name ?? (name = "download");
|
|
5192
|
+
} else if (typeof data === "string") {
|
|
5193
|
+
const mime = fmt && MIME[fmt] || "text/plain";
|
|
5194
|
+
blob = new Blob([data], { type: `${mime};charset=utf-8` });
|
|
5195
|
+
name ?? (name = `download.${(fmt ?? "TXT").toLowerCase()}`);
|
|
5196
|
+
} else {
|
|
5197
|
+
blob = new Blob([JSON.stringify(data, null, 2)], {
|
|
5198
|
+
type: "application/json;charset=utf-8"
|
|
5199
|
+
});
|
|
5200
|
+
name ?? (name = "download.json");
|
|
5201
|
+
}
|
|
5202
|
+
triggerDownload(blob, name);
|
|
5203
|
+
return true;
|
|
5204
|
+
}
|
|
5205
|
+
function performOpenLink(action) {
|
|
5206
|
+
if (typeof window === "undefined" || !action.href) return false;
|
|
5207
|
+
window.open(action.href, action.target ?? "_blank", "noopener,noreferrer");
|
|
5208
|
+
return true;
|
|
5209
|
+
}
|
|
5210
|
+
function runDefaultAction(action) {
|
|
5211
|
+
switch (action.type) {
|
|
5212
|
+
case "DOWNLOAD":
|
|
5213
|
+
return performDownload(action);
|
|
5214
|
+
case "OPEN_LINK":
|
|
5215
|
+
return performOpenLink(action);
|
|
5216
|
+
default:
|
|
5217
|
+
return false;
|
|
5218
|
+
}
|
|
5219
|
+
}
|
|
5220
|
+
function withDefaultActions(onAction) {
|
|
5221
|
+
return (action) => {
|
|
5222
|
+
runDefaultAction(action);
|
|
5223
|
+
onAction?.(action);
|
|
5224
|
+
};
|
|
5225
|
+
}
|
|
4977
5226
|
|
|
4978
|
-
export { AiRenderer, AiStream, ChartBlock, ErrorBoundary, ErrorView, FallbackBlock, FilterBlock, InsightBlock, KpiBlock, Markdown, RecommendationBlock, TableBlock, TextBlock, aiResponseSchema, analyticsResponseSchema, blockSchema, chartBlockSchema, chartTypeSchema, contentEventSchema, createConversation, dataSourceSchema, defaultBlockComponents, deleteConversation, errorEventSchema, errorResponseSchema, filterBlockSchema, filterDefSchema, filterTypeSchema, getConversation, getMessages, initialStreamState, insightBlockSchema, knownBlockSchema, kpiBlockSchema, kpiItemSchema, listConversations, makeErrorResponse, messageUrl, noopAction, parseAiResponse, parseBlock, parseSseEvent, progressEventSchema, progressPhaseSchema, recommendationBlockSchema, recommendationItemSchema, registerBlock, registeredBlockTypes, renameConversation, resolveBlockComponent, responseEndSchema, responseMetadataSchema, responseStartSchema, responseTypeSchema, safeParseAiResponse, severitySchema, streamMessage, streamReducer, tableBlockSchema, tableColumnSchema, textBlockSchema, textFormatSchema, textResponseSchema, trendSchema, unregisterBlock, useAiStream, useChat };
|
|
5227
|
+
export { AiRenderer, AiStream, AiWidget, ChartBlock, ErrorBoundary, ErrorView, FallbackBlock, FilterBlock, InsightBlock, KpiBlock, Markdown, RecommendationBlock, TableBlock, TextBlock, aiResponseSchema, analyticsResponseSchema, blockSchema, chartBlockSchema, chartTypeSchema, contentEventSchema, createConversation, dataSourceSchema, defaultBlockComponents, deleteConversation, errorEventSchema, errorResponseSchema, filterBlockSchema, filterDefSchema, filterTypeSchema, getConversation, getMessages, initialStreamState, insightBlockSchema, knownBlockSchema, kpiBlockSchema, kpiItemSchema, listConversations, makeErrorResponse, messageUrl, noopAction, parseAiResponse, parseBlock, parseSseEvent, performDownload, performOpenLink, progressEventSchema, progressPhaseSchema, recommendationBlockSchema, recommendationItemSchema, registerBlock, registeredBlockTypes, renameConversation, resolveBlockComponent, responseEndSchema, responseMetadataSchema, responseStartSchema, responseTypeSchema, runDefaultAction, safeParseAiResponse, severitySchema, streamMessage, streamReducer, tableBlockSchema, tableColumnSchema, textBlockSchema, textFormatSchema, textResponseSchema, trendSchema, triggerDownload, unregisterBlock, useAiStream, useChat, withDefaultActions };
|
|
4979
5228
|
//# sourceMappingURL=index.js.map
|
|
4980
5229
|
//# sourceMappingURL=index.js.map
|