@flamingo-stack/openframe-frontend-core 0.0.321 → 0.0.322
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/{chunk-PDOTUMJC.cjs → chunk-27UIZKPP.cjs} +31 -31
- package/dist/{chunk-PDOTUMJC.cjs.map → chunk-27UIZKPP.cjs.map} +1 -1
- package/dist/{chunk-TFCGMQPK.cjs → chunk-2JFIPRZM.cjs} +25 -25
- package/dist/{chunk-TFCGMQPK.cjs.map → chunk-2JFIPRZM.cjs.map} +1 -1
- package/dist/{chunk-DEEBJBFQ.js → chunk-2L6XJRWU.js} +2 -2
- package/dist/{chunk-WCRJWZUA.js → chunk-2ZMEIVHB.js} +4 -4
- package/dist/{chunk-TV6VD6LP.js → chunk-3CUHOXPN.js} +4 -4
- package/dist/{chunk-J65CQLX6.js → chunk-3NOGHXE5.js} +2 -2
- package/dist/{chunk-CD56IAXU.cjs → chunk-6GHEXJ6H.cjs} +5 -5
- package/dist/{chunk-CD56IAXU.cjs.map → chunk-6GHEXJ6H.cjs.map} +1 -1
- package/dist/{chunk-WCCZGPPP.cjs → chunk-AOD7KNNL.cjs} +62 -62
- package/dist/{chunk-WCCZGPPP.cjs.map → chunk-AOD7KNNL.cjs.map} +1 -1
- package/dist/{chunk-MN2WQYXS.cjs → chunk-APGXPHP2.cjs} +15 -15
- package/dist/{chunk-MN2WQYXS.cjs.map → chunk-APGXPHP2.cjs.map} +1 -1
- package/dist/{chunk-FNK67HTC.js → chunk-HYW3BYDX.js} +2 -2
- package/dist/{chunk-6DH2TCRH.js → chunk-KFEIMA2T.js} +2 -2
- package/dist/{chunk-563D7EB2.js → chunk-KJNTCTV4.js} +4 -4
- package/dist/{chunk-NEY347ME.cjs → chunk-M5RW5ASP.cjs} +26 -26
- package/dist/{chunk-NEY347ME.cjs.map → chunk-M5RW5ASP.cjs.map} +1 -1
- package/dist/{chunk-Y2TJ64S5.cjs → chunk-MQFGEYOG.cjs} +12 -12
- package/dist/{chunk-Y2TJ64S5.cjs.map → chunk-MQFGEYOG.cjs.map} +1 -1
- package/dist/{chunk-TPJJJ6KC.js → chunk-MQHD6CTN.js} +145 -90
- package/dist/chunk-MQHD6CTN.js.map +1 -0
- package/dist/{chunk-7M3QIYFW.cjs → chunk-NCFCQWMH.cjs} +56 -56
- package/dist/{chunk-7M3QIYFW.cjs.map → chunk-NCFCQWMH.cjs.map} +1 -1
- package/dist/{chunk-GAQAPTBU.cjs → chunk-NTEAD4ZM.cjs} +37 -37
- package/dist/{chunk-GAQAPTBU.cjs.map → chunk-NTEAD4ZM.cjs.map} +1 -1
- package/dist/{chunk-VNWWOPIY.js → chunk-PZYSR23M.js} +2 -2
- package/dist/{chunk-HALW7FPF.js → chunk-S3X2KEFA.js} +2 -2
- package/dist/{chunk-ZFER75HU.cjs → chunk-S6W5YPAB.cjs} +9 -9
- package/dist/{chunk-ZFER75HU.cjs.map → chunk-S6W5YPAB.cjs.map} +1 -1
- package/dist/{chunk-7C5G45KU.cjs → chunk-UFUOM6ZT.cjs} +732 -677
- package/dist/chunk-UFUOM6ZT.cjs.map +1 -0
- package/dist/{chunk-V4U7ASRM.js → chunk-WQ4OIM4E.js} +2 -2
- package/dist/{chunk-BRERE4E5.js → chunk-XF3GIE5U.js} +4 -4
- package/dist/{chunk-5HQIFRRE.cjs → chunk-YKIU2GXU.cjs} +7 -7
- package/dist/{chunk-5HQIFRRE.cjs.map → chunk-YKIU2GXU.cjs.map} +1 -1
- package/dist/components/case-studies/index.cjs +8 -8
- package/dist/components/case-studies/index.js +2 -2
- package/dist/components/chat/embeddable-chat.d.ts +2 -0
- package/dist/components/chat/embeddable-chat.d.ts.map +1 -1
- package/dist/components/chat/index.cjs +2 -2
- package/dist/components/chat/index.js +1 -1
- package/dist/components/chat/mingo-chat-history.d.ts +11 -2
- package/dist/components/chat/mingo-chat-history.d.ts.map +1 -1
- package/dist/components/chat/mingo-welcome.d.ts +5 -1
- package/dist/components/chat/mingo-welcome.d.ts.map +1 -1
- package/dist/components/contact/index.cjs +3 -3
- package/dist/components/contact/index.js +2 -2
- package/dist/components/docs/index.cjs +5 -5
- package/dist/components/docs/index.js +4 -4
- package/dist/components/embeds/index.cjs +3 -3
- package/dist/components/embeds/index.js +2 -2
- package/dist/components/faq/index.cjs +3 -3
- package/dist/components/faq/index.js +2 -2
- package/dist/components/features/index.cjs +2 -2
- package/dist/components/features/index.js +1 -1
- package/dist/components/help-center-pages/index.cjs +20 -20
- package/dist/components/help-center-pages/index.js +11 -11
- package/dist/components/index.cjs +120 -120
- package/dist/components/index.js +9 -9
- package/dist/components/navigation/index.cjs +2 -2
- package/dist/components/navigation/index.js +1 -1
- package/dist/components/onboarding-guides/index.cjs +5 -5
- package/dist/components/onboarding-guides/index.js +4 -4
- package/dist/components/related-content/index.cjs +3 -3
- package/dist/components/related-content/index.js +2 -2
- package/dist/components/tickets/index.cjs +5 -5
- package/dist/components/tickets/index.js +4 -4
- package/dist/components/ui/index.cjs +2 -2
- package/dist/components/ui/index.js +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/components/chat/embeddable-chat.tsx +15 -1
- package/src/components/chat/mingo-chat-history.tsx +136 -53
- package/src/components/chat/mingo-welcome.tsx +6 -1
- package/dist/chunk-7C5G45KU.cjs.map +0 -1
- package/dist/chunk-TPJJJ6KC.js.map +0 -1
- /package/dist/{chunk-DEEBJBFQ.js.map → chunk-2L6XJRWU.js.map} +0 -0
- /package/dist/{chunk-WCRJWZUA.js.map → chunk-2ZMEIVHB.js.map} +0 -0
- /package/dist/{chunk-TV6VD6LP.js.map → chunk-3CUHOXPN.js.map} +0 -0
- /package/dist/{chunk-J65CQLX6.js.map → chunk-3NOGHXE5.js.map} +0 -0
- /package/dist/{chunk-FNK67HTC.js.map → chunk-HYW3BYDX.js.map} +0 -0
- /package/dist/{chunk-6DH2TCRH.js.map → chunk-KFEIMA2T.js.map} +0 -0
- /package/dist/{chunk-563D7EB2.js.map → chunk-KJNTCTV4.js.map} +0 -0
- /package/dist/{chunk-VNWWOPIY.js.map → chunk-PZYSR23M.js.map} +0 -0
- /package/dist/{chunk-HALW7FPF.js.map → chunk-S3X2KEFA.js.map} +0 -0
- /package/dist/{chunk-V4U7ASRM.js.map → chunk-WQ4OIM4E.js.map} +0 -0
- /package/dist/{chunk-BRERE4E5.js.map → chunk-XF3GIE5U.js.map} +0 -0
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
import * as React from 'react'
|
|
4
4
|
import { cn } from '../../utils/cn'
|
|
5
|
+
import { useDebounce } from '../../hooks/ui/use-debounce'
|
|
5
6
|
import { ActionsMenuDropdown, type ActionsMenuItem } from '../ui/actions-menu'
|
|
6
7
|
import { Button } from '../ui/button'
|
|
7
|
-
import {
|
|
8
|
+
import { Input } from '../ui/input'
|
|
9
|
+
import { Ellipsis01Icon, SearchIcon } from '../icons-v2-generated'
|
|
8
10
|
import type { DialogItem } from './types/component.types'
|
|
9
11
|
|
|
10
12
|
// =============================================================================
|
|
@@ -24,6 +26,12 @@ export interface MingoChatHistoryProps {
|
|
|
24
26
|
/** Request archive — enables the row "Archive chat" action. The host opens
|
|
25
27
|
* the Archive confirmation modal. */
|
|
26
28
|
onRequestArchive?: (dialog: DialogItem) => void
|
|
29
|
+
/** Seed value for the search input. The host owns the search term and refetches
|
|
30
|
+
* the dialog list server-side; the list itself does no filtering. */
|
|
31
|
+
searchQuery?: string
|
|
32
|
+
/** Emit the (debounced) search term — enables the dialog search bar above the
|
|
33
|
+
* list. Omit to hide the search bar entirely. */
|
|
34
|
+
onSearchChange?: (query: string) => void
|
|
27
35
|
/** Whether more dialogs remain (cursor pagination). */
|
|
28
36
|
hasMore?: boolean
|
|
29
37
|
/** True while the next page is loading. */
|
|
@@ -211,7 +219,15 @@ function MingoChatHistoryRow({
|
|
|
211
219
|
* two layouts are mutually exclusive — swapping between them mid-load reads as
|
|
212
220
|
* a flicker). Pure ODS tokens, `animate-pulse`.
|
|
213
221
|
*/
|
|
214
|
-
export function MingoChatHistorySkeleton({
|
|
222
|
+
export function MingoChatHistorySkeleton({
|
|
223
|
+
className,
|
|
224
|
+
searchable = false,
|
|
225
|
+
}: {
|
|
226
|
+
className?: string
|
|
227
|
+
/** Render a search-bar placeholder above the groups — match the real list,
|
|
228
|
+
* which shows the search bar only when search is wired. */
|
|
229
|
+
searchable?: boolean
|
|
230
|
+
}) {
|
|
215
231
|
// Mirror the real grouped list: a group label, then a bordered container of
|
|
216
232
|
// `h-12` rows. `withBadge` adds the leading unread-badge square on the first
|
|
217
233
|
// N rows; `widths` varies the title-bar length so the placeholder reads like
|
|
@@ -234,6 +250,15 @@ export function MingoChatHistorySkeleton({ className }: { className?: string })
|
|
|
234
250
|
className,
|
|
235
251
|
)}
|
|
236
252
|
>
|
|
253
|
+
{/* Search-bar placeholder — mirrors the real `Input` (border, rounded,
|
|
254
|
+
h-11/12) with a leading icon + text bar so the loading state matches
|
|
255
|
+
the searchable layout. */}
|
|
256
|
+
{searchable && (
|
|
257
|
+
<div className="flex h-11 md:h-12 shrink-0 items-center gap-2 rounded-[6px] border border-ods-border bg-ods-card px-3">
|
|
258
|
+
<div className="size-4 md:size-6 shrink-0 animate-pulse rounded bg-ods-border" />
|
|
259
|
+
<div className="h-4 w-32 animate-pulse rounded bg-ods-border" />
|
|
260
|
+
</div>
|
|
261
|
+
)}
|
|
237
262
|
{groups.map((group, g) => (
|
|
238
263
|
<div key={g} className="flex shrink-0 flex-col gap-[var(--spacing-system-xxs)]">
|
|
239
264
|
{/* Group label (Today / Yesterday). */}
|
|
@@ -261,6 +286,46 @@ export function MingoChatHistorySkeleton({ className }: { className?: string })
|
|
|
261
286
|
)
|
|
262
287
|
}
|
|
263
288
|
|
|
289
|
+
// =============================================================================
|
|
290
|
+
// Search bar
|
|
291
|
+
// =============================================================================
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Dialog search field. Holds its own input text for snappy typing and emits
|
|
295
|
+
* the DEBOUNCED term via `onSearchChange` — the host owns the search state
|
|
296
|
+
* and refetches the dialog list server-side, so the list never
|
|
297
|
+
* filters locally. `initialValue` only seeds the field on mount.
|
|
298
|
+
*/
|
|
299
|
+
function DialogSearchBar({
|
|
300
|
+
initialValue,
|
|
301
|
+
onSearchChange,
|
|
302
|
+
}: {
|
|
303
|
+
initialValue?: string
|
|
304
|
+
onSearchChange: (query: string) => void
|
|
305
|
+
}) {
|
|
306
|
+
const [value, setValue] = React.useState(initialValue ?? '')
|
|
307
|
+
const debounced = useDebounce(value, 300)
|
|
308
|
+
const lastEmitted = React.useRef(initialValue ?? '')
|
|
309
|
+
|
|
310
|
+
React.useEffect(() => {
|
|
311
|
+
if (debounced === lastEmitted.current) return
|
|
312
|
+
lastEmitted.current = debounced
|
|
313
|
+
onSearchChange(debounced)
|
|
314
|
+
}, [debounced, onSearchChange])
|
|
315
|
+
|
|
316
|
+
return (
|
|
317
|
+
<Input
|
|
318
|
+
type="text"
|
|
319
|
+
value={value}
|
|
320
|
+
onChange={(e) => setValue(e.target.value)}
|
|
321
|
+
placeholder="Search for Chats"
|
|
322
|
+
aria-label="Search chats"
|
|
323
|
+
startAdornment={<SearchIcon />}
|
|
324
|
+
className="shrink-0"
|
|
325
|
+
/>
|
|
326
|
+
)
|
|
327
|
+
}
|
|
328
|
+
|
|
264
329
|
// =============================================================================
|
|
265
330
|
// Component
|
|
266
331
|
// =============================================================================
|
|
@@ -282,12 +347,15 @@ export function MingoChatHistory({
|
|
|
282
347
|
onSelectDialog,
|
|
283
348
|
onRequestRename,
|
|
284
349
|
onRequestArchive,
|
|
350
|
+
searchQuery,
|
|
351
|
+
onSearchChange,
|
|
285
352
|
hasMore = false,
|
|
286
353
|
isLoadingMore = false,
|
|
287
354
|
onLoadMore,
|
|
288
355
|
className,
|
|
289
356
|
}: MingoChatHistoryProps) {
|
|
290
357
|
const groups = React.useMemo(() => groupDialogs(dialogs), [dialogs])
|
|
358
|
+
const noSearchResults = groups.length === 0 && !!searchQuery?.trim()
|
|
291
359
|
|
|
292
360
|
// Scroll-fade affordances (same pattern as MingoWelcome's greeting region).
|
|
293
361
|
const scrollRef = React.useRef<HTMLDivElement>(null)
|
|
@@ -333,58 +401,73 @@ export function MingoChatHistory({
|
|
|
333
401
|
}, [hasMore])
|
|
334
402
|
|
|
335
403
|
return (
|
|
336
|
-
<div className={cn('relative flex flex-1 min-h-0 flex-col', className)}>
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
>
|
|
342
|
-
{groups.map((group) => (
|
|
343
|
-
<div
|
|
344
|
-
key={group.key}
|
|
345
|
-
className="flex flex-col gap-[var(--spacing-system-xxs)]"
|
|
346
|
-
>
|
|
347
|
-
<p className="text-h5 text-ods-text-secondary">{group.label}</p>
|
|
348
|
-
<div className="overflow-hidden rounded-md border border-ods-border">
|
|
349
|
-
{group.items.map((dialog) => (
|
|
350
|
-
<MingoChatHistoryRow
|
|
351
|
-
key={dialog.id}
|
|
352
|
-
dialog={dialog}
|
|
353
|
-
isActive={dialog.id === activeDialogId}
|
|
354
|
-
onSelect={onSelectDialog}
|
|
355
|
-
onRequestRename={onRequestRename}
|
|
356
|
-
onRequestArchive={onRequestArchive}
|
|
357
|
-
/>
|
|
358
|
-
))}
|
|
359
|
-
</div>
|
|
360
|
-
</div>
|
|
361
|
-
))}
|
|
362
|
-
{hasMore ? <div ref={sentinelRef} className="h-px shrink-0" /> : null}
|
|
363
|
-
</div>
|
|
404
|
+
<div className={cn('relative flex flex-1 min-h-0 flex-col gap-[var(--spacing-system-m)]', className)}>
|
|
405
|
+
{/* Pinned search bar — stays put while the grouped list scrolls below. */}
|
|
406
|
+
{onSearchChange ? (
|
|
407
|
+
<DialogSearchBar initialValue={searchQuery} onSearchChange={onSearchChange} />
|
|
408
|
+
) : null}
|
|
364
409
|
|
|
365
|
-
{/* Scroll
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
410
|
+
{/* Scroll region — `relative` so the fades anchor here (below the search
|
|
411
|
+
bar), not over it. */}
|
|
412
|
+
<div className="relative flex flex-1 min-h-0 flex-col">
|
|
413
|
+
<div
|
|
414
|
+
ref={scrollRef}
|
|
415
|
+
onScroll={updateFade}
|
|
416
|
+
className="flex flex-1 min-h-0 flex-col gap-[var(--spacing-system-m)] overflow-y-auto"
|
|
417
|
+
>
|
|
418
|
+
{noSearchResults ? (
|
|
419
|
+
<p className="py-[var(--spacing-system-m)] text-center text-h5 text-ods-text-secondary">
|
|
420
|
+
No chats found
|
|
421
|
+
</p>
|
|
422
|
+
) : (
|
|
423
|
+
groups.map((group) => (
|
|
424
|
+
<div
|
|
425
|
+
key={group.key}
|
|
426
|
+
className="flex flex-col gap-[var(--spacing-system-xxs)]"
|
|
427
|
+
>
|
|
428
|
+
<p className="text-h5 text-ods-text-secondary">{group.label}</p>
|
|
429
|
+
<div className="overflow-hidden rounded-md border border-ods-border">
|
|
430
|
+
{group.items.map((dialog) => (
|
|
431
|
+
<MingoChatHistoryRow
|
|
432
|
+
key={dialog.id}
|
|
433
|
+
dialog={dialog}
|
|
434
|
+
isActive={dialog.id === activeDialogId}
|
|
435
|
+
onSelect={onSelectDialog}
|
|
436
|
+
onRequestRename={onRequestRename}
|
|
437
|
+
onRequestArchive={onRequestArchive}
|
|
438
|
+
/>
|
|
439
|
+
))}
|
|
440
|
+
</div>
|
|
441
|
+
</div>
|
|
442
|
+
))
|
|
443
|
+
)}
|
|
444
|
+
{hasMore ? <div ref={sentinelRef} className="h-px shrink-0" /> : null}
|
|
445
|
+
</div>
|
|
446
|
+
|
|
447
|
+
{/* Scroll-fade — only while content is hidden in that direction. */}
|
|
448
|
+
<div
|
|
449
|
+
aria-hidden
|
|
450
|
+
className={cn(
|
|
451
|
+
'pointer-events-none absolute inset-x-0 top-0 h-12 transition-opacity duration-150',
|
|
452
|
+
fade.top ? 'opacity-100' : 'opacity-0',
|
|
453
|
+
)}
|
|
454
|
+
style={{
|
|
455
|
+
background:
|
|
456
|
+
'linear-gradient(0deg, transparent 0%, var(--color-bg-card) 100%)',
|
|
457
|
+
}}
|
|
458
|
+
/>
|
|
459
|
+
<div
|
|
460
|
+
aria-hidden
|
|
461
|
+
className={cn(
|
|
462
|
+
'pointer-events-none absolute inset-x-0 bottom-0 h-12 transition-opacity duration-150',
|
|
463
|
+
fade.bottom ? 'opacity-100' : 'opacity-0',
|
|
464
|
+
)}
|
|
465
|
+
style={{
|
|
466
|
+
background:
|
|
467
|
+
'linear-gradient(180deg, transparent 0%, var(--color-bg-card) 100%)',
|
|
468
|
+
}}
|
|
469
|
+
/>
|
|
470
|
+
</div>
|
|
388
471
|
</div>
|
|
389
472
|
)
|
|
390
473
|
}
|
|
@@ -92,6 +92,10 @@ export interface MingoWelcomeProps {
|
|
|
92
92
|
loadError?: boolean
|
|
93
93
|
/** Retry handler for the `loadError` state. */
|
|
94
94
|
onRetry?: () => void
|
|
95
|
+
/** Whether the dialog history has a search bar — when true, the loading
|
|
96
|
+
* skeleton includes a search-bar placeholder so it matches the loaded
|
|
97
|
+
* layout. Ignored once `dialogHistory` is provided. */
|
|
98
|
+
historySearchable?: boolean
|
|
95
99
|
/** When provided, renders the "Start Guide Chat" chip (the only wired
|
|
96
100
|
* action — switches the host chat to Guide mode) and enables the default
|
|
97
101
|
* promo notification. When omitted, both are suppressed. */
|
|
@@ -170,6 +174,7 @@ export function MingoWelcome({
|
|
|
170
174
|
isLoadingHistory = false,
|
|
171
175
|
loadError = false,
|
|
172
176
|
onRetry,
|
|
177
|
+
historySearchable = false,
|
|
173
178
|
onStartGuideChat,
|
|
174
179
|
className,
|
|
175
180
|
}: MingoWelcomeProps) {
|
|
@@ -287,7 +292,7 @@ export function MingoWelcome({
|
|
|
287
292
|
)}
|
|
288
293
|
</div>
|
|
289
294
|
) : isLoadingHistory ? (
|
|
290
|
-
<MingoChatHistorySkeleton />
|
|
295
|
+
<MingoChatHistorySkeleton searchable={historySearchable} />
|
|
291
296
|
) : (
|
|
292
297
|
<>
|
|
293
298
|
{/* Scrollable region — only the greeting + grid scroll; the notification
|