@memori.ai/memori-react 8.2.0 → 8.4.0-rc.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.
Files changed (146) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/components/Chat/Chat.js +8 -1
  3. package/dist/components/Chat/Chat.js.map +1 -1
  4. package/dist/components/MemoriArtifactSystem/components/ArtifactActions/ArtifactActions.css +160 -0
  5. package/dist/components/MemoriArtifactSystem/components/ArtifactActions/ArtifactActions.d.ts +4 -0
  6. package/dist/components/MemoriArtifactSystem/components/ArtifactActions/ArtifactActions.js +166 -0
  7. package/dist/components/MemoriArtifactSystem/components/ArtifactActions/ArtifactActions.js.map +1 -0
  8. package/dist/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.css +877 -0
  9. package/dist/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.d.ts +3 -0
  10. package/dist/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js +115 -0
  11. package/dist/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js.map +1 -0
  12. package/dist/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.css +238 -0
  13. package/dist/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.d.ts +4 -0
  14. package/dist/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.js +104 -0
  15. package/dist/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.js.map +1 -0
  16. package/dist/components/MemoriArtifactSystem/components/ArtifactHistory/ArtifactHistory.css +319 -0
  17. package/dist/components/MemoriArtifactSystem/components/ArtifactHistory/ArtifactHistory.d.ts +4 -0
  18. package/dist/components/MemoriArtifactSystem/components/ArtifactHistory/ArtifactHistory.js +50 -0
  19. package/dist/components/MemoriArtifactSystem/components/ArtifactHistory/ArtifactHistory.js.map +1 -0
  20. package/dist/components/MemoriArtifactSystem/components/ArtifactPreview/ArtifactPreview.css +343 -0
  21. package/dist/components/MemoriArtifactSystem/components/ArtifactPreview/ArtifactPreview.d.ts +4 -0
  22. package/dist/components/MemoriArtifactSystem/components/ArtifactPreview/ArtifactPreview.js +78 -0
  23. package/dist/components/MemoriArtifactSystem/components/ArtifactPreview/ArtifactPreview.js.map +1 -0
  24. package/dist/components/MemoriArtifactSystem/context/ArtifactSystemContext.d.ts +12 -0
  25. package/dist/components/MemoriArtifactSystem/context/ArtifactSystemContext.js +22 -0
  26. package/dist/components/MemoriArtifactSystem/context/ArtifactSystemContext.js.map +1 -0
  27. package/dist/components/MemoriArtifactSystem/hooks/useArtifactSystem.d.ts +12 -0
  28. package/dist/components/MemoriArtifactSystem/hooks/useArtifactSystem.js +288 -0
  29. package/dist/components/MemoriArtifactSystem/hooks/useArtifactSystem.js.map +1 -0
  30. package/dist/components/MemoriArtifactSystem/index.d.ts +9 -0
  31. package/dist/components/MemoriArtifactSystem/index.js +28 -0
  32. package/dist/components/MemoriArtifactSystem/index.js.map +1 -0
  33. package/dist/components/MemoriArtifactSystem/types/artifact.types.d.ts +108 -0
  34. package/dist/components/MemoriArtifactSystem/types/artifact.types.js +31 -0
  35. package/dist/components/MemoriArtifactSystem/types/artifact.types.js.map +1 -0
  36. package/dist/components/icons/Print.d.ts +6 -0
  37. package/dist/components/icons/Print.js +6 -0
  38. package/dist/components/icons/Print.js.map +1 -0
  39. package/dist/components/layouts/Chat.js +29 -1
  40. package/dist/components/layouts/Chat.js.map +1 -1
  41. package/dist/components/layouts/FullPage.js +33 -1
  42. package/dist/components/layouts/FullPage.js.map +1 -1
  43. package/dist/components/layouts/ZoomedFullBody.js +29 -2
  44. package/dist/components/layouts/ZoomedFullBody.js.map +1 -1
  45. package/dist/components/layouts/chat.css +335 -13
  46. package/dist/components/layouts/zoomed-full-body.css +1 -3
  47. package/dist/helpers/message.js +1 -0
  48. package/dist/helpers/message.js.map +1 -1
  49. package/dist/helpers/stt/useSTT.js +76 -9
  50. package/dist/helpers/stt/useSTT.js.map +1 -1
  51. package/dist/index.js +58 -15
  52. package/dist/index.js.map +1 -1
  53. package/dist/styles.css +5 -0
  54. package/esm/components/Chat/Chat.js +8 -1
  55. package/esm/components/Chat/Chat.js.map +1 -1
  56. package/esm/components/MemoriArtifactSystem/components/ArtifactActions/ArtifactActions.css +160 -0
  57. package/esm/components/MemoriArtifactSystem/components/ArtifactActions/ArtifactActions.d.ts +4 -0
  58. package/esm/components/MemoriArtifactSystem/components/ArtifactActions/ArtifactActions.js +163 -0
  59. package/esm/components/MemoriArtifactSystem/components/ArtifactActions/ArtifactActions.js.map +1 -0
  60. package/esm/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.css +877 -0
  61. package/esm/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.d.ts +3 -0
  62. package/esm/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js +112 -0
  63. package/esm/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js.map +1 -0
  64. package/esm/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.css +238 -0
  65. package/esm/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.d.ts +4 -0
  66. package/esm/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.js +101 -0
  67. package/esm/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.js.map +1 -0
  68. package/esm/components/MemoriArtifactSystem/components/ArtifactHistory/ArtifactHistory.css +319 -0
  69. package/esm/components/MemoriArtifactSystem/components/ArtifactHistory/ArtifactHistory.d.ts +4 -0
  70. package/esm/components/MemoriArtifactSystem/components/ArtifactHistory/ArtifactHistory.js +47 -0
  71. package/esm/components/MemoriArtifactSystem/components/ArtifactHistory/ArtifactHistory.js.map +1 -0
  72. package/esm/components/MemoriArtifactSystem/components/ArtifactPreview/ArtifactPreview.css +343 -0
  73. package/esm/components/MemoriArtifactSystem/components/ArtifactPreview/ArtifactPreview.d.ts +4 -0
  74. package/esm/components/MemoriArtifactSystem/components/ArtifactPreview/ArtifactPreview.js +75 -0
  75. package/esm/components/MemoriArtifactSystem/components/ArtifactPreview/ArtifactPreview.js.map +1 -0
  76. package/esm/components/MemoriArtifactSystem/context/ArtifactSystemContext.d.ts +12 -0
  77. package/esm/components/MemoriArtifactSystem/context/ArtifactSystemContext.js +17 -0
  78. package/esm/components/MemoriArtifactSystem/context/ArtifactSystemContext.js.map +1 -0
  79. package/esm/components/MemoriArtifactSystem/hooks/useArtifactSystem.d.ts +12 -0
  80. package/esm/components/MemoriArtifactSystem/hooks/useArtifactSystem.js +281 -0
  81. package/esm/components/MemoriArtifactSystem/hooks/useArtifactSystem.js.map +1 -0
  82. package/esm/components/MemoriArtifactSystem/index.d.ts +9 -0
  83. package/esm/components/MemoriArtifactSystem/index.js +9 -0
  84. package/esm/components/MemoriArtifactSystem/index.js.map +1 -0
  85. package/esm/components/MemoriArtifactSystem/types/artifact.types.d.ts +108 -0
  86. package/esm/components/MemoriArtifactSystem/types/artifact.types.js +28 -0
  87. package/esm/components/MemoriArtifactSystem/types/artifact.types.js.map +1 -0
  88. package/esm/components/icons/Print.d.ts +6 -0
  89. package/esm/components/icons/Print.js +4 -0
  90. package/esm/components/icons/Print.js.map +1 -0
  91. package/esm/components/layouts/Chat.js +29 -1
  92. package/esm/components/layouts/Chat.js.map +1 -1
  93. package/esm/components/layouts/FullPage.js +33 -1
  94. package/esm/components/layouts/FullPage.js.map +1 -1
  95. package/esm/components/layouts/ZoomedFullBody.js +30 -3
  96. package/esm/components/layouts/ZoomedFullBody.js.map +1 -1
  97. package/esm/components/layouts/chat.css +335 -13
  98. package/esm/components/layouts/zoomed-full-body.css +1 -3
  99. package/esm/helpers/message.js +1 -0
  100. package/esm/helpers/message.js.map +1 -1
  101. package/esm/helpers/stt/useSTT.js +76 -9
  102. package/esm/helpers/stt/useSTT.js.map +1 -1
  103. package/esm/index.js +58 -15
  104. package/esm/index.js.map +1 -1
  105. package/esm/styles.css +5 -0
  106. package/package.json +1 -1
  107. package/src/components/Avatar/Avatar.test.tsx +13 -0
  108. package/src/components/Chat/Chat.stories.tsx +33 -2
  109. package/src/components/Chat/Chat.test.tsx +340 -213
  110. package/src/components/Chat/Chat.tsx +27 -4
  111. package/src/components/MemoriArtifactSystem/components/ArtifactActions/ArtifactActions.css +160 -0
  112. package/src/components/MemoriArtifactSystem/components/ArtifactActions/ArtifactActions.tsx +278 -0
  113. package/src/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.css +877 -0
  114. package/src/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.tsx +308 -0
  115. package/src/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.css +238 -0
  116. package/src/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.tsx +282 -0
  117. package/src/components/MemoriArtifactSystem/components/ArtifactHistory/ArtifactHistory.css +319 -0
  118. package/src/components/MemoriArtifactSystem/components/ArtifactHistory/ArtifactHistory.tsx +178 -0
  119. package/src/components/MemoriArtifactSystem/components/ArtifactPreview/ArtifactPreview.css +343 -0
  120. package/src/components/MemoriArtifactSystem/components/ArtifactPreview/ArtifactPreview.tsx +190 -0
  121. package/src/components/MemoriArtifactSystem/context/ArtifactSystemContext.tsx +57 -0
  122. package/src/components/MemoriArtifactSystem/hooks/useArtifactSystem.ts +419 -0
  123. package/src/components/MemoriArtifactSystem/index.ts +45 -0
  124. package/src/components/MemoriArtifactSystem/types/artifact.types.ts +180 -0
  125. package/src/components/icons/Print.tsx +34 -0
  126. package/src/components/layouts/Chat.test.tsx +13 -0
  127. package/src/components/layouts/Chat.tsx +80 -25
  128. package/src/components/layouts/FullPage.test.tsx +40 -11
  129. package/src/components/layouts/FullPage.tsx +92 -24
  130. package/src/components/layouts/HiddenChat.test.tsx +13 -0
  131. package/src/components/layouts/Totem.test.tsx +13 -0
  132. package/src/components/layouts/WebsiteAssistant.test.tsx +13 -0
  133. package/src/components/layouts/ZoomedFullBody.test.tsx +13 -0
  134. package/src/components/layouts/ZoomedFullBody.tsx +78 -14
  135. package/src/components/layouts/__snapshots__/Chat.test.tsx.snap +252 -248
  136. package/src/components/layouts/__snapshots__/FullPage.test.tsx.snap +504 -496
  137. package/src/components/layouts/__snapshots__/ZoomedFullBody.test.tsx.snap +252 -248
  138. package/src/components/layouts/chat.css +335 -13
  139. package/src/components/layouts/layouts.stories.tsx +13 -2
  140. package/src/components/layouts/zoomed-full-body.css +1 -3
  141. package/src/helpers/message.ts +1 -0
  142. package/src/helpers/stt/useSTT.ts +101 -16
  143. package/src/index.stories.tsx +26 -22
  144. package/src/index.tsx +46 -0
  145. package/src/mocks/data.ts +258 -0
  146. package/src/styles.css +5 -0
