@sybilion/uilib 1.3.43 → 1.3.46
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 +7 -5
- package/dist/esm/components/ui/Chat/ChatPrompt/ChatPrompt.styl.js +1 -1
- package/dist/esm/components/ui/Chat/ChatPrompt/ChatPromptComposer.js +8 -4
- package/dist/esm/components/ui/Chat/ChatPrompt/chatPromptComposerInsert.js +67 -0
- package/dist/esm/components/ui/Chat/ChatPrompt/useChatPromptEditor.js +24 -17
- 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/ui/Page/PageHeader/PageHeader.js +1 -1
- package/dist/esm/components/ui/TextWithDeferTooltip/TextWithDeferTooltip.js +23 -1
- package/dist/esm/components/widgets/DriverCard/DriverCard.js +1 -1
- 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 -3
- 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/ChatPrompt/useChatPromptEditor.d.ts +0 -2
- 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/docs/pages/ChatSheetPage.d.ts +1 -0
- package/dist/esm/types/src/tiptap/slash-mention/types.d.ts +7 -2
- package/package.json +1 -1
- 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 +26 -1
- package/src/components/ui/Chat/ChatPrompt/ChatPrompt.tsx +86 -65
- package/src/components/ui/Chat/ChatPrompt/ChatPromptComposer.tsx +31 -13
- 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/ChatPrompt/useChatPromptEditor.ts +34 -21
- 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/components/ui/Page/PageHeader/PageHeader.tsx +1 -1
- package/src/components/ui/TextWithDeferTooltip/TextWithDeferTooltip.tsx +35 -4
- package/src/components/widgets/DriverCard/DriverCard.tsx +5 -1
- package/src/docs/DocsShell.tsx +1 -6
- package/src/docs/pages/ChatSheetPage.tsx +61 -0
- package/src/docs/pages/ChatSlashCommandsPage.tsx +46 -120
- package/src/docs/pages/TooltipPage.tsx +0 -31
- package/src/docs/registry.ts +6 -0
- 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,15 +1,16 @@
|
|
|
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
|
-
const { editor, trimmedMessage, resetAfterSend
|
|
13
|
+
const { editor, trimmedMessage, resetAfterSend } = useChatPromptEditor({
|
|
13
14
|
disabled,
|
|
14
15
|
placeholder,
|
|
15
16
|
slashCommandItems,
|
|
@@ -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;
|
|
@@ -42,7 +44,7 @@ function ChatPrompt({ onSubmit, placeholder, className, footer, prefillMessage,
|
|
|
42
44
|
if (!editor) {
|
|
43
45
|
return null;
|
|
44
46
|
}
|
|
45
|
-
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
|
|
46
|
-
}
|
|
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] }));
|
|
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: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 = '';
|
|
@@ -19,7 +23,7 @@ function ChatPromptComposer({ editor, disabled, trimmedMessage, attachments, att
|
|
|
19
23
|
return (jsxs("div", { className: S.composer, children: [showAttachButton ? (jsxs(Fragment, { children: [jsx("input", { ref: fileInputRef, type: "file", accept: attachmentAccept, multiple: true, className: S.fileInput, disabled: disabled, onChange: handleFileInputChange }), jsx(Button, { type: "button", variant: "ghost", icon: true, size: "sm", className: S.attachButton, "aria-label": "Attach file", disabled: disabled, onClick: e => {
|
|
20
24
|
e.preventDefault();
|
|
21
25
|
fileInputRef.current?.click();
|
|
22
|
-
}, children: jsx(PaperclipIcon, { size: 16 }) })] })) : null, jsx("div", { className: S.editorWrap,
|
|
23
|
-
}
|
|
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 }) }) })] }));
|
|
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 };
|
|
@@ -44,7 +44,6 @@ function useChatPromptEditor({ disabled, placeholder, slashCommandItems, onSlash
|
|
|
44
44
|
Placeholder.configure({
|
|
45
45
|
placeholder: placeholderText,
|
|
46
46
|
showOnlyWhenEditable: true,
|
|
47
|
-
showOnlyCurrent: false,
|
|
48
47
|
}),
|
|
49
48
|
];
|
|
50
49
|
if (slashItemsStable.length > 0) {
|
|
@@ -70,6 +69,28 @@ function useChatPromptEditor({ disabled, placeholder, slashCommandItems, onSlash
|
|
|
70
69
|
});
|
|
71
70
|
}, []);
|
|
72
71
|
const trimmedMessage = plainDraft.trim();
|
|
72
|
+
const trimmedMessageRef = useRef(trimmedMessage);
|
|
73
|
+
trimmedMessageRef.current = trimmedMessage;
|
|
74
|
+
const attachmentsCountRef = useRef(attachmentsCount);
|
|
75
|
+
attachmentsCountRef.current = attachmentsCount;
|
|
76
|
+
const onEnterSubmitRef = useRef(onEnterSubmit);
|
|
77
|
+
onEnterSubmitRef.current = onEnterSubmit;
|
|
78
|
+
const handleEditorKeyDown = useCallback((_view, event) => {
|
|
79
|
+
if (!(event.key === 'Enter' &&
|
|
80
|
+
!event.shiftKey &&
|
|
81
|
+
!event.metaKey &&
|
|
82
|
+
!event.ctrlKey)) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
if (slashOpenRef.current)
|
|
86
|
+
return false;
|
|
87
|
+
if (!trimmedMessageRef.current && attachmentsCountRef.current === 0) {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
event.preventDefault();
|
|
91
|
+
onEnterSubmitRef.current();
|
|
92
|
+
return true;
|
|
93
|
+
}, []);
|
|
73
94
|
const editor = useEditor({
|
|
74
95
|
extensions,
|
|
75
96
|
content: CHAT_PROMPT_EMPTY_DOC,
|
|
@@ -80,6 +101,7 @@ function useChatPromptEditor({ disabled, placeholder, slashCommandItems, onSlash
|
|
|
80
101
|
spellcheck: 'true',
|
|
81
102
|
'aria-label': ariaLabelComposer,
|
|
82
103
|
},
|
|
104
|
+
handleKeyDown: handleEditorKeyDown,
|
|
83
105
|
},
|
|
84
106
|
onTransaction: ({ editor: ed }) => {
|
|
85
107
|
const dom = chatPromptSafeEditorDom(ed);
|
|
@@ -89,7 +111,7 @@ function useChatPromptEditor({ disabled, placeholder, slashCommandItems, onSlash
|
|
|
89
111
|
setPlainDraft(ed.getText());
|
|
90
112
|
},
|
|
91
113
|
onCreate: bindEditorDom,
|
|
92
|
-
}, [extensions, bindEditorDom, ariaLabelComposer]);
|
|
114
|
+
}, [extensions, bindEditorDom, ariaLabelComposer, handleEditorKeyDown]);
|
|
93
115
|
useEffect(() => {
|
|
94
116
|
if (!editor)
|
|
95
117
|
return;
|
|
@@ -131,8 +153,6 @@ function useChatPromptEditor({ disabled, placeholder, slashCommandItems, onSlash
|
|
|
131
153
|
return;
|
|
132
154
|
syncChatPromptComposerHeight(dom, plainDraft);
|
|
133
155
|
}, [editor, plainDraft]);
|
|
134
|
-
const onEnterSubmitRef = useRef(onEnterSubmit);
|
|
135
|
-
onEnterSubmitRef.current = onEnterSubmit;
|
|
136
156
|
const resetAfterSend = useCallback(() => {
|
|
137
157
|
if (!editor)
|
|
138
158
|
return;
|
|
@@ -144,23 +164,10 @@ function useChatPromptEditor({ disabled, placeholder, slashCommandItems, onSlash
|
|
|
144
164
|
});
|
|
145
165
|
setPlainDraft('');
|
|
146
166
|
}, [editor]);
|
|
147
|
-
const handleComposerKeyDown = useCallback((e) => {
|
|
148
|
-
if (!(e.key === 'Enter' && !e.shiftKey && !e.metaKey && !e.ctrlKey))
|
|
149
|
-
return;
|
|
150
|
-
if (!editorDomRef.current?.contains(e.target))
|
|
151
|
-
return;
|
|
152
|
-
if (slashOpenRef.current)
|
|
153
|
-
return;
|
|
154
|
-
if (!trimmedMessage && attachmentsCount === 0)
|
|
155
|
-
return;
|
|
156
|
-
e.preventDefault();
|
|
157
|
-
onEnterSubmitRef.current();
|
|
158
|
-
}, [attachmentsCount, trimmedMessage]);
|
|
159
167
|
return {
|
|
160
168
|
editor,
|
|
161
169
|
trimmedMessage,
|
|
162
170
|
resetAfterSend,
|
|
163
|
-
handleComposerKeyDown,
|
|
164
171
|
};
|
|
165
172
|
}
|
|
166
173
|
|
|
@@ -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 };
|
|
@@ -8,7 +8,7 @@ import S from './PageHeader.styl.js';
|
|
|
8
8
|
|
|
9
9
|
function PageHeader({ breadcrumbs, breadcrumbClientLogo, breadcrumbCompanyName, breadcrumbSidebarTrigger = true, title, subheader, actions, }) {
|
|
10
10
|
const { isScrolled } = useContext(PageContext);
|
|
11
|
-
return (jsx("div", { className: cn(S.root, actions && S.hasActions, isScrolled && S.scrolled), children: jsxs("div", { className: S.inner, children: [jsx(Breadcrumbs, { className: S.breadcrumbs, items: breadcrumbs ?? [], clientLogo: breadcrumbClientLogo, companyName: breadcrumbCompanyName, sidebarTrigger: breadcrumbSidebarTrigger, children: isScrolled && (jsxs("div", { className: S.titleDupe, children: [jsx(BreadCrumbsSeparator, { size: 14 }), title] })) }), jsxs("div", { className: S.main, children: [jsxs("div", { className: S.title, children: [jsx("h1", { children: title }), subheader && (jsx(TextWithDeferTooltip, { className: S.subheader, children: subheader }))] }), actions && jsx("div", { className: S.actions, children: actions })] })] }) }));
|
|
11
|
+
return (jsx("div", { className: cn(S.root, actions && S.hasActions, isScrolled && S.scrolled), children: jsxs("div", { className: S.inner, children: [jsx(Breadcrumbs, { className: S.breadcrumbs, items: breadcrumbs ?? [], clientLogo: breadcrumbClientLogo, companyName: breadcrumbCompanyName, sidebarTrigger: breadcrumbSidebarTrigger, children: isScrolled && (jsxs("div", { className: S.titleDupe, children: [jsx(BreadCrumbsSeparator, { size: 14 }), title] })) }), jsxs("div", { className: S.main, children: [jsxs("div", { className: S.title, children: [jsx("h1", { children: title }), subheader && (jsx(TextWithDeferTooltip, { className: S.subheader, overTrigger: true, children: subheader }))] }), actions && jsx("div", { className: S.actions, children: actions })] })] }) }));
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export { PageHeader };
|
|
@@ -4,19 +4,41 @@ import { Tooltip, TooltipTrigger, TooltipContent } from '../Tooltip/Tooltip.js';
|
|
|
4
4
|
|
|
5
5
|
function TextWithDeferTooltip({ className, children, width, maxWidth, side = 'bottom', overTrigger = false, ...props }) {
|
|
6
6
|
const [withTooltip, setWithTooltip] = useState(false);
|
|
7
|
+
const [tooltipStyles, setTooltipStyles] = useState({});
|
|
7
8
|
const ref = useRef(null);
|
|
9
|
+
const cachedFontSizeRef = useRef(null);
|
|
8
10
|
const handleMouseEnter = () => {
|
|
9
11
|
if (!ref.current)
|
|
10
12
|
return;
|
|
11
13
|
const isOverflowingHorizontally = ref.current.scrollWidth - ref.current.clientWidth > 3;
|
|
12
14
|
const isOverflowingVertically = ref.current.scrollHeight - ref.current.clientHeight > 3;
|
|
13
15
|
if (isOverflowingHorizontally || isOverflowingVertically) {
|
|
16
|
+
const styles = {
|
|
17
|
+
fontSize: cachedFontSizeRef.current || undefined,
|
|
18
|
+
};
|
|
19
|
+
if (ref.current) {
|
|
20
|
+
const { width: rectWidth, left, top, } = ref.current.getBoundingClientRect();
|
|
21
|
+
styles.width = `${width ?? rectWidth}px`;
|
|
22
|
+
if (!cachedFontSizeRef.current) {
|
|
23
|
+
const { fontSize } = window.getComputedStyle(ref.current);
|
|
24
|
+
cachedFontSizeRef.current = fontSize;
|
|
25
|
+
styles.fontSize = fontSize;
|
|
26
|
+
}
|
|
27
|
+
if (overTrigger) {
|
|
28
|
+
styles.transform = `translate(${left}px, ${top}px) !important`;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
setTooltipStyles(styles);
|
|
14
32
|
setWithTooltip(true);
|
|
15
33
|
}
|
|
16
34
|
};
|
|
17
35
|
const textElement = (jsx("div", { ref: ref, className: className, onMouseEnter: handleMouseEnter, ...props, children: children }));
|
|
18
36
|
if (withTooltip) {
|
|
19
|
-
|
|
37
|
+
const tooltipSide = overTrigger ? 'bottom' : side;
|
|
38
|
+
return (jsxs(Tooltip, { open: withTooltip, onOpenChange: setWithTooltip, children: [jsx(TooltipTrigger, { asChild: true, children: textElement }), jsx(TooltipContent, { side: tooltipSide, style: {
|
|
39
|
+
...(maxWidth !== undefined && { maxWidth: `${maxWidth}px` }),
|
|
40
|
+
...tooltipStyles,
|
|
41
|
+
}, overTrigger: overTrigger, children: children })] }));
|
|
20
42
|
}
|
|
21
43
|
return textElement;
|
|
22
44
|
}
|
|
@@ -83,7 +83,7 @@ function DriverCard({ selectedDriver, isLoading, inQueue = false, driverSelector
|
|
|
83
83
|
const directionText = direction > 0 ? 'Positive' : 'Negative';
|
|
84
84
|
const DirectionIcon = direction > 0 ? TrendUpIcon : TrendDownIcon;
|
|
85
85
|
const nameElem = (jsx("h4", { className: `${S.driverTitle} ${S.truncated}`, children: name }));
|
|
86
|
-
return (jsx(Card, { className: S.root, paddingSize: "l", children: jsx(CardContent, { noScroll: true, children: jsxs("div", { className: S.cardContent, children: [jsx("div", { className: S.driverHeader, children: jsxs("div", { className: S.headerContent, children: [jsxs("div", { className: S.topHeader, children: [jsxs("p", { className: S.categoryInfo, children: [jsx("span", { className: S.categoryIcon, children: getCategoryIcon(category) }), jsx("span", { className: S.categoryText, children: category })] }), driverSelector] }), name.length > 60 ? (jsxs(Tooltip, { children: [jsx(LabelWithId, { id: id, label: jsx(TooltipTrigger, { asChild: true, children: nameElem }) }), jsx(TooltipContent, { side: "left", className: S.tooltipContent, children: jsx("div", { className: S.tooltipTitle, children: name }) })] })) : (jsx(LabelWithId, { id: id, label: nameElem })), jsx("p", { className: S.regionDisplay, children: regionDisplay })] }) }), jsx("div", { className: S.metricsSection, children: jsx("div", { className: S.importanceScore, children: importanceDisplay }) }), jsxs("div", { className: S.directionLagSection, children: [jsxs(Badge, { variant: direction > 0 ? 'green' : 'red', className: S.directionBadge, children: [jsx(DirectionIcon, { className: S.trendIcon }), directionText, " correlation"] }), jsxs("span", { className: S.lagInfo, children: ["Lag: ", lag] })] }), jsx(DriverPerformanceChart, { driver: selectedDriver }), jsx("p", { className: S.description, children: summary ?? '' })] }) }) }));
|
|
86
|
+
return (jsx(Card, { className: S.root, paddingSize: "l", children: jsx(CardContent, { noScroll: true, children: jsxs("div", { className: S.cardContent, children: [jsx("div", { className: S.driverHeader, children: jsxs("div", { className: S.headerContent, children: [jsxs("div", { className: S.topHeader, children: [jsxs("p", { className: S.categoryInfo, children: [jsx("span", { className: S.categoryIcon, children: getCategoryIcon(category) }), jsx("span", { className: S.categoryText, children: category })] }), driverSelector] }), name.length > 60 ? (jsxs(Tooltip, { children: [jsx(LabelWithId, { id: id, label: jsx(TooltipTrigger, { asChild: true, children: nameElem }) }), jsx(TooltipContent, { side: "left", className: S.tooltipContent, overTrigger: true, children: jsx("div", { className: S.tooltipTitle, children: name }) })] })) : (jsx(LabelWithId, { id: id, label: nameElem })), jsx("p", { className: S.regionDisplay, children: regionDisplay })] }) }), jsx("div", { className: S.metricsSection, children: jsx("div", { className: S.importanceScore, children: importanceDisplay }) }), jsxs("div", { className: S.directionLagSection, children: [jsxs(Badge, { variant: direction > 0 ? 'green' : 'red', className: S.directionBadge, children: [jsx(DirectionIcon, { className: S.trendIcon }), directionText, " correlation"] }), jsxs("span", { className: S.lagInfo, children: ["Lag: ", lag] })] }), jsx(DriverPerformanceChart, { driver: selectedDriver }), jsx("p", { className: S.description, children: summary ?? '' })] }) }) }));
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
export { DriverCard };
|
|
@@ -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>>;
|