@admin-layout/tailwind-chat-pro 12.2.5-alpha.2 → 12.2.5-alpha.22
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/CHANGELOG.md +63 -0
- package/lib/components/messages-container-ui/MessagesContainerUI.d.ts +2 -2
- package/lib/components/messages-container-ui/MessagesContainerUI.d.ts.map +1 -1
- package/lib/components/messages-container-ui/ModernMessageGroup.d.ts +3 -0
- package/lib/components/messages-container-ui/ModernMessageGroup.d.ts.map +1 -1
- package/lib/components/messages-container-ui/ModernMessageGroup.js +75 -19
- package/lib/components/messages-container-ui/ModernMessageGroup.js.map +1 -1
- package/lib/components/messages-container-ui/PlanModeView.d.ts +2 -2
- package/lib/components/messages-container-ui/PlanModeView.d.ts.map +1 -1
- package/lib/components/messages-container-ui/PlanModeView.js +13 -4
- package/lib/components/messages-container-ui/PlanModeView.js.map +1 -1
- package/lib/components/messages-container-ui/index.d.ts +1 -1
- package/lib/components/messages-container-ui/index.d.ts.map +1 -1
- package/lib/components/messages-container-ui/markdownTables.d.ts +25 -0
- package/lib/components/messages-container-ui/markdownTables.d.ts.map +1 -0
- package/lib/components/messages-container-ui/markdownTables.js +103 -0
- package/lib/components/messages-container-ui/markdownTables.js.map +1 -0
- package/lib/components/messages-container-ui/messenger-slot-fill-name-enum.d.ts +5 -1
- package/lib/components/messages-container-ui/messenger-slot-fill-name-enum.d.ts.map +1 -1
- package/lib/components/messages-container-ui/messenger-slot-fill-name-enum.js +6 -0
- package/lib/components/messages-container-ui/messenger-slot-fill-name-enum.js.map +1 -1
- package/lib/components/messages-container-ui/modernStreaming.d.ts +2 -1
- package/lib/components/messages-container-ui/modernStreaming.d.ts.map +1 -1
- package/lib/components/messages-container-ui/modernStreaming.js +26 -9
- package/lib/components/messages-container-ui/modernStreaming.js.map +1 -1
- package/lib/components/messages-container-ui/types.d.ts +7 -0
- package/lib/components/messages-container-ui/types.d.ts.map +1 -1
- package/lib/components/messages-container-ui/useBubbleEntrance.d.ts +12 -0
- package/lib/components/messages-container-ui/useBubbleEntrance.d.ts.map +1 -0
- package/lib/components/messages-container-ui/useBubbleEntrance.js +36 -0
- package/lib/components/messages-container-ui/useBubbleEntrance.js.map +1 -0
- package/package.json +9 -10
- package/src/__tests__/stubs/common-graphql.ts +2 -0
- package/src/__tests__/stubs/common.ts +5 -0
- package/src/__tests__/stubs/components-pro.ts +2 -0
- package/src/components/messages-container-ui/MessagesContainerUI.tsx +2 -2
- package/src/components/messages-container-ui/ModernMessageGroup.tsx +88 -23
- package/src/components/messages-container-ui/PlanModeView.tsx +26 -18
- package/src/components/messages-container-ui/__tests__/markdownTables.test.tsx +94 -0
- package/src/components/messages-container-ui/index.ts +7 -1
- package/src/components/messages-container-ui/markdownTables.ts +108 -0
- package/src/components/messages-container-ui/messenger-slot-fill-name-enum.ts +6 -0
- package/src/components/messages-container-ui/modernStreaming.tsx +20 -6
- package/src/components/messages-container-ui/types.ts +8 -0
- package/src/components/messages-container-ui/useBubbleEntrance.ts +31 -0
- package/vitest.config.ts +17 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown tables in a chat message: every table sits in its own box that scrolls sideways, and
|
|
3
|
+
* nothing inside a table may break a word to make it fit.
|
|
4
|
+
*
|
|
5
|
+
* A message's prose wraps anywhere (`overflow-wrap: anywhere`), so a long path or URL never
|
|
6
|
+
* pushes the chat wider. That rule also counts every character as a break when a table sizes its
|
|
7
|
+
* columns, so a table in a narrow pane squeezed its number columns to a few characters and split
|
|
8
|
+
* "2,000" into "2,00" / "0". Inside a table a line now breaks only where the text has a space,
|
|
9
|
+
* and a table still too wide for the message scrolls in its box instead.
|
|
10
|
+
*/
|
|
11
|
+
/** The box every rendered markdown table sits in. */
|
|
12
|
+
export declare const TABLE_SCROLL_CLASS = "llm-table-scroll";
|
|
13
|
+
/**
|
|
14
|
+
* Put each `<table>` of rendered HTML in a {@link TABLE_SCROLL_CLASS} box. Every opening tag gets
|
|
15
|
+
* a box and every closing tag closes it, so well-formed HTML stays balanced (nested tables too).
|
|
16
|
+
* Escaped markup, such as a table inside a code block, is text and is left alone.
|
|
17
|
+
*/
|
|
18
|
+
export declare function wrapTables(html: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* The box, the no-split rule and the scroll cue, for both the assistant's reply and the person's
|
|
21
|
+
* own bubble. `.llm-table-scroll table *` outranks the bubbles' wrap-anywhere rules
|
|
22
|
+
* (`.user-message *`, the reply's bubble), which is what keeps a number whole.
|
|
23
|
+
*/
|
|
24
|
+
export declare const TABLE_STYLES = "\n .llm-table-scroll {\n max-width: 100%;\n overflow-x: auto;\n }\n\n /* The box carries the spacing: a scroll box never collapses its child's margins, so a\n table's own (prose gives it 1em) would show as an empty band inside the box. */\n .llm-table-scroll > table {\n margin-top: 0;\n margin-bottom: 0;\n }\n\n .llm-table-scroll table,\n .llm-table-scroll table * {\n word-break: normal;\n overflow-wrap: normal;\n }\n\n .llm-table-scroll th,\n .llm-table-scroll td {\n font-variant-numeric: tabular-nums;\n }\n\n /* A cut-off column alone reads as a finished table (or as a number split in two), so a side\n that has more columns to scroll to carries a soft shadow. Both shadows are pinned to the\n box's edges (sticky, in the table's grid cell) and fade with the scroll position; a table\n that fits has no scroll timeline, so neither shows. Where the browser cannot tie an\n animation to scrolling, the box scrolls without the cue. */\n @supports (animation-timeline: scroll()) {\n .llm-table-scroll {\n display: grid;\n scroll-timeline: --llm-table-scroll inline;\n }\n\n .llm-table-scroll > table,\n .llm-table-scroll::before,\n .llm-table-scroll::after {\n grid-area: 1 / 1;\n }\n\n .llm-table-scroll::before,\n .llm-table-scroll::after {\n content: '';\n position: sticky;\n z-index: 1;\n width: 0.875rem;\n pointer-events: none;\n opacity: 0;\n }\n\n .llm-table-scroll::before {\n left: 0;\n justify-self: start;\n background: linear-gradient(to right, var(--llm-table-scroll-shadow, rgba(18, 25, 38, 0.14)), transparent);\n animation: llm-table-scroll-start linear both;\n animation-timeline: --llm-table-scroll;\n }\n\n .llm-table-scroll::after {\n right: 0;\n justify-self: end;\n background: linear-gradient(to left, var(--llm-table-scroll-shadow, rgba(18, 25, 38, 0.14)), transparent);\n animation: llm-table-scroll-end linear both;\n animation-timeline: --llm-table-scroll;\n }\n }\n\n @keyframes llm-table-scroll-start {\n 0% { opacity: 0; }\n 6%, 100% { opacity: 1; }\n }\n\n @keyframes llm-table-scroll-end {\n 0%, 94% { opacity: 1; }\n 100% { opacity: 0; }\n }\n";
|
|
25
|
+
//# sourceMappingURL=markdownTables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdownTables.d.ts","sourceRoot":"","sources":["../../../src/components/messages-container-ui/markdownTables.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,qDAAqD;AACrD,eAAO,MAAM,kBAAkB,qBAAqB,CAAC;AAErD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI/C;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,q/EA6ExB,CAAC"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown tables in a chat message: every table sits in its own box that scrolls sideways, and
|
|
3
|
+
* nothing inside a table may break a word to make it fit.
|
|
4
|
+
*
|
|
5
|
+
* A message's prose wraps anywhere (`overflow-wrap: anywhere`), so a long path or URL never
|
|
6
|
+
* pushes the chat wider. That rule also counts every character as a break when a table sizes its
|
|
7
|
+
* columns, so a table in a narrow pane squeezed its number columns to a few characters and split
|
|
8
|
+
* "2,000" into "2,00" / "0". Inside a table a line now breaks only where the text has a space,
|
|
9
|
+
* and a table still too wide for the message scrolls in its box instead.
|
|
10
|
+
*/
|
|
11
|
+
/** The box every rendered markdown table sits in. */
|
|
12
|
+
const TABLE_SCROLL_CLASS = 'llm-table-scroll';
|
|
13
|
+
/**
|
|
14
|
+
* Put each `<table>` of rendered HTML in a {@link TABLE_SCROLL_CLASS} box. Every opening tag gets
|
|
15
|
+
* a box and every closing tag closes it, so well-formed HTML stays balanced (nested tables too).
|
|
16
|
+
* Escaped markup, such as a table inside a code block, is text and is left alone.
|
|
17
|
+
*/
|
|
18
|
+
function wrapTables(html) {
|
|
19
|
+
return html.replace(/<table\b[^>]*>/gi, open => `<div class="${TABLE_SCROLL_CLASS}">${open}`).replace(/<\/table\s*>/gi, close => `${close}</div>`);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The box, the no-split rule and the scroll cue, for both the assistant's reply and the person's
|
|
23
|
+
* own bubble. `.llm-table-scroll table *` outranks the bubbles' wrap-anywhere rules
|
|
24
|
+
* (`.user-message *`, the reply's bubble), which is what keeps a number whole.
|
|
25
|
+
*/
|
|
26
|
+
const TABLE_STYLES = `
|
|
27
|
+
.${TABLE_SCROLL_CLASS} {
|
|
28
|
+
max-width: 100%;
|
|
29
|
+
overflow-x: auto;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/* The box carries the spacing: a scroll box never collapses its child's margins, so a
|
|
33
|
+
table's own (prose gives it 1em) would show as an empty band inside the box. */
|
|
34
|
+
.${TABLE_SCROLL_CLASS} > table {
|
|
35
|
+
margin-top: 0;
|
|
36
|
+
margin-bottom: 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.${TABLE_SCROLL_CLASS} table,
|
|
40
|
+
.${TABLE_SCROLL_CLASS} table * {
|
|
41
|
+
word-break: normal;
|
|
42
|
+
overflow-wrap: normal;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.${TABLE_SCROLL_CLASS} th,
|
|
46
|
+
.${TABLE_SCROLL_CLASS} td {
|
|
47
|
+
font-variant-numeric: tabular-nums;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* A cut-off column alone reads as a finished table (or as a number split in two), so a side
|
|
51
|
+
that has more columns to scroll to carries a soft shadow. Both shadows are pinned to the
|
|
52
|
+
box's edges (sticky, in the table's grid cell) and fade with the scroll position; a table
|
|
53
|
+
that fits has no scroll timeline, so neither shows. Where the browser cannot tie an
|
|
54
|
+
animation to scrolling, the box scrolls without the cue. */
|
|
55
|
+
@supports (animation-timeline: scroll()) {
|
|
56
|
+
.${TABLE_SCROLL_CLASS} {
|
|
57
|
+
display: grid;
|
|
58
|
+
scroll-timeline: --llm-table-scroll inline;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.${TABLE_SCROLL_CLASS} > table,
|
|
62
|
+
.${TABLE_SCROLL_CLASS}::before,
|
|
63
|
+
.${TABLE_SCROLL_CLASS}::after {
|
|
64
|
+
grid-area: 1 / 1;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.${TABLE_SCROLL_CLASS}::before,
|
|
68
|
+
.${TABLE_SCROLL_CLASS}::after {
|
|
69
|
+
content: '';
|
|
70
|
+
position: sticky;
|
|
71
|
+
z-index: 1;
|
|
72
|
+
width: 0.875rem;
|
|
73
|
+
pointer-events: none;
|
|
74
|
+
opacity: 0;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.${TABLE_SCROLL_CLASS}::before {
|
|
78
|
+
left: 0;
|
|
79
|
+
justify-self: start;
|
|
80
|
+
background: linear-gradient(to right, var(--llm-table-scroll-shadow, rgba(18, 25, 38, 0.14)), transparent);
|
|
81
|
+
animation: llm-table-scroll-start linear both;
|
|
82
|
+
animation-timeline: --llm-table-scroll;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.${TABLE_SCROLL_CLASS}::after {
|
|
86
|
+
right: 0;
|
|
87
|
+
justify-self: end;
|
|
88
|
+
background: linear-gradient(to left, var(--llm-table-scroll-shadow, rgba(18, 25, 38, 0.14)), transparent);
|
|
89
|
+
animation: llm-table-scroll-end linear both;
|
|
90
|
+
animation-timeline: --llm-table-scroll;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@keyframes llm-table-scroll-start {
|
|
95
|
+
0% { opacity: 0; }
|
|
96
|
+
6%, 100% { opacity: 1; }
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
@keyframes llm-table-scroll-end {
|
|
100
|
+
0%, 94% { opacity: 1; }
|
|
101
|
+
100% { opacity: 0; }
|
|
102
|
+
}
|
|
103
|
+
`;export{TABLE_SCROLL_CLASS,TABLE_STYLES,wrapTables};//# sourceMappingURL=markdownTables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdownTables.js","sources":["../../../src/components/messages-container-ui/markdownTables.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA;;;;;;;;;AASG;AAEH;AACO,MAAM,kBAAkB,GAAG;AAElC;;;;AAIG;AACG,SAAU,UAAU,CAAC,IAAY,EAAA;AACnC,EAAA,OAAA,IAAO,CAAA,OAAI,CAAA,kBAAA,EAAA,IAAA,IAAA,CAAA,YAAA,EAAA,kBAAA,CAAA,EAAA,EAAA,IAAA,CAAA,CAAA,CAAA,CAAA,OAAA,CAAA,gBAAA,EAAA,KAAA,IAAA,CAAA,EAAA,KAAA,CAAA,MAAA,CAAA,CAAA;AACN;AACA;AACT;AAEA;;;;AAIG,KAAA,EAAA,kBAAA,CAAA;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAmCW,kBAAkB,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -11,6 +11,10 @@ export declare enum MessengerSlotFillNameEnum {
|
|
|
11
11
|
MEDIA_NAME = "media",
|
|
12
12
|
WORKFLOW_NAME = "workflow",
|
|
13
13
|
CONNECTOR_NAME = "connector",
|
|
14
|
-
GENERIC_NAME = "generic"
|
|
14
|
+
GENERIC_NAME = "generic",
|
|
15
|
+
SHOPPING_NAME = "shopping",
|
|
16
|
+
MOVIES_NAME = "movies",
|
|
17
|
+
JOBS_NAME = "jobs",
|
|
18
|
+
RESUME_NAME = "resume"
|
|
15
19
|
}
|
|
16
20
|
//# sourceMappingURL=messenger-slot-fill-name-enum.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messenger-slot-fill-name-enum.d.ts","sourceRoot":"","sources":["../../../src/components/messages-container-ui/messenger-slot-fill-name-enum.ts"],"names":[],"mappings":"AAAA,oBAAY,yBAAyB;IACjC,mBAAmB,wBAAwB;IAC3C,2BAA2B,gCAAgC;IAC3D,aAAa,kBAAkB;IAC/B,YAAY,YAAY;IACxB,aAAa,aAAa;IAC1B,cAAc,cAAc;IAC5B,gBAAgB,gBAAgB;IAChC,YAAY,YAAY;IACxB,WAAW,WAAW;IACtB,UAAU,UAAU;IACpB,aAAa,aAAa;IAC1B,cAAc,cAAc;IAC5B,YAAY,YAAY;
|
|
1
|
+
{"version":3,"file":"messenger-slot-fill-name-enum.d.ts","sourceRoot":"","sources":["../../../src/components/messages-container-ui/messenger-slot-fill-name-enum.ts"],"names":[],"mappings":"AAAA,oBAAY,yBAAyB;IACjC,mBAAmB,wBAAwB;IAC3C,2BAA2B,gCAAgC;IAC3D,aAAa,kBAAkB;IAC/B,YAAY,YAAY;IACxB,aAAa,aAAa;IAC1B,cAAc,cAAc;IAC5B,gBAAgB,gBAAgB;IAChC,YAAY,YAAY;IACxB,WAAW,WAAW;IACtB,UAAU,UAAU;IACpB,aAAa,aAAa;IAC1B,cAAc,cAAc;IAC5B,YAAY,YAAY;IAGxB,aAAa,aAAa;IAC1B,WAAW,WAAW;IACtB,SAAS,SAAS;IAClB,WAAW,WAAW;CACzB"}
|
|
@@ -13,4 +13,10 @@ var MessengerSlotFillNameEnum;
|
|
|
13
13
|
MessengerSlotFillNameEnum["WORKFLOW_NAME"] = "workflow";
|
|
14
14
|
MessengerSlotFillNameEnum["CONNECTOR_NAME"] = "connector";
|
|
15
15
|
MessengerSlotFillNameEnum["GENERIC_NAME"] = "generic";
|
|
16
|
+
// Result cards registered by ai-chat-ext (MessageResults): a row of product, showtime or
|
|
17
|
+
// role cards, and the single resume document card.
|
|
18
|
+
MessengerSlotFillNameEnum["SHOPPING_NAME"] = "shopping";
|
|
19
|
+
MessengerSlotFillNameEnum["MOVIES_NAME"] = "movies";
|
|
20
|
+
MessengerSlotFillNameEnum["JOBS_NAME"] = "jobs";
|
|
21
|
+
MessengerSlotFillNameEnum["RESUME_NAME"] = "resume";
|
|
16
22
|
})(MessengerSlotFillNameEnum || (MessengerSlotFillNameEnum = {}));export{MessengerSlotFillNameEnum};//# sourceMappingURL=messenger-slot-fill-name-enum.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messenger-slot-fill-name-enum.js","sources":["../../../src/components/messages-container-ui/messenger-slot-fill-name-enum.ts"],"sourcesContent":[null],"names":[],"mappings":"IAAY;AAAZ,CAAA,UAAY,yBAAyB,EAAA;AACjC,EAAA,yBAAA,CAAA,qBAAA,CAAA,GAAA,qBAAA;AACA,EAAA,yBAAA,CAAA,6BAAA,CAAA,GAAA,6BAAA;AACA,EAAA,yBAAA,CAAA,eAAA,CAAA,GAAA,eAAA;AACA,EAAA,yBAAA,CAAA,cAAA,CAAA,GAAA,SAAA;AACA,EAAA,yBAAA,CAAA,eAAA,CAAA,GAAA,UAAA;AACA,EAAA,yBAAA,CAAA,gBAAA,CAAA,GAAA,WAAA;AACA,EAAA,yBAAA,CAAA,kBAAA,CAAA,GAAA,aAAA;AACA,EAAA,yBAAA,CAAA,cAAA,CAAA,GAAA,SAAA;AACA,EAAA,yBAAA,CAAA,aAAA,CAAA,GAAA,QAAA;AACA,EAAA,yBAAA,CAAA,YAAA,CAAA,GAAA,OAAA;AACA,EAAA,yBAAA,CAAA,eAAA,CAAA,GAAA,UAAA;AACA,EAAA,yBAAA,CAAA,gBAAA,CAAA,GAAA,WAAA;AACA,EAAA,yBAAA,CAAA,cAAA,CAAA,GAAA,SAAA;AACJ,CAAC,
|
|
1
|
+
{"version":3,"file":"messenger-slot-fill-name-enum.js","sources":["../../../src/components/messages-container-ui/messenger-slot-fill-name-enum.ts"],"sourcesContent":[null],"names":[],"mappings":"IAAY;AAAZ,CAAA,UAAY,yBAAyB,EAAA;AACjC,EAAA,yBAAA,CAAA,qBAAA,CAAA,GAAA,qBAAA;AACA,EAAA,yBAAA,CAAA,6BAAA,CAAA,GAAA,6BAAA;AACA,EAAA,yBAAA,CAAA,eAAA,CAAA,GAAA,eAAA;AACA,EAAA,yBAAA,CAAA,cAAA,CAAA,GAAA,SAAA;AACA,EAAA,yBAAA,CAAA,eAAA,CAAA,GAAA,UAAA;AACA,EAAA,yBAAA,CAAA,gBAAA,CAAA,GAAA,WAAA;AACA,EAAA,yBAAA,CAAA,kBAAA,CAAA,GAAA,aAAA;AACA,EAAA,yBAAA,CAAA,cAAA,CAAA,GAAA,SAAA;AACA,EAAA,yBAAA,CAAA,aAAA,CAAA,GAAA,QAAA;AACA,EAAA,yBAAA,CAAA,YAAA,CAAA,GAAA,OAAA;AACA,EAAA,yBAAA,CAAA,eAAA,CAAA,GAAA,UAAA;AACA,EAAA,yBAAA,CAAA,gBAAA,CAAA,GAAA,WAAA;AACA,EAAA,yBAAA,CAAA,cAAA,CAAA,GAAA,SAAA;;;AAGA,EAAA,yBAAA,CAAA,eAAA,CAAA,GAAA,UAAA;AACA,EAAA,yBAAA,CAAA,aAAA,CAAA,GAAA,QAAA;AACA,EAAA,yBAAA,CAAA,WAAA,CAAA,GAAA,MAAA;AACA,EAAA,yBAAA,CAAA,aAAA,CAAA,GAAA,QAAA;AACJ,CAAC,EApBW,yBAAyB,KAAzB,yBAAyB,GAAA,EAAA,CAAA,CAAA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import type { StreamingRenderOptions } from './types';
|
|
2
3
|
/**
|
|
3
4
|
* Renders in-flight streaming assistant content with the rich Modern renderer:
|
|
4
5
|
* raw-code content goes through {@link CodeFormatter}, everything else through
|
|
@@ -7,5 +8,5 @@ import React from 'react';
|
|
|
7
8
|
* Pass this as `MessagesContainerUI` / `PlanModeView`'s `renderStreamingContent` to keep
|
|
8
9
|
* markdown / code rendering while streaming (the base default is plain text).
|
|
9
10
|
*/
|
|
10
|
-
export declare function renderModernStreamingContent(content: string,
|
|
11
|
+
export declare function renderModernStreamingContent(content: string, opts?: StreamingRenderOptions): React.ReactNode;
|
|
11
12
|
//# sourceMappingURL=modernStreaming.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modernStreaming.d.ts","sourceRoot":"","sources":["../../../src/components/messages-container-ui/modernStreaming.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"modernStreaming.d.ts","sourceRoot":"","sources":["../../../src/components/messages-container-ui/modernStreaming.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAEtD;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,sBAA2B,GAAG,KAAK,CAAC,SAAS,CAmBhH"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {jsx}from'react/jsx-runtime';import {detectContentType,CodeFormatter,FormattedMessageContent}from'./ModernMessageGroup.js';/**
|
|
1
|
+
import {jsx}from'react/jsx-runtime';import {detectContentType,CodeFormatter,FormattedMessageContent,assistantFrameClass}from'./ModernMessageGroup.js';/**
|
|
2
2
|
* Renders in-flight streaming assistant content with the rich Modern renderer:
|
|
3
3
|
* raw-code content goes through {@link CodeFormatter}, everything else through
|
|
4
4
|
* {@link FormattedMessageContent} (markdown + embedded code blocks).
|
|
@@ -6,12 +6,29 @@ import {jsx}from'react/jsx-runtime';import {detectContentType,CodeFormatter,Form
|
|
|
6
6
|
* Pass this as `MessagesContainerUI` / `PlanModeView`'s `renderStreamingContent` to keep
|
|
7
7
|
* markdown / code rendering while streaming (the base default is plain text).
|
|
8
8
|
*/
|
|
9
|
-
function renderModernStreamingContent(content,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
function renderModernStreamingContent(content, opts = {}) {
|
|
10
|
+
const {
|
|
11
|
+
isDesktopView = false,
|
|
12
|
+
isSmallScreen = false,
|
|
13
|
+
showCopyDownloadOnCodeBlock = true
|
|
14
|
+
} = opts;
|
|
15
|
+
return (
|
|
16
|
+
// Same frame as ModernMessageGroup's assistant post, so nothing restyles when the stream lands.
|
|
17
|
+
jsx("div", {
|
|
18
|
+
className: `group rounded-lg ${assistantFrameClass(isDesktopView, isSmallScreen)}`,
|
|
19
|
+
children: jsx("div", {
|
|
20
|
+
className: "min-w-0 overflow-hidden py-2",
|
|
21
|
+
children: jsx("div", {
|
|
22
|
+
className: "min-w-0 relative max-w-full w-full text-foreground",
|
|
23
|
+
children: detectContentType(content) === 'code' ? jsx(CodeFormatter, {
|
|
24
|
+
content: content,
|
|
25
|
+
showCopyDownload: showCopyDownloadOnCodeBlock
|
|
26
|
+
}) : jsx(FormattedMessageContent, {
|
|
27
|
+
content: content,
|
|
28
|
+
showCopyDownloadOnCodeBlock: showCopyDownloadOnCodeBlock
|
|
29
|
+
})
|
|
30
|
+
})
|
|
31
|
+
})
|
|
32
|
+
})
|
|
33
|
+
);
|
|
17
34
|
}export{renderModernStreamingContent};//# sourceMappingURL=modernStreaming.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modernStreaming.js","sources":["../../../src/components/messages-container-ui/modernStreaming.tsx"],"sourcesContent":[null],"names":[
|
|
1
|
+
{"version":3,"file":"modernStreaming.js","sources":["../../../src/components/messages-container-ui/modernStreaming.tsx"],"sourcesContent":[null],"names":[],"mappings":"sJAIA;;;;;;;AAOG;SACa,4BAA4B,CAAC,OAAe,EAAE,OAA+B,EAAE,EAAA;AAC3F,EAAA,MAAA;IACA,aAAO,GAAA,KAAA;IACH,aAAA,GAAA,KAAA;AACA,IAAA,2BAAgB,GAAA;AAexB,GAAC,GAAA,IAAA;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -11,6 +11,7 @@ export interface PlanMessage {
|
|
|
11
11
|
createdAt?: Date | string;
|
|
12
12
|
/** Optional: pass through to the injected message-group renderer (propsConfiguration, props, files, etc.) */
|
|
13
13
|
propsConfiguration?: any;
|
|
14
|
+
/** `props.animateEntry: true` plays the just-sent entrance on a user bubble (see useBubbleEntrance). */
|
|
14
15
|
props?: any;
|
|
15
16
|
files?: any;
|
|
16
17
|
author?: any;
|
|
@@ -60,4 +61,10 @@ export interface MessageGroupRenderProps {
|
|
|
60
61
|
}
|
|
61
62
|
/** The injectable message-group renderer. Defaults to a plain-text bubble renderer. */
|
|
62
63
|
export type MessageGroupComponentType = React.ComponentType<MessageGroupRenderProps>;
|
|
64
|
+
/** What `renderStreamingContent` gets to frame the stream like the post it becomes. */
|
|
65
|
+
export interface StreamingRenderOptions {
|
|
66
|
+
isDesktopView?: boolean;
|
|
67
|
+
isSmallScreen?: boolean;
|
|
68
|
+
showCopyDownloadOnCodeBlock?: boolean;
|
|
69
|
+
}
|
|
63
70
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/messages-container-ui/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B;;;;GAIG;AAEH,MAAM,WAAW,WAAW;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;IAC1B,6GAA6G;IAC7G,kBAAkB,CAAC,EAAE,GAAG,CAAC;IACzB,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,yDAAyD;AACzD,MAAM,WAAW,6BAA6B;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yGAAyG;IACzG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;IACd,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACpC,iFAAiF;IACjF,QAAQ,EAAE,GAAG,EAAE,CAAC;IAChB,WAAW,EAAE,GAAG,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IACjC,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAC;IACpC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,GAAG,EAAE,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,UAAU,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACzC;AAED,uFAAuF;AACvF,MAAM,MAAM,yBAAyB,GAAG,KAAK,CAAC,aAAa,CAAC,uBAAuB,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/messages-container-ui/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B;;;;GAIG;AAEH,MAAM,WAAW,WAAW;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;IAC1B,6GAA6G;IAC7G,kBAAkB,CAAC,EAAE,GAAG,CAAC;IACzB,wGAAwG;IACxG,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,yDAAyD;AACzD,MAAM,WAAW,6BAA6B;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yGAAyG;IACzG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;IACd,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACpC,iFAAiF;IACjF,QAAQ,EAAE,GAAG,EAAE,CAAC;IAChB,WAAW,EAAE,GAAG,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IACjC,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAC;IACpC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,GAAG,EAAE,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,UAAU,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACzC;AAED,uFAAuF;AACvF,MAAM,MAAM,yBAAyB,GAAG,KAAK,CAAC,aAAa,CAAC,uBAAuB,CAAC,CAAC;AAErF,uFAAuF;AACvF,MAAM,WAAW,sBAAsB;IACnC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACzC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The entrance a message plays when the user has just sent it (a post with
|
|
3
|
+
* `props.animateEntry`). History, chat switches and re-renders never animate:
|
|
4
|
+
* the host flags only the bubble it just appended, and the decision is taken
|
|
5
|
+
* once at mount so the flag going away later cannot cut or replay it.
|
|
6
|
+
*
|
|
7
|
+
* Transform and opacity only, so it runs on the compositor and never moves the
|
|
8
|
+
* layout around it. Runs before paint, so the bubble never flashes in place
|
|
9
|
+
* first. Reduced-motion users get the bubble with no motion.
|
|
10
|
+
*/
|
|
11
|
+
export declare function useBubbleEntrance<T extends HTMLElement>(requested: boolean): import("react").RefObject<T>;
|
|
12
|
+
//# sourceMappingURL=useBubbleEntrance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useBubbleEntrance.d.ts","sourceRoot":"","sources":["../../../src/components/messages-container-ui/useBubbleEntrance.ts"],"names":[],"mappings":"AASA;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,WAAW,EAAE,SAAS,EAAE,OAAO,gCAW1E"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {useRef,useState,useLayoutEffect}from'react';/** Rises out of the composer toward its tail corner; ease-out so it lands softly. */
|
|
2
|
+
const KEYFRAMES = [{
|
|
3
|
+
opacity: 0,
|
|
4
|
+
transform: 'translateY(12px) scale(0.96)',
|
|
5
|
+
transformOrigin: 'right bottom'
|
|
6
|
+
}, {
|
|
7
|
+
opacity: 1,
|
|
8
|
+
transform: 'translateY(0) scale(1)',
|
|
9
|
+
transformOrigin: 'right bottom'
|
|
10
|
+
}];
|
|
11
|
+
const TIMING = {
|
|
12
|
+
duration: 320,
|
|
13
|
+
easing: 'cubic-bezier(0.22, 1, 0.36, 1)'
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* The entrance a message plays when the user has just sent it (a post with
|
|
17
|
+
* `props.animateEntry`). History, chat switches and re-renders never animate:
|
|
18
|
+
* the host flags only the bubble it just appended, and the decision is taken
|
|
19
|
+
* once at mount so the flag going away later cannot cut or replay it.
|
|
20
|
+
*
|
|
21
|
+
* Transform and opacity only, so it runs on the compositor and never moves the
|
|
22
|
+
* layout around it. Runs before paint, so the bubble never flashes in place
|
|
23
|
+
* first. Reduced-motion users get the bubble with no motion.
|
|
24
|
+
*/
|
|
25
|
+
function useBubbleEntrance(requested) {
|
|
26
|
+
const ref = useRef(null);
|
|
27
|
+
const [play] = useState(requested);
|
|
28
|
+
useLayoutEffect(() => {
|
|
29
|
+
const el = ref.current;
|
|
30
|
+
if (!play || !el || typeof el.animate !== 'function') return undefined;
|
|
31
|
+
if (window.matchMedia?.('(prefers-reduced-motion: reduce)').matches) return undefined;
|
|
32
|
+
const animation = el.animate(KEYFRAMES, TIMING);
|
|
33
|
+
return () => animation.cancel();
|
|
34
|
+
}, [play]);
|
|
35
|
+
return ref;
|
|
36
|
+
}export{useBubbleEntrance};//# sourceMappingURL=useBubbleEntrance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useBubbleEntrance.js","sources":["../../../src/components/messages-container-ui/useBubbleEntrance.ts"],"sourcesContent":[null],"names":[],"mappings":"oDAEA;AACA,MAAM,SAAS,GAAe,CAAA;SACxB,EAAA,CAAA;WACA,EAAO,8BAAgB;EAC3B,eAAA,EAAA;AACF,CAAA,EAAA;AAEA,EAAA,OAAA,EAAA,CAAA;;;;;;;;;AASG;AACH;AACI;;;AAGI;;AACsD;;AACe,SAAA,iBAAiB,CAAA,SAAA,EAAA;QACtF,GAAA,GAAM,MAAA,CAAA,IAAS,CAAG;AAClB,EAAA,MAAA,CAAA,IAAA,CAAA,qBAAuB,CAAA;AAC3B,EAAA,eAAW,CAAA,MAAA;AACX,IAAA,MAAA,KAAW,GAAA,CAAA,OAAA;AACf,IAAC,IAAA,CAAA,IAAA,IAAA,CAAA,EAAA,IAAA,OAAA,EAAA,CAAA,OAAA,KAAA,UAAA,EAAA,OAAA,SAAA;;;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@admin-layout/tailwind-chat-pro",
|
|
3
|
-
"version": "12.2.5-alpha.
|
|
3
|
+
"version": "12.2.5-alpha.22",
|
|
4
4
|
"description": "Customizable base chat / messages container UI (plan mode). The message renderer is injectable, so consumers plug in their own message-group component.",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"author": "CDMBase LLC",
|
|
@@ -13,15 +13,13 @@
|
|
|
13
13
|
"build:clean": "rimraf lib",
|
|
14
14
|
"build:lib": "rollup -c rollup.config.mjs",
|
|
15
15
|
"build:lib:watch": "yarn build:lib -- --watch",
|
|
16
|
-
"jest": "./node_modules/.bin/jest",
|
|
17
16
|
"prepublish": "yarn build",
|
|
18
|
-
"test": "
|
|
19
|
-
"test:
|
|
20
|
-
"test:watch": "npm test -- --watch",
|
|
17
|
+
"test": "vitest run",
|
|
18
|
+
"test:watch": "vitest",
|
|
21
19
|
"watch": "yarn build:lib:watch"
|
|
22
20
|
},
|
|
23
21
|
"dependencies": {
|
|
24
|
-
"@admin-layout/tailwind-ui": "12.2.5-alpha.
|
|
22
|
+
"@admin-layout/tailwind-ui": "12.2.5-alpha.22",
|
|
25
23
|
"clsx": "^2.1.1",
|
|
26
24
|
"date-fns": "^4.1.0",
|
|
27
25
|
"marked": "7.0.5",
|
|
@@ -30,12 +28,13 @@
|
|
|
30
28
|
"remark-gfm": "^4.0.1"
|
|
31
29
|
},
|
|
32
30
|
"devDependencies": {
|
|
33
|
-
"common": "12.2.5-alpha.2"
|
|
31
|
+
"common": "12.2.5-alpha.2",
|
|
32
|
+
"vitest": "^3.0.4"
|
|
34
33
|
},
|
|
35
34
|
"peerDependencies": {
|
|
36
|
-
"@admin-layout/tailwind-ui": "12.2.5-alpha.
|
|
35
|
+
"@admin-layout/tailwind-ui": "12.2.5-alpha.15",
|
|
37
36
|
"@common-stack/components-pro": "*",
|
|
38
|
-
"common": "12.2.5-alpha.
|
|
37
|
+
"common": "12.2.5-alpha.2",
|
|
39
38
|
"react": ">=18"
|
|
40
39
|
},
|
|
41
40
|
"publishConfig": {
|
|
@@ -44,5 +43,5 @@
|
|
|
44
43
|
"typescript": {
|
|
45
44
|
"definition": "lib/index.d.ts"
|
|
46
45
|
},
|
|
47
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "d8db495e828063c09a588df4e27936a00dce3293"
|
|
48
47
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import clsx from 'clsx';
|
|
3
3
|
import { PlanModeView } from './PlanModeView';
|
|
4
|
-
import type { PlanMessage, MessageGroupComponentType } from './types';
|
|
4
|
+
import type { PlanMessage, MessageGroupComponentType, StreamingRenderOptions } from './types';
|
|
5
5
|
import type { PlanModeViewInputToolbarProps } from './PlanModeView';
|
|
6
6
|
|
|
7
7
|
export interface MessagesContainerUIProps {
|
|
@@ -80,7 +80,7 @@ export interface MessagesContainerUIProps {
|
|
|
80
80
|
*/
|
|
81
81
|
MessageGroupComponent?: MessageGroupComponentType;
|
|
82
82
|
/** Optional: how to render the in-flight streaming assistant content (default: plain text). */
|
|
83
|
-
renderStreamingContent?: (content: string) => React.ReactNode;
|
|
83
|
+
renderStreamingContent?: (content: string, opts?: StreamingRenderOptions) => React.ReactNode;
|
|
84
84
|
/** Optional: override how a PlanMessage is mapped to the post shape handed to the renderer. */
|
|
85
85
|
mapMessageToPost?: (msg: PlanMessage, currentUser: MessagesContainerUIProps['currentUser']) => any;
|
|
86
86
|
}
|