@@ -0,0 +1,282 @@
1
+ /**
2
+ * ArtifactHandler Component
3
+ * Creates artifact handlers in chat messages and manages artifact display
4
+ * Following the project's component patterns and design system
5
+ */
6
+
7
+ import React, { useCallback, useEffect, useMemo } from 'react';
8
+ import { useTranslation } from 'react-i18next';
9
+ import cx from 'classnames';
10
+ import { ArtifactData, ArtifactHandlerProps } from '../../types/artifact.types';
11
+ import { useArtifactCreator, useArtifactProcessor, useArtifactDetector } from '../../hooks/useArtifactSystem';
12
+
13
+ const ArtifactHandler: React.FC<ArtifactHandlerProps> = ({
14
+ artifact,
15
+ artifacts,
16
+ customTitle,
17
+ config,
18
+ actions,
19
+ message,
20
+ onArtifactCreated,
21
+ }) => {
22
+ const { t } = useTranslation();
23
+ const { createArtifact } = useArtifactCreator();
24
+ const { processArtifactContent } = useArtifactProcessor();
25
+ const { hasArtifacts } = useArtifactDetector();
26
+
27
+ /**
28
+ * Format file size
29
+ */
30
+ const formatBytes = useCallback((bytes: number): string => {
31
+ if (bytes === 0) return '0 Bytes';
32
+ const k = 1024;
33
+ const sizes = ['Bytes', 'KB', 'MB'];
34
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
35
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
36
+ }, []);
37
+
38
+ /**
39
+ * Format timestamp
40
+ */
41
+ const formatTimestamp = useCallback((timestamp: Date): string => {
42
+ return timestamp?.toLocaleTimeString('en-US', {
43
+ hour: '2-digit',
44
+ minute: '2-digit',
45
+ });
46
+ }, []);
47
+
48
+ /**
49
+ * Handle artifact click
50
+ */
51
+ const handleArtifactClick = useCallback(() => {
52
+ const artifactData = artifact;
53
+
54
+ if (onArtifactCreated) {
55
+ onArtifactCreated(artifactData!);
56
+ }
57
+ }, [artifact, onArtifactCreated]);
58
+
59
+ /**
60
+ * Process new dialog state for artifacts
61
+ */
62
+ useEffect(() => {
63
+ const handleMemoriNewDialogState = (message: string) => {
64
+ if (!message || typeof message !== 'string') return;
65
+ console.log('🎨 Processing message for artifacts...');
66
+
67
+ // controllo
68
+ // Process the message content to find and handle any artifacts
69
+ // processArtifactContent returns true if artifacts were found and processed
70
+ const processed = processArtifactContent(
71
+ message, // The message text to scan for artifacts
72
+ (content, mimeType, title) => {
73
+ // Callback when artifact is found
74
+
75
+ // Create a new artifact object with:
76
+ // - Unique ID combining type, timestamp and random string
77
+ // - Content and metadata from the artifact
78
+ // - Type info from config or default fallback
79
+ // - Generated or custom title
80
+ // - Creation timestamp and size
81
+ const artifact = {
82
+ // Generate unique ID
83
+ id: `artifact-${mimeType}-${Date.now()}-${Math.random()
84
+ .toString(36)
85
+ .substr(2, 9)}`,
86
+ content, // The artifact content
87
+ mimeType: mimeType as any,
88
+ // Get type info from config or use default
89
+ typeInfo: config.supportedMimeTypes?.[
90
+ mimeType as keyof typeof config.supportedMimeTypes
91
+ ] || {
92
+ name: mimeType.toUpperCase(),
93
+ icon: '📄',
94
+ hasPreview: false,
95
+ language: 'text',
96
+ mimeType: 'text/plain',
97
+ },
98
+ // Use provided title or generate one from type info
99
+ title:
100
+ title ||
101
+ `${
102
+ config.supportedMimeTypes?.[
103
+ mimeType as keyof typeof config.supportedMimeTypes
104
+ ]?.icon || '📄'
105
+ } ${
106
+ config.supportedMimeTypes?.[
107
+ mimeType as keyof typeof config.supportedMimeTypes
108
+ ]?.name || mimeType.toUpperCase()
109
+ } Artifact`,
110
+ customTitle: title,
111
+ messageID: (message as any).timestamp || `msg-${Date.now()}`,
112
+ timestamp: new Date(),
113
+ size: content.length,
114
+ };
115
+
116
+ // Add the new artifact to the artifact system state
117
+ actions.addArtifact(artifact as ArtifactData);
118
+
119
+ // If auto-open is enabled in config,
120
+ // select/open the artifact after a short delay
121
+ if (config.autoOpenArtifacts) {
122
+ setTimeout(() => {
123
+ actions.selectArtifact(artifact as ArtifactData);
124
+ }, 500);
125
+ }
126
+
127
+ // Call the onArtifactCreated callback if provided
128
+ if (onArtifactCreated) {
129
+ onArtifactCreated(artifact as ArtifactData);
130
+ }
131
+ }
132
+ );
133
+
134
+ if (processed) {
135
+ console.log('✅ Artifacts processed successfully');
136
+ }
137
+ };
138
+ if (!message.fromUser) {
139
+ handleMemoriNewDialogState(message.translatedText || message.text);
140
+ }
141
+ }, [message]);
142
+
143
+ // Check if this message contains artifacts
144
+ const messageText = message.translatedText || message.text || '';
145
+ const messageHasArtifacts = useMemo(() => hasArtifacts(messageText), [messageText]);
146
+
147
+ // Only render if the message contains artifacts
148
+ if (!messageHasArtifacts) {
149
+ return null;
150
+ }
151
+
152
+ // If we have artifacts for this message, render them
153
+ if (artifacts && artifacts.length > 0) {
154
+ return (
155
+ <div className="memori-artifact-handler-container">
156
+ {artifacts.map((messageArtifact) => (
157
+ <div
158
+ key={messageArtifact.id}
159
+ className={cx('memori-artifact-handler', 'memori-card', {
160
+ 'memori-artifact-handler-active': messageArtifact.isActive,
161
+ })}
162
+ onClick={() => {
163
+ actions.selectArtifact(messageArtifact);
164
+ if (onArtifactCreated) {
165
+ onArtifactCreated(messageArtifact);
166
+ }
167
+ }}
168
+ >
169
+ <div className="memori-artifact-handler-content">
170
+ <div className="memori-artifact-handler-icon">
171
+ {messageArtifact.typeInfo?.icon || '📄'}
172
+ </div>
173
+
174
+ <div className="memori-artifact-handler-info">
175
+ <div className="memori-artifact-handler-title">
176
+ {messageArtifact.title}
177
+ </div>
178
+
179
+ <div className="memori-artifact-handler-subtitle">
180
+ {t('artifact.generatedAt', 'Generated at')}{' '}
181
+ {formatTimestamp(messageArtifact.timestamp)} •{' '}
182
+ {formatBytes(messageArtifact.size)}
183
+ </div>
184
+
185
+ <div className="memori-artifact-handler-meta">
186
+ <span className="memori-artifact-handler-type">
187
+ {messageArtifact.typeInfo?.name || 'Text'}
188
+ </span>
189
+ {messageArtifact.customTitle && (
190
+ <span className="memori-artifact-handler-custom-title">
191
+ {messageArtifact.customTitle}
192
+ </span>
193
+ )}
194
+ </div>
195
+ </div>
196
+
197
+ <div className="memori-artifact-handler-actions">
198
+ <button
199
+ className="memori-artifact-handler-toggle"
200
+ title={t('artifact.open', 'Open artifact') || 'Open artifact'}
201
+ >
202
+ <svg
203
+ width="16"
204
+ height="16"
205
+ viewBox="0 0 24 24"
206
+ fill="none"
207
+ stroke="currentColor"
208
+ strokeWidth="2"
209
+ >
210
+ <rect x="3" y="3" width="18" height="18" rx="2" ry="2" />
211
+ <path d="M9 9l6 6m0-6l-6 6" />
212
+ </svg>
213
+ </button>
214
+ </div>
215
+ </div>
216
+ </div>
217
+ ))}
218
+ </div>
219
+ );
220
+ }
221
+
222
+ // If we have a single artifact prop, render it (legacy support)
223
+ if (artifact) {
224
+ return (
225
+ <div
226
+ className={cx('memori-artifact-handler', 'memori-card')}
227
+ onClick={handleArtifactClick}
228
+ >
229
+ <div className="memori-artifact-handler-content">
230
+ <div className="memori-artifact-handler-icon">
231
+ {artifact.typeInfo?.icon || '📄'}
232
+ </div>
233
+
234
+ <div className="memori-artifact-handler-info">
235
+ <div className="memori-artifact-handler-title">{artifact.title}</div>
236
+
237
+ <div className="memori-artifact-handler-subtitle">
238
+ {t('artifact.generatedAt', 'Generated at')}{' '}
239
+ {formatTimestamp(artifact.timestamp)} •{' '}
240
+ {formatBytes(artifact.size)}
241
+ </div>
242
+
243
+ <div className="memori-artifact-handler-meta">
244
+ <span className="memori-artifact-handler-type">
245
+ {artifact.typeInfo?.name || 'Text'}
246
+ </span>
247
+ {customTitle && (
248
+ <span className="memori-artifact-handler-custom-title">
249
+ {customTitle}
250
+ </span>
251
+ )}
252
+ </div>
253
+ </div>
254
+
255
+ <div className="memori-artifact-handler-actions">
256
+ <button
257
+ className="memori-artifact-handler-toggle"
258
+ title={t('artifact.open', 'Open artifact') || 'Open artifact'}
259
+ >
260
+ <svg
261
+ width="16"
262
+ height="16"
263
+ viewBox="0 0 24 24"
264
+ fill="none"
265
+ stroke="currentColor"
266
+ strokeWidth="2"
267
+ >
268
+ <rect x="3" y="3" width="18" height="18" rx="2" ry="2" />
269
+ <path d="M9 9l6 6m0-6l-6 6" />
270
+ </svg>
271
+ </button>
272
+ </div>
273
+ </div>
274
+ </div>
275
+ );
276
+ }
277
+
278
+ // If no artifacts to display, return null
279
+ return null;
280
+ };
281
+
282
+ export default ArtifactHandler;
@@ -0,0 +1,319 @@
1
+ /**
2
+ * ArtifactHistory CSS Styles
3
+ * Following the project's design system and CSS patterns
4
+ */
5
+
6
+ .memori-artifact-history {
7
+ display: flex;
8
+ height: 100%;
9
+ min-height: 0;
10
+ flex-direction: column;
11
+ }
12
+
13
+ /* Header */
14
+ .memori-artifact-history-header {
15
+ display: flex;
16
+ align-items: center;
17
+ justify-content: space-between;
18
+ padding: 0.75rem 0;
19
+ border-bottom: 1px solid var(--memori-button-border-color, #e9ecef);
20
+ margin-bottom: 1rem;
21
+ }
22
+
23
+ .memori-artifact-history-title {
24
+ margin: 0;
25
+ color: var(--memori-text-color, #333);
26
+ font-size: 1rem;
27
+ font-weight: 600;
28
+ }
29
+
30
+ .memori-artifact-history-actions {
31
+ display: flex;
32
+ align-items: center;
33
+ gap: 0.5rem;
34
+ }
35
+
36
+ .memori-artifact-history-clear-btn {
37
+ padding: 0.375rem;
38
+ border-radius: var(--memori-border-radius, 4px);
39
+ font-size: 0.875rem;
40
+ transition: all 0.2s ease;
41
+ }
42
+
43
+ .memori-artifact-history-clear-btn:hover {
44
+ border-color: var(--memori-error-color, #ff4d4f);
45
+ background: var(--memori-error-color, #ff4d4f);
46
+ color: white;
47
+ }
48
+
49
+ /* Empty State */
50
+ .memori-artifact-history-empty {
51
+ display: flex;
52
+ flex: 1;
53
+ flex-direction: column;
54
+ align-items: center;
55
+ justify-content: center;
56
+ padding: 2rem 1rem;
57
+ color: var(--memori-text-color, #666);
58
+ text-align: center;
59
+ }
60
+
61
+ .memori-artifact-history-empty-icon {
62
+ margin-bottom: 1rem;
63
+ font-size: 3rem;
64
+ opacity: 0.5;
65
+ }
66
+
67
+ .memori-artifact-history-empty-text {
68
+ margin: 0 0 0.5rem;
69
+ color: var(--memori-text-color, #333);
70
+ font-size: 1rem;
71
+ font-weight: 500;
72
+ }
73
+
74
+ .memori-artifact-history-empty-subtext {
75
+ margin: 0;
76
+ font-size: 0.875rem;
77
+ opacity: 0.7;
78
+ }
79
+
80
+ /* History List */
81
+ .memori-artifact-history-list {
82
+ flex: 1;
83
+ padding-right: 0.25rem;
84
+ overflow-y: auto;
85
+ }
86
+
87
+ .memori-artifact-history-item {
88
+ border: 1px solid var(--memori-button-border-color, #e9ecef);
89
+ border-radius: var(--memori-border-radius, 8px);
90
+ margin-bottom: 0.75rem;
91
+ animation: fadeInUp 0.4s ease forwards;
92
+ background: var(--memori-chat-bubble-bg, #fff);
93
+ cursor: pointer;
94
+ opacity: 0;
95
+ transform: translateY(10px);
96
+ transition: all 0.3s ease;
97
+ }
98
+
99
+ .memori-artifact-history-item:hover {
100
+ border-color: var(--memori-primary);
101
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
102
+ transform: translateY(-2px);
103
+ }
104
+
105
+ .memori-artifact-history-item--active {
106
+ border-color: var(--memori-primary);
107
+ background: linear-gradient(135deg, var(--memori-primary) 0%, #764ba2 100%);
108
+ box-shadow: 0 4px 12px rgba(130, 70, 175, 0.3);
109
+ color: var(--memori-primary-text, #fff);
110
+ }
111
+
112
+ .memori-artifact-history-item--active:hover {
113
+ box-shadow: 0 6px 16px rgba(130, 70, 175, 0.4);
114
+ transform: translateY(-2px);
115
+ }
116
+
117
+ .memori-artifact-history-item-content {
118
+ display: flex;
119
+ align-items: center;
120
+ padding: 1rem;
121
+ gap: 0.75rem;
122
+ }
123
+
124
+ .memori-artifact-history-item-icon {
125
+ flex-shrink: 0;
126
+ font-size: 1.5rem;
127
+ line-height: 1;
128
+ }
129
+
130
+ .memori-artifact-history-item-info {
131
+ min-width: 0;
132
+ flex: 1;
133
+ }
134
+
135
+ .memori-artifact-history-item-title {
136
+ overflow: hidden;
137
+ margin-bottom: 0.25rem;
138
+ color: inherit;
139
+ font-size: 0.875rem;
140
+ font-weight: 600;
141
+ text-overflow: ellipsis;
142
+ white-space: nowrap;
143
+ }
144
+
145
+ .memori-artifact-history-item-subtitle {
146
+ overflow: hidden;
147
+ margin-bottom: 0.25rem;
148
+ color: inherit;
149
+ font-size: 0.75rem;
150
+ opacity: 0.7;
151
+ text-overflow: ellipsis;
152
+ white-space: nowrap;
153
+ }
154
+
155
+ .memori-artifact-history-item-meta {
156
+ display: flex;
157
+ flex-wrap: wrap;
158
+ font-size: 0.625rem;
159
+ gap: 0.5rem;
160
+ opacity: 0.6;
161
+ }
162
+
163
+ .memori-artifact-history-item-type {
164
+ padding: 0.125rem 0.375rem;
165
+ border-radius: 10px;
166
+ background: rgba(0, 0, 0, 0.1);
167
+ font-weight: 500;
168
+ letter-spacing: 0.025em;
169
+ text-transform: uppercase;
170
+ }
171
+
172
+ .memori-artifact-history-item-custom-title {
173
+ overflow: hidden;
174
+ max-width: 100px;
175
+ padding: 0.125rem 0.375rem;
176
+ border-radius: 10px;
177
+ background: rgba(0, 0, 0, 0.1);
178
+ font-style: italic;
179
+ text-overflow: ellipsis;
180
+ white-space: nowrap;
181
+ }
182
+
183
+ .memori-artifact-history-item--active .memori-artifact-history-item-type,
184
+ .memori-artifact-history-item--active .memori-artifact-history-item-custom-title {
185
+ background: rgba(255, 255, 255, 0.2);
186
+ }
187
+
188
+ .memori-artifact-history-item-actions {
189
+ flex-shrink: 0;
190
+ }
191
+
192
+ .memori-artifact-history-item-toggle {
193
+ padding: 0.375rem;
194
+ border: 1px solid rgba(0, 0, 0, 0.1);
195
+ border-radius: var(--memori-border-radius, 4px);
196
+ background: rgba(0, 0, 0, 0.05);
197
+ transition: all 0.2s ease;
198
+ }
199
+
200
+ .memori-artifact-history-item-toggle:hover {
201
+ background: rgba(0, 0, 0, 0.1);
202
+ transform: scale(1.05);
203
+ }
204
+
205
+ .memori-artifact-history-item--active .memori-artifact-history-item-toggle {
206
+ border-color: rgba(255, 255, 255, 0.3);
207
+ background: rgba(255, 255, 255, 0.2);
208
+ color: inherit;
209
+ }
210
+
211
+ .memori-artifact-history-item--active .memori-artifact-history-item-toggle:hover {
212
+ background: rgba(255, 255, 255, 0.3);
213
+ }
214
+
215
+ /* More Items Indicator */
216
+ .memori-artifact-history-more {
217
+ padding: 1rem;
218
+ border-top: 1px solid var(--memori-button-border-color, #e9ecef);
219
+ margin-top: 1rem;
220
+ text-align: center;
221
+ }
222
+
223
+ .memori-artifact-history-more-text {
224
+ margin: 0;
225
+ color: var(--memori-text-color, #666);
226
+ font-size: 0.75rem;
227
+ opacity: 0.7;
228
+ }
229
+
230
+ /* Animations */
231
+ @keyframes fadeInUp {
232
+ from {
233
+ opacity: 0;
234
+ transform: translateY(10px);
235
+ }
236
+ to {
237
+ opacity: 1;
238
+ transform: translateY(0);
239
+ }
240
+ }
241
+
242
+ /* Scrollbar Styling */
243
+ .memori-artifact-history-list::-webkit-scrollbar {
244
+ width: 4px;
245
+ }
246
+
247
+ .memori-artifact-history-list::-webkit-scrollbar-track {
248
+ background: transparent;
249
+ }
250
+
251
+ .memori-artifact-history-list::-webkit-scrollbar-thumb {
252
+ border-radius: 2px;
253
+ background: var(--memori-button-border-color, #e9ecef);
254
+ }
255
+
256
+ .memori-artifact-history-list::-webkit-scrollbar-thumb:hover {
257
+ background: var(--memori-text-color, #999);
258
+ }
259
+
260
+ /* Responsive Design */
261
+ @media (max-width: 768px) {
262
+ .memori-artifact-history-header {
263
+ flex-direction: column;
264
+ align-items: flex-start;
265
+ gap: 0.75rem;
266
+ }
267
+
268
+ .memori-artifact-history-actions {
269
+ width: 100%;
270
+ justify-content: flex-end;
271
+ }
272
+
273
+ .memori-artifact-history-item-content {
274
+ padding: 0.75rem;
275
+ gap: 0.5rem;
276
+ }
277
+
278
+ .memori-artifact-history-item-icon {
279
+ font-size: 1.25rem;
280
+ }
281
+
282
+ .memori-artifact-history-item-title {
283
+ font-size: 0.8125rem;
284
+ }
285
+
286
+ .memori-artifact-history-item-subtitle {
287
+ font-size: 0.6875rem;
288
+ }
289
+
290
+ .memori-artifact-history-item-meta {
291
+ font-size: 0.5625rem;
292
+ }
293
+ }
294
+
295
+ /* Dark Mode Support */
296
+ @media (prefers-color-scheme: dark) {
297
+ .memori-artifact-history-item {
298
+ border-color: var(--memori-button-border-color, #404040);
299
+ background: var(--memori-chat-bubble-bg, #1a1a1a);
300
+ }
301
+
302
+ .memori-artifact-history-item:hover {
303
+ box-shadow: 0 4px 12px rgba(255, 255, 255, 0.1);
304
+ }
305
+
306
+ .memori-artifact-history-item-type,
307
+ .memori-artifact-history-item-custom-title {
308
+ background: rgba(255, 255, 255, 0.1);
309
+ }
310
+
311
+ .memori-artifact-history-item-toggle {
312
+ border-color: rgba(255, 255, 255, 0.1);
313
+ background: rgba(255, 255, 255, 0.05);
314
+ }
315
+
316
+ .memori-artifact-history-item-toggle:hover {
317
+ background: rgba(255, 255, 255, 0.1);
318
+ }
319
+ }