@elizaos/ui 2.0.0-alpha.343 → 2.0.0-alpha.345

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/package.json +1 -1
  2. package/packages/typescript/src/features/basic-capabilities/providers/actionState.d.ts.map +1 -1
  3. package/packages/typescript/src/features/basic-capabilities/providers/actionState.js +8 -51
  4. package/packages/typescript/src/features/basic-capabilities/providers/actions.d.ts.map +1 -1
  5. package/packages/typescript/src/features/basic-capabilities/providers/actions.js +2 -2
  6. package/packages/typescript/src/features/basic-capabilities/providers/non-actionable-chatter.d.ts.map +1 -1
  7. package/packages/typescript/src/features/basic-capabilities/providers/non-actionable-chatter.js +2 -4
  8. package/packages/typescript/src/features/basic-capabilities/providers/providers.d.ts.map +1 -1
  9. package/packages/typescript/src/features/basic-capabilities/providers/providers.js +2 -2
  10. package/packages/typescript/src/features/knowledge/utils.d.ts.map +1 -1
  11. package/packages/typescript/src/features/knowledge/utils.js +4 -3
  12. package/packages/typescript/src/runtime.d.ts +2 -0
  13. package/packages/typescript/src/runtime.d.ts.map +1 -1
  14. package/packages/typescript/src/runtime.js +80 -0
  15. package/packages/typescript/src/services/message.d.ts +3 -1
  16. package/packages/typescript/src/services/message.d.ts.map +1 -1
  17. package/packages/typescript/src/services/message.js +29 -35
  18. package/packages/typescript/src/utils/action-results.d.ts +33 -0
  19. package/packages/typescript/src/utils/action-results.d.ts.map +1 -0
  20. package/packages/typescript/src/utils/action-results.js +169 -0
  21. package/packages/typescript/src/utils/context-catalog.d.ts.map +1 -1
  22. package/packages/typescript/src/utils/context-catalog.js +11 -0
  23. package/packages/typescript/src/utils/context-routing.d.ts +3 -0
  24. package/packages/typescript/src/utils/context-routing.d.ts.map +1 -1
  25. package/packages/typescript/src/utils/context-routing.js +88 -0
  26. package/packages/typescript/src/utils/message-text.d.ts +5 -0
  27. package/packages/typescript/src/utils/message-text.d.ts.map +1 -0
  28. package/packages/typescript/src/utils/message-text.js +24 -0
  29. package/packages/typescript/src/utils.d.ts +2 -1
  30. package/packages/typescript/src/utils.d.ts.map +1 -1
  31. package/packages/typescript/src/utils.js +2 -1
  32. package/packages/ui/src/components/composites/chat/chat-composer.d.ts.map +1 -1
  33. package/packages/ui/src/components/composites/chat/chat-composer.js +101 -19
  34. package/packages/ui/src/layouts/page-layout/page-layout-mobile-drawer.d.ts.map +1 -1
  35. package/packages/ui/src/layouts/page-layout/page-layout-mobile-drawer.js +23 -4
  36. package/packages/ui/src/layouts/workspace-layout/index.d.ts +1 -0
  37. package/packages/ui/src/layouts/workspace-layout/index.d.ts.map +1 -1
  38. package/packages/ui/src/layouts/workspace-layout/index.js +1 -0
  39. package/packages/ui/src/layouts/workspace-layout/workspace-layout.d.ts.map +1 -1
  40. package/packages/ui/src/layouts/workspace-layout/workspace-layout.js +8 -2
  41. package/packages/ui/src/layouts/workspace-layout/workspace-mobile-sidebar-controls.d.ts +13 -0
  42. package/packages/ui/src/layouts/workspace-layout/workspace-mobile-sidebar-controls.d.ts.map +1 -0
  43. package/packages/ui/src/layouts/workspace-layout/workspace-mobile-sidebar-controls.js +5 -0
@@ -1,12 +1,51 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { ArrowUp, Mic, Paperclip, Plus, Send, Square, Volume2, VolumeX, } from "lucide-react";
3
- import { useEffect, useRef, useState, } from "react";
3
+ import { useEffect, useLayoutEffect, useRef, useState, } from "react";
4
4
  import { Button } from "../../ui/button";
