@sybilion/uilib 1.3.44 → 1.3.47
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/assets/logo.svg +1 -1
- package/dist/esm/components/ui/Chart/Chart.styl.js +1 -1
- package/dist/esm/components/ui/ChartAreaInteractive/ChartAreaInteractive.js +7 -1
- package/dist/esm/components/ui/Chat/ChatPrompt/ChatPrompt.js +5 -3
- package/dist/esm/components/ui/Chat/ChatPrompt/ChatPrompt.styl.js +1 -1
- package/dist/esm/components/ui/Chat/ChatPrompt/ChatPromptComposer.js +7 -3
- package/dist/esm/components/ui/Chat/ChatPrompt/chatPromptComposerInsert.js +67 -0
- package/dist/esm/components/ui/Logo/Logo.styl.js +1 -1
- package/dist/esm/components/ui/Logo/logo.svg.js +1 -1
- package/dist/esm/components/ui/Page/PageFooter/PageFooter.js +3 -2
- package/dist/esm/components/widgets/DriversComparisonChart/DriversComparisonChart.js +1 -0
- package/dist/esm/components/widgets/PerformanceChart/PerformanceTable.js +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/tiptap/slash-mention/SlashSuggestionList.styl.js +2 -2
- package/dist/esm/tiptap/slash-mention/createSlashMentionExtension.js +45 -28
- package/dist/esm/types/src/components/ui/Chat/Chat.d.ts +1 -2
- package/dist/esm/types/src/components/ui/Chat/Chat.types.d.ts +1 -1
- package/dist/esm/types/src/components/ui/Chat/ChatPrompt/ChatPrompt.d.ts +3 -1
- package/dist/esm/types/src/components/ui/Chat/ChatPrompt/ChatPromptComposer.d.ts +3 -1
- package/dist/esm/types/src/components/ui/Chat/ChatPrompt/ChatPromptComposer.types.d.ts +2 -0
- package/dist/esm/types/src/components/ui/Chat/ChatPrompt/chatPromptComposerInsert.d.ts +35 -0
- package/dist/esm/types/src/components/ui/Chat/index.d.ts +3 -0
- package/dist/esm/types/src/components/ui/Page/PageFooter/PageFooter.d.ts +1 -2
- package/dist/esm/types/src/tiptap/slash-mention/types.d.ts +7 -2
- package/package.json +8 -15
- package/src/components/ui/Chart/Chart.styl +2 -1
- package/src/components/ui/ChartAreaInteractive/ChartAreaInteractive.tsx +8 -1
- package/src/components/ui/Chat/Chat.types.ts +1 -1
- package/src/components/ui/Chat/ChatPrompt/ChatPrompt.styl +25 -0
- package/src/components/ui/Chat/ChatPrompt/ChatPrompt.tsx +94 -71
- package/src/components/ui/Chat/ChatPrompt/ChatPromptComposer.tsx +35 -10
- package/src/components/ui/Chat/ChatPrompt/ChatPromptComposer.types.ts +11 -0
- package/src/components/ui/Chat/ChatPrompt/chatPromptComposerInsert.ts +122 -0
- package/src/components/ui/Chat/index.ts +9 -0
- package/src/components/ui/Logo/Logo.styl +1 -0
- package/src/components/ui/Logo/logo.svg +1 -1
- package/src/components/ui/Page/PageFooter/PageFooter.tsx +2 -3
- package/src/docs/DocsShell.tsx +1 -6
- package/src/docs/pages/ChatSlashCommandsPage.tsx +46 -120
- package/src/tiptap/slash-mention/SlashSuggestionList.styl +4 -0
- package/src/tiptap/slash-mention/SlashSuggestionList.styl.d.ts +1 -0
- package/src/tiptap/slash-mention/createSlashMentionExtension.ts +46 -27
- package/src/tiptap/slash-mention/types.ts +7 -2
package/assets/logo.svg
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
|
|
2
|
-
<path fill="
|
|
2
|
+
<path fill="currentColor" d="M13.43 24.023h-2.836v-2.836h2.836zm-2.835-2.844H5.63v-2.74h4.965Zm10.527-2.74h-2.726v2.74h-4.965v-2.74h4.952v-4.965h2.74zm-15.5 0h-2.74v-4.965h2.74ZM2.87 13.462H.034v-2.836H2.87Zm21.096 0H21.13v-2.836h2.836zM5.617 10.635h-2.74V5.669h2.74zm15.505 0h-2.74V5.669h2.74zM10.588 2.927v2.74H5.623v-2.74Zm2.842 0h4.96v2.74h-4.966v-2.74h-2.83V.09h2.836z" style="stroke-width:.13252" />
|
|
3
3
|
</svg>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import styleInject from 'style-inject';
|
|
2
2
|
|
|
3
|
-
var css_248z = "@media (max-width:768px){:root{--page-x-padding:var(--p-6);--page-y-padding:var(--p-6)}}.Chart_chartContainer__--q1l{aspect-ratio:16/9;display:flex;font-size:.75rem;justify-content:center;line-height:1rem;max-width:100%;touch-action:none;width:100%}.Chart_chartContainer__--q1l .recharts-cartesian-axis-tick text{fill:var(--muted-foreground)}.Chart_chartContainer__--q1l .recharts-cartesian-grid line[stroke=\"#ccc\"]{stroke:var(--border)}.dark .Chart_chartContainer__--q1l .recharts-cartesian-grid line[stroke=\"#ccc\"]{stroke:var(--sb-slate-900)}.Chart_chartContainer__--q1l .recharts-curve.recharts-tooltip-cursor,.Chart_chartContainer__--q1l .recharts-polar-grid [stroke=\"#ccc\"]{stroke:var(--border)}.Chart_chartContainer__--q1l .recharts-radial-bar-background-sector,.Chart_chartContainer__--q1l .recharts-rectangle.recharts-tooltip-cursor{fill:var(--muted)}.Chart_chartContainer__--q1l .recharts-reference-line [stroke=\"#ccc\"]{stroke:var(--border)}.Chart_chartContainer__--q1l .recharts-dot[stroke=\"#fff\"]{stroke:transparent}.Chart_chartContainer__--q1l .recharts-layer,.Chart_chartContainer__--q1l .recharts-sector{outline:none}.Chart_chartContainer__--q1l .recharts-sector[stroke=\"#fff\"]{stroke:transparent}.Chart_chartContainer__--q1l .recharts-surface{outline:none}.Chart_chartContainer__--q1l .recharts-wrapper{position:relative}.Chart_chartContainer__--q1l .recharts-surface{position:relative;z-index:1}.Chart_chartContainer__--q1l .recharts-tooltip-wrapper{box-sizing:border-box;max-width:90%;z-index:3!important}.Chart_chartContainer__--q1l .recharts-active-dot{z-index:3}.Chart_chartGrid__t52WF{stroke-width:.6}.Chart_tooltipContainer__6tc0q{align-items:start;box-sizing:border-box;display:grid;max-width:min(500px,90vw);min-width:0;overflow-wrap:break-word;width:100%;word-break:break-word;grid-gap:.375rem;backdrop-filter:blur(10px);background-color:color-mix(in srgb,var(--background)
|
|
3
|
+
var css_248z = "@media (max-width:768px){:root{--page-x-padding:var(--p-6);--page-y-padding:var(--p-6)}}.Chart_chartContainer__--q1l{aspect-ratio:16/9;display:flex;font-size:.75rem;justify-content:center;line-height:1rem;max-width:100%;touch-action:none;width:100%}.Chart_chartContainer__--q1l .recharts-cartesian-axis-tick text{fill:var(--muted-foreground)}.Chart_chartContainer__--q1l .recharts-cartesian-grid line[stroke=\"#ccc\"]{stroke:var(--border)}.dark .Chart_chartContainer__--q1l .recharts-cartesian-grid line[stroke=\"#ccc\"]{stroke:var(--sb-slate-900)}.Chart_chartContainer__--q1l .recharts-curve.recharts-tooltip-cursor,.Chart_chartContainer__--q1l .recharts-polar-grid [stroke=\"#ccc\"]{stroke:var(--border)}.Chart_chartContainer__--q1l .recharts-radial-bar-background-sector,.Chart_chartContainer__--q1l .recharts-rectangle.recharts-tooltip-cursor{fill:var(--muted)}.Chart_chartContainer__--q1l .recharts-reference-line [stroke=\"#ccc\"]{stroke:var(--border)}.Chart_chartContainer__--q1l .recharts-dot[stroke=\"#fff\"]{stroke:transparent}.Chart_chartContainer__--q1l .recharts-layer,.Chart_chartContainer__--q1l .recharts-sector{outline:none}.Chart_chartContainer__--q1l .recharts-sector[stroke=\"#fff\"]{stroke:transparent}.Chart_chartContainer__--q1l .recharts-surface{outline:none}.Chart_chartContainer__--q1l .recharts-wrapper{position:relative}.Chart_chartContainer__--q1l .recharts-surface{position:relative;z-index:1}.Chart_chartContainer__--q1l .recharts-tooltip-wrapper{box-sizing:border-box;max-width:90%;z-index:3!important}.Chart_chartContainer__--q1l .recharts-active-dot{z-index:3}.Chart_chartGrid__t52WF{stroke-width:.6}.Chart_tooltipContainer__6tc0q{align-items:start;box-sizing:border-box;display:grid;max-width:min(500px,90vw);min-width:0;overflow-wrap:break-word;width:100%;word-break:break-word;grid-gap:.375rem;backdrop-filter:blur(10px);background-color:color-mix(in srgb,var(--background) 70%,transparent);border:1px solid var(--border)/.5;border-radius:.5rem;box-shadow:0 10px 10px -5px rgba(0,0,0,.2),0 0 1px 0 var(--muted-foreground);font-size:.75rem;gap:.375rem;line-height:1rem;opacity:0;padding:.375rem .625rem;transition:opacity .5s ease-out}.dark .Chart_tooltipContainer__6tc0q{background-color:color-mix(in srgb,var(--background) 50%,transparent);box-shadow:0 0 1px 0 var(--sb-slate-700),0 10px 10px -5px rgba(0,0,0,.7)}.Chart_chartContainer__--q1l:hover .Chart_tooltipContainer__6tc0q{opacity:1;transition-duration:.5s}.Chart_tooltipItem__j8I9T{align-items:stretch;display:flex;flex-wrap:wrap;gap:.5rem;width:100%}.Chart_tooltipItem__j8I9T>svg{color:var(--muted-foreground);height:.625rem;width:.625rem}.Chart_tooltipIndicator__Z-JWp{background-color:var(--color-bg);border-color:var(--color-border);border-radius:2px;border-width:1px;flex-shrink:0}.Chart_tooltipIndicator__Z-JWp.Chart_indicator-dot__MWcmW{height:.625rem;width:.625rem}.Chart_tooltipIndicator__Z-JWp.Chart_indicator-line__MO3ul{width:.25rem}.Chart_tooltipIndicator__Z-JWp.Chart_indicator-dashed__2LqIN{background-color:transparent;border-style:dashed;border-width:1.5px;width:0}.Chart_tooltipIndicator__Z-JWp.Chart_indicator-dashed__2LqIN.Chart_nested__7EWWk{margin-bottom:.125rem;margin-top:.125rem}.Chart_tooltipContent__M3R-W{display:flex;flex:1 1 0%;justify-content:space-between;line-height:1;min-width:0}.Chart_tooltipLabel__zMpjZ{display:grid;min-width:0;grid-gap:.375rem;gap:.375rem}.Chart_tooltipLabelText__45osJ{display:-webkit-box;-webkit-line-clamp:3;max-width:100%;min-width:0;overflow:hidden;word-break:break-word;-webkit-box-orient:vertical}.Chart_tooltipValue__vTQxU{color:var(--foreground);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:\"tnum\";font-variant-numeric:tabular-nums;font-weight:500;margin-left:var(--p-3);white-space:nowrap}.Chart_legendContainer__u1J3U{align-items:center;display:flex;gap:1rem;justify-content:center}.Chart_legendItem__0CSyC{align-items:center;display:flex;gap:.375rem}.Chart_legendItem__0CSyC>svg{color:var(--muted-foreground);height:.75rem;width:.75rem}.Chart_legendIndicator__erzzP{border-radius:2px;flex-shrink:0;height:.5rem;width:.5rem}.chart-line-blinking path{animation:chart-line-blink 1s ease-in-out infinite;animation-direction:alternate}@keyframes Chart_chart-line-blink__4EI-g{0%{opacity:.5}to{opacity:1}}";
|
|
4
4
|
var S = {"chartContainer":"Chart_chartContainer__--q1l","chartGrid":"Chart_chartGrid__t52WF","tooltipContainer":"Chart_tooltipContainer__6tc0q","tooltipItem":"Chart_tooltipItem__j8I9T","tooltipIndicator":"Chart_tooltipIndicator__Z-JWp","indicator-dot":"Chart_indicator-dot__MWcmW","indicator-line":"Chart_indicator-line__MO3ul","indicator-dashed":"Chart_indicator-dashed__2LqIN","nested":"Chart_nested__7EWWk","tooltipContent":"Chart_tooltipContent__M3R-W","tooltipLabel":"Chart_tooltipLabel__zMpjZ","tooltipLabelText":"Chart_tooltipLabelText__45osJ","tooltipValue":"Chart_tooltipValue__vTQxU","legendContainer":"Chart_legendContainer__u1J3U","legendItem":"Chart_legendItem__0CSyC","legendIndicator":"Chart_legendIndicator__erzzP","chart-line-blink":"Chart_chart-line-blink__4EI-g"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
@@ -42,7 +42,13 @@ function ChartAreaInteractive({ className, chartContainerClassName, legendClassN
|
|
|
42
42
|
const timeFilteredChartData = useMemo(() => {
|
|
43
43
|
const raw = selectedAnalysisId ?? selectedForecast?.id ?? null;
|
|
44
44
|
const anchorId = raw == null ? null : typeof raw === 'number' ? raw : Number(raw);
|
|
45
|
-
const
|
|
45
|
+
const anchorForecastLoaded = anchorId != null &&
|
|
46
|
+
Number.isFinite(anchorId) &&
|
|
47
|
+
chartData.some(row => {
|
|
48
|
+
const value = row[`forecast_${anchorId}`];
|
|
49
|
+
return typeof value === 'number' && Number.isFinite(value);
|
|
50
|
+
});
|
|
51
|
+
const opts = anchorId != null && Number.isFinite(anchorId) && anchorForecastLoaded
|
|
46
52
|
? { endDateAnchorAnalysisId: anchorId }
|
|
47
53
|
: undefined;
|
|
48
54
|
return filterDataForTimeRange(chartData, timeRange, opts);
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import cn from 'classnames';
|
|
3
|
-
import { useRef, useCallback } from 'react';
|
|
3
|
+
import { forwardRef, useRef, useImperativeHandle, useCallback } from 'react';
|
|
4
4
|
import S from './ChatPrompt.styl.js';
|
|
5
5
|
import { ChatPromptAttachments } from './ChatPromptAttachments.js';
|
|
6
6
|
import { ChatPromptComposer } from './ChatPromptComposer.js';
|
|
7
|
+
import { createChatPromptComposerHandle } from './chatPromptComposerInsert.js';
|
|
7
8
|
import { useChatPromptEditor } from './useChatPromptEditor.js';
|
|
8
9
|
|
|
9
|
-
function ChatPrompt({ onSubmit, placeholder, className, footer, prefillMessage, slashCommandItems, onSlashItemCommand, attachments = [], onRemoveAttachment, disabled = false, attachmentAccept, onAttachmentFiles, }) {
|
|
10
|
+
const ChatPrompt = forwardRef(function ChatPrompt({ onSubmit, placeholder, className, footer, prefillMessage, slashCommandItems, onSlashItemCommand, attachments = [], onRemoveAttachment, disabled = false, attachmentAccept, onAttachmentFiles, }, ref) {
|
|
10
11
|
const attachmentsCount = attachments.length;
|
|
11
12
|
const emitSubmitRef = useRef(() => { });
|
|
12
13
|
const { editor, trimmedMessage, resetAfterSend } = useChatPromptEditor({
|
|
@@ -18,6 +19,7 @@ function ChatPrompt({ onSubmit, placeholder, className, footer, prefillMessage,
|
|
|
18
19
|
attachmentsCount,
|
|
19
20
|
onEnterSubmit: () => emitSubmitRef.current(),
|
|
20
21
|
});
|
|
22
|
+
useImperativeHandle(ref, () => (editor ? createChatPromptComposerHandle(editor) : null), [editor]);
|
|
21
23
|
const emitSubmitAndClear = useCallback(() => {
|
|
22
24
|
if (!editor)
|
|
23
25
|
return;
|
|
@@ -43,6 +45,6 @@ function ChatPrompt({ onSubmit, placeholder, className, footer, prefillMessage,
|
|
|
43
45
|
return null;
|
|
44
46
|
}
|
|
45
47
|
return (jsxs("form", { onSubmit: handleSubmitForm, className: cn(S.root, className), children: [jsx(ChatPromptAttachments, { attachments: attachments, onRemove: index => onRemoveAttachment?.(index), disabled: disabled }), jsx(ChatPromptComposer, { editor: editor, disabled: disabled, trimmedMessage: trimmedMessage, attachments: attachments, attachmentAccept: attachmentAccept, onAttachmentFiles: onAttachmentFiles }), footer] }));
|
|
46
|
-
}
|
|
48
|
+
});
|
|
47
49
|
|
|
48
50
|
export { ChatPrompt };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import styleInject from 'style-inject';
|
|
2
2
|
|
|
3
|
-
var css_248z = "@media (max-width:768px){:root{--page-x-padding:var(--p-6);--page-y-padding:var(--p-6)}}.ChatPrompt_root__5G5bq{align-items:stretch;display:flex;flex-direction:column;gap:var(--p-2);padding:var(--p-6);padding-top:var(--p-5);position:relative}.ChatPrompt_composer__H3c3N{align-items:flex-end;display:flex;flex-direction:row;gap:var(--p-3);position:relative;width:100%}.ChatPrompt_fileInput__xdgPn{display:none}.ChatPrompt_attachButton__gi-qF{align-self:flex-end;flex-shrink:0}.ChatPrompt_editorWrap__Q7gat{align-self:stretch;flex:1;min-width:0}.ChatPrompt_editorMount__Phh4D{background:transparent;border:none;border-radius:0!important;box-shadow:none!important;display:flex;flex:1;flex-direction:column;max-height:200px;min-height:40px;min-width:0;padding:0!important}.ChatPrompt_editorMount__Phh4D:focus-within{box-shadow:none!important}.ChatPrompt_editorMount__Phh4D .ProseMirror{border:none!important;box-shadow:none!important;flex:1;margin:0;max-height:200px!important;min-height:40px!important;outline:none!important;overflow-x:hidden!important;overflow-y:auto!important;padding:var(--p-2) 0 0!important;resize:none!important;white-space:pre-wrap;word-break:break-word}.ChatPrompt_editorMount__Phh4D .ProseMirror p.is-empty.is-editor-empty:before{color:var(--muted-foreground);content:attr(data-placeholder);float:left;height:0;pointer-events:none}.ChatPrompt_submitColumn__0rY1R{align-items:center;display:flex;flex-direction:column;flex-shrink:0;justify-content:flex-end}.ChatPrompt_submitColumn__0rY1R>button:focus{box-shadow:0 0 0 2px var(--brand-color-500)!important}.ChatPrompt_submitColumn__0rY1R>button:first-child{border:none;position:relative;transition:all .2s}.ChatPrompt_submitColumn__0rY1R>button:first-child:focus{transform:scale(1.2)}.ChatPrompt_submitColumn__0rY1R>button:first-child:before{bottom:-100%;content:\"\";left:-100%;position:absolute;right:-100%;top:-100%}.ChatPrompt_attachments__KG-fG{display:flex;flex-wrap:wrap;gap:var(--p-2);margin-bottom:var(--p-2)}.ChatPrompt_attachmentItem__QJk7J{flex:1 1 300px;max-width:300px;min-width:0}";
|
|
3
|
+
var css_248z = "@media (max-width:768px){:root{--page-x-padding:var(--p-6);--page-y-padding:var(--p-6)}}.ChatPrompt_root__5G5bq{align-items:stretch;display:flex;flex-direction:column;gap:var(--p-2);padding:var(--p-6);padding-top:var(--p-5);position:relative}.ChatPrompt_composer__H3c3N{align-items:flex-end;display:flex;flex-direction:row;gap:var(--p-3);position:relative;width:100%}.ChatPrompt_fileInput__xdgPn{display:none}.ChatPrompt_attachButton__gi-qF{align-self:flex-end;flex-shrink:0}.ChatPrompt_editorWrap__Q7gat{align-self:stretch;flex:1;min-width:0}.ChatPrompt_editorMount__Phh4D{background:transparent;border:none;border-radius:0!important;box-shadow:none!important;display:flex;flex:1;flex-direction:column;max-height:200px;min-height:40px;min-width:0;padding:0!important}.ChatPrompt_editorMount__Phh4D:focus-within{box-shadow:none!important}.ChatPrompt_editorMount__Phh4D .ProseMirror{border:none!important;box-shadow:none!important;flex:1;margin:0;max-height:200px!important;min-height:40px!important;outline:none!important;overflow-x:hidden!important;overflow-y:auto!important;padding:var(--p-2) 0 0!important;resize:none!important;white-space:pre-wrap;word-break:break-word}.ChatPrompt_editorMount__Phh4D .ProseMirror p.is-empty.is-editor-empty:before{color:var(--muted-foreground);content:attr(data-placeholder);float:left;height:0;pointer-events:none}.ChatPrompt_editorMount__Phh4D .ProseMirror .chat-prompt-command-chip,.ChatPrompt_editorMount__Phh4D .ProseMirror .slash-mention{align-items:center;background:var(--muted);border-radius:var(--radius-sm);display:inline-flex;font-size:.875em;line-height:1.4;padding:0 var(--p-1);-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:baseline;white-space:nowrap}.ChatPrompt_editorMount__Phh4D .ProseMirror .chat-prompt-command-chip{color:var(--foreground)}.ChatPrompt_submitColumn__0rY1R{align-items:center;display:flex;flex-direction:column;flex-shrink:0;justify-content:flex-end}.ChatPrompt_submitColumn__0rY1R>button:focus{box-shadow:0 0 0 2px var(--brand-color-500)!important}.ChatPrompt_submitColumn__0rY1R>button:first-child{border:none;position:relative;transition:all .2s}.ChatPrompt_submitColumn__0rY1R>button:first-child:focus{transform:scale(1.2)}.ChatPrompt_submitColumn__0rY1R>button:first-child:before{bottom:-100%;content:\"\";left:-100%;position:absolute;right:-100%;top:-100%}.ChatPrompt_attachments__KG-fG{display:flex;flex-wrap:wrap;gap:var(--p-2);margin-bottom:var(--p-2)}.ChatPrompt_attachmentItem__QJk7J{flex:1 1 300px;max-width:300px;min-width:0}";
|
|
4
4
|
var S = {"root":"ChatPrompt_root__5G5bq","composer":"ChatPrompt_composer__H3c3N","fileInput":"ChatPrompt_fileInput__xdgPn","attachButton":"ChatPrompt_attachButton__gi-qF","editorWrap":"ChatPrompt_editorWrap__Q7gat","editorMount":"ChatPrompt_editorMount__Phh4D","submitColumn":"ChatPrompt_submitColumn__0rY1R","attachments":"ChatPrompt_attachments__KG-fG","attachmentItem":"ChatPrompt_attachmentItem__QJk7J"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { useRef, useCallback } from 'react';
|
|
2
|
+
import { forwardRef, useRef, useImperativeHandle, useCallback } from 'react';
|
|
3
3
|
import { EditorContent } from '@tiptap/react';
|
|
4
4
|
import { PaperclipIcon, SendHorizontalIcon } from 'lucide-react';
|
|
5
5
|
import { Button } from '../../Button/Button.js';
|
|
6
6
|
import S from './ChatPrompt.styl.js';
|
|
7
|
+
import { createChatPromptComposerHandle } from './chatPromptComposerInsert.js';
|
|
7
8
|
|
|
8
|
-
function ChatPromptComposer({ editor, disabled, trimmedMessage, attachments, attachmentAccept, onAttachmentFiles, }) {
|
|
9
|
+
const ChatPromptComposer = forwardRef(function ChatPromptComposer({ editor, disabled, trimmedMessage, attachments, attachmentAccept, onAttachmentFiles, }, ref) {
|
|
9
10
|
const fileInputRef = useRef(null);
|
|
10
11
|
const showAttachButton = Boolean(attachmentAccept && onAttachmentFiles);
|
|
12
|
+
useImperativeHandle(ref, () => createChatPromptComposerHandle(editor), [
|
|
13
|
+
editor,
|
|
14
|
+
]);
|
|
11
15
|
const handleFileInputChange = useCallback((e) => {
|
|
12
16
|
const files = Array.from(e.target.files ?? []);
|
|
13
17
|
e.target.value = '';
|
|
@@ -20,6 +24,6 @@ function ChatPromptComposer({ editor, disabled, trimmedMessage, attachments, att
|
|
|
20
24
|
e.preventDefault();
|
|
21
25
|
fileInputRef.current?.click();
|
|
22
26
|
}, children: jsx(PaperclipIcon, { size: 16 }) })] })) : null, jsx("div", { className: S.editorWrap, children: jsx(EditorContent, { editor: editor, className: S.editorMount }) }), jsx("div", { className: S.submitColumn, children: jsx(Button, { type: "submit", size: "sm", disabled: disabled || !canSubmit, onMouseDown: e => e.preventDefault(), children: jsx(SendHorizontalIcon, { size: 16 }) }) })] }));
|
|
23
|
-
}
|
|
27
|
+
});
|
|
24
28
|
|
|
25
29
|
export { ChatPromptComposer };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/** Global class for inline command chips inserted via `insertAtCaret`. */
|
|
2
|
+
const CHAT_PROMPT_COMMAND_CHIP_CLASS = 'chat-prompt-command-chip';
|
|
3
|
+
/** Range of the unfinished token immediately before `pos` (back to space or line start). */
|
|
4
|
+
function getChatPromptTokenRangeBeforePos(editor, pos) {
|
|
5
|
+
const $pos = editor.state.doc.resolve(pos);
|
|
6
|
+
const textBefore = $pos.parent.textBetween(0, $pos.parentOffset, undefined, '\ufffc');
|
|
7
|
+
const token = textBefore.match(/[^\s]*$/)?.[0] ?? '';
|
|
8
|
+
return { from: pos - token.length, to: pos };
|
|
9
|
+
}
|
|
10
|
+
function escapeHtml(text) {
|
|
11
|
+
return text
|
|
12
|
+
.replaceAll('&', '&')
|
|
13
|
+
.replaceAll('<', '<')
|
|
14
|
+
.replaceAll('>', '>')
|
|
15
|
+
.replaceAll('"', '"');
|
|
16
|
+
}
|
|
17
|
+
/** Build inline chip HTML for `insertAtCaret` (uses global `CHAT_PROMPT_COMMAND_CHIP_CLASS`). */
|
|
18
|
+
function chatPromptChipHtml(text, className = CHAT_PROMPT_COMMAND_CHIP_CLASS) {
|
|
19
|
+
const cls = className ? ` class="${className}"` : '';
|
|
20
|
+
return `<span${cls} data-chat-prompt-chip="true">${escapeHtml(text)}</span>`;
|
|
21
|
+
}
|
|
22
|
+
function insertChatPromptContentAtCaret(editor, content, options) {
|
|
23
|
+
if (editor.isDestroyed)
|
|
24
|
+
return;
|
|
25
|
+
const { replaceRange, replaceTriggerToken = true, trailingSpace = true, } = options ?? {};
|
|
26
|
+
const { from: selFrom, to: selTo } = editor.state.selection;
|
|
27
|
+
let from;
|
|
28
|
+
let to;
|
|
29
|
+
if (replaceRange) {
|
|
30
|
+
from = replaceRange.from;
|
|
31
|
+
to = replaceRange.to;
|
|
32
|
+
}
|
|
33
|
+
else if (replaceTriggerToken) {
|
|
34
|
+
({ from, to } = getChatPromptTokenRangeBeforePos(editor, selFrom));
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
from = selFrom;
|
|
38
|
+
to = selTo;
|
|
39
|
+
}
|
|
40
|
+
const chain = editor.chain().focus().deleteRange({ from, to });
|
|
41
|
+
if (typeof content === 'string') {
|
|
42
|
+
chain.insertContentAt(from, trailingSpace ? `${content} ` : content);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
chain.insertContentAt(from, content);
|
|
46
|
+
if (trailingSpace) {
|
|
47
|
+
chain.insertContent(' ');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
chain.run();
|
|
51
|
+
queueMicrotask(() => {
|
|
52
|
+
editor.view.dom.ownerDocument?.defaultView
|
|
53
|
+
?.getSelection?.()
|
|
54
|
+
?.collapseToEnd();
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
function createChatPromptComposerHandle(editor) {
|
|
58
|
+
return {
|
|
59
|
+
insertAtCaret: (content, options) => insertChatPromptContentAtCaret(editor, content, options),
|
|
60
|
+
focus: () => {
|
|
61
|
+
editor.commands.focus();
|
|
62
|
+
},
|
|
63
|
+
getEditor: () => editor,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export { CHAT_PROMPT_COMMAND_CHIP_CLASS, chatPromptChipHtml, createChatPromptComposerHandle, getChatPromptTokenRangeBeforePos, insertChatPromptContentAtCaret };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import styleInject from 'style-inject';
|
|
2
2
|
|
|
3
|
-
var css_248z = ".Logo_root__-IFVw{align-items:center;color:var(--color-foreground);display:flex;gap:8px}.Logo_icon__cE1BI{display:block;flex-shrink:0;height:24px;width:auto}.Logo_text__YpU3U{font-family:var(--font-family-heading);line-height:48px}.Logo_sm__p25D- .Logo_icon__cE1BI{height:18px}.Logo_sm__p25D- .Logo_text__YpU3U{font-size:var(--text-lg);line-height:36px}.Logo_md__1Y9mG .Logo_icon__cE1BI{height:24px}.Logo_md__1Y9mG .Logo_text__YpU3U{font-size:var(--text-2xl);line-height:48px}.Logo_lg__V9Yy2 .Logo_icon__cE1BI{height:32px}.Logo_lg__V9Yy2 .Logo_text__YpU3U{font-size:var(--text-3xl);line-height:56px}";
|
|
3
|
+
var css_248z = ".Logo_root__-IFVw{align-items:center;color:var(--color-foreground);display:flex;gap:8px}.Logo_icon__cE1BI{color:var(--brand-color);display:block;flex-shrink:0;height:24px;width:auto}.Logo_text__YpU3U{font-family:var(--font-family-heading);line-height:48px}.Logo_sm__p25D- .Logo_icon__cE1BI{height:18px}.Logo_sm__p25D- .Logo_text__YpU3U{font-size:var(--text-lg);line-height:36px}.Logo_md__1Y9mG .Logo_icon__cE1BI{height:24px}.Logo_md__1Y9mG .Logo_text__YpU3U{font-size:var(--text-2xl);line-height:48px}.Logo_lg__V9Yy2 .Logo_icon__cE1BI{height:32px}.Logo_lg__V9Yy2 .Logo_text__YpU3U{font-size:var(--text-3xl);line-height:56px}";
|
|
4
4
|
var S = {"root":"Logo_root__-IFVw","icon":"Logo_icon__cE1BI","text":"Logo_text__YpU3U","sm":"Logo_sm__p25D-","md":"Logo_md__1Y9mG","lg":"Logo_lg__V9Yy2"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
@@ -7,7 +7,7 @@ var SvgLogo = function SvgLogo(props) {
|
|
|
7
7
|
viewBox: "0 0 24 24",
|
|
8
8
|
fill: "none"
|
|
9
9
|
}, props), /*#__PURE__*/React.createElement("path", {
|
|
10
|
-
fill: "
|
|
10
|
+
fill: "currentColor",
|
|
11
11
|
d: "M13.43 24.023h-2.836v-2.836h2.836zm-2.835-2.844H5.63v-2.74h4.965Zm10.527-2.74h-2.726v2.74h-4.965v-2.74h4.952v-4.965h2.74zm-15.5 0h-2.74v-4.965h2.74ZM2.87 13.462H.034v-2.836H2.87Zm21.096 0H21.13v-2.836h2.836zM5.617 10.635h-2.74V5.669h2.74zm15.505 0h-2.74V5.669h2.74zM10.588 2.927v2.74H5.623v-2.74Zm2.842 0h4.96v2.74h-4.966v-2.74h-2.83V.09h2.836z",
|
|
12
12
|
style: {
|
|
13
13
|
strokeWidth: 0.13252
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import { Link } from 'react-router-dom';
|
|
3
|
+
import { Logo } from '../../Logo/Logo.js';
|
|
3
4
|
import { GlobeIcon, MailIcon } from 'lucide-react';
|
|
4
5
|
import S from './PageFooter.styl.js';
|
|
5
6
|
|
|
@@ -8,7 +9,7 @@ function PageFooterLinkEl({ item }) {
|
|
|
8
9
|
const openInNewTab = /^https?:\/\//i.test(url);
|
|
9
10
|
return (jsx("a", { href: url, className: S.link, ...(ariaLabel !== undefined ? { 'aria-label': ariaLabel } : {}), ...(openInNewTab ? { target: '_blank', rel: 'noreferrer' } : {}), children: label }));
|
|
10
11
|
}
|
|
11
|
-
function PageFooter({ children, versionLink, versionLabel, homeTo = '/', brandText = 'Sybilion',
|
|
12
|
+
function PageFooter({ children, versionLink, versionLabel, homeTo = '/', brandText = 'Sybilion', websiteHref = 'https://sybilion.com', mailHref = 'mailto:support@sybilion.com', copyrightText = '© 2026 Sybilion. All rights reserved.', links: linksProp, }) {
|
|
12
13
|
const resolvedLinks = linksProp !== undefined
|
|
13
14
|
? linksProp
|
|
14
15
|
: [
|
|
@@ -25,7 +26,7 @@ function PageFooter({ children, versionLink, versionLabel, homeTo = '/', brandTe
|
|
|
25
26
|
ariaLabel: 'Contact support via email',
|
|
26
27
|
},
|
|
27
28
|
];
|
|
28
|
-
return (jsx("footer", { className: S.root, children: jsxs("div", { className: S.line, children: [jsxs("div", { className: S.logo, children: [jsxs(Link, { to: homeTo, children: [
|
|
29
|
+
return (jsx("footer", { className: S.root, children: jsxs("div", { className: S.line, children: [jsxs("div", { className: S.logo, children: [jsxs(Link, { to: homeTo, children: [jsx(Logo, {}), "\u00A0", brandText] }), versionLink !== '' && (jsx("div", { className: S.version, children: jsx(Link, { to: versionLink, className: S.versionLink, children: versionLabel }) }))] }), children, jsxs("div", { className: S.meta, children: [jsx("div", { className: S.copyright, children: copyrightText }), resolvedLinks.length > 0 && (jsx("nav", { className: S.links, "aria-label": "Footer links", children: resolvedLinks.map(item => (jsx(PageFooterLinkEl, { item: item }, item.id))) }))] })] }) }));
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
export { PageFooter };
|
|
@@ -17,6 +17,7 @@ import '../../ui/Page/PageContent/PageContent.styl.js';
|
|
|
17
17
|
import '@homecode/ui';
|
|
18
18
|
import '../../ui/Page/PageScroll/PageScroll.styl.js';
|
|
19
19
|
import { PageXScroll } from '../../ui/Page/PageXScroll/PageXScroll.js';
|
|
20
|
+
import '../../ui/Logo/Logo.styl.js';
|
|
20
21
|
import '../../ui/Page/PageFooter/PageFooter.styl.js';
|
|
21
22
|
import '@radix-ui/react-tabs';
|
|
22
23
|
import '../../ui/Tabs/Tabs.styl.js';
|
|
@@ -16,6 +16,7 @@ import '../../ui/Page/PageContent/PageContent.styl.js';
|
|
|
16
16
|
import '@homecode/ui';
|
|
17
17
|
import '../../ui/Page/PageScroll/PageScroll.styl.js';
|
|
18
18
|
import { PageXScroll } from '../../ui/Page/PageXScroll/PageXScroll.js';
|
|
19
|
+
import '../../ui/Logo/Logo.styl.js';
|
|
19
20
|
import '../../ui/Page/PageFooter/PageFooter.styl.js';
|
|
20
21
|
import '@radix-ui/react-tabs';
|
|
21
22
|
import '../../ui/Tabs/Tabs.styl.js';
|
package/dist/esm/index.js
CHANGED
|
@@ -31,6 +31,7 @@ export { ChatSheet } from './components/ui/Chat/ChatSheet/ChatSheet.js';
|
|
|
31
31
|
export { useChatPanelChromeModel } from './components/ui/Chat/ChatSheet/useChatPanelChromeModel.js';
|
|
32
32
|
export { ChatMessage } from './components/ui/Chat/ChatMessage/ChatMessage.js';
|
|
33
33
|
export { ChatPrompt } from './components/ui/Chat/ChatPrompt/ChatPrompt.js';
|
|
34
|
+
export { CHAT_PROMPT_COMMAND_CHIP_CLASS, chatPromptChipHtml, createChatPromptComposerHandle, getChatPromptTokenRangeBeforePos, insertChatPromptContentAtCaret } from './components/ui/Chat/ChatPrompt/chatPromptComposerInsert.js';
|
|
34
35
|
export { ChatPresets } from './components/ui/Chat/ChatPresets/ChatPresets.js';
|
|
35
36
|
export { MessageRole } from './components/ui/Chat/Chat.types.js';
|
|
36
37
|
export { CsvIcon } from './components/icons/CsvIcon/CsvIcon.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import styleInject from 'style-inject';
|
|
2
2
|
|
|
3
|
-
var css_248z = "@media (max-width:768px){:root{--page-x-padding:var(--p-6);--page-y-padding:var(--p-6)}}.SlashSuggestionList_root__9KCb1{background:var(--popover,var(--card));border:1px solid var(--border);border-radius:8px;border-radius:var(--radius-lg,8px);box-shadow:0 8px 24px rgba(0,0,0,.12);color:var(--foreground);display:flex;flex-direction:column;font-size:var(--text-sm);list-style:none;margin:0;max-height:40vh;max-width:90vw;min-width:220px;overflow-y:auto;padding:var(--p-1)}.dark .SlashSuggestionList_root__9KCb1{box-shadow:0 8px 24px rgba(0,0,0,.5)}.SlashSuggestionList_item__9JBeY{align-items:flex-start;background:transparent;border:none;border-radius:6px;border-radius:var(--radius-md,6px);color:inherit;cursor:pointer;display:flex;flex-direction:column;margin:0;padding:var(--p-1) var(--p-2);text-align:left;width:100%}.SlashSuggestionList_itemHighlighted__cStZr,.SlashSuggestionList_item__9JBeY:hover{background:var(--muted)}.SlashSuggestionList_itemLabel__OMaov{font-weight:600}.SlashSuggestionList_itemDesc__fAdcA{color:var(--muted-foreground);font-size:var(--text-xs)}";
|
|
4
|
-
var S = {"root":"SlashSuggestionList_root__9KCb1","item":"SlashSuggestionList_item__9JBeY","itemHighlighted":"SlashSuggestionList_itemHighlighted__cStZr","itemLabel":"SlashSuggestionList_itemLabel__OMaov","itemDesc":"SlashSuggestionList_itemDesc__fAdcA"};
|
|
3
|
+
var css_248z = "@media (max-width:768px){:root{--page-x-padding:var(--p-6);--page-y-padding:var(--p-6)}}.SlashSuggestionList_root__9KCb1{background:var(--popover,var(--card));border:1px solid var(--border);border-radius:8px;border-radius:var(--radius-lg,8px);box-shadow:0 8px 24px rgba(0,0,0,.12);color:var(--foreground);display:flex;flex-direction:column;font-size:var(--text-sm);list-style:none;margin:0;max-height:40vh;max-width:90vw;min-width:220px;overflow-y:auto;padding:var(--p-1)}.dark .SlashSuggestionList_root__9KCb1{box-shadow:0 8px 24px rgba(0,0,0,.5)}.SlashSuggestionList_item__9JBeY{align-items:flex-start;background:transparent;border:none;border-radius:6px;border-radius:var(--radius-md,6px);color:inherit;cursor:pointer;display:flex;flex-direction:column;margin:0;padding:var(--p-1) var(--p-2);text-align:left;width:100%}.SlashSuggestionList_itemHighlighted__cStZr,.SlashSuggestionList_item__9JBeY:hover{background:var(--muted)}.SlashSuggestionList_itemLabel__OMaov{font-weight:600}.SlashSuggestionList_itemDesc__fAdcA{color:var(--muted-foreground);font-size:var(--text-xs)}.SlashSuggestionList_mention__aT45p{border-radius:.3em;padding:0 .3em}";
|
|
4
|
+
var S = {"root":"SlashSuggestionList_root__9KCb1","item":"SlashSuggestionList_item__9JBeY","itemHighlighted":"SlashSuggestionList_itemHighlighted__cStZr","itemLabel":"SlashSuggestionList_itemLabel__OMaov","itemDesc":"SlashSuggestionList_itemDesc__fAdcA","mention":"SlashSuggestionList_mention__aT45p"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
7
7
|
export { S as default };
|
|
@@ -2,8 +2,34 @@ import { mergeAttributes } from '@tiptap/core';
|
|
|
2
2
|
import Mention from '@tiptap/extension-mention';
|
|
3
3
|
import { ReactRenderer } from '@tiptap/react';
|
|
4
4
|
import { SlashSuggestionList } from './SlashSuggestionList.js';
|
|
5
|
+
import S from './SlashSuggestionList.styl.js';
|
|
5
6
|
import { filterSlashItems } from './defaultChatSlashItems.js';
|
|
6
7
|
|
|
8
|
+
const SlashMention = Mention.extend({
|
|
9
|
+
addAttributes() {
|
|
10
|
+
return {
|
|
11
|
+
...this.parent?.(),
|
|
12
|
+
className: {
|
|
13
|
+
default: null,
|
|
14
|
+
parseHTML: element => element.getAttribute('data-slash-class'),
|
|
15
|
+
renderHTML: attributes => {
|
|
16
|
+
if (!attributes.className)
|
|
17
|
+
return {};
|
|
18
|
+
return { 'data-slash-class': attributes.className };
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
color: {
|
|
22
|
+
default: null,
|
|
23
|
+
parseHTML: element => element.getAttribute('data-slash-color'),
|
|
24
|
+
renderHTML: attributes => {
|
|
25
|
+
if (!attributes.color)
|
|
26
|
+
return {};
|
|
27
|
+
return { 'data-slash-color': attributes.color };
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
});
|
|
7
33
|
const SUGGESTION_GAP_PX = 4;
|
|
8
34
|
function placeSlashSuggestionPopup(popupElement, clientRect, placement) {
|
|
9
35
|
if (!clientRect)
|
|
@@ -68,27 +94,10 @@ function slashMentionSuggestionRender(uiRef, placement = 'below') {
|
|
|
68
94
|
onKeyDown: ({ event }) => uiRef.current?.onKeyboardEvent(event) ?? false,
|
|
69
95
|
};
|
|
70
96
|
}
|
|
71
|
-
function
|
|
72
|
-
if (
|
|
73
|
-
return;
|
|
74
|
-
|
|
75
|
-
editor.chain().focus().deleteRange(range).clearContent().run();
|
|
76
|
-
}
|
|
77
|
-
catch {
|
|
78
|
-
// Editor view may be tearing down during suggestion exit.
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
function collapseEditorSelectionEnd(editor) {
|
|
82
|
-
if (editor.isDestroyed)
|
|
83
|
-
return;
|
|
84
|
-
try {
|
|
85
|
-
editor.view?.dom?.ownerDocument?.defaultView
|
|
86
|
-
?.getSelection?.()
|
|
87
|
-
?.collapseToEnd();
|
|
88
|
-
}
|
|
89
|
-
catch {
|
|
90
|
-
// view.dom throws when editor is not mounted
|
|
91
|
-
}
|
|
97
|
+
function slashMentionChipStyle(color) {
|
|
98
|
+
if (!color)
|
|
99
|
+
return undefined;
|
|
100
|
+
return `color: ${color}; background-color: color-mix(in srgb, ${color} 30%, transparent);`;
|
|
92
101
|
}
|
|
93
102
|
function insertDefaultMention(editor, range, props, slashChar) {
|
|
94
103
|
const nodeAfter = editor.view.state.selection.$to.nodeAfter;
|
|
@@ -104,6 +113,8 @@ function insertDefaultMention(editor, range, props, slashChar) {
|
|
|
104
113
|
id: props.id,
|
|
105
114
|
label: props.label,
|
|
106
115
|
mentionSuggestionChar: slashChar,
|
|
116
|
+
className: props.className ?? null,
|
|
117
|
+
color: props.color ?? null,
|
|
107
118
|
},
|
|
108
119
|
},
|
|
109
120
|
{ type: 'text', text: ' ' },
|
|
@@ -129,23 +140,31 @@ function createSlashMentionExtension({ items: resolvedItems, slashChar = '/', pl
|
|
|
129
140
|
const uiRef = {
|
|
130
141
|
current: null,
|
|
131
142
|
};
|
|
132
|
-
return
|
|
143
|
+
return SlashMention.configure({
|
|
133
144
|
renderText({ node }) {
|
|
134
145
|
return `/${node.attrs.id}`;
|
|
135
146
|
},
|
|
136
|
-
renderHTML({ options, node
|
|
137
|
-
const suggestionChar = suggestion?.char ?? slashChar;
|
|
147
|
+
renderHTML({ options, node }) {
|
|
138
148
|
const id = typeof node.attrs.id === 'string'
|
|
139
149
|
? node.attrs.id
|
|
140
150
|
: String(node.attrs.id ?? '');
|
|
151
|
+
const label = typeof node.attrs.label === 'string' && node.attrs.label.trim() !== ''
|
|
152
|
+
? node.attrs.label
|
|
153
|
+
: id;
|
|
154
|
+
const color = typeof node.attrs.color === 'string' ? node.attrs.color : null;
|
|
155
|
+
const className = [S.mention, node.attrs.className]
|
|
156
|
+
.filter(Boolean)
|
|
157
|
+
.join(' ');
|
|
158
|
+
const chipStyle = slashMentionChipStyle(color);
|
|
141
159
|
return [
|
|
142
160
|
'span',
|
|
143
161
|
mergeAttributes({
|
|
144
162
|
'data-type': 'mention',
|
|
145
163
|
'data-slash-command': id,
|
|
146
|
-
class:
|
|
164
|
+
class: className,
|
|
165
|
+
...(chipStyle ? { style: chipStyle } : {}),
|
|
147
166
|
}, options.HTMLAttributes),
|
|
148
|
-
|
|
167
|
+
label,
|
|
149
168
|
];
|
|
150
169
|
},
|
|
151
170
|
suggestion: {
|
|
@@ -157,8 +176,6 @@ function createSlashMentionExtension({ items: resolvedItems, slashChar = '/', pl
|
|
|
157
176
|
command: ({ editor, range, props }) => {
|
|
158
177
|
const item = props;
|
|
159
178
|
if (onItemCommand?.({ editor, range, item }) === true) {
|
|
160
|
-
clearSlashTriggerEditor(editor, range);
|
|
161
|
-
queueMicrotask(() => collapseEditorSelectionEnd(editor));
|
|
162
179
|
return null;
|
|
163
180
|
}
|
|
164
181
|
insertDefaultMention(editor, range, item, slashChar);
|
|
@@ -2,10 +2,9 @@ import { ChatPresets } from '#uilib/components/ui/Chat/ChatPresets';
|
|
|
2
2
|
import type { ChatProps } from './Chat.types';
|
|
3
3
|
import { ChatEmptyState } from './ChatEmptyState/ChatEmptyState';
|
|
4
4
|
import { ChatMessage } from './ChatMessage';
|
|
5
|
-
import { ChatPrompt } from './ChatPrompt';
|
|
6
5
|
export declare function Chat({ children, className, isEmpty, scopeId, onChatDeleted, ...props }: ChatProps): import("react/jsx-runtime").JSX.Element;
|
|
7
6
|
export declare namespace Chat {
|
|
8
|
-
var Prompt:
|
|
7
|
+
var Prompt: import("react").ForwardRefExoticComponent<import("./Chat.types").ChatPromptProps & import("react").RefAttributes<import(".").ChatPromptComposerHandle>>;
|
|
9
8
|
var Message: typeof ChatMessage;
|
|
10
9
|
var Presets: typeof ChatPresets;
|
|
11
10
|
var EmptyState: typeof ChatEmptyState;
|
|
@@ -84,7 +84,7 @@ export interface ChatPromptProps {
|
|
|
84
84
|
onAttachmentFiles?: (files: File[]) => void;
|
|
85
85
|
/** Slash menu (`/`); omit or pass empty to disable Mention trigger (no default items). */
|
|
86
86
|
slashCommandItems?: SlashCommandItem[];
|
|
87
|
-
/** Custom slash pick handler; return true to skip default mention insert. */
|
|
87
|
+
/** Custom slash pick handler; return true to skip default mention insert and insert via composer API. */
|
|
88
88
|
onSlashItemCommand?: SlashOnItemCommand;
|
|
89
89
|
}
|
|
90
90
|
export interface ChatMessageProps {
|
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
import type { ChatPromptProps } from '../Chat.types';
|
|
2
|
-
|
|
2
|
+
import { type ChatPromptComposerHandle } from './ChatPromptComposer';
|
|
3
|
+
export type { ChatPromptComposerHandle } from './ChatPromptComposer';
|
|
4
|
+
export declare const ChatPrompt: import("react").ForwardRefExoticComponent<ChatPromptProps & import("react").RefAttributes<ChatPromptComposerHandle>>;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { Editor } from '@tiptap/core';
|
|
2
2
|
import type { ChatAttachmentDropItem } from '../Chat.types';
|
|
3
|
+
import { type ChatPromptComposerHandle } from './chatPromptComposerInsert';
|
|
4
|
+
export type { ChatPromptComposerHandle, ChatPromptComposerInsertOptions, } from './ChatPromptComposer.types';
|
|
3
5
|
export type ChatPromptComposerProps = {
|
|
4
6
|
editor: Editor;
|
|
5
7
|
disabled: boolean;
|
|
@@ -8,4 +10,4 @@ export type ChatPromptComposerProps = {
|
|
|
8
10
|
attachmentAccept?: string;
|
|
9
11
|
onAttachmentFiles?: (files: File[]) => void;
|
|
10
12
|
};
|
|
11
|
-
export declare
|
|
13
|
+
export declare const ChatPromptComposer: import("react").ForwardRefExoticComponent<ChatPromptComposerProps & import("react").RefAttributes<ChatPromptComposerHandle>>;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export type { ChatPromptComposerHandle, ChatPromptComposerInsertOptions, } from './chatPromptComposerInsert';
|
|
2
|
+
export { CHAT_PROMPT_COMMAND_CHIP_CLASS, chatPromptChipHtml, createChatPromptComposerHandle, getChatPromptTokenRangeBeforePos, insertChatPromptContentAtCaret, } from './chatPromptComposerInsert';
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Editor, JSONContent } from '@tiptap/core';
|
|
2
|
+
export type ChatPromptComposerInsertOptions = {
|
|
3
|
+
/**
|
|
4
|
+
* Doc range to replace before insert (e.g. slash suggestion `range` covering `/query`).
|
|
5
|
+
* When set, `replaceTriggerToken` is ignored.
|
|
6
|
+
*/
|
|
7
|
+
replaceRange?: {
|
|
8
|
+
from: number;
|
|
9
|
+
to: number;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* When true and no `replaceRange`, delete text from caret back to the preceding
|
|
13
|
+
* space or start of line before insert. Default true.
|
|
14
|
+
*/
|
|
15
|
+
replaceTriggerToken?: boolean;
|
|
16
|
+
/** Append a space after inserted content so the user can keep typing. Default true. */
|
|
17
|
+
trailingSpace?: boolean;
|
|
18
|
+
};
|
|
19
|
+
/** Global class for inline command chips inserted via `insertAtCaret`. */
|
|
20
|
+
export declare const CHAT_PROMPT_COMMAND_CHIP_CLASS = "chat-prompt-command-chip";
|
|
21
|
+
export type ChatPromptComposerHandle = {
|
|
22
|
+
/** Insert HTML string or TipTap JSON at the caret (or after clearing trigger text). */
|
|
23
|
+
insertAtCaret: (content: string | JSONContent, options?: ChatPromptComposerInsertOptions) => void;
|
|
24
|
+
focus: () => void;
|
|
25
|
+
getEditor: () => Editor;
|
|
26
|
+
};
|
|
27
|
+
/** Range of the unfinished token immediately before `pos` (back to space or line start). */
|
|
28
|
+
export declare function getChatPromptTokenRangeBeforePos(editor: Editor, pos: number): {
|
|
29
|
+
from: number;
|
|
30
|
+
to: number;
|
|
31
|
+
};
|
|
32
|
+
/** Build inline chip HTML for `insertAtCaret` (uses global `CHAT_PROMPT_COMMAND_CHIP_CLASS`). */
|
|
33
|
+
export declare function chatPromptChipHtml(text: string, className?: string): string;
|
|
34
|
+
export declare function insertChatPromptContentAtCaret(editor: Editor, content: string | JSONContent, options?: ChatPromptComposerInsertOptions): void;
|
|
35
|
+
export declare function createChatPromptComposerHandle(editor: Editor): ChatPromptComposerHandle;
|
|
@@ -11,6 +11,9 @@ export type { ChatSheetActions, ChatSheetProps } from './ChatSheet/ChatSheet';
|
|
|
11
11
|
export type { UseChatPanelChromeModelInput, UseChatPanelChromeModelResult, } from './ChatSheet/useChatPanelChromeModel';
|
|
12
12
|
export { ChatMessage } from './ChatMessage';
|
|
13
13
|
export { ChatPrompt } from './ChatPrompt';
|
|
14
|
+
export type { ChatPromptComposerHandle } from './ChatPrompt/ChatPromptComposer';
|
|
15
|
+
export { CHAT_PROMPT_COMMAND_CHIP_CLASS, chatPromptChipHtml, createChatPromptComposerHandle, getChatPromptTokenRangeBeforePos, insertChatPromptContentAtCaret, } from './ChatPrompt/chatPromptComposerInsert';
|
|
16
|
+
export type { ChatPromptComposerInsertOptions } from './ChatPrompt/ChatPromptComposer.types';
|
|
14
17
|
export { ChatPresets } from './ChatPresets';
|
|
15
18
|
export type { ChatEmptyStateConfig, ChatEmptyStateContext, ChatEmptyStateProps, } from './ChatEmptyState/ChatEmptyState.types';
|
|
16
19
|
export type { Chat as ChatType, ChatAttachmentDropItem, ChatSendMessagePayload, ChatProps, ChatPreset as ChatPresetType, Message, UserTextFileAttachment, } from './Chat.types';
|
|
@@ -7,7 +7,6 @@ export interface PageFooterLinkItem {
|
|
|
7
7
|
ariaLabel?: string;
|
|
8
8
|
}
|
|
9
9
|
export interface PageFooterProps {
|
|
10
|
-
logo?: ReactNode;
|
|
11
10
|
/** Rendered between logo block and copyright (e.g. debug UI from the app). */
|
|
12
11
|
children?: ReactNode;
|
|
13
12
|
/** When non-empty, version badge links here (e.g. `/releases`). */
|
|
@@ -25,4 +24,4 @@ export interface PageFooterProps {
|
|
|
25
24
|
*/
|
|
26
25
|
links?: PageFooterLinkItem[];
|
|
27
26
|
}
|
|
28
|
-
export declare function PageFooter({ children, versionLink, versionLabel, homeTo, brandText,
|
|
27
|
+
export declare function PageFooter({ children, versionLink, versionLabel, homeTo, brandText, websiteHref, mailHref, copyrightText, links: linksProp, }: PageFooterProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -3,6 +3,10 @@ export type SlashCommandItem = {
|
|
|
3
3
|
id: string;
|
|
4
4
|
label: string;
|
|
5
5
|
description?: string;
|
|
6
|
+
/** Extra class on the inserted mention chip (merged with `slash-mention`). */
|
|
7
|
+
className?: string;
|
|
8
|
+
/** CSS color for chip text; background is 30% of this color mixed with transparent. */
|
|
9
|
+
color?: string;
|
|
6
10
|
};
|
|
7
11
|
export type SlashItemCommandContext = {
|
|
8
12
|
item: SlashCommandItem;
|
|
@@ -11,8 +15,9 @@ export type SlashItemCommandContext = {
|
|
|
11
15
|
range?: Range;
|
|
12
16
|
};
|
|
13
17
|
/**
|
|
14
|
-
* If provided, run when a slash item is picked. Return true to skip mention insert
|
|
15
|
-
*
|
|
18
|
+
* If provided, run when a slash item is picked. Return true to skip default mention insert
|
|
19
|
+
* and handle the composer yourself (e.g. `createChatPromptComposerHandle(editor).insertAtCaret`
|
|
20
|
+
* with `{ replaceRange: range }` to replace `/query` with a custom chip).
|
|
16
21
|
*/
|
|
17
22
|
export type SlashOnItemCommand = (ctx: SlashItemCommandContext) => boolean;
|
|
18
23
|
/** Where the slash palette opens relative to the caret. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sybilion/uilib",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.47",
|
|
4
4
|
"description": "Sybilion Design System — React UI components (Webpack + Stylus)",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -99,6 +99,13 @@
|
|
|
99
99
|
"@radix-ui/react-toggle": "^1.1.10",
|
|
100
100
|
"@radix-ui/react-toggle-group": "^1.1.11",
|
|
101
101
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
102
|
+
"@tiptap/core": "^3.22.1",
|
|
103
|
+
"@tiptap/extension-mention": "^3.22.1",
|
|
104
|
+
"@tiptap/extensions": "^3.22.1",
|
|
105
|
+
"@tiptap/pm": "^3.22.1",
|
|
106
|
+
"@tiptap/react": "^3.22.1",
|
|
107
|
+
"@tiptap/starter-kit": "^3.22.1",
|
|
108
|
+
"@tiptap/suggestion": "^3.22.1",
|
|
102
109
|
"@vimeo/player": "^2.29.3",
|
|
103
110
|
"classnames": "^2.3.2",
|
|
104
111
|
"lightweight-charts": "^5.0.9",
|
|
@@ -117,13 +124,6 @@
|
|
|
117
124
|
"peerDependencies": {
|
|
118
125
|
"@auth0/auth0-react": "^2.3.1",
|
|
119
126
|
"@sybilion/platform-sdk": ">=0.0.1",
|
|
120
|
-
"@tiptap/core": "^3.22.0",
|
|
121
|
-
"@tiptap/extension-mention": "^3.22.0",
|
|
122
|
-
"@tiptap/extensions": "^3.22.0",
|
|
123
|
-
"@tiptap/pm": "^3.22.0",
|
|
124
|
-
"@tiptap/react": "^3.22.0",
|
|
125
|
-
"@tiptap/starter-kit": "^3.22.0",
|
|
126
|
-
"@tiptap/suggestion": "^3.22.0",
|
|
127
127
|
"react": ">=18.0.0",
|
|
128
128
|
"react-dom": ">=18.0.0",
|
|
129
129
|
"react-router-dom": ">=6.0.0",
|
|
@@ -158,13 +158,6 @@
|
|
|
158
158
|
"@testing-library/dom": "^10.4.1",
|
|
159
159
|
"@testing-library/jest-dom": "^6.5.0",
|
|
160
160
|
"@testing-library/react": "^16.0.1",
|
|
161
|
-
"@tiptap/core": "^3.22.1",
|
|
162
|
-
"@tiptap/extension-mention": "^3.22.1",
|
|
163
|
-
"@tiptap/extensions": "^3.22.1",
|
|
164
|
-
"@tiptap/pm": "^3.22.1",
|
|
165
|
-
"@tiptap/react": "^3.22.1",
|
|
166
|
-
"@tiptap/starter-kit": "^3.22.1",
|
|
167
|
-
"@tiptap/suggestion": "^3.22.1",
|
|
168
161
|
"@trivago/prettier-plugin-sort-imports": "^6.0.2",
|
|
169
162
|
"@types/jest": "^29.4.0",
|
|
170
163
|
"@types/node": "^18.14.0",
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
border 1px solid var(--border) / 0.5
|
|
92
92
|
// background-color var(--background)
|
|
93
93
|
backdrop-filter blur(10px)
|
|
94
|
-
background-color unquote('color-mix(in srgb, var(--background)
|
|
94
|
+
background-color unquote('color-mix(in srgb, var(--background) 70%, transparent)')
|
|
95
95
|
font-size 0.75rem /* text-xs */
|
|
96
96
|
line-height 1rem
|
|
97
97
|
box-shadow 0 10px 10px -5px rgba(0 0 0 0.2), 0 0 1px 0 var(--muted-foreground)
|
|
@@ -99,6 +99,7 @@
|
|
|
99
99
|
transition opacity 0.5s ease-out
|
|
100
100
|
|
|
101
101
|
:global(.dark) &
|
|
102
|
+
background-color unquote('color-mix(in srgb, var(--background) 50%, transparent)')
|
|
102
103
|
box-shadow 0 0 1px 0 var(--sb-slate-700), 0 10px 10px -5px rgba(0 0 0 0.7)
|
|
103
104
|
|
|
104
105
|
.chartContainer:hover &
|