@djangocfg/ui-tools 2.1.349 → 2.1.350

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/dist/index.cjs CHANGED
@@ -7,7 +7,7 @@ var chunkKNDLV4PI_cjs = require('./chunk-KNDLV4PI.cjs');
7
7
  var chunk5I5QNGUG_cjs = require('./chunk-5I5QNGUG.cjs');
8
8
  var chunkYW5IVWHQ_cjs = require('./chunk-YW5IVWHQ.cjs');
9
9
  var chunk76NNDZH6_cjs = require('./chunk-76NNDZH6.cjs');
10
- var chunkXYGB26BY_cjs = require('./chunk-XYGB26BY.cjs');
10
+ var chunkHVIL2FEQ_cjs = require('./chunk-HVIL2FEQ.cjs');
11
11
  var chunkYXZ6GU7H_cjs = require('./chunk-YXZ6GU7H.cjs');
12
12
  var chunkIEEAENLX_cjs = require('./chunk-IEEAENLX.cjs');
13
13
  var chunkQW4RBGHN_cjs = require('./chunk-QW4RBGHN.cjs');
@@ -372,7 +372,7 @@ var LazyTree = createLazyComponent(
372
372
  }
373
373
  );
374
374
  var LazyChat = createLazyComponent(
375
- () => import('./ChatRoot-VTYANC7M.cjs').then((m) => ({ default: m.ChatRoot })),
375
+ () => import('./ChatRoot-7TTJRYBA.cjs').then((m) => ({ default: m.ChatRoot })),
376
376
  {
377
377
  displayName: "LazyChat",
378
378
  fallback: /* @__PURE__ */ jsxRuntime.jsx(LoadingFallback, { minHeight: 320, text: "Loading chat\u2026" })
@@ -409,7 +409,7 @@ async function* parseSSE(response, options = {}) {
409
409
  throw new Error("SSE response has no body");
410
410
  }
411
411
  const map = options.map ?? DEFAULT_MAP;
412
- const idleMs = options.idleTimeoutMs ?? chunkXYGB26BY_cjs.LIMITS.sseIdleMs;
412
+ const idleMs = options.idleTimeoutMs ?? chunkHVIL2FEQ_cjs.LIMITS.sseIdleMs;
413
413
  const reader = response.body.getReader();
414
414
  const decoder = new TextDecoder();
415
415
  let buffer = "";
@@ -612,7 +612,7 @@ function createMockTransport(opts = {}) {
612
612
  async createSession(_opts) {
613
613
  await sleep(latency);
614
614
  return {
615
- sessionId: chunkXYGB26BY_cjs.createId("s"),
615
+ sessionId: chunkHVIL2FEQ_cjs.createId("s"),
616
616
  messages: history.length ? [...history] : void 0,
617
617
  hasMore: false,
618
618
  cursor: null,
@@ -629,12 +629,12 @@ function createMockTransport(opts = {}) {
629
629
  throw new Error("mock transport scripted failure");
630
630
  }
631
631
  history.push({
632
- id: chunkXYGB26BY_cjs.createId("u"),
632
+ id: chunkHVIL2FEQ_cjs.createId("u"),
633
633
  role: "user",
634
634
  content,
635
635
  createdAt: Date.now()
636
636
  });
637
- const messageId = chunkXYGB26BY_cjs.createId("a");
637
+ const messageId = chunkHVIL2FEQ_cjs.createId("a");
638
638
  yield { type: "message_start", messageId, sessionId: _sid };
639
639
  const reply = replies[turn % replies.length];
640
640
  turn += 1;
@@ -663,7 +663,7 @@ function createMockTransport(opts = {}) {
663
663
  turn += 1;
664
664
  const text = typeof reply === "string" ? reply : reply.filter((e) => e.type === "chunk").map((e) => e.delta).join("");
665
665
  return {
666
- id: chunkXYGB26BY_cjs.createId("a"),
666
+ id: chunkHVIL2FEQ_cjs.createId("a"),
667
667
  role: "assistant",
668
668
  content: text || DEFAULT_REPLY,
669
669
  createdAt: Date.now()
@@ -2019,159 +2019,159 @@ Object.defineProperty(exports, "useCronWeekDays", {
2019
2019
  });
2020
2020
  Object.defineProperty(exports, "Attachments", {
2021
2021
  enumerable: true,
2022
- get: function () { return chunkXYGB26BY_cjs.Attachments; }
2022
+ get: function () { return chunkHVIL2FEQ_cjs.Attachments; }
2023
2023
  });
2024
2024
  Object.defineProperty(exports, "AttachmentsGrid", {
2025
2025
  enumerable: true,
2026
- get: function () { return chunkXYGB26BY_cjs.AttachmentsGrid; }
2026
+ get: function () { return chunkHVIL2FEQ_cjs.AttachmentsGrid; }
2027
2027
  });
2028
2028
  Object.defineProperty(exports, "AttachmentsList", {
2029
2029
  enumerable: true,
2030
- get: function () { return chunkXYGB26BY_cjs.AttachmentsList; }
2030
+ get: function () { return chunkHVIL2FEQ_cjs.AttachmentsList; }
2031
2031
  });
2032
2032
  Object.defineProperty(exports, "CHAT_EVENT_NAME", {
2033
2033
  enumerable: true,
2034
- get: function () { return chunkXYGB26BY_cjs.CHAT_EVENT_NAME; }
2034
+ get: function () { return chunkHVIL2FEQ_cjs.CHAT_EVENT_NAME; }
2035
2035
  });
2036
2036
  Object.defineProperty(exports, "CSS_VARS", {
2037
2037
  enumerable: true,
2038
- get: function () { return chunkXYGB26BY_cjs.CSS_VARS; }
2038
+ get: function () { return chunkHVIL2FEQ_cjs.CSS_VARS; }
2039
2039
  });
2040
2040
  Object.defineProperty(exports, "ChatProvider", {
2041
2041
  enumerable: true,
2042
- get: function () { return chunkXYGB26BY_cjs.ChatProvider; }
2042
+ get: function () { return chunkHVIL2FEQ_cjs.ChatProvider; }
2043
2043
  });
2044
2044
  Object.defineProperty(exports, "ChatRoot", {
2045
2045
  enumerable: true,
2046
- get: function () { return chunkXYGB26BY_cjs.ChatRoot; }
2046
+ get: function () { return chunkHVIL2FEQ_cjs.ChatRoot; }
2047
2047
  });
2048
2048
  Object.defineProperty(exports, "Composer", {
2049
2049
  enumerable: true,
2050
- get: function () { return chunkXYGB26BY_cjs.Composer; }
2050
+ get: function () { return chunkHVIL2FEQ_cjs.Composer; }
2051
2051
  });
2052
2052
  Object.defineProperty(exports, "DEFAULT_LABELS", {
2053
2053
  enumerable: true,
2054
- get: function () { return chunkXYGB26BY_cjs.DEFAULT_LABELS; }
2054
+ get: function () { return chunkHVIL2FEQ_cjs.DEFAULT_LABELS; }
2055
2055
  });
2056
2056
  Object.defineProperty(exports, "DEFAULT_SIDEBAR", {
2057
2057
  enumerable: true,
2058
- get: function () { return chunkXYGB26BY_cjs.DEFAULT_SIDEBAR; }
2058
+ get: function () { return chunkHVIL2FEQ_cjs.DEFAULT_SIDEBAR; }
2059
2059
  });
2060
2060
  Object.defineProperty(exports, "DEFAULT_Z_INDEX", {
2061
2061
  enumerable: true,
2062
- get: function () { return chunkXYGB26BY_cjs.DEFAULT_Z_INDEX; }
2062
+ get: function () { return chunkHVIL2FEQ_cjs.DEFAULT_Z_INDEX; }
2063
2063
  });
2064
2064
  Object.defineProperty(exports, "EmptyState", {
2065
2065
  enumerable: true,
2066
- get: function () { return chunkXYGB26BY_cjs.EmptyState; }
2066
+ get: function () { return chunkHVIL2FEQ_cjs.EmptyState; }
2067
2067
  });
2068
2068
  Object.defineProperty(exports, "ErrorBanner", {
2069
2069
  enumerable: true,
2070
- get: function () { return chunkXYGB26BY_cjs.ErrorBanner; }
2070
+ get: function () { return chunkHVIL2FEQ_cjs.ErrorBanner; }
2071
2071
  });
2072
2072
  Object.defineProperty(exports, "HOTKEYS", {
2073
2073
  enumerable: true,
2074
- get: function () { return chunkXYGB26BY_cjs.HOTKEYS; }
2074
+ get: function () { return chunkHVIL2FEQ_cjs.HOTKEYS; }
2075
2075
  });
2076
2076
  Object.defineProperty(exports, "JumpToLatest", {
2077
2077
  enumerable: true,
2078
- get: function () { return chunkXYGB26BY_cjs.JumpToLatest; }
2078
+ get: function () { return chunkHVIL2FEQ_cjs.JumpToLatest; }
2079
2079
  });
2080
2080
  Object.defineProperty(exports, "LIMITS", {
2081
2081
  enumerable: true,
2082
- get: function () { return chunkXYGB26BY_cjs.LIMITS; }
2082
+ get: function () { return chunkHVIL2FEQ_cjs.LIMITS; }
2083
2083
  });
2084
2084
  Object.defineProperty(exports, "MessageActions", {
2085
2085
  enumerable: true,
2086
- get: function () { return chunkXYGB26BY_cjs.MessageActions; }
2086
+ get: function () { return chunkHVIL2FEQ_cjs.MessageActions; }
2087
2087
  });
2088
2088
  Object.defineProperty(exports, "MessageBubble", {
2089
2089
  enumerable: true,
2090
- get: function () { return chunkXYGB26BY_cjs.MessageBubble; }
2090
+ get: function () { return chunkHVIL2FEQ_cjs.MessageBubble; }
2091
2091
  });
2092
2092
  Object.defineProperty(exports, "MessageList", {
2093
2093
  enumerable: true,
2094
- get: function () { return chunkXYGB26BY_cjs.MessageList; }
2094
+ get: function () { return chunkHVIL2FEQ_cjs.MessageList; }
2095
2095
  });
2096
2096
  Object.defineProperty(exports, "STORAGE_KEYS", {
2097
2097
  enumerable: true,
2098
- get: function () { return chunkXYGB26BY_cjs.STORAGE_KEYS; }
2098
+ get: function () { return chunkHVIL2FEQ_cjs.STORAGE_KEYS; }
2099
2099
  });
2100
2100
  Object.defineProperty(exports, "Sources", {
2101
2101
  enumerable: true,
2102
- get: function () { return chunkXYGB26BY_cjs.Sources; }
2102
+ get: function () { return chunkHVIL2FEQ_cjs.Sources; }
2103
2103
  });
2104
2104
  Object.defineProperty(exports, "StreamingIndicator", {
2105
2105
  enumerable: true,
2106
- get: function () { return chunkXYGB26BY_cjs.StreamingIndicator; }
2106
+ get: function () { return chunkHVIL2FEQ_cjs.StreamingIndicator; }
2107
2107
  });
2108
2108
  Object.defineProperty(exports, "ToolCalls", {
2109
2109
  enumerable: true,
2110
- get: function () { return chunkXYGB26BY_cjs.ToolCalls; }
2110
+ get: function () { return chunkHVIL2FEQ_cjs.ToolCalls; }
2111
2111
  });
2112
2112
  Object.defineProperty(exports, "createId", {
2113
2113
  enumerable: true,
2114
- get: function () { return chunkXYGB26BY_cjs.createId; }
2114
+ get: function () { return chunkHVIL2FEQ_cjs.createId; }
2115
2115
  });
2116
2116
  Object.defineProperty(exports, "createTokenBuffer", {
2117
2117
  enumerable: true,
2118
- get: function () { return chunkXYGB26BY_cjs.createTokenBuffer; }
2118
+ get: function () { return chunkHVIL2FEQ_cjs.createTokenBuffer; }
2119
2119
  });
2120
2120
  Object.defineProperty(exports, "deriveInitials", {
2121
2121
  enumerable: true,
2122
- get: function () { return chunkXYGB26BY_cjs.deriveInitials; }
2122
+ get: function () { return chunkHVIL2FEQ_cjs.deriveInitials; }
2123
2123
  });
2124
2124
  Object.defineProperty(exports, "getChatLogger", {
2125
2125
  enumerable: true,
2126
- get: function () { return chunkXYGB26BY_cjs.getChatLogger; }
2126
+ get: function () { return chunkHVIL2FEQ_cjs.getChatLogger; }
2127
2127
  });
2128
2128
  Object.defineProperty(exports, "initialState", {
2129
2129
  enumerable: true,
2130
- get: function () { return chunkXYGB26BY_cjs.initialState; }
2130
+ get: function () { return chunkHVIL2FEQ_cjs.initialState; }
2131
2131
  });
2132
2132
  Object.defineProperty(exports, "reducer", {
2133
2133
  enumerable: true,
2134
- get: function () { return chunkXYGB26BY_cjs.reducer; }
2134
+ get: function () { return chunkHVIL2FEQ_cjs.reducer; }
2135
2135
  });
2136
2136
  Object.defineProperty(exports, "resolvePersona", {
2137
2137
  enumerable: true,
2138
- get: function () { return chunkXYGB26BY_cjs.resolvePersona; }
2138
+ get: function () { return chunkHVIL2FEQ_cjs.resolvePersona; }
2139
2139
  });
2140
2140
  Object.defineProperty(exports, "useChat", {
2141
2141
  enumerable: true,
2142
- get: function () { return chunkXYGB26BY_cjs.useChat; }
2142
+ get: function () { return chunkHVIL2FEQ_cjs.useChat; }
2143
2143
  });
2144
2144
  Object.defineProperty(exports, "useChatAudio", {
2145
2145
  enumerable: true,
2146
- get: function () { return chunkXYGB26BY_cjs.useChatAudio; }
2146
+ get: function () { return chunkHVIL2FEQ_cjs.useChatAudio; }
2147
2147
  });
2148
2148
  Object.defineProperty(exports, "useChatAudioPrefs", {
2149
2149
  enumerable: true,
2150
- get: function () { return chunkXYGB26BY_cjs.useChatAudioPrefs; }
2150
+ get: function () { return chunkHVIL2FEQ_cjs.useChatAudioPrefs; }
2151
2151
  });
2152
2152
  Object.defineProperty(exports, "useChatComposer", {
2153
2153
  enumerable: true,
2154
- get: function () { return chunkXYGB26BY_cjs.useChatComposer; }
2154
+ get: function () { return chunkHVIL2FEQ_cjs.useChatComposer; }
2155
2155
  });
2156
2156
  Object.defineProperty(exports, "useChatContext", {
2157
2157
  enumerable: true,
2158
- get: function () { return chunkXYGB26BY_cjs.useChatContext; }
2158
+ get: function () { return chunkHVIL2FEQ_cjs.useChatContext; }
2159
2159
  });
2160
2160
  Object.defineProperty(exports, "useChatContextOptional", {
2161
2161
  enumerable: true,
2162
- get: function () { return chunkXYGB26BY_cjs.useChatContextOptional; }
2162
+ get: function () { return chunkHVIL2FEQ_cjs.useChatContextOptional; }
2163
2163
  });
2164
2164
  Object.defineProperty(exports, "useChatHistory", {
2165
2165
  enumerable: true,
2166
- get: function () { return chunkXYGB26BY_cjs.useChatHistory; }
2166
+ get: function () { return chunkHVIL2FEQ_cjs.useChatHistory; }
2167
2167
  });
2168
2168
  Object.defineProperty(exports, "useChatLayout", {
2169
2169
  enumerable: true,
2170
- get: function () { return chunkXYGB26BY_cjs.useChatLayout; }
2170
+ get: function () { return chunkHVIL2FEQ_cjs.useChatLayout; }
2171
2171
  });
2172
2172
  Object.defineProperty(exports, "useChatScroll", {
2173
2173
  enumerable: true,
2174
- get: function () { return chunkXYGB26BY_cjs.useChatScroll; }
2174
+ get: function () { return chunkHVIL2FEQ_cjs.useChatScroll; }
2175
2175
  });
2176
2176
  Object.defineProperty(exports, "TreeError", {
2177
2177
  enumerable: true,
package/dist/index.d.cts CHANGED
@@ -1869,6 +1869,32 @@ interface UseChatComposerReturn {
1869
1869
  }
1870
1870
  declare function useChatComposer(options: UseChatComposerOptions): UseChatComposerReturn;
1871
1871
 
1872
+ type ComposerSize = 'sm' | 'md' | 'lg';
1873
+ interface ComposerProps {
1874
+ composer: UseChatComposerReturn;
1875
+ placeholder?: string;
1876
+ disabled?: boolean;
1877
+ showAttachmentButton?: boolean;
1878
+ onPickFiles?: () => void;
1879
+ toolbarStart?: ReactNode;
1880
+ toolbarEnd?: ReactNode;
1881
+ attachmentTray?: ReactNode;
1882
+ className?: string;
1883
+ textareaClassName?: string;
1884
+ /** Visual size — controls textarea height + button slot size.
1885
+ *
1886
+ * - ``sm`` — 32px slot, dense compact composer (admin sidebars, etc).
1887
+ * - ``md`` — 36px slot, default. Same as the legacy fixed size.
1888
+ * - ``lg`` — 48px slot, generous textarea. Use when the chat is
1889
+ * the page's primary surface (onboarding, support).
1890
+ */
1891
+ size?: ComposerSize;
1892
+ /** Show "Stop" button instead of "Send" while streaming. */
1893
+ isStreaming?: boolean;
1894
+ onCancel?: () => void;
1895
+ }
1896
+ declare const Composer: react.ForwardRefExoticComponent<ComposerProps & react.RefAttributes<HTMLDivElement>>;
1897
+
1872
1898
  interface AttachmentRendererArgs {
1873
1899
  attachment: ChatAttachment;
1874
1900
  /** True when shown inside the composer's staging tray (denser layout). */
@@ -1980,6 +2006,9 @@ interface ChatRootProps {
1980
2006
  onPickFiles?: () => void;
1981
2007
  /** Hide the composer input area entirely (e.g. while waiting for human approval). */
1982
2008
  hideComposer?: boolean;
2009
+ /** Composer size variant. Default ``md`` (36px slot). Use ``lg`` for primary
2010
+ * surfaces (onboarding, full-page chat), ``sm`` for dense sidebars. */
2011
+ composerSize?: ComposerSize;
1983
2012
  }
1984
2013
  declare function ChatRoot(props: ChatRootProps): react_jsx_runtime.JSX.Element;
1985
2014
 
@@ -2315,23 +2344,6 @@ interface MessageActionsProps {
2315
2344
  }
2316
2345
  declare function MessageActions({ role, onCopy, onRegenerate, onEdit, onDelete, hideOn, className, }: MessageActionsProps): react_jsx_runtime.JSX.Element;
2317
2346
 
2318
- interface ComposerProps {
2319
- composer: UseChatComposerReturn;
2320
- placeholder?: string;
2321
- disabled?: boolean;
2322
- showAttachmentButton?: boolean;
2323
- onPickFiles?: () => void;
2324
- toolbarStart?: ReactNode;
2325
- toolbarEnd?: ReactNode;
2326
- attachmentTray?: ReactNode;
2327
- className?: string;
2328
- textareaClassName?: string;
2329
- /** Show "Stop" button instead of "Send" while streaming. */
2330
- isStreaming?: boolean;
2331
- onCancel?: () => void;
2332
- }
2333
- declare const Composer: react.ForwardRefExoticComponent<ComposerProps & react.RefAttributes<HTMLDivElement>>;
2334
-
2335
2347
  interface SourcesProps {
2336
2348
  sources: ChatSource[];
2337
2349
  layout?: 'inline' | 'grid';
package/dist/index.d.ts CHANGED
@@ -1869,6 +1869,32 @@ interface UseChatComposerReturn {
1869
1869
  }
1870
1870
  declare function useChatComposer(options: UseChatComposerOptions): UseChatComposerReturn;
1871
1871
 
1872
+ type ComposerSize = 'sm' | 'md' | 'lg';
1873
+ interface ComposerProps {
1874
+ composer: UseChatComposerReturn;
1875
+ placeholder?: string;
1876
+ disabled?: boolean;
1877
+ showAttachmentButton?: boolean;
1878
+ onPickFiles?: () => void;
1879
+ toolbarStart?: ReactNode;
1880
+ toolbarEnd?: ReactNode;
1881
+ attachmentTray?: ReactNode;
1882
+ className?: string;
1883
+ textareaClassName?: string;
1884
+ /** Visual size — controls textarea height + button slot size.
1885
+ *
1886
+ * - ``sm`` — 32px slot, dense compact composer (admin sidebars, etc).
1887
+ * - ``md`` — 36px slot, default. Same as the legacy fixed size.
1888
+ * - ``lg`` — 48px slot, generous textarea. Use when the chat is
1889
+ * the page's primary surface (onboarding, support).
1890
+ */
1891
+ size?: ComposerSize;
1892
+ /** Show "Stop" button instead of "Send" while streaming. */
1893
+ isStreaming?: boolean;
1894
+ onCancel?: () => void;
1895
+ }
1896
+ declare const Composer: react.ForwardRefExoticComponent<ComposerProps & react.RefAttributes<HTMLDivElement>>;
1897
+
1872
1898
  interface AttachmentRendererArgs {
1873
1899
  attachment: ChatAttachment;
1874
1900
  /** True when shown inside the composer's staging tray (denser layout). */
@@ -1980,6 +2006,9 @@ interface ChatRootProps {
1980
2006
  onPickFiles?: () => void;
1981
2007
  /** Hide the composer input area entirely (e.g. while waiting for human approval). */
1982
2008
  hideComposer?: boolean;
2009
+ /** Composer size variant. Default ``md`` (36px slot). Use ``lg`` for primary
2010
+ * surfaces (onboarding, full-page chat), ``sm`` for dense sidebars. */
2011
+ composerSize?: ComposerSize;
1983
2012
  }
1984
2013
  declare function ChatRoot(props: ChatRootProps): react_jsx_runtime.JSX.Element;
1985
2014
 
@@ -2315,23 +2344,6 @@ interface MessageActionsProps {
2315
2344
  }
2316
2345
  declare function MessageActions({ role, onCopy, onRegenerate, onEdit, onDelete, hideOn, className, }: MessageActionsProps): react_jsx_runtime.JSX.Element;
2317
2346
 
2318
- interface ComposerProps {
2319
- composer: UseChatComposerReturn;
2320
- placeholder?: string;
2321
- disabled?: boolean;
2322
- showAttachmentButton?: boolean;
2323
- onPickFiles?: () => void;
2324
- toolbarStart?: ReactNode;
2325
- toolbarEnd?: ReactNode;
2326
- attachmentTray?: ReactNode;
2327
- className?: string;
2328
- textareaClassName?: string;
2329
- /** Show "Stop" button instead of "Send" while streaming. */
2330
- isStreaming?: boolean;
2331
- onCancel?: () => void;
2332
- }
2333
- declare const Composer: react.ForwardRefExoticComponent<ComposerProps & react.RefAttributes<HTMLDivElement>>;
2334
-
2335
2347
  interface SourcesProps {
2336
2348
  sources: ChatSource[];
2337
2349
  layout?: 'inline' | 'grid';
package/dist/index.mjs CHANGED
@@ -5,8 +5,8 @@ export { NativeProvider, StreamProvider, VideoControls, VideoErrorFallback, Vide
5
5
  export { ImageViewer } from './chunk-OBRSGM64.mjs';
6
6
  export { generateContentKey, useAudioCache, useBlobUrlCleanup, useImageCache, useMediaCacheStore, useVideoCache, useVideoPlayerSettings } from './chunk-C6GXVH5J.mjs';
7
7
  export { CronSchedulerProvider, CustomInput, DayChips, MonthDayGrid, SchedulePreview, ScheduleTypeSelector, TimeSelector, buildCron, humanizeCron, isValidCron, parseCron, useCronCustom, useCronMonthDays, useCronPreview, useCronScheduler, useCronSchedulerContext, useCronTime, useCronType, useCronWeekDays } from './chunk-PVAX67JG.mjs';
8
- import { LIMITS, createId } from './chunk-QCKJVSJF.mjs';
9
- export { Attachments, AttachmentsGrid, AttachmentsList, CHAT_EVENT_NAME, CSS_VARS, ChatProvider, ChatRoot, Composer, DEFAULT_LABELS, DEFAULT_SIDEBAR, DEFAULT_Z_INDEX, EmptyState, ErrorBanner, HOTKEYS, JumpToLatest, LIMITS, MessageActions, MessageBubble, MessageList, STORAGE_KEYS, Sources, StreamingIndicator, ToolCalls, createId, createTokenBuffer, deriveInitials, getChatLogger, initialState, reducer, resolvePersona, useChat, useChatAudio, useChatAudioPrefs, useChatComposer, useChatContext, useChatContextOptional, useChatHistory, useChatLayout, useChatScroll } from './chunk-QCKJVSJF.mjs';
8
+ import { LIMITS, createId } from './chunk-XG3XAO7W.mjs';
9
+ export { Attachments, AttachmentsGrid, AttachmentsList, CHAT_EVENT_NAME, CSS_VARS, ChatProvider, ChatRoot, Composer, DEFAULT_LABELS, DEFAULT_SIDEBAR, DEFAULT_Z_INDEX, EmptyState, ErrorBanner, HOTKEYS, JumpToLatest, LIMITS, MessageActions, MessageBubble, MessageList, STORAGE_KEYS, Sources, StreamingIndicator, ToolCalls, createId, createTokenBuffer, deriveInitials, getChatLogger, initialState, reducer, resolvePersona, useChat, useChatAudio, useChatAudioPrefs, useChatComposer, useChatContext, useChatContextOptional, useChatHistory, useChatLayout, useChatScroll } from './chunk-XG3XAO7W.mjs';
10
10
  export { TreeError, TreeSkeleton, createDemoTree } from './chunk-B6IR5KSC.mjs';
11
11
  export { DEFAULT_TREE_APPEARANCE, DEFAULT_TREE_LABELS, TreeRoot as Tree, TreeChevron, TreeContent, TreeEmpty, TreeIcon, TreeIndentGuides, TreeLabel, TreeProvider, TreeRoot, TreeRow, TreeSearchInput, appearanceToStyle, clearTreeState, createChildCache, flattenTree, loadTreeState, resolveAppearance, resolveChildren, saveTreeState, useTreeActions, useTreeContext, useTreeExpansion, useTreeFocus, useTreeKeyboard, useTreeLabels, useTreeRows, useTreeSearch, useTreeSelection, useTreeTypeAhead } from './chunk-G5IEC7SR.mjs';
12
12
  import { PlaygroundProvider } from './chunk-ZUFTH5IR.mjs';
@@ -347,7 +347,7 @@ var LazyTree = createLazyComponent(
347
347
  }
348
348
  );
349
349
  var LazyChat = createLazyComponent(
350
- () => import('./ChatRoot-CZMOJOGD.mjs').then((m) => ({ default: m.ChatRoot })),
350
+ () => import('./ChatRoot-3FZ6DXBD.mjs').then((m) => ({ default: m.ChatRoot })),
351
351
  {
352
352
  displayName: "LazyChat",
353
353
  fallback: /* @__PURE__ */ jsx(LoadingFallback, { minHeight: 320, text: "Loading chat\u2026" })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@djangocfg/ui-tools",
3
- "version": "2.1.349",
3
+ "version": "2.1.350",
4
4
  "description": "Heavy React tools with lazy loading - for Electron, Vite, CRA, Next.js apps",
5
5
  "keywords": [
6
6
  "ui-tools",
@@ -101,8 +101,8 @@
101
101
  "check": "tsc --noEmit"
102
102
  },
103
103
  "peerDependencies": {
104
- "@djangocfg/i18n": "^2.1.349",
105
- "@djangocfg/ui-core": "^2.1.349",
104
+ "@djangocfg/i18n": "^2.1.350",
105
+ "@djangocfg/ui-core": "^2.1.350",
106
106
  "consola": "^3.4.2",
107
107
  "lodash-es": "^4.18.1",
108
108
  "lucide-react": "^0.545.0",
@@ -155,10 +155,10 @@
155
155
  "material-file-icons": "^2.4.0"
156
156
  },
157
157
  "devDependencies": {
158
- "@djangocfg/i18n": "^2.1.349",
158
+ "@djangocfg/i18n": "^2.1.350",
159
159
  "@djangocfg/playground": "workspace:*",
160
- "@djangocfg/typescript-config": "^2.1.349",
161
- "@djangocfg/ui-core": "^2.1.349",
160
+ "@djangocfg/typescript-config": "^2.1.350",
161
+ "@djangocfg/ui-core": "^2.1.350",
162
162
  "@types/lodash-es": "^4.17.12",
163
163
  "@types/mapbox__mapbox-gl-draw": "^1.4.8",
164
164
  "@types/node": "^24.7.2",
@@ -101,6 +101,39 @@ export const Default = () => {
101
101
  );
102
102
  };
103
103
 
104
+ // ---------------------------------------------------------------------------
105
+ // 1b) ComposerSizes — sm / md / lg side-by-side
106
+ // ---------------------------------------------------------------------------
107
+
108
+ export const ComposerSizes = () => {
109
+ const make = () =>
110
+ createMockTransport({
111
+ replies: ['I scale with the composer size — try `lg` on a primary surface.'],
112
+ latencyMs: 25,
113
+ });
114
+ const cells: Array<{ size: 'sm' | 'md' | 'lg'; label: string }> = [
115
+ { size: 'sm', label: 'sm — 32px (compact)' },
116
+ { size: 'md', label: 'md — 36px (default)' },
117
+ { size: 'lg', label: 'lg — 48px (primary surface)' },
118
+ ];
119
+ return (
120
+ <div className="grid h-[640px] grid-cols-3 gap-3">
121
+ {cells.map(({ size, label }) => (
122
+ <Frame key={size} h={620}>
123
+ <ChatRoot
124
+ transport={make()}
125
+ config={{
126
+ greeting: label,
127
+ placeholder: 'Type a message…',
128
+ }}
129
+ composerSize={size}
130
+ />
131
+ </Frame>
132
+ ))}
133
+ </div>
134
+ );
135
+ };
136
+
104
137
  // ---------------------------------------------------------------------------
105
138
  // 2) WithToolCalls — scripted tool invocations
106
139
  // ---------------------------------------------------------------------------
@@ -10,7 +10,7 @@ import { ChatProvider, useChatContext, type ChatContextValue } from '../context'
10
10
  import { useChatComposer, type UseChatComposerReturn } from '../hooks/useChatComposer';
11
11
  import { useChatScroll } from '../hooks/useChatScroll';
12
12
  import { useChatHistory } from '../hooks/useChatHistory';
13
- import { Composer } from './Composer';
13
+ import { Composer, type ComposerSize } from './Composer';
14
14
  import { EmptyState } from './EmptyState';
15
15
  import { ErrorBanner } from './ErrorBanner';
16
16
  import { JumpToLatest } from './JumpToLatest';
@@ -75,6 +75,9 @@ export interface ChatRootProps {
75
75
  onPickFiles?: () => void;
76
76
  /** Hide the composer input area entirely (e.g. while waiting for human approval). */
77
77
  hideComposer?: boolean;
78
+ /** Composer size variant. Default ``md`` (36px slot). Use ``lg`` for primary
79
+ * surfaces (onboarding, full-page chat), ``sm`` for dense sidebars. */
80
+ composerSize?: ComposerSize;
78
81
  }
79
82
 
80
83
  export function ChatRoot(props: ChatRootProps) {
@@ -195,6 +198,7 @@ function ChatRootShell({ className, slots }: ChatRootShellProps) {
195
198
  toolbarStart={slots.composerToolbarStart}
196
199
  toolbarEnd={slots.composerToolbarEnd}
197
200
  attachmentTray={slots.composerAttachmentTray}
201
+ size={slots.composerSize}
198
202
  />
199
203
  )}
200
204
  {slots.footer ?? null}
@@ -10,6 +10,8 @@ import { useChatContextOptional } from '../context';
10
10
  import type { UseChatComposerReturn } from '../hooks/useChatComposer';
11
11
  import { Attachments } from './Attachments';
12
12
 
13
+ export type ComposerSize = 'sm' | 'md' | 'lg';
14
+
13
15
  export interface ComposerProps {
14
16
  composer: UseChatComposerReturn;
15
17
  placeholder?: string;
@@ -21,11 +23,57 @@ export interface ComposerProps {
21
23
  attachmentTray?: ReactNode;
22
24
  className?: string;
23
25
  textareaClassName?: string;
26
+ /** Visual size — controls textarea height + button slot size.
27
+ *
28
+ * - ``sm`` — 32px slot, dense compact composer (admin sidebars, etc).
29
+ * - ``md`` — 36px slot, default. Same as the legacy fixed size.
30
+ * - ``lg`` — 48px slot, generous textarea. Use when the chat is
31
+ * the page's primary surface (onboarding, support).
32
+ */
33
+ size?: ComposerSize;
24
34
  /** Show "Stop" button instead of "Send" while streaming. */
25
35
  isStreaming?: boolean;
26
36
  onCancel?: () => void;
27
37
  }
28
38
 
39
+ const SIZE_CLASSES: Record<ComposerSize, {
40
+ slot: string;
41
+ button: string;
42
+ iconButton: string;
43
+ textarea: string;
44
+ text: string;
45
+ padding: string;
46
+ containerPadding: string;
47
+ }> = {
48
+ sm: {
49
+ slot: '[&>:not(textarea)]:h-8',
50
+ button: 'h-8 w-8',
51
+ iconButton: 'size-3.5',
52
+ textarea: 'min-h-8 max-h-48 px-3 py-1.5',
53
+ text: 'text-sm',
54
+ padding: 'gap-1.5',
55
+ containerPadding: 'px-2 pt-1.5 pb-[max(0.375rem,env(safe-area-inset-bottom))]',
56
+ },
57
+ md: {
58
+ slot: '[&>:not(textarea)]:h-9',
59
+ button: 'h-9 w-9',
60
+ iconButton: 'size-4',
61
+ textarea: 'min-h-9 max-h-60 px-3.5 py-2',
62
+ text: 'text-base sm:text-sm',
63
+ padding: 'gap-1.5',
64
+ containerPadding: 'px-2.5 pt-2 pb-[max(0.5rem,env(safe-area-inset-bottom))]',
65
+ },
66
+ lg: {
67
+ slot: '[&>:not(textarea)]:h-12',
68
+ button: 'h-12 w-12',
69
+ iconButton: 'size-5',
70
+ textarea: 'min-h-12 max-h-72 px-4 py-3',
71
+ text: 'text-base',
72
+ padding: 'gap-2',
73
+ containerPadding: 'px-3.5 pt-3 pb-[max(0.875rem,env(safe-area-inset-bottom))]',
74
+ },
75
+ };
76
+
29
77
  export const Composer = forwardRef<HTMLDivElement, ComposerProps>(function Composer(
30
78
  {
31
79
  composer,
@@ -38,6 +86,7 @@ export const Composer = forwardRef<HTMLDivElement, ComposerProps>(function Compo
38
86
  attachmentTray,
39
87
  className,
40
88
  textareaClassName,
89
+ size = 'md',
41
90
  isStreaming: isStreamingProp,
42
91
  onCancel: onCancelProp,
43
92
  },
@@ -47,12 +96,14 @@ export const Composer = forwardRef<HTMLDivElement, ComposerProps>(function Compo
47
96
  const isStreaming = isStreamingProp ?? ctx?.isStreaming ?? false;
48
97
  const onCancel = onCancelProp ?? ctx?.cancelStream;
49
98
  const isDisabled = disabled ?? isStreaming;
99
+ const sz = SIZE_CLASSES[size];
50
100
 
51
101
  return (
52
102
  <div
53
103
  ref={ref}
54
104
  className={cn(
55
- 'border-t border-border bg-background/95 px-2.5 pt-2 pb-[max(0.5rem,env(safe-area-inset-bottom))]',
105
+ 'border-t border-border bg-background/95',
106
+ sz.containerPadding,
56
107
  className,
57
108
  )}
58
109
  >
@@ -67,11 +118,11 @@ export const Composer = forwardRef<HTMLDivElement, ComposerProps>(function Compo
67
118
  </div>
68
119
  ) : null}
69
120
 
70
- {/* `[&>*]:h-9` enforces a consistent 36px slot height so toolbar
71
- * buttons line up with the textarea baseline (`min-h-[36px]`).
72
- * Toolbar slots that want to opt out can pass an explicit class
73
- * like `!h-auto`. */}
74
- <div className="flex items-end gap-1.5 [&>:not(textarea)]:shrink-0 [&>:not(textarea)]:h-9">
121
+ {/* Size-aware slot row. ``[&>:not(textarea)]:h-{N}`` enforces a
122
+ * consistent slot height so toolbar buttons line up with the
123
+ * textarea baseline. Toolbar slots that want to opt out can
124
+ * pass an explicit class like `!h-auto`. */}
125
+ <div className={cn('flex items-end [&>:not(textarea)]:shrink-0', sz.padding, sz.slot)}>
75
126
  {showAttachmentButton ? (
76
127
  <Button
77
128
  type="button"
@@ -80,9 +131,9 @@ export const Composer = forwardRef<HTMLDivElement, ComposerProps>(function Compo
80
131
  onClick={onPickFiles}
81
132
  aria-label="Attach files"
82
133
  disabled={isDisabled}
83
- className="h-9 w-9"
134
+ className={sz.button}
84
135
  >
85
- <Paperclip aria-hidden className="size-4" />
136
+ <Paperclip aria-hidden className={sz.iconButton} />
86
137
  </Button>
87
138
  ) : null}
88
139
 
@@ -96,7 +147,9 @@ export const Composer = forwardRef<HTMLDivElement, ComposerProps>(function Compo
96
147
  aria-multiline="true"
97
148
  disabled={isDisabled}
98
149
  className={cn(
99
- 'min-h-9 max-h-60 flex-1 resize-none rounded-2xl px-3.5 py-2 text-base sm:text-sm',
150
+ 'flex-1 resize-none rounded-2xl',
151
+ sz.textarea,
152
+ sz.text,
100
153
  textareaClassName,
101
154
  )}
102
155
  />
@@ -111,9 +164,9 @@ export const Composer = forwardRef<HTMLDivElement, ComposerProps>(function Compo
111
164
  onClick={onCancel}
112
165
  aria-label="Stop"
113
166
  aria-keyshortcuts="Escape"
114
- className="h-9 w-9"
167
+ className={sz.button}
115
168
  >
116
- <Square aria-hidden className="size-3.5" />
169
+ <Square aria-hidden className={sz.iconButton} />
117
170
  </Button>
118
171
  ) : (
119
172
  <Button
@@ -123,9 +176,9 @@ export const Composer = forwardRef<HTMLDivElement, ComposerProps>(function Compo
123
176
  disabled={!composer.canSubmit}
124
177
  aria-label="Send"
125
178
  aria-keyshortcuts="Enter"
126
- className="h-9 w-9"
179
+ className={sz.button}
127
180
  >
128
- <Send aria-hidden className="size-4" />
181
+ <Send aria-hidden className={sz.iconButton} />
129
182
  </Button>
130
183
  )}
131
184
  </div>