@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.
Files changed (43) hide show
  1. package/assets/logo.svg +1 -1
  2. package/dist/esm/components/ui/Chart/Chart.styl.js +1 -1
  3. package/dist/esm/components/ui/ChartAreaInteractive/ChartAreaInteractive.js +7 -1
  4. package/dist/esm/components/ui/Chat/ChatPrompt/ChatPrompt.js +5 -3
  5. package/dist/esm/components/ui/Chat/ChatPrompt/ChatPrompt.styl.js +1 -1
  6. package/dist/esm/components/ui/Chat/ChatPrompt/ChatPromptComposer.js +7 -3
  7. package/dist/esm/components/ui/Chat/ChatPrompt/chatPromptComposerInsert.js +67 -0
  8. package/dist/esm/components/ui/Logo/Logo.styl.js +1 -1
  9. package/dist/esm/components/ui/Logo/logo.svg.js +1 -1
  10. package/dist/esm/components/ui/Page/PageFooter/PageFooter.js +3 -2
  11. package/dist/esm/components/widgets/DriversComparisonChart/DriversComparisonChart.js +1 -0
  12. package/dist/esm/components/widgets/PerformanceChart/PerformanceTable.js +1 -0
  13. package/dist/esm/index.js +1 -0
  14. package/dist/esm/tiptap/slash-mention/SlashSuggestionList.styl.js +2 -2
  15. package/dist/esm/tiptap/slash-mention/createSlashMentionExtension.js +45 -28
  16. package/dist/esm/types/src/components/ui/Chat/Chat.d.ts +1 -2
  17. package/dist/esm/types/src/components/ui/Chat/Chat.types.d.ts +1 -1
  18. package/dist/esm/types/src/components/ui/Chat/ChatPrompt/ChatPrompt.d.ts +3 -1
  19. package/dist/esm/types/src/components/ui/Chat/ChatPrompt/ChatPromptComposer.d.ts +3 -1
  20. package/dist/esm/types/src/components/ui/Chat/ChatPrompt/ChatPromptComposer.types.d.ts +2 -0
  21. package/dist/esm/types/src/components/ui/Chat/ChatPrompt/chatPromptComposerInsert.d.ts +35 -0
  22. package/dist/esm/types/src/components/ui/Chat/index.d.ts +3 -0
  23. package/dist/esm/types/src/components/ui/Page/PageFooter/PageFooter.d.ts +1 -2
  24. package/dist/esm/types/src/tiptap/slash-mention/types.d.ts +7 -2
  25. package/package.json +8 -15
  26. package/src/components/ui/Chart/Chart.styl +2 -1
  27. package/src/components/ui/ChartAreaInteractive/ChartAreaInteractive.tsx +8 -1
  28. package/src/components/ui/Chat/Chat.types.ts +1 -1
  29. package/src/components/ui/Chat/ChatPrompt/ChatPrompt.styl +25 -0
  30. package/src/components/ui/Chat/ChatPrompt/ChatPrompt.tsx +94 -71
  31. package/src/components/ui/Chat/ChatPrompt/ChatPromptComposer.tsx +35 -10
  32. package/src/components/ui/Chat/ChatPrompt/ChatPromptComposer.types.ts +11 -0
  33. package/src/components/ui/Chat/ChatPrompt/chatPromptComposerInsert.ts +122 -0
  34. package/src/components/ui/Chat/index.ts +9 -0
  35. package/src/components/ui/Logo/Logo.styl +1 -0
  36. package/src/components/ui/Logo/logo.svg +1 -1
  37. package/src/components/ui/Page/PageFooter/PageFooter.tsx +2 -3
  38. package/src/docs/DocsShell.tsx +1 -6
  39. package/src/docs/pages/ChatSlashCommandsPage.tsx +46 -120
  40. package/src/tiptap/slash-mention/SlashSuggestionList.styl +4 -0
  41. package/src/tiptap/slash-mention/SlashSuggestionList.styl.d.ts +1 -0
  42. package/src/tiptap/slash-mention/createSlashMentionExtension.ts +46 -27
  43. package/src/tiptap/slash-mention/types.ts +7 -2