5
5
  import { Textarea } from "../../ui/textarea";
6
6
  import { CreateTaskPopover } from "./create-task-popover";
7
+ const INLINE_TEXTAREA_MIN_HEIGHT_PX = 32;
8
+ const INLINE_TEXTAREA_MAX_HEIGHT_PX = 128;
9
+ const INLINE_STACKED_INLINE_PADDING_PX = 12;
10
+ const inlineTextareaClass = "block h-8 max-h-[128px] min-h-0 w-full min-w-0 resize-none overflow-y-hidden appearance-none rounded-none border-0 bg-transparent px-2 py-[6px] text-sm leading-5 text-txt shadow-none outline-none ring-0 placeholder:text-muted/60 focus:!border-0 focus:!outline-none focus:!ring-0 focus-visible:!border-0 focus-visible:!outline-none focus-visible:!ring-0 focus-visible:!ring-offset-0 focus-visible:!shadow-none";
11
+ const inlineMeasureTextareaClass = `${inlineTextareaClass} pointer-events-none fixed left-0 top-0 z-[-1] opacity-0`;
12
+ const chatComposerFocusResetClass = "[&_button:focus]:!outline-none [&_button:focus-visible]:!outline-none [&_button:focus-visible]:!ring-0 [&_button:focus-visible]:!ring-offset-0 [&_button:focus-visible]:!shadow-none [&_textarea:focus]:!outline-none [&_textarea:focus-visible]:!outline-none [&_textarea:focus-visible]:!ring-0 [&_textarea:focus-visible]:!ring-offset-0 [&_textarea:focus-visible]:!shadow-none";
13
+ function getTextareaVerticalPadding(textarea) {
14
+ const styles = window.getComputedStyle(textarea);
15
+ const paddingTop = Number.parseFloat(styles.paddingTop);
16
+ const paddingBottom = Number.parseFloat(styles.paddingBottom);
17
+ const verticalPadding = paddingTop + paddingBottom;
18
+ if (Number.isFinite(paddingTop) &&
19
+ Number.isFinite(paddingBottom) &&
20
+ verticalPadding > 0) {
21
+ return verticalPadding;
22
+ }
23
+ return 12;
24
+ }
25
+ function getTextareaLineHeight(textarea) {
26
+ const lineHeight = Number.parseFloat(window.getComputedStyle(textarea).lineHeight);
27
+ return Number.isFinite(lineHeight) && lineHeight > 0 ? lineHeight : 20;
28
+ }
29
+ function measureInlineTextarea(textarea, value, width) {
30
+ textarea.value = value.endsWith("\n") ? `${value} ` : value || " ";
31
+ textarea.style.width = `${Math.max(1, width)}px`;
32
+ textarea.style.height = "auto";
33
+ textarea.style.overflowY = "hidden";
34
+ const scrollHeight = textarea.scrollHeight;
35
+ const contentHeight = Math.max(0, scrollHeight - getTextareaVerticalPadding(textarea));
36
+ const lineHeight = getTextareaLineHeight(textarea);
37
+ return {
38
+ scrollHeight,
39
+ wraps: contentHeight > lineHeight * 1.25,
40
+ };
41
+ }
7
42
  export function ChatComposer({ variant, layout = "default", textareaRef, chatInput, chatPendingImagesCount, isComposerLocked, isAgentStarting, chatSending, voice, agentVoiceEnabled, showAgentVoiceToggle = true, t, onAttachImage, onChatInputChange, onKeyDown, onSend, onStop, onStopSpeaking, onToggleAgentVoice, codingAgentsAvailable = false, onCreateTask, hideAttachButton = false, placeholder, textareaAriaLabel, }) {
8
43
  const [isNarrow, setIsNarrow] = useState(() => typeof window !== "undefined" && window.innerWidth < 310);
9
44
  const [isInlineMultiline, setIsInlineMultiline] = useState(false);
45
+ const [inlineMeasureVersion, setInlineMeasureVersion] = useState(0);
46
+ const inlineRootRef = useRef(null);
47
+ const inlineMeasureRef = useRef(null);
48
+ const lastInlineSingleLineWidthRef = useRef(null);
10
49
  useEffect(() => {
11
50
  if (typeof window === "undefined" || !window.matchMedia)
12
51
  return;
@@ -53,9 +92,6 @@ export function ChatComposer({ variant, layout = "default", textareaRef, chatInp
53
92
  ? t("chat.listening")
54
93
  : inputPlaceholder
55
94
  : inputPlaceholder;
56
- const inlineTextareaClass = isInlineMultiline
57
- ? "block h-8 max-h-[128px] min-h-0 w-full min-w-0 resize-none overflow-y-hidden appearance-none rounded-none border-0 bg-transparent px-2 py-[6px] text-sm leading-5 text-txt shadow-none outline-none ring-0 placeholder:text-muted/60 focus:border-0 focus:outline-none focus:ring-0 focus-visible:border-0 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0 focus-visible:shadow-none"
58
- : "block h-8 max-h-[128px] min-h-0 w-full min-w-0 resize-none overflow-y-hidden appearance-none rounded-none border-0 bg-transparent px-1 py-[5px] text-sm leading-5 text-txt shadow-none outline-none ring-0 placeholder:text-muted/60 focus:border-0 focus:outline-none focus:ring-0 focus-visible:border-0 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0 focus-visible:shadow-none";
59
95
  useEffect(() => {
60
96
  return () => {
61
97
  if (holdTimerRef.current) {
@@ -64,24 +100,70 @@ export function ChatComposer({ variant, layout = "default", textareaRef, chatInp
64
100
  }
65
101
  };
66
102
  }, []);
67
- // biome-ignore lint/correctness/useExhaustiveDependencies: chatInput changes must rerun inline textarea autosizing.
68
103
  useEffect(() => {
104
+ if (!isInline)
105
+ return;
106
+ const root = inlineRootRef.current;
107
+ if (!root || typeof ResizeObserver === "undefined")
108
+ return;
109
+ let frame = 0;
110
+ const observer = new ResizeObserver(() => {
111
+ if (frame)
112
+ cancelAnimationFrame(frame);
113
+ frame = requestAnimationFrame(() => {
114
+ setInlineMeasureVersion((version) => version + 1);
115
+ });
116
+ });
117
+ observer.observe(root);
118
+ return () => {
119
+ if (frame)
120
+ cancelAnimationFrame(frame);
121
+ observer.disconnect();
122
+ };
123
+ }, [isInline]);
124
+ // biome-ignore lint/correctness/useExhaustiveDependencies: inlineMeasureVersion is a ResizeObserver tick that reruns measurement after width changes.
125
+ useLayoutEffect(() => {
69
126
  if (!isInline) {
70
127
  setIsInlineMultiline(false);
128
+ lastInlineSingleLineWidthRef.current = null;
71
129
  return;
72
130
  }
73
131
  const textarea = textareaRef.current;
74
- if (!textarea)
132
+ const measureTextarea = inlineMeasureRef.current;
133
+ const root = inlineRootRef.current;
134
+ if (!textarea || !measureTextarea || !root)
75
135
  return;
76
- const minHeight = 32;
77
- const maxHeight = 128;
78
- textarea.style.height = "auto";
79
- const nextHeight = Math.min(Math.max(textarea.scrollHeight, minHeight), maxHeight);
136
+ const measuredSingleLineWidth = textarea.clientWidth > 0 ? textarea.clientWidth : null;
137
+ const currentSingleLineWidth = isInlineMultiline
138
+ ? lastInlineSingleLineWidthRef.current
139
+ : measuredSingleLineWidth;
140
+ if (!isInlineMultiline && measuredSingleLineWidth) {
141
+ lastInlineSingleLineWidthRef.current = measuredSingleLineWidth;
142
+ }
143
+ const decisionWidth = currentSingleLineWidth ??
144
+ Math.max(1, root.clientWidth - INLINE_STACKED_INLINE_PADDING_PX);
145
+ const stackedWidth = Math.max(1, root.clientWidth - INLINE_STACKED_INLINE_PADDING_PX);
146
+ const decision = measureInlineTextarea(measureTextarea, chatInput, decisionWidth);
147
+ const nextIsInlineMultiline = chatInput.includes("\n") || decision.wraps;
148
+ const heightMeasurement = nextIsInlineMultiline
149
+ ? measureInlineTextarea(measureTextarea, chatInput, stackedWidth)
150
+ : decision;
151
+ const nextHeight = nextIsInlineMultiline
152
+ ? Math.min(Math.max(heightMeasurement.scrollHeight, INLINE_TEXTAREA_MIN_HEIGHT_PX), INLINE_TEXTAREA_MAX_HEIGHT_PX)
153
+ : INLINE_TEXTAREA_MIN_HEIGHT_PX;
80
154
  textarea.style.height = `${nextHeight}px`;
81
155
  textarea.style.overflowY =
82
- textarea.scrollHeight > maxHeight ? "auto" : "hidden";
83
- setIsInlineMultiline(nextHeight > minHeight);
84
- }, [chatInput, isInline, textareaRef]);
156
+ heightMeasurement.scrollHeight > INLINE_TEXTAREA_MAX_HEIGHT_PX
157
+ ? "auto"
158
+ : "hidden";
159
+ setIsInlineMultiline(nextIsInlineMultiline);
160
+ }, [
161
+ chatInput,
162
+ inlineMeasureVersion,
163
+ isInline,
164
+ isInlineMultiline,
165
+ textareaRef,
166
+ ]);
85
167
  const startPushToTalk = () => {
86
168
  if (isComposerLocked || voice.isListening)
87
169
  return;
@@ -161,13 +243,13 @@ export function ChatComposer({ variant, layout = "default", textareaRef, chatInp
161
243
  const inlineStopButton = (_jsx(Button, { variant: "surfaceDestructive", "data-testid": "chat-composer-action", className: "h-8 w-8 shrink-0 rounded-full bg-danger/15 p-0 text-danger shadow-none transition-colors hover:bg-danger/25 focus-visible:ring-0 focus-visible:ring-offset-0", onClick: onStop, size: "icon", title: actionButtonLabel, "aria-label": actionButtonLabel, children: _jsx(Square, { className: "h-3.5 w-3.5 fill-current" }) }));
162
244
  const inlineStopSpeakingButton = (_jsx(Button, { variant: "surfaceDestructive", "data-testid": "chat-composer-action", className: "h-8 w-8 shrink-0 rounded-full bg-danger/15 p-0 text-danger shadow-none transition-colors hover:bg-danger/25 focus-visible:ring-0 focus-visible:ring-offset-0", onClick: onStopSpeaking, size: "icon", title: actionButtonLabel, "aria-label": actionButtonLabel, children: _jsx(Square, { className: "h-3.5 w-3.5 fill-current" }) }));
163
245
  const inlineTrailingActions = shouldShowStopButton ? (inlineStopButton) : !isGameModal && voice.isSpeaking && !hasDraft ? (inlineStopSpeakingButton) : isInlineMultiline ? (_jsxs(_Fragment, { children: [inlineMicButton, inlineSendButton] })) : hasDraft ? (inlineSendButton) : (inlineMicButton);
164
- return (_jsx("div", { "data-inline-layout": isInlineMultiline ? "stacked" : "single-line", className: isInlineMultiline
165
- ? "flex min-h-[64px] flex-col gap-1 rounded-[22px] border border-border/35 bg-card/45 px-1.5 py-1.5"
166
- : "flex min-h-[40px] items-center gap-1 rounded-full border border-border/35 bg-card/45 px-1 py-1", children: isInlineMultiline ? (_jsxs(_Fragment, { children: [inlineTextarea, _jsxs("div", { className: "flex min-w-0 items-center gap-1", children: [inlineAttachButton, renderCreateTaskButton(), _jsx("div", { className: "min-w-0 flex-1" }), inlineTrailingActions] })] })) : (_jsxs(_Fragment, { children: [inlineAttachButton, renderCreateTaskButton(), inlineTextarea, inlineTrailingActions] })) }));
246
+ return (_jsxs("div", { ref: inlineRootRef, "data-chat-composer": "true", "data-inline-layout": isInlineMultiline ? "stacked" : "single-line", className: isInlineMultiline
247
+ ? `flex min-h-[64px] flex-col gap-1 rounded-[22px] border border-border/35 bg-card/45 px-1.5 py-1.5 ${chatComposerFocusResetClass}`
248
+ : `flex min-h-[40px] items-center gap-1 rounded-full border border-border/35 bg-card/45 px-1 py-1 ${chatComposerFocusResetClass}`, children: [_jsx("textarea", { ref: inlineMeasureRef, "aria-hidden": "true", className: inlineMeasureTextareaClass, "data-chat-composer-measure": "true", readOnly: true, rows: 1, tabIndex: -1, value: chatInput }), isInlineMultiline ? (_jsxs(_Fragment, { children: [inlineTextarea, _jsxs("div", { className: "flex min-w-0 items-center gap-1", children: [inlineAttachButton, renderCreateTaskButton(), _jsx("div", { className: "min-w-0 flex-1" }), inlineTrailingActions] })] })) : (_jsxs(_Fragment, { children: [inlineAttachButton, renderCreateTaskButton(), inlineTextarea, inlineTrailingActions] }))] }));
167
249
  }
168
- return (_jsxs("div", { className: isGameModal
169
- ? "relative flex w-full items-end gap-2 transition-all max-[380px]:gap-1.5"
170
- : "flex items-center gap-1.5 sm:gap-2", children: [!isGameModal && !hideAttachButton ? (_jsx(Button, { variant: "ghost", size: "icon", className: isInline
250
+ return (_jsxs("div", { "data-chat-composer": "true", className: isGameModal
251
+ ? `relative flex w-full items-end gap-2 transition-all max-[380px]:gap-1.5 ${chatComposerFocusResetClass}`
252
+ : `flex items-center gap-1.5 sm:gap-2 ${chatComposerFocusResetClass}`, children: [!isGameModal && !hideAttachButton ? (_jsx(Button, { variant: "ghost", size: "icon", className: isInline
171
253
  ? `h-8 w-8 shrink-0 rounded-full bg-bg/60 p-0 text-muted shadow-none transition-colors hover:bg-bg/60 hover:text-txt focus-visible:ring-0 focus-visible:ring-offset-0 ${chatPendingImagesCount > 0
172
254
  ? "text-accent hover:text-accent"
173
255
  : ""}`
@@ -1 +1 @@
1
- {"version":3,"file":"page-layout-mobile-drawer.d.ts","sourceRoot":"","sources":["../../../../../../src/layouts/page-layout/page-layout-mobile-drawer.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAEvE,wBAAgB,sBAAsB,CAAC,EACrC,SAAS,EACT,kBAAkB,EAClB,iBAAiB,EACjB,6BAA6B,EAC7B,yBAAyB,EACzB,OAAO,GACR,EAAE,2BAA2B,kDAsD7B"}
1
+ {"version":3,"file":"page-layout-mobile-drawer.d.ts","sourceRoot":"","sources":["../../../../../../src/layouts/page-layout/page-layout-mobile-drawer.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAEvE,wBAAgB,sBAAsB,CAAC,EACrC,SAAS,EACT,kBAAkB,EAClB,iBAAiB,EACjB,6BAA6B,EAC7B,yBAAyB,EACzB,OAAO,GACR,EAAE,2BAA2B,kDAsE7B"}
@@ -2,11 +2,11 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { PanelLeftOpen } from "lucide-react";
3
3
  import * as React from "react";
4
4
  import { Button } from "../../components/ui/button";
5
- import { DrawerSheet, DrawerSheetContent, DrawerSheetHeader, DrawerSheetTitle, } from "../../components/ui/drawer-sheet";
6
5
  import { cn } from "../../lib/utils";
6
+ import { useWorkspaceMobileSidebarControls } from "../workspace-layout/workspace-mobile-sidebar-controls";
7
7
  export function PageLayoutMobileDrawer({ isDesktop, mobileSidebarLabel, mobileSidebarOpen, mobileSidebarTriggerClassName, onMobileSidebarOpenChange, sidebar, }) {
8
- if (isDesktop)
9
- return null;
8
+ const controls = useWorkspaceMobileSidebarControls();
9
+ const sidebarId = React.useId();
10
10
  const mobileSidebarElement = React.cloneElement(sidebar, {
11
11
  className: cn("!mt-0 !h-full !w-full !min-w-0", sidebar.props.className),
12
12
  collapsible: false,
@@ -14,5 +14,24 @@ export function PageLayoutMobileDrawer({ isDesktop, mobileSidebarLabel, mobileSi
14
14
  onMobileClose: () => onMobileSidebarOpenChange(false),
15
15
  });
16
16
  const drawerLabel = sidebar.props.mobileTitle ?? mobileSidebarLabel ?? "Browse";
17
- return (_jsxs(_Fragment, { children: [!mobileSidebarOpen ? (_jsx("div", { className: "pointer-events-none fixed left-2 z-40 md:hidden", style: { top: "var(--safe-area-top, 0px)" }, children: _jsx("div", { className: "pointer-events-auto", children: _jsxs(Button, { type: "button", variant: "outline", size: "sm", className: cn("h-[2.375rem] max-w-[min(11rem,calc(100vw-5.5rem))] rounded-full border-border/40 bg-card/92 px-3 text-sm font-semibold text-txt shadow-sm backdrop-blur-md", mobileSidebarTriggerClassName), onClick: () => onMobileSidebarOpenChange(true), children: [_jsx(PanelLeftOpen, { className: "h-4 w-4 shrink-0" }), _jsx("span", { className: "truncate", children: drawerLabel })] }) }) })) : null, _jsx(DrawerSheet, { open: mobileSidebarOpen, onOpenChange: onMobileSidebarOpenChange, children: _jsxs(DrawerSheetContent, { "aria-describedby": undefined, className: "h-[min(calc(100dvh-1rem-var(--safe-area-top,0px)-var(--safe-area-bottom,0px)),46rem)] p-0", showCloseButton: false, children: [_jsx(DrawerSheetHeader, { className: "sr-only", children: _jsx(DrawerSheetTitle, { children: drawerLabel }) }), mobileSidebarElement] }) })] }));
17
+ React.useEffect(() => {
18
+ if (!controls || isDesktop)
19
+ return undefined;
20
+ return controls.register({
21
+ id: sidebarId,
22
+ label: drawerLabel,
23
+ open: mobileSidebarOpen,
24
+ setOpen: onMobileSidebarOpenChange,
25
+ });
26
+ }, [
27
+ controls,
28
+ drawerLabel,
29
+ isDesktop,
30
+ mobileSidebarOpen,
31
+ onMobileSidebarOpenChange,
32
+ sidebarId,
33
+ ]);
34
+ if (isDesktop)
35
+ return null;
36
+ return (_jsxs(_Fragment, { children: [!mobileSidebarOpen && !controls ? (_jsx("div", { className: "pointer-events-none fixed left-2 z-40 md:hidden", style: { top: "calc(var(--safe-area-top, 0px) + 2.75rem)" }, children: _jsx("div", { className: "pointer-events-auto", children: _jsxs(Button, { type: "button", variant: "outline", size: "sm", className: cn("h-[2.375rem] max-w-[min(11rem,calc(100vw-5.5rem))] rounded-full border-border/40 bg-card/92 px-3 text-sm font-semibold text-txt shadow-sm backdrop-blur-md", mobileSidebarTriggerClassName), "data-testid": "page-layout-mobile-sidebar-trigger", onClick: () => onMobileSidebarOpenChange(true), children: [_jsx(PanelLeftOpen, { className: "h-4 w-4 shrink-0" }), _jsx("span", { className: "truncate", children: drawerLabel })] }) }) })) : null, mobileSidebarOpen ? (_jsx("section", { className: "flex min-h-0 w-full flex-1 overflow-hidden", "data-testid": "page-layout-mobile-sidebar-drawer", "aria-label": typeof drawerLabel === "string" ? drawerLabel : undefined, children: mobileSidebarElement })) : null] }));
18
37
  }
@@ -1,3 +1,4 @@
1
1
  export * from "./workspace-layout";
2
2
  export * from "./workspace-layout-types";
3
+ export * from "./workspace-mobile-sidebar-controls";
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/layouts/workspace-layout/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/layouts/workspace-layout/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qCAAqC,CAAC"}
@@ -1,2 +1,3 @@
1
1
  export * from "./workspace-layout";
2
2
  export * from "./workspace-layout-types";
3
+ export * from "./workspace-mobile-sidebar-controls";
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-layout.d.ts","sourceRoot":"","sources":["../../../../../../src/layouts/workspace-layout/workspace-layout.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAiDrE,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,sBAAsB,EACtB,qBAAqB,EACrB,cAAqB,EACrB,UAAU,EACV,MAAM,EACN,eAAe,EACf,eAA2B,EAC3B,kBAAkB,EAClB,6BAA6B,EAC7B,OAAO,EACP,kBAAyB,EACzB,GAAG,KAAK,EACT,EAAE,oBAAoB,2CA8FtB"}
1
+ {"version":3,"file":"workspace-layout.d.ts","sourceRoot":"","sources":["../../../../../../src/layouts/workspace-layout/workspace-layout.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAiDrE,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,sBAAsB,EACtB,qBAAqB,EACrB,cAAqB,EACrB,UAAU,EACV,MAAM,EACN,eAAe,EACf,eAA2B,EAC3B,kBAAkB,EAClB,6BAA6B,EAC7B,OAAO,EACP,kBAAyB,EACzB,GAAG,KAAK,EACT,EAAE,oBAAoB,2CAwGtB"}
@@ -41,6 +41,7 @@ function useWorkspaceLayoutDesktopMode() {
41
41
  export function WorkspaceLayout({ children, className, contentClassName, contentHeader, contentHeaderClassName, contentInnerClassName, contentPadding = true, contentRef, footer, footerClassName, headerPlacement = "outside", mobileSidebarLabel, mobileSidebarTriggerClassName, sidebar, sidebarCollapsible = true, ...props }) {
42
42
  const isDesktop = useWorkspaceLayoutDesktopMode();
43
43
  const [mobileSidebarOpen, setMobileSidebarOpen] = React.useState(false);
44
+ const showMobileSidebarPane = Boolean(sidebar && !isDesktop && mobileSidebarOpen);
44
45
  React.useEffect(() => {
45
46
  if (isDesktop) {
46
47
  setMobileSidebarOpen(false);
@@ -54,6 +55,11 @@ export function WorkspaceLayout({ children, className, contentClassName, content
54
55
  })
55
56
  : null;
56
57
  const headerElement = contentHeader ? (_jsx(PageLayoutHeader, { className: contentHeaderClassName, children: contentHeader })) : null;
57
- return (_jsxs("div", { className: cn("flex w-full min-h-0 min-w-0 flex-1 flex-col overflow-hidden", className), ...props, children: [contentHeader && headerPlacement === "outside" ? (_jsx("div", { className: cn("shrink-0", contentPadding && "px-4 pt-2 sm:px-6 sm:pt-3 lg:px-7 lg:pt-4"), children: headerElement })) : null, _jsxs("div", { className: cn("flex w-full min-h-0 min-w-0 flex-1 flex-col", sidebar && "md:flex-row"), children: [desktopSidebarElement ? (_jsx("div", { className: cn("hidden min-h-0 w-full shrink-0 items-stretch px-0 pb-0 md:flex md:w-auto", contentPadding && "pt-2 sm:pt-3 lg:pt-4"), children: desktopSidebarElement })) : null, _jsxs("main", { ref: (node) => assignRef(contentRef, node), className: cn("chat-native-scrollbar relative flex min-w-0 flex-1 flex-col overflow-y-auto bg-transparent", contentPadding &&
58
- "px-4 pb-4 pt-2 sm:px-6 sm:pb-6 sm:pt-3 lg:px-7 lg:pb-7 lg:pt-4", contentClassName), children: [sidebar ? (_jsx(PageLayoutMobileDrawer, { isDesktop: isDesktop, mobileSidebarLabel: mobileSidebarLabel, mobileSidebarOpen: mobileSidebarOpen, mobileSidebarTriggerClassName: mobileSidebarTriggerClassName, onMobileSidebarOpenChange: setMobileSidebarOpen, sidebar: sidebar })) : null, contentHeader && headerPlacement === "inside" ? headerElement : null, _jsx("div", { className: cn("flex w-full min-h-0 flex-1 flex-col", contentInnerClassName), children: children })] })] })] }));
58
+ return (_jsxs("div", { className: cn("flex w-full min-h-0 min-w-0 flex-1 flex-col overflow-hidden", className), ...props, children: [contentHeader && headerPlacement === "outside" ? (_jsx("div", { className: cn("shrink-0", contentPadding && "px-4 pt-2 sm:px-6 sm:pt-3 lg:px-7 lg:pt-4"), children: headerElement })) : null, _jsxs("div", { className: cn("flex w-full min-h-0 min-w-0 flex-1 flex-col", sidebar && "md:flex-row"), children: [desktopSidebarElement ? (_jsx("div", { className: cn("hidden min-h-0 w-full shrink-0 items-stretch px-0 pb-0 md:flex md:w-auto", contentPadding && "pt-2 sm:pt-3 lg:pt-4"), children: desktopSidebarElement })) : null, _jsxs("main", { ref: (node) => assignRef(contentRef, node), className: cn("chat-native-scrollbar relative flex min-w-0 flex-1 flex-col bg-transparent", showMobileSidebarPane ? "overflow-hidden" : "overflow-y-auto", contentPadding &&
59
+ !showMobileSidebarPane &&
60
+ "px-4 pb-4 pt-2 sm:px-6 sm:pb-6 sm:pt-3 lg:px-7 lg:pb-7 lg:pt-4", !showMobileSidebarPane && contentClassName), children: [sidebar ? (_jsx(PageLayoutMobileDrawer, { isDesktop: isDesktop, mobileSidebarLabel: mobileSidebarLabel, mobileSidebarOpen: mobileSidebarOpen, mobileSidebarTriggerClassName: mobileSidebarTriggerClassName, onMobileSidebarOpenChange: setMobileSidebarOpen, sidebar: sidebar })) : null, contentHeader &&
61
+ headerPlacement === "inside" &&
62
+ !showMobileSidebarPane
63
+ ? headerElement
64
+ : null, _jsx("div", { className: cn("flex w-full min-h-0 flex-1 flex-col", contentInnerClassName, showMobileSidebarPane && "hidden"), children: children })] })] })] }));
59
65
  }
@@ -0,0 +1,13 @@
1
+ import * as React from "react";
2
+ export interface WorkspaceMobileSidebarControl {
3
+ id: string;
4
+ label?: React.ReactNode;
5
+ open: boolean;
6
+ setOpen: (open: boolean) => void;
7
+ }
8
+ export interface WorkspaceMobileSidebarControls {
9
+ register: (control: WorkspaceMobileSidebarControl) => () => void;
10
+ }
11
+ export declare const WorkspaceMobileSidebarControlsContext: React.Context<WorkspaceMobileSidebarControls | null>;
12
+ export declare function useWorkspaceMobileSidebarControls(): WorkspaceMobileSidebarControls | null;
13
+ //# sourceMappingURL=workspace-mobile-sidebar-controls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-mobile-sidebar-controls.d.ts","sourceRoot":"","sources":["../../../../../../src/layouts/workspace-layout/workspace-mobile-sidebar-controls.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,WAAW,6BAA6B;IAC5C,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,EAAE,CAAC,OAAO,EAAE,6BAA6B,KAAK,MAAM,IAAI,CAAC;CAClE;AAED,eAAO,MAAM,qCAAqC,sDACgB,CAAC;AAEnE,wBAAgB,iCAAiC,IAAI,8BAA8B,GAAG,IAAI,CAEzF"}
@@ -0,0 +1,5 @@
1
+ import * as React from "react";
2
+ export const WorkspaceMobileSidebarControlsContext = React.createContext(null);
3
+ export function useWorkspaceMobileSidebarControls() {
4
+ return React.useContext(WorkspaceMobileSidebarControlsContext);
5
+ }