@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,308 @@
1
+ /**
2
+ * ArtifactDrawer Component
3
+ * Displays artifacts as a drawer on mobile and as a split panel on web
4
+ * Following the project's design system and responsive patterns
5
+ */
6
+
7
+ import React, { useState, useCallback, useMemo, useEffect } from 'react';
8
+ import { useTranslation } from 'react-i18next';
9
+ import { Dialog, Transition } from '@headlessui/react';
10
+ import cx from 'classnames';
11
+ import Button from '../../../ui/Button';
12
+ import Close from '../../../icons/Close';
13
+ import ArtifactActions from '../ArtifactActions/ArtifactActions';
14
+ import ArtifactPreview from '../ArtifactPreview/ArtifactPreview';
15
+ import ArtifactHistory from '../ArtifactHistory/ArtifactHistory';
16
+ import { ArtifactTab } from '../../types/artifact.types';
17
+ import { useArtifactSystemContext } from '../../context/ArtifactSystemContext';
18
+
19
+ const ArtifactDrawer: React.FC = () => {
20
+ const { actions, state } = useArtifactSystemContext();
21
+ const { t } = useTranslation();
22
+ const [activeTab, setActiveTab] = useState<ArtifactTab>('preview');
23
+ const [showHistory, setShowHistory] = useState(false);
24
+ const [isMobile, setIsMobile] = useState(false);
25
+ const [isAnimating, setIsAnimating] = useState(false);
26
+
27
+ /**
28
+ * Handle window resize to detect mobile/desktop changes
29
+ */
30
+ useEffect(() => {
31
+ const handleResize = () => {
32
+ const newIsMobile = window.innerWidth < 769;
33
+ if (newIsMobile !== isMobile) {
34
+ setIsAnimating(true);
35
+ setTimeout(() => {
36
+ setIsMobile(newIsMobile);
37
+ setIsAnimating(false);
38
+ }, 150);
39
+ } else {
40
+ setIsMobile(newIsMobile);
41
+ }
42
+ };
43
+
44
+ // Set initial value
45
+ handleResize();
46
+
47
+ // Add event listener
48
+ window.addEventListener('resize', handleResize);
49
+
50
+ // Cleanup
51
+ return () => window.removeEventListener('resize', handleResize);
52
+ }, [isMobile]);
53
+
54
+ /**
55
+ * Handle tab change
56
+ */
57
+ const handleTabChange = useCallback((tab: ArtifactTab) => {
58
+ setActiveTab(tab);
59
+ }, []);
60
+
61
+ /**
62
+ * Handle copy action
63
+ */
64
+ const handleCopy = useCallback(async () => {
65
+ if (!state.currentArtifact) return;
66
+
67
+ try {
68
+ if (navigator.clipboard && navigator.clipboard.writeText) {
69
+ await navigator.clipboard.writeText(state.currentArtifact.content);
70
+ } else {
71
+ // Fallback for older browsers
72
+ const textArea = document.createElement('textarea');
73
+ textArea.value = state.currentArtifact.content;
74
+ textArea.style.position = 'fixed';
75
+ textArea.style.left = '-999999px';
76
+ textArea.style.top = '-999999px';
77
+ document.body.appendChild(textArea);
78
+ textArea.focus();
79
+ textArea.select();
80
+ document.execCommand('copy');
81
+ document.body.removeChild(textArea);
82
+ }
83
+ } catch (error) {
84
+ console.error('Copy failed:', error);
85
+ throw error;
86
+ }
87
+ }, [state.currentArtifact]);
88
+
89
+ /**
90
+ * Handle download action
91
+ */
92
+ const handleDownload = useCallback(() => {
93
+ // This will be handled by the ArtifactActions component
94
+ console.log('Download triggered');
95
+ }, []);
96
+
97
+ /**
98
+ * Handle print action
99
+ */
100
+ const handlePrint = useCallback(() => {
101
+ // This will be handled by the ArtifactActions component
102
+ console.log('Print triggered');
103
+ }, []);
104
+
105
+ /**
106
+ * Handle external open action
107
+ */
108
+ const handleOpenExternal = useCallback(() => {
109
+ // This will be handled by the ArtifactActions component
110
+ console.log('External open triggered');
111
+ }, []);
112
+
113
+ /**
114
+ * Handle fullscreen toggle
115
+ */
116
+ const handleToggleFullscreen = useCallback(() => {
117
+ if (actions.toggleFullscreen) {
118
+ actions.toggleFullscreen();
119
+ }
120
+ }, [actions.toggleFullscreen]);
121
+
122
+ /**
123
+ * Handle close with escape key
124
+ */
125
+ const handleClose = useCallback(() => {
126
+ setIsAnimating(true);
127
+ setTimeout(() => {
128
+ actions.closeDrawer();
129
+ setIsAnimating(false);
130
+ }, 200);
131
+ }, [actions.closeDrawer]);
132
+
133
+ /**
134
+ * Toggle history panel
135
+ */
136
+ const toggleHistory = useCallback(() => {
137
+ setShowHistory(prev => !prev);
138
+ }, []);
139
+
140
+
141
+ if (!state.currentArtifact) {
142
+ return null;
143
+ }
144
+
145
+ // Render mobile drawer
146
+ if (isMobile) {
147
+ return (
148
+ <Transition show={state.isDrawerOpen}>
149
+ {state.isDrawerOpen && (
150
+ <Dialog
151
+ open={state.isDrawerOpen}
152
+ onClose={handleClose}
153
+ className="memori-artifact-drawer memori-artifact-drawer--mobile"
154
+ as="div"
155
+ >
156
+ <div
157
+ className="memori-artifact-drawer--backdrop"
158
+ onClick={handleClose}
159
+ />
160
+ <div className="memori-artifact-drawer--panel memori-artifact-drawer--panel-mobile">
161
+ {/* Header */}
162
+ <div className="memori-artifact-drawer--header">
163
+ <div className="memori-artifact-drawer--header-content">
164
+ <h2 className="memori-artifact-drawer--title">
165
+ {state.currentArtifact.title}
166
+ </h2>
167
+ <p className="memori-artifact-drawer--subtitle">
168
+ {state.currentArtifact.customTitle ||
169
+ `${state.currentArtifact.typeInfo.name} Content`}
170
+ </p>
171
+ <div className="memori-artifact-drawer--meta">
172
+ <span className="memori-artifact-drawer--meta-item">
173
+ {t('artifact.type', 'Type')}: {state.currentArtifact.typeInfo.name}
174
+ </span>
175
+ <span className="memori-artifact-drawer--meta-item">
176
+ {t('artifact.size', 'Size')}: {formatBytes(state.currentArtifact.size)}
177
+ </span>
178
+ <span className="memori-artifact-drawer--meta-item">
179
+ {t('artifact.generated', 'Generated')}:{' '}
180
+ {formatTimestamp(state.currentArtifact.timestamp)}
181
+ </span>
182
+ </div>
183
+ </div>
184
+
185
+ <div className="memori-artifact-drawer--header-actions">
186
+ <ArtifactActions
187
+ artifact={state.currentArtifact}
188
+ onCopy={handleCopy}
189
+ onDownload={handleDownload}
190
+ onPrint={handlePrint}
191
+ onOpenExternal={handleOpenExternal}
192
+ onToggleFullscreen={handleToggleFullscreen}
193
+ isFullscreen={state.isFullscreen}
194
+ />
195
+ </div>
196
+
197
+ <Button
198
+ onClick={handleClose}
199
+ className="memori-artifact-drawer--close"
200
+ ghost
201
+ title={t('artifact.close', 'Close') || 'Close'}
202
+ >
203
+ <Close className="memori-artifact-drawer--close-icon" />
204
+ </Button>
205
+ </div>
206
+
207
+ {/* Content */}
208
+ <div className="memori-artifact-drawer--content">
209
+ <div className="memori-artifact-drawer--main">
210
+ <ArtifactPreview
211
+ artifact={state.currentArtifact}
212
+ activeTab={activeTab}
213
+ onTabChange={handleTabChange}
214
+ />
215
+ </div>
216
+ </div>
217
+ </div>
218
+ </Dialog>
219
+ )}
220
+ </Transition>
221
+ );
222
+ }
223
+
224
+ // Render web split panel
225
+ return (
226
+ <div className="memori-artifact-panel">
227
+ {/* Header */}
228
+ <div className="memori-artifact-panel--header">
229
+ <div className="memori-artifact-panel--header-content">
230
+ <h2 className="memori-artifact-panel--title">
231
+ {state.currentArtifact.title}
232
+ </h2>
233
+ <p className="memori-artifact-panel--subtitle">
234
+ {state.currentArtifact.customTitle ||
235
+ `${state.currentArtifact.typeInfo.name} Content`}
236
+ </p>
237
+ <div className="memori-artifact-panel--meta">
238
+ <span className="memori-artifact-panel--meta-item">
239
+ {t('artifact.type', 'Type')}: {state.currentArtifact.typeInfo.name}
240
+ </span>
241
+ <span className="memori-artifact-panel--meta-item">
242
+ {t('artifact.size', 'Size')}: {formatBytes(state.currentArtifact.size)}
243
+ </span>
244
+ <span className="memori-artifact-panel--meta-item">
245
+ {t('artifact.generated', 'Generated')}:{' '}
246
+ {formatTimestamp(state.currentArtifact.timestamp)}
247
+ </span>
248
+ </div>
249
+ </div>
250
+
251
+ <div className="memori-artifact-panel--header-actions">
252
+ <ArtifactActions
253
+ artifact={state.currentArtifact}
254
+ onCopy={handleCopy}
255
+ onDownload={handleDownload}
256
+ onPrint={handlePrint}
257
+ onOpenExternal={handleOpenExternal}
258
+ onToggleFullscreen={handleToggleFullscreen}
259
+ isFullscreen={state.isFullscreen}
260
+ />
261
+ </div>
262
+
263
+ <Button
264
+ onClick={handleClose}
265
+ className="memori-artifact-panel--close"
266
+ ghost
267
+ title={t('artifact.close', 'Close') || 'Close'}
268
+ >
269
+ <Close className="memori-artifact-panel--close-icon" />
270
+ </Button>
271
+ </div>
272
+
273
+ {/* Content */}
274
+ <div className="memori-artifact-panel--content">
275
+ <div className="memori-artifact-panel--main">
276
+ <ArtifactPreview
277
+ artifact={state.currentArtifact}
278
+ activeTab={activeTab}
279
+ onTabChange={handleTabChange}
280
+ />
281
+ </div>
282
+ </div>
283
+ </div>
284
+ );
285
+ };
286
+
287
+ /**
288
+ * Format file size in human readable format
289
+ */
290
+ function formatBytes(bytes: number): string {
291
+ if (bytes === 0) return '0 Bytes';
292
+ const k = 1024;
293
+ const sizes = ['Bytes', 'KB', 'MB'];
294
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
295
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
296
+ }
297
+
298
+ /**
299
+ * Format timestamp for display
300
+ */
301
+ function formatTimestamp(timestamp: Date): string {
302
+ return timestamp.toLocaleTimeString('en-US', {
303
+ hour: '2-digit',
304
+ minute: '2-digit',
305
+ });
306
+ }
307
+
308
+ export default ArtifactDrawer;
@@ -0,0 +1,238 @@
1
+ /**
2
+ * ArtifactHandler CSS Styles
3
+ * Following the project's design system and CSS patterns
4
+ */
5
+
6
+ .memori-artifact-handler {
7
+ border: 1px solid var(--memori-button-border-color, #e9ecef);
8
+ border-radius: var(--memori-border-radius, 12px);
9
+ margin: 0.75rem 0;
10
+ animation: fadeInUp 0.5s ease forwards;
11
+ backdrop-filter: blur(4px);
12
+ background: rgba(255, 255, 255, 0.95);
13
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
14
+ cursor: pointer;
15
+ opacity: 0;
16
+ transform: translateY(10px);
17
+ transition: all 0.3s ease;
18
+ }
19
+
20
+ .memori-artifact-handler:hover {
21
+ border-color: var(--memori-primary);
22
+ background: rgba(130, 70, 175, 0.05);
23
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
24
+ transform: translateY(-2px);
25
+ }
26
+
27
+ .memori-artifact-handler--active {
28
+ border-color: var(--memori-primary);
29
+ background: linear-gradient(135deg, var(--memori-primary) 0%, #764ba2 100%);
30
+ box-shadow: 0 4px 16px rgba(130, 70, 175, 0.3);
31
+ color: var(--memori-primary-text, #fff);
32
+ }
33
+
34
+ .memori-artifact-handler--active:hover {
35
+ box-shadow: 0 6px 20px rgba(130, 70, 175, 0.4);
36
+ transform: translateY(-2px);
37
+ }
38
+
39
+ .memori-artifact-handler-content {
40
+ display: flex;
41
+ align-items: center;
42
+ padding: 1rem;
43
+ gap: 0.75rem;
44
+ }
45
+
46
+ .memori-artifact-handler-icon {
47
+ flex-shrink: 0;
48
+ font-size: 1.5rem;
49
+ line-height: 1;
50
+ }
51
+
52
+ .memori-artifact-handler-info {
53
+ min-width: 0;
54
+ flex: 1;
55
+ }
56
+
57
+ .memori-artifact-handler-title {
58
+ overflow: hidden;
59
+ margin-bottom: 0.25rem;
60
+ color: inherit;
61
+ font-size: 0.875rem;
62
+ font-weight: 600;
63
+ line-height: 1.3;
64
+ text-overflow: ellipsis;
65
+ white-space: nowrap;
66
+ }
67
+
68
+ .memori-artifact-handler-subtitle {
69
+ overflow: hidden;
70
+ margin-bottom: 0.25rem;
71
+ color: inherit;
72
+ font-size: 0.75rem;
73
+ opacity: 0.7;
74
+ text-overflow: ellipsis;
75
+ white-space: nowrap;
76
+ }
77
+
78
+ .memori-artifact-handler-meta {
79
+ display: flex;
80
+ flex-wrap: wrap;
81
+ font-size: 0.625rem;
82
+ gap: 0.5rem;
83
+ opacity: 0.6;
84
+ }
85
+
86
+ .memori-artifact-handler-type {
87
+ padding: 0.125rem 0.375rem;
88
+ border-radius: 10px;
89
+ background: rgba(0, 0, 0, 0.1);
90
+ color: inherit;
91
+ font-weight: 500;
92
+ letter-spacing: 0.025em;
93
+ text-transform: uppercase;
94
+ }
95
+
96
+ .memori-artifact-handler-custom-title {
97
+ overflow: hidden;
98
+ max-width: 120px;
99
+ padding: 0.125rem 0.375rem;
100
+ border-radius: 10px;
101
+ background: rgba(0, 0, 0, 0.1);
102
+ color: inherit;
103
+ font-style: italic;
104
+ text-overflow: ellipsis;
105
+ white-space: nowrap;
106
+ }
107
+
108
+ .memori-artifact-handler--active .memori-artifact-handler-type,
109
+ .memori-artifact-handler--active .memori-artifact-handler-custom-title {
110
+ background: rgba(255, 255, 255, 0.2);
111
+ }
112
+
113
+ .memori-artifact-handler-actions {
114
+ flex-shrink: 0;
115
+ }
116
+
117
+ .memori-artifact-handler-toggle {
118
+ display: flex;
119
+ align-items: center;
120
+ justify-content: center;
121
+ padding: 0.375rem;
122
+ border: 1px solid rgba(0, 0, 0, 0.1);
123
+ border-radius: var(--memori-border-radius, 6px);
124
+ background: rgba(0, 0, 0, 0.05);
125
+ color: inherit;
126
+ cursor: pointer;
127
+ transition: all 0.2s ease;
128
+ }
129
+
130
+ .memori-artifact-handler-toggle:hover {
131
+ background: rgba(0, 0, 0, 0.1);
132
+ transform: scale(1.05);
133
+ }
134
+
135
+ .memori-artifact-handler--active .memori-artifact-handler-toggle {
136
+ border-color: rgba(255, 255, 255, 0.3);
137
+ background: rgba(255, 255, 255, 0.2);
138
+ }
139
+
140
+ .memori-artifact-handler-toggle:focus {
141
+ outline: 2px solid var(--memori-primary);
142
+ outline-offset: 2px;
143
+ }
144
+
145
+ .memori-artifact-handler-toggle:focus:not(:focus-visible) {
146
+ outline: none;
147
+ }
148
+
149
+ .memori-artifact-handler--active .memori-artifact-handler-toggle:hover {
150
+ background: rgba(255, 255, 255, 0.3);
151
+ }
152
+
153
+ .memori-artifact-handler-toggle svg {
154
+ width: 16px;
155
+ height: 16px;
156
+ stroke-width: 2;
157
+ }
158
+
159
+ /* Animation */
160
+ @keyframes fadeInUp {
161
+ from {
162
+ opacity: 0;
163
+ transform: translateY(10px);
164
+ }
165
+ to {
166
+ opacity: 1;
167
+ transform: translateY(0);
168
+ }
169
+ }
170
+
171
+ /* Responsive Design */
172
+ @media (max-width: 768px) {
173
+ .memori-artifact-handler {
174
+ margin: 0.5rem 0;
175
+ }
176
+
177
+ .memori-artifact-handler-content {
178
+ padding: 0.75rem;
179
+ gap: 0.5rem;
180
+ }
181
+
182
+ .memori-artifact-handler-icon {
183
+ font-size: 1.25rem;
184
+ }
185
+
186
+ .memori-artifact-handler-title {
187
+ font-size: 0.8125rem;
188
+ }
189
+
190
+ .memori-artifact-handler-subtitle {
191
+ font-size: 0.6875rem;
192
+ }
193
+
194
+ .memori-artifact-handler-meta {
195
+ font-size: 0.5625rem;
196
+ }
197
+
198
+ .memori-artifact-handler-custom-title {
199
+ max-width: 80px;
200
+ }
201
+ }
202
+
203
+ /* Dark Mode Support */
204
+ @media (prefers-color-scheme: dark) {
205
+ .memori-artifact-handler {
206
+ /* background: rgba(26, 26, 26, 0.95); */
207
+ border-color: var(--memori-button-border-color, #404040);
208
+ }
209
+
210
+ .memori-artifact-handler:hover {
211
+ background: rgba(130, 70, 175, 0.1);
212
+ box-shadow: 0 4px 16px rgba(255, 255, 255, 0.1);
213
+ }
214
+
215
+ .memori-artifact-handler-type,
216
+ .memori-artifact-handler-custom-title {
217
+ background: rgba(255, 255, 255, 0.1);
218
+ }
219
+
220
+ .memori-artifact-handler-toggle {
221
+ border-color: rgba(255, 255, 255, 0.1);
222
+ background: rgba(255, 255, 255, 0.05);
223
+ }
224
+
225
+ .memori-artifact-handler-toggle:hover {
226
+ background: rgba(255, 255, 255, 0.1);
227
+ }
228
+ }
229
+
230
+ /* Focus States for Accessibility */
231
+ .memori-artifact-handler:focus {
232
+ outline: 2px solid var(--memori-primary);
233
+ outline-offset: 2px;
234
+ }
235
+
236
+ .memori-artifact-handler:focus:not(:focus-visible) {
237
+ outline: none;
238
+ }