@@ -103,8 +103,15 @@ export function ChartAreaInteractive({
103
103
  const raw = selectedAnalysisId ?? selectedForecast?.id ?? null;
104
104
  const anchorId =
105
105
  raw == null ? null : typeof raw === 'number' ? raw : Number(raw);
106
+ const anchorForecastLoaded =
107
+ anchorId != null &&
108
+ Number.isFinite(anchorId) &&
109
+ chartData.some(row => {
110
+ const value = row[`forecast_${anchorId}`];
111
+ return typeof value === 'number' && Number.isFinite(value);
112
+ });
106
113
  const opts =
107
- anchorId != null && Number.isFinite(anchorId)
114
+ anchorId != null && Number.isFinite(anchorId) && anchorForecastLoaded
108
115
  ? { endDateAnchorAnalysisId: anchorId }
109
116
  : undefined;
110
117
  return filterDataForTimeRange(chartData, timeRange, opts);
@@ -98,7 +98,7 @@ export interface ChatPromptProps {
98
98
  onAttachmentFiles?: (files: File[]) => void;
99
99
  /** Slash menu (`/`); omit or pass empty to disable Mention trigger (no default items). */
100
100
  slashCommandItems?: SlashCommandItem[];
101
- /** Custom slash pick handler; return true to skip default mention insert. */
101
+ /** Custom slash pick handler; return true to skip default mention insert and insert via composer API. */
102
102
  onSlashItemCommand?: SlashOnItemCommand;
103
103
  }
104
104
 
@@ -69,6 +69,31 @@ INPUT_MAX_HEIGHT = 200px
69
69
  height 0
70
70
  pointer-events none
71
71
 
72
+ & :global(.ProseMirror .slash-mention)
73
+ display inline-flex
74
+ align-items center
75
+ padding 0 var(--p-1)
76
+ border-radius var(--radius-sm)
77
+ background var(--muted)
78
+ font-size 0.875em
79
+ line-height 1.4
80
+ white-space nowrap
81
+ user-select none
82
+ vertical-align baseline
83
+
84
+ & :global(.ProseMirror .chat-prompt-command-chip)
85
+ display inline-flex
86
+ align-items center
87
+ padding 0 var(--p-1)
88
+ border-radius var(--radius-sm)
89
+ background var(--muted)
90
+ color var(--foreground)
91
+ font-size 0.875em
92
+ line-height 1.4
93
+ white-space nowrap
94
+ user-select none
95
+ vertical-align baseline
96
+
72
97
  .submitColumn
73
98
  display flex
74
99
  flex-direction column
@@ -1,85 +1,108 @@
1
1
  import cn from 'classnames';
2
- import { FormEvent, useCallback, useRef } from 'react';
2
+ import {
3
+ FormEvent,
4
+ forwardRef,
5
+ useCallback,
6
+ useImperativeHandle,
7
+ useRef,
8
+ } from 'react';
3
9
 
4
10
  import type { ChatPromptProps } from '../Chat.types';
5
11
  import S from './ChatPrompt.styl';
6
12
  import { ChatPromptAttachments } from './ChatPromptAttachments';
7
- import { ChatPromptComposer } from './ChatPromptComposer';
13
+ import {
14
+ ChatPromptComposer,
15
+ type ChatPromptComposerHandle,
16
+ } from './ChatPromptComposer';
17
+ import { createChatPromptComposerHandle } from './chatPromptComposerInsert';
8
18
  import { useChatPromptEditor } from './useChatPromptEditor';
9
19
 
10
- export function ChatPrompt({
11
- onSubmit,
12
- placeholder,
13
- className,
14
- footer,
15
- prefillMessage,
16
- slashCommandItems,
17
- onSlashItemCommand,
18
- attachments = [],
19
- onRemoveAttachment,
20
- disabled = false,
21
- attachmentAccept,
22
- onAttachmentFiles,
23
- }: ChatPromptProps) {
24
- const attachmentsCount = attachments.length;
20
+ export type { ChatPromptComposerHandle } from './ChatPromptComposer';
25
21
 
26
- const emitSubmitRef = useRef(() => {});
27
- const { editor, trimmedMessage, resetAfterSend } = useChatPromptEditor({
28
- disabled,
29
- placeholder,
30
- slashCommandItems,
31
- onSlashItemCommand,
32
- prefillMessage,
33
- attachmentsCount,
34
- onEnterSubmit: () => emitSubmitRef.current(),
35
- });
22
+ export const ChatPrompt = forwardRef<ChatPromptComposerHandle, ChatPromptProps>(
23
+ function ChatPrompt(
24
+ {
25
+ onSubmit,
26
+ placeholder,
27
+ className,
28
+ footer,
29
+ prefillMessage,
30
+ slashCommandItems,
31
+ onSlashItemCommand,
32
+ attachments = [],
33
+ onRemoveAttachment,
34
+ disabled = false,
35
+ attachmentAccept,
36
+ onAttachmentFiles,
37
+ },
38
+ ref,
39
+ ) {
40
+ const attachmentsCount = attachments.length;
36
41
 
37
- const emitSubmitAndClear = useCallback(() => {
38
- if (!editor) return;
39
- if (!trimmedMessage && attachmentsCount === 0) return;
42
+ const emitSubmitRef = useRef(() => {});
43
+ const { editor, trimmedMessage, resetAfterSend } = useChatPromptEditor({
44
+ disabled,
45
+ placeholder,
46
+ slashCommandItems,
47
+ onSlashItemCommand,
48
+ prefillMessage,
49
+ attachmentsCount,
50
+ onEnterSubmit: () => emitSubmitRef.current(),
51
+ });
40
52
 
41
- const msg = trimmedMessage;
42
- resetAfterSend();
43
- onSubmit(msg, attachmentsCount > 0 ? attachments : undefined);
44
- }, [
45
- attachments,
46
- attachmentsCount,
47
- editor,
48
- onSubmit,
49
- resetAfterSend,
50
- trimmedMessage,
51
- ]);
53
+ useImperativeHandle(
54
+ ref,
55
+ () => (editor ? createChatPromptComposerHandle(editor) : null!),
56
+ [editor],
57
+ );
52
58
 
53
- emitSubmitRef.current = emitSubmitAndClear;
59
+ const emitSubmitAndClear = useCallback(() => {
60
+ if (!editor) return;
61
+ if (!trimmedMessage && attachmentsCount === 0) return;
54
62
 
55
- const handleSubmitForm = useCallback(
56
- (e?: FormEvent) => {
57
- e?.preventDefault();
58
- emitSubmitAndClear();
59
- },
60
- [emitSubmitAndClear],
61
- );
63
+ const msg = trimmedMessage;
64
+ resetAfterSend();
65
+ onSubmit(msg, attachmentsCount > 0 ? attachments : undefined);
66
+ }, [
67
+ attachments,
68
+ attachmentsCount,
69
+ editor,
70
+ onSubmit,
71
+ resetAfterSend,
72
+ trimmedMessage,
73
+ ]);
74
+
75
+ emitSubmitRef.current = emitSubmitAndClear;
76
+
77
+ const handleSubmitForm = useCallback(
78
+ (e?: FormEvent) => {
79
+ e?.preventDefault();
80
+ emitSubmitAndClear();
81
+ },
82
+ [emitSubmitAndClear],
83
+ );
62
84
 
63
- if (!editor) {
64
- return null;
65
- }
85
+ if (!editor) {
86
+ return null;
87
+ }
66
88
 
67
- return (
68
- <form onSubmit={handleSubmitForm} className={cn(S.root, className)}>
69
- <ChatPromptAttachments
70
- attachments={attachments}
71
- onRemove={index => onRemoveAttachment?.(index)}
72
- disabled={disabled}
73
- />
74
- <ChatPromptComposer
75
- editor={editor}
76
- disabled={disabled}
77
- trimmedMessage={trimmedMessage}
78
- attachments={attachments}
79
- attachmentAccept={attachmentAccept}
80
- onAttachmentFiles={onAttachmentFiles}
81
- />
82
- {footer}
83
- </form>
84
- );
85
- }
89
+ return (
90
+ <form onSubmit={handleSubmitForm} className={cn(S.root, className)}>
91
+ <ChatPromptAttachments
92
+ attachments={attachments}
93
+ onRemove={index => onRemoveAttachment?.(index)}
94
+ disabled={disabled}
95
+ />
96
+ <ChatPromptComposer
97
+ editor={editor}
98
+ disabled={disabled}
99
+ trimmedMessage={trimmedMessage}
100
+ attachments={attachments}
101
+ attachmentAccept={attachmentAccept}
102
+ onAttachmentFiles={onAttachmentFiles}
103
+ />
104
+ {footer}
105
+ </form>
106
+ );
107
+ },
108
+ );
@@ -1,4 +1,10 @@
1
- import { type ChangeEvent, useCallback, useRef } from 'react';
1
+ import {
2
+ type ChangeEvent,
3
+ forwardRef,
4
+ useCallback,
5
+ useImperativeHandle,
6
+ useRef,
7
+ } from 'react';
2
8
 
3
9
  import type { Editor } from '@tiptap/core';
4
10
  import { EditorContent } from '@tiptap/react';
@@ -7,6 +13,15 @@ import { PaperclipIcon, SendHorizontalIcon } from 'lucide-react';
7
13
  import { Button } from '../../Button';
8
14
  import type { ChatAttachmentDropItem } from '../Chat.types';
9
15
  import S from './ChatPrompt.styl';
16
+ import {
17
+ type ChatPromptComposerHandle,
18
+ createChatPromptComposerHandle,
19
+ } from './chatPromptComposerInsert';
20
+
21
+ export type {
22
+ ChatPromptComposerHandle,
23
+ ChatPromptComposerInsertOptions,
24
+ } from './ChatPromptComposer.types';
10
25
 
11
26
  export type ChatPromptComposerProps = {
12
27
  editor: Editor;
@@ -17,17 +32,27 @@ export type ChatPromptComposerProps = {
17
32
  onAttachmentFiles?: (files: File[]) => void;
18
33
  };
19
34
 
20
- export function ChatPromptComposer({
21
- editor,
22
- disabled,
23
- trimmedMessage,
24
- attachments,
25
- attachmentAccept,
26
- onAttachmentFiles,
27
- }: ChatPromptComposerProps) {
35
+ export const ChatPromptComposer = forwardRef<
36
+ ChatPromptComposerHandle,
37
+ ChatPromptComposerProps
38
+ >(function ChatPromptComposer(
39
+ {
40
+ editor,
41
+ disabled,
42
+ trimmedMessage,
43
+ attachments,
44
+ attachmentAccept,
45
+ onAttachmentFiles,
46
+ },
47
+ ref,
48
+ ) {
28
49
  const fileInputRef = useRef<HTMLInputElement>(null);
29
50
  const showAttachButton = Boolean(attachmentAccept && onAttachmentFiles);
30
51
 
52
+ useImperativeHandle(ref, () => createChatPromptComposerHandle(editor), [
53
+ editor,
54
+ ]);
55
+
31
56
  const handleFileInputChange = useCallback(
32
57
  (e: ChangeEvent<HTMLInputElement>) => {
33
58
  const files = Array.from(e.target.files ?? []);
@@ -88,4 +113,4 @@ export function ChatPromptComposer({
88
113
  </div>
89
114
  </div>
90
115
  );
91
- }
116
+ });
@@ -0,0 +1,11 @@
1
+ export type {
2
+ ChatPromptComposerHandle,
3
+ ChatPromptComposerInsertOptions,
4
+ } from './chatPromptComposerInsert';
5
+ export {
6
+ CHAT_PROMPT_COMMAND_CHIP_CLASS,
7
+ chatPromptChipHtml,
8
+ createChatPromptComposerHandle,
9
+ getChatPromptTokenRangeBeforePos,
10
+ insertChatPromptContentAtCaret,
11
+ } from './chatPromptComposerInsert';
@@ -0,0 +1,122 @@
1
+ import type { Editor, JSONContent } from '@tiptap/core';
2
+
3
+ export type ChatPromptComposerInsertOptions = {
4
+ /**
5
+ * Doc range to replace before insert (e.g. slash suggestion `range` covering `/query`).
6
+ * When set, `replaceTriggerToken` is ignored.
7
+ */
8
+ replaceRange?: { from: number; to: number };
9
+ /**
10
+ * When true and no `replaceRange`, delete text from caret back to the preceding
11
+ * space or start of line before insert. Default true.
12
+ */
13
+ replaceTriggerToken?: boolean;
14
+ /** Append a space after inserted content so the user can keep typing. Default true. */
15
+ trailingSpace?: boolean;
16
+ };
17
+
18
+ /** Global class for inline command chips inserted via `insertAtCaret`. */
19
+ export const CHAT_PROMPT_COMMAND_CHIP_CLASS = 'chat-prompt-command-chip';
20
+
21
+ export type ChatPromptComposerHandle = {
22
+ /** Insert HTML string or TipTap JSON at the caret (or after clearing trigger text). */
23
+ insertAtCaret: (
24
+ content: string | JSONContent,
25
+ options?: ChatPromptComposerInsertOptions,
26
+ ) => void;
27
+ focus: () => void;
28
+ getEditor: () => Editor;
29
+ };
30
+
31
+ /** Range of the unfinished token immediately before `pos` (back to space or line start). */
32
+ export function getChatPromptTokenRangeBeforePos(
33
+ editor: Editor,
34
+ pos: number,
35
+ ): { from: number; to: number } {
36
+ const $pos = editor.state.doc.resolve(pos);
37
+ const textBefore = $pos.parent.textBetween(
38
+ 0,
39
+ $pos.parentOffset,
40
+ undefined,
41
+ '\ufffc',
42
+ );
43
+ const token = textBefore.match(/[^\s]*$/)?.[0] ?? '';
44
+ return { from: pos - token.length, to: pos };
45
+ }
46
+
47
+ function escapeHtml(text: string): string {
48
+ return text
49
+ .replaceAll('&', '&amp;')
50
+ .replaceAll('<', '&lt;')
51
+ .replaceAll('>', '&gt;')
52
+ .replaceAll('"', '&quot;');
53
+ }
54
+
55
+ /** Build inline chip HTML for `insertAtCaret` (uses global `CHAT_PROMPT_COMMAND_CHIP_CLASS`). */
56
+ export function chatPromptChipHtml(
57
+ text: string,
58
+ className: string = CHAT_PROMPT_COMMAND_CHIP_CLASS,
59
+ ): string {
60
+ const cls = className ? ` class="${className}"` : '';
61
+ return `<span${cls} data-chat-prompt-chip="true">${escapeHtml(text)}</span>`;
62
+ }
63
+
64
+ export function insertChatPromptContentAtCaret(
65
+ editor: Editor,
66
+ content: string | JSONContent,
67
+ options?: ChatPromptComposerInsertOptions,
68
+ ): void {
69
+ if (editor.isDestroyed) return;
70
+
71
+ const {
72
+ replaceRange,
73
+ replaceTriggerToken = true,
74
+ trailingSpace = true,
75
+ } = options ?? {};
76
+
77
+ const { from: selFrom, to: selTo } = editor.state.selection;
78
+ let from: number;
79
+ let to: number;
80
+
81
+ if (replaceRange) {
82
+ from = replaceRange.from;
83
+ to = replaceRange.to;
84
+ } else if (replaceTriggerToken) {
85
+ ({ from, to } = getChatPromptTokenRangeBeforePos(editor, selFrom));
86
+ } else {
87
+ from = selFrom;
88
+ to = selTo;
89
+ }
90
+
91
+ const chain = editor.chain().focus().deleteRange({ from, to });
92
+
93
+ if (typeof content === 'string') {
94
+ chain.insertContentAt(from, trailingSpace ? `${content} ` : content);
95
+ } else {
96
+ chain.insertContentAt(from, content);
97
+ if (trailingSpace) {
98
+ chain.insertContent(' ');
99
+ }
100
+ }
101
+
102
+ chain.run();
103
+
104
+ queueMicrotask(() => {
105
+ editor.view.dom.ownerDocument?.defaultView
106
+ ?.getSelection?.()
107
+ ?.collapseToEnd();
108
+ });
109
+ }
110
+
111
+ export function createChatPromptComposerHandle(
112
+ editor: Editor,
113
+ ): ChatPromptComposerHandle {
114
+ return {
115
+ insertAtCaret: (content, options) =>
116
+ insertChatPromptContentAtCaret(editor, content, options),
117
+ focus: () => {
118
+ editor.commands.focus();
119
+ },
120
+ getEditor: () => editor,
121
+ };
122
+ }
@@ -27,6 +27,15 @@ export type {
27
27
  } from './ChatSheet/useChatPanelChromeModel';
28
28
  export { ChatMessage } from './ChatMessage';
29
29
  export { ChatPrompt } from './ChatPrompt';
30
+ export type { ChatPromptComposerHandle } from './ChatPrompt/ChatPromptComposer';
31
+ export {
32
+ CHAT_PROMPT_COMMAND_CHIP_CLASS,
33
+ chatPromptChipHtml,
34
+ createChatPromptComposerHandle,
35
+ getChatPromptTokenRangeBeforePos,
36
+ insertChatPromptContentAtCaret,
37
+ } from './ChatPrompt/chatPromptComposerInsert';
38
+ export type { ChatPromptComposerInsertOptions } from './ChatPrompt/ChatPromptComposer.types';
30
39
  export { ChatPresets } from './ChatPresets';
31
40
  export type {
32
41
  ChatEmptyStateConfig,
@@ -9,6 +9,7 @@
9
9
  flex-shrink 0
10
10
  height 24px
11
11
  width auto
12
+ color var(--brand-color)
12
13
 
13
14
  .text
14
15
  font-family var(--font-family-heading)
@@ -1,3 +1,3 @@
1
1
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
2
- <path fill="#C259FF" 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" />
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,7 @@
1
1
  import type { ReactNode } from 'react';
2
2
  import { Link } from 'react-router-dom';
3
3
 
4
+ import { Logo } from '#uilib/components/ui/Logo';
4
5
  import { GlobeIcon, MailIcon } from 'lucide-react';
5
6
 
6
7
  import S from './PageFooter.styl';
@@ -14,7 +15,6 @@ export interface PageFooterLinkItem {
14
15
  }
15
16
 
16
17
  export interface PageFooterProps {
17
- logo?: ReactNode;
18
18
  /** Rendered between logo block and copyright (e.g. debug UI from the app). */
19
19
  children?: ReactNode;
20
20
  /** When non-empty, version badge links here (e.g. `/releases`). */
@@ -55,7 +55,6 @@ export function PageFooter({
55
55
  versionLabel,
56
56
  homeTo = '/',
57
57
  brandText = 'Sybilion',
58
- logo,
59
58
  websiteHref = 'https://sybilion.com',
60
59
  mailHref = 'mailto:support@sybilion.com',
61
60
  copyrightText = '© 2026 Sybilion. All rights reserved.',
@@ -84,7 +83,7 @@ export function PageFooter({
84
83
  <div className={S.line}>
85
84
  <div className={S.logo}>
86
85
  <Link to={homeTo}>
87
- {logo}
86
+ <Logo />
88
87
  &nbsp;{brandText}
89
88
  </Link>
90
89
  {versionLink !== '' && (
@@ -1,7 +1,6 @@
1
1
  import { Outlet, useLocation, useNavigate } from 'react-router-dom';
2
2
 
3
3
  import { AppHeaderHost } from '#uilib/components/ui/AppHeader';
4
- import { LogoMark } from '#uilib/components/ui/Logo';
5
4
  import { AppShell, AppShellMainContent } from '#uilib/components/ui/Page';
6
5
  import { PageFooter } from '#uilib/components/ui/Page/PageFooter/PageFooter';
7
6
  import { PageScroll } from '#uilib/components/ui/Page/PageScroll/PageScroll';
@@ -23,11 +22,7 @@ export function DocsShell() {
23
22
  <AppShellMainContent
24
23
  header={<AppHeaderHost />}
25
24
  footer={
26
- <PageFooter
27
- logo={<LogoMark />}
28
- versionLink="/releases"
29
- versionLabel="1.0.0-docs"
30
- />
25
+ <PageFooter versionLink="/releases" versionLabel="1.0.0-docs" />
31
26
  }
32
27
  >
33
28
  <SybilionAppHeader