@memori.ai/memori-react 8.18.2 → 8.19.0
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 +8 -0
- package/README.md +2 -0
- package/dist/components/Chat/Chat.d.ts +2 -0
- package/dist/components/Chat/Chat.js +2 -2
- package/dist/components/Chat/Chat.js.map +1 -1
- package/dist/components/ChatInputs/ChatInputs.d.ts +2 -0
- package/dist/components/ChatInputs/ChatInputs.js +5 -3
- package/dist/components/ChatInputs/ChatInputs.js.map +1 -1
- package/dist/components/ChatTextArea/ChatTextArea.css +19 -1
- package/dist/components/ChatTextArea/ChatTextArea.d.ts +1 -0
- package/dist/components/ChatTextArea/ChatTextArea.js +46 -27
- package/dist/components/ChatTextArea/ChatTextArea.js.map +1 -1
- package/dist/components/MemoriWidget/MemoriWidget.d.ts +3 -1
- package/dist/components/MemoriWidget/MemoriWidget.js +3 -1
- package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/esm/components/Chat/Chat.d.ts +2 -0
- package/esm/components/Chat/Chat.js +2 -2
- package/esm/components/Chat/Chat.js.map +1 -1
- package/esm/components/ChatInputs/ChatInputs.d.ts +2 -0
- package/esm/components/ChatInputs/ChatInputs.js +5 -3
- package/esm/components/ChatInputs/ChatInputs.js.map +1 -1
- package/esm/components/ChatTextArea/ChatTextArea.css +19 -1
- package/esm/components/ChatTextArea/ChatTextArea.d.ts +1 -0
- package/esm/components/ChatTextArea/ChatTextArea.js +47 -28
- package/esm/components/ChatTextArea/ChatTextArea.js.map +1 -1
- package/esm/components/MemoriWidget/MemoriWidget.d.ts +3 -1
- package/esm/components/MemoriWidget/MemoriWidget.js +3 -1
- package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/esm/index.d.ts +2 -0
- package/esm/index.js +4 -2
- package/esm/index.js.map +1 -1
- package/esm/version.d.ts +1 -1
- package/esm/version.js +1 -1
- package/package.json +1 -1
- package/src/components/Chat/Chat.tsx +8 -0
- package/src/components/ChatInputs/ChatInputs.tsx +9 -1
- package/src/components/ChatTextArea/ChatTextArea.css +19 -1
- package/src/components/ChatTextArea/ChatTextArea.tsx +38 -7
- package/src/components/MemoriWidget/MemoriWidget.tsx +8 -0
- package/src/components/layouts/layouts.stories.tsx +1 -0
- package/src/index.stories.tsx +15 -0
- package/src/index.tsx +11 -1
- package/src/version.ts +1 -1
|
@@ -15,6 +15,8 @@ export interface Props {
|
|
|
15
15
|
onFocus?: (e: React.FocusEvent) => void;
|
|
16
16
|
onBlur?: (e: React.FocusEvent) => void;
|
|
17
17
|
onExpandedChange?: (expanded: boolean) => void;
|
|
18
|
+
/** When set, shows a character counter (e.g. "0 / 500") above the textarea and enforces the max length. */
|
|
19
|
+
maxTextareaCharacters?: number;
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
const ChatTextArea: React.FC<Props> = ({
|
|
@@ -26,6 +28,7 @@ const ChatTextArea: React.FC<Props> = ({
|
|
|
26
28
|
onFocus,
|
|
27
29
|
onBlur,
|
|
28
30
|
onExpandedChange,
|
|
31
|
+
maxTextareaCharacters,
|
|
29
32
|
}) => {
|
|
30
33
|
const { t } = useTranslation();
|
|
31
34
|
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
|
@@ -78,22 +81,48 @@ const ChatTextArea: React.FC<Props> = ({
|
|
|
78
81
|
}
|
|
79
82
|
}, [value]);
|
|
80
83
|
|
|
84
|
+
const displayValue =
|
|
85
|
+
maxTextareaCharacters != null
|
|
86
|
+
? value.slice(0, maxTextareaCharacters)
|
|
87
|
+
: value;
|
|
88
|
+
|
|
89
|
+
// Keep parent state in sync when value exceeds limit (e.g. paste or prop change)
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
if (
|
|
92
|
+
maxTextareaCharacters != null &&
|
|
93
|
+
value.length > maxTextareaCharacters
|
|
94
|
+
) {
|
|
95
|
+
onChange(value.slice(0, maxTextareaCharacters));
|
|
96
|
+
}
|
|
97
|
+
}, [maxTextareaCharacters, value, onChange]);
|
|
98
|
+
|
|
81
99
|
return (
|
|
82
100
|
<div
|
|
83
101
|
data-testid="chat-textarea"
|
|
84
102
|
className={cx('memori-chat-textarea', {
|
|
85
103
|
'memori-chat-textarea--disabled': disabled,
|
|
104
|
+
'memori-chat-textarea--with-counter': maxTextareaCharacters != null,
|
|
86
105
|
})}
|
|
87
106
|
>
|
|
107
|
+
{maxTextareaCharacters != null && (
|
|
108
|
+
<div className="memori-chat-textarea--counter" aria-live="polite">
|
|
109
|
+
{displayValue.length} / {maxTextareaCharacters}
|
|
110
|
+
</div>
|
|
111
|
+
)}
|
|
88
112
|
<div ref={innerRef} className="memori-chat-textarea--inner">
|
|
89
113
|
<textarea
|
|
90
114
|
ref={textareaRef}
|
|
91
115
|
className="memori-chat-textarea--input"
|
|
92
116
|
disabled={disabled}
|
|
93
|
-
value={
|
|
117
|
+
value={displayValue}
|
|
94
118
|
placeholder={t('placeholder', 'Ask a question') || 'Ask a question'}
|
|
95
119
|
onChange={e => {
|
|
96
|
-
|
|
120
|
+
const next = e.target.value;
|
|
121
|
+
if (maxTextareaCharacters != null) {
|
|
122
|
+
onChange(next.slice(0, maxTextareaCharacters));
|
|
123
|
+
} else {
|
|
124
|
+
onChange(next);
|
|
125
|
+
}
|
|
97
126
|
}}
|
|
98
127
|
onKeyDownCapture={e => {
|
|
99
128
|
// On mobile/tablet only: Enter creates a new line instead of sending.
|
|
@@ -106,10 +135,12 @@ const ChatTextArea: React.FC<Props> = ({
|
|
|
106
135
|
e.preventDefault();
|
|
107
136
|
|
|
108
137
|
const el = textareaRef.current;
|
|
109
|
-
const start = el?.selectionStart ??
|
|
110
|
-
const end = el?.selectionEnd ??
|
|
111
|
-
|
|
112
|
-
|
|
138
|
+
const start = el?.selectionStart ?? displayValue.length;
|
|
139
|
+
const end = el?.selectionEnd ?? displayValue.length;
|
|
140
|
+
let nextValue = `${displayValue.slice(0, start)}\n${displayValue.slice(end)}`;
|
|
141
|
+
if (maxTextareaCharacters != null) {
|
|
142
|
+
nextValue = nextValue.slice(0, maxTextareaCharacters);
|
|
143
|
+
}
|
|
113
144
|
onChange(nextValue);
|
|
114
145
|
|
|
115
146
|
// Restore caret right after the inserted newline
|
|
@@ -130,7 +161,7 @@ const ChatTextArea: React.FC<Props> = ({
|
|
|
130
161
|
onPaste={onPaste}
|
|
131
162
|
onFocus={onFocus}
|
|
132
163
|
onBlur={onBlur}
|
|
133
|
-
maxLength={100000}
|
|
164
|
+
maxLength={maxTextareaCharacters ?? 100000}
|
|
134
165
|
/>
|
|
135
166
|
</div>
|
|
136
167
|
</div>
|
|
@@ -435,6 +435,10 @@ export interface Props {
|
|
|
435
435
|
__WEBCOMPONENT__?: boolean;
|
|
436
436
|
/** Override total document payload and per-document content limit (character count). Default from constants. */
|
|
437
437
|
maxTotalMessagePayload?: number;
|
|
438
|
+
/** When true, pasted text is not added as a document attachment (normal paste only). Default false. */
|
|
439
|
+
disablePastedText?: boolean;
|
|
440
|
+
/** Max characters in chat textarea; shows counter and disables paste-as-attachment when set. */
|
|
441
|
+
maxTextareaCharacters?: number;
|
|
438
442
|
}
|
|
439
443
|
|
|
440
444
|
const MemoriWidget = ({
|
|
@@ -491,6 +495,8 @@ const MemoriWidget = ({
|
|
|
491
495
|
applyVarsToRoot = false,
|
|
492
496
|
showFunctionCache = false,
|
|
493
497
|
maxTotalMessagePayload,
|
|
498
|
+
disablePastedText = false,
|
|
499
|
+
maxTextareaCharacters,
|
|
494
500
|
}: Props) => {
|
|
495
501
|
const { t, i18n } = useTranslation();
|
|
496
502
|
|
|
@@ -3025,6 +3031,8 @@ const MemoriWidget = ({
|
|
|
3025
3031
|
experts,
|
|
3026
3032
|
useMathFormatting: applyMathFormatting,
|
|
3027
3033
|
maxTotalMessagePayload,
|
|
3034
|
+
disablePastedText,
|
|
3035
|
+
maxTextareaCharacters,
|
|
3028
3036
|
};
|
|
3029
3037
|
|
|
3030
3038
|
const integrationBackground =
|
package/src/index.stories.tsx
CHANGED
|
@@ -101,6 +101,21 @@ WithUploadWithMaxTotalMessagePayload.args = {
|
|
|
101
101
|
maxTotalMessagePayload: 300000,
|
|
102
102
|
};
|
|
103
103
|
|
|
104
|
+
export const WithMaxTextareaCharacters = Template.bind({});
|
|
105
|
+
WithMaxTextareaCharacters.args = {
|
|
106
|
+
ownerUserName: 'nzambello',
|
|
107
|
+
memoriName: 'Nicola',
|
|
108
|
+
tenantID: 'www.aisuru.com',
|
|
109
|
+
engineURL: 'https://engine.memori.ai',
|
|
110
|
+
apiURL: 'https://backend.memori.ai',
|
|
111
|
+
baseURL: 'https://www.aisuru.com',
|
|
112
|
+
uiLang: 'IT',
|
|
113
|
+
spokenLang: 'IT',
|
|
114
|
+
enableAudio: true,
|
|
115
|
+
showUpload: true,
|
|
116
|
+
maxTextareaCharacters: 500,
|
|
117
|
+
};
|
|
118
|
+
|
|
104
119
|
export const WithPrivateAgent = Template.bind({});
|
|
105
120
|
WithPrivateAgent.args = {
|
|
106
121
|
memoriName: 'Test Private',
|
package/src/index.tsx
CHANGED
|
@@ -48,7 +48,7 @@ export interface Props {
|
|
|
48
48
|
__WEBCOMPONENT__?: boolean;
|
|
49
49
|
showClear?: boolean;
|
|
50
50
|
showOnlyLastMessages?: boolean;
|
|
51
|
-
showTypingText?: boolean;
|
|
51
|
+
showTypingText?: boolean;
|
|
52
52
|
showLogin?: boolean;
|
|
53
53
|
showUpload?: boolean;
|
|
54
54
|
showReasoning?: boolean;
|
|
@@ -77,6 +77,10 @@ export interface Props {
|
|
|
77
77
|
applyVarsToRoot?: boolean;
|
|
78
78
|
/** Override total document payload and per-document content limit (character count). Default from constants (200000). */
|
|
79
79
|
maxTotalMessagePayload?: number;
|
|
80
|
+
/** When true, pasted text is not added as a document attachment (normal paste only). Default false. */
|
|
81
|
+
disablePastedText?: boolean;
|
|
82
|
+
/** Max characters allowed in the chat textarea. When set, shows a counter (e.g. "0 / 500") and disables paste-as-attachment by default. */
|
|
83
|
+
maxTextareaCharacters?: number;
|
|
80
84
|
}
|
|
81
85
|
|
|
82
86
|
const getPreferredLanguages = () => {
|
|
@@ -156,6 +160,8 @@ const Memori: React.FC<Props> = ({
|
|
|
156
160
|
applyVarsToRoot = false,
|
|
157
161
|
__WEBCOMPONENT__ = false,
|
|
158
162
|
maxTotalMessagePayload,
|
|
163
|
+
disablePastedText = false,
|
|
164
|
+
maxTextareaCharacters,
|
|
159
165
|
}) => {
|
|
160
166
|
const [memori, setMemori] = useState<IMemori>();
|
|
161
167
|
const [tenant, setTenant] = useState<Tenant>();
|
|
@@ -469,6 +475,8 @@ const Memori: React.FC<Props> = ({
|
|
|
469
475
|
userAvatar={userAvatar}
|
|
470
476
|
applyVarsToRoot={applyVarsToRoot}
|
|
471
477
|
maxTotalMessagePayload={maxTotalMessagePayload}
|
|
478
|
+
disablePastedText={disablePastedText ?? (maxTextareaCharacters != null)}
|
|
479
|
+
maxTextareaCharacters={maxTextareaCharacters}
|
|
472
480
|
disableTextEnteredEvents={disableTextEnteredEvents}
|
|
473
481
|
// From layout, from client if allowed
|
|
474
482
|
{...clientAttributes}
|
|
@@ -570,5 +578,7 @@ Memori.propTypes = {
|
|
|
570
578
|
autoStart: PropTypes.bool,
|
|
571
579
|
applyVarsToRoot: PropTypes.bool,
|
|
572
580
|
maxTotalMessagePayload: PropTypes.number,
|
|
581
|
+
disablePastedText: PropTypes.bool,
|
|
582
|
+
maxTextareaCharacters: PropTypes.number,
|
|
573
583
|
};
|
|
574
584
|
export default Memori;
|
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// This file is auto-generated. Do not edit manually.
|
|
2
|
-
export const version = '8.
|
|
2
|
+
export const version = '8.19.0';
|