@projectcor/maia-components 2.11.101-1 → 2.11.102-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 (71) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/lib/components/atoms/AttachmentPreviewModal/AttachmentPreviewModal.js +4 -18
  3. package/lib/components/atoms/MAIAInput/MAIAInput.js +1 -3
  4. package/lib/components/atoms/MAIAMessage/MAIAMessage.js +4 -18
  5. package/lib/components/atoms/MaiaStreamdown/MaiaStreamdown.config.js +23 -0
  6. package/lib/components/atoms/MaiaStreamdown/MaiaStreamdown.interfaces.js +2 -0
  7. package/lib/components/atoms/MaiaStreamdown/MaiaStreamdown.js +51 -0
  8. package/lib/components/atoms/MaiaStreamdown/MaiaStreamdown.styles.js +26 -0
  9. package/lib/components/atoms/MaiaStreamdown/index.js +2 -0
  10. package/lib/components/atoms/icons/index.js +1 -2
  11. package/lib/components/atoms/index.js +2 -1
  12. package/lib/components/molecules/ChatAIMessages/ChatAIMessages.js +12 -65
  13. package/lib/components/molecules/ChatAIMessages/newStyles.js +3 -15
  14. package/lib/components/molecules/ChatAIModal/ChatAIModal.js +62 -195
  15. package/lib/components/molecules/ChatAIModal/ChatAIModal.styles.js +18 -28
  16. package/lib/components/molecules/ChatAIModal/components/ChatAiModalFooter/ChatAiModalFooter.js +2 -9
  17. package/lib/components/molecules/ChatAIModal/components/ChatAiModalHeader/ChatAiModalHeader.js +3 -15
  18. package/lib/components/molecules/ChatAIModal/components/ChatAiModalHeader/ChatAiModalHeader.styles.js +1 -5
  19. package/lib/components/molecules/ChatFooter/ChatFooter.js +2 -4
  20. package/lib/components/molecules/Sidebar/Sidebar.js +61 -104
  21. package/lib/components/molecules/Sidebar/Sidebar.layout.styles.js +1 -16
  22. package/lib/components/molecules/Sidebar/Sidebar.styles.js +29 -30
  23. package/lib/components/organisms/AbmSkillModal/AbmSkillModal.js +4 -23
  24. package/lib/components/organisms/ChatAI/ChatAI.js +5 -14
  25. package/lib/context/global-context.js +1 -3
  26. package/lib/hooks/useChatManager/useChatManager.js +438 -530
  27. package/lib/hooks/useChatMessages/useChatMessages.js +236 -414
  28. package/lib/hooks/useChats/useChats.js +4 -21
  29. package/lib/hooks/useOrchestratorStream/useOrchestratorStream.interface.js +1 -1
  30. package/lib/hooks/useOrchestratorStream/useOrchestratorStream.js +521 -139
  31. package/lib/hooks/useStreamdownStyles.js +7 -14
  32. package/lib/hooks/useStreamingMessage/index.js +3 -2
  33. package/lib/hooks/useStreamingMessage/streamingStore.js +69 -0
  34. package/lib/hooks/useStreamingMessage/useStreamingMessage.js +17 -13
  35. package/lib/index.css +14 -247
  36. package/lib/lang/br/index.js +1 -11
  37. package/lib/lang/en/index.js +1 -11
  38. package/lib/lang/es/index.js +1 -11
  39. package/lib/lang/fr/index.js +2 -13
  40. package/lib/services/maia/Chats/getChatsByUserId.js +4 -6
  41. package/lib/services/maia/Chats/index.js +1 -3
  42. package/lib/store/chatsStore.types.js +1 -1
  43. package/lib/store/useChatsStore.js +12 -149
  44. package/lib/streamdownStyles.js +7 -4
  45. package/lib/types/Chat.js +1 -1
  46. package/lib/utils/ensureStreamdownStyles.js +21 -0
  47. package/package.json +1 -1
  48. package/lib/components/atoms/SessionGeneratingDot/SessionGeneratingDot.js +0 -20
  49. package/lib/components/atoms/SessionGeneratingDot/SessionGeneratingDot.styles.js +0 -20
  50. package/lib/components/atoms/SessionGeneratingDot/index.js +0 -2
  51. package/lib/components/atoms/icons/MaiaSparkleIcon.js +0 -75
  52. package/lib/components/molecules/ChatAIModal/components/MaiaMinimizedPill/MaiaMinimizedPill.js +0 -66
  53. package/lib/components/molecules/ChatAIModal/components/MaiaMinimizedPill/MaiaMinimizedPill.styles.js +0 -55
  54. package/lib/components/molecules/ChatAIModal/components/MaiaMinimizedPill/index.js +0 -2
  55. package/lib/hooks/useMinimizedPillBottomOffset.js +0 -97
  56. package/lib/services/maia/Chats/markSessionAsRead.js +0 -32
  57. package/lib/store/chatsSidebarOptimistic.js +0 -92
  58. package/lib/store/maiaMinimizedPersistence.js +0 -49
  59. package/lib/store/sessions/activeView.js +0 -22
  60. package/lib/store/sessions/index.js +0 -9
  61. package/lib/store/sessions/sessionHitlContext.js +0 -15
  62. package/lib/store/sessions/sessionNotificationSound.js +0 -57
  63. package/lib/store/sessions/sessionNotifications.js +0 -110
  64. package/lib/store/sessions/sessionNotifications.types.js +0 -2
  65. package/lib/store/sessions/sessionStreamManager.js +0 -576
  66. package/lib/store/sessions/sessionStreamingText.js +0 -80
  67. package/lib/store/sessions/sessions.types.js +0 -35
  68. package/lib/store/sessions/useSessionMeta.js +0 -39
  69. package/lib/store/sessions/useSessionStreamingText.js +0 -18
  70. package/lib/store/sessions/useSessionsStore.js +0 -197
  71. package/lib/utils/formatUnreadCount.js +0 -6
@@ -1,20 +1,13 @@
1
- import { useEffect } from 'react';
2
- import { STREAMDOWN_STYLES } from '../streamdownStyles';
3
- var STYLE_ID = 'maia-streamdown-styles';
1
+ import { useLayoutEffect } from 'react';
2
+ import { ensureStreamdownStyles } from '../utils/ensureStreamdownStyles';
4
3
 
5
4
  /**
6
- * Inyecta los estilos de Streamdown en el documento.
7
- * Se ejecuta una sola vez para que funcionen tablas, code blocks, mermaid, etc.
8
- * en cualquier app consumidora sin necesidad de importar CSS.
5
+ * @deprecated Usar `<MaiaStreamdown />` o `ensureStreamdownStyles()` directamente.
6
+ * Se mantiene por compatibilidad con consumidores que aún lo importen.
9
7
  */
10
8
  export var useStreamdownStyles = function useStreamdownStyles() {
11
- useEffect(function () {
12
- if (typeof document === 'undefined') return;
13
- if (document.getElementById(STYLE_ID)) return;
14
- var style = document.createElement('style');
15
- style.id = STYLE_ID;
16
- style.textContent = STREAMDOWN_STYLES;
17
- document.head.appendChild(style);
9
+ useLayoutEffect(function () {
10
+ ensureStreamdownStyles();
18
11
  }, []);
19
12
  };
20
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJ1c2VFZmZlY3QiLCJTVFJFQU1ET1dOX1NUWUxFUyIsIlNUWUxFX0lEIiwidXNlU3RyZWFtZG93blN0eWxlcyIsImRvY3VtZW50IiwiZ2V0RWxlbWVudEJ5SWQiLCJzdHlsZSIsImNyZWF0ZUVsZW1lbnQiLCJpZCIsInRleHRDb250ZW50IiwiaGVhZCIsImFwcGVuZENoaWxkIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2hvb2tzL3VzZVN0cmVhbWRvd25TdHlsZXMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgdXNlRWZmZWN0IH0gZnJvbSAncmVhY3QnXG5pbXBvcnQgeyBTVFJFQU1ET1dOX1NUWUxFUyB9IGZyb20gJy4uL3N0cmVhbWRvd25TdHlsZXMnXG5cbmNvbnN0IFNUWUxFX0lEID0gJ21haWEtc3RyZWFtZG93bi1zdHlsZXMnXG5cbi8qKlxuICogSW55ZWN0YSBsb3MgZXN0aWxvcyBkZSBTdHJlYW1kb3duIGVuIGVsIGRvY3VtZW50by5cbiAqIFNlIGVqZWN1dGEgdW5hIHNvbGEgdmV6IHBhcmEgcXVlIGZ1bmNpb25lbiB0YWJsYXMsIGNvZGUgYmxvY2tzLCBtZXJtYWlkLCBldGMuXG4gKiBlbiBjdWFscXVpZXIgYXBwIGNvbnN1bWlkb3JhIHNpbiBuZWNlc2lkYWQgZGUgaW1wb3J0YXIgQ1NTLlxuICovXG5leHBvcnQgY29uc3QgdXNlU3RyZWFtZG93blN0eWxlcyA9ICgpID0+IHtcbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAodHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJykgcmV0dXJuXG4gICAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFNUWUxFX0lEKSkgcmV0dXJuXG5cbiAgICBjb25zdCBzdHlsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJylcbiAgICBzdHlsZS5pZCA9IFNUWUxFX0lEXG4gICAgc3R5bGUudGV4dENvbnRlbnQgPSBTVFJFQU1ET1dOX1NUWUxFU1xuICAgIGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoc3R5bGUpXG4gIH0sIFtdKVxufVxuIl0sIm1hcHBpbmdzIjoiQUFBQSxTQUFTQSxTQUFTLFFBQVEsT0FBTztBQUNqQyxTQUFTQyxpQkFBaUIsUUFBUSxxQkFBcUI7QUFFdkQsSUFBTUMsUUFBUSxHQUFHLHdCQUF3Qjs7QUFFekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU8sSUFBTUMsbUJBQW1CLEdBQUcsU0FBdEJBLG1CQUFtQkEsQ0FBQSxFQUFTO0VBQ3ZDSCxTQUFTLENBQUMsWUFBTTtJQUNkLElBQUksT0FBT0ksUUFBUSxLQUFLLFdBQVcsRUFBRTtJQUNyQyxJQUFJQSxRQUFRLENBQUNDLGNBQWMsQ0FBQ0gsUUFBUSxDQUFDLEVBQUU7SUFFdkMsSUFBTUksS0FBSyxHQUFHRixRQUFRLENBQUNHLGFBQWEsQ0FBQyxPQUFPLENBQUM7SUFDN0NELEtBQUssQ0FBQ0UsRUFBRSxHQUFHTixRQUFRO0lBQ25CSSxLQUFLLENBQUNHLFdBQVcsR0FBR1IsaUJBQWlCO0lBQ3JDRyxRQUFRLENBQUNNLElBQUksQ0FBQ0MsV0FBVyxDQUFDTCxLQUFLLENBQUM7RUFDbEMsQ0FBQyxFQUFFLEVBQUUsQ0FBQztBQUNSLENBQUMiLCJpZ25vcmVMaXN0IjpbXX0=
13
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJ1c2VMYXlvdXRFZmZlY3QiLCJlbnN1cmVTdHJlYW1kb3duU3R5bGVzIiwidXNlU3RyZWFtZG93blN0eWxlcyJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ob29rcy91c2VTdHJlYW1kb3duU3R5bGVzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHVzZUxheW91dEVmZmVjdCB9IGZyb20gJ3JlYWN0J1xuaW1wb3J0IHsgZW5zdXJlU3RyZWFtZG93blN0eWxlcyB9IGZyb20gJy4uL3V0aWxzL2Vuc3VyZVN0cmVhbWRvd25TdHlsZXMnXG5cbi8qKlxuICogQGRlcHJlY2F0ZWQgVXNhciBgPE1haWFTdHJlYW1kb3duIC8+YCBvIGBlbnN1cmVTdHJlYW1kb3duU3R5bGVzKClgIGRpcmVjdGFtZW50ZS5cbiAqIFNlIG1hbnRpZW5lIHBvciBjb21wYXRpYmlsaWRhZCBjb24gY29uc3VtaWRvcmVzIHF1ZSBhw7puIGxvIGltcG9ydGVuLlxuICovXG5leHBvcnQgY29uc3QgdXNlU3RyZWFtZG93blN0eWxlcyA9ICgpID0+IHtcbiAgdXNlTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBlbnN1cmVTdHJlYW1kb3duU3R5bGVzKClcbiAgfSwgW10pXG59XG4iXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLGVBQWUsUUFBUSxPQUFPO0FBQ3ZDLFNBQVNDLHNCQUFzQixRQUFRLGlDQUFpQzs7QUFFeEU7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPLElBQU1DLG1CQUFtQixHQUFHLFNBQXRCQSxtQkFBbUJBLENBQUEsRUFBUztFQUN2Q0YsZUFBZSxDQUFDLFlBQU07SUFDcEJDLHNCQUFzQixDQUFDLENBQUM7RUFDMUIsQ0FBQyxFQUFFLEVBQUUsQ0FBQztBQUNSLENBQUMiLCJpZ25vcmVMaXN0IjpbXX0=
@@ -1,2 +1,3 @@
1
- export { useStreamingMessage } from './useStreamingMessage';
2
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJ1c2VTdHJlYW1pbmdNZXNzYWdlIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2hvb2tzL3VzZVN0cmVhbWluZ01lc3NhZ2UvaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHsgdXNlU3RyZWFtaW5nTWVzc2FnZSB9IGZyb20gJy4vdXNlU3RyZWFtaW5nTWVzc2FnZSdcbiJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsbUJBQW1CLFFBQVEsdUJBQXVCIiwiaWdub3JlTGlzdCI6W119
1
+ export { useStreamingMessage, useStreamingMessageId } from './useStreamingMessage';
2
+ export { streamingStore } from './streamingStore';
3
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJ1c2VTdHJlYW1pbmdNZXNzYWdlIiwidXNlU3RyZWFtaW5nTWVzc2FnZUlkIiwic3RyZWFtaW5nU3RvcmUiXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvaG9va3MvdXNlU3RyZWFtaW5nTWVzc2FnZS9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgeyB1c2VTdHJlYW1pbmdNZXNzYWdlLCB1c2VTdHJlYW1pbmdNZXNzYWdlSWQgfSBmcm9tICcuL3VzZVN0cmVhbWluZ01lc3NhZ2UnXG5leHBvcnQgeyBzdHJlYW1pbmdTdG9yZSB9IGZyb20gJy4vc3RyZWFtaW5nU3RvcmUnXG4iXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLG1CQUFtQixFQUFFQyxxQkFBcUIsUUFBUSx1QkFBdUI7QUFDbEYsU0FBU0MsY0FBYyxRQUFRLGtCQUFrQiIsImlnbm9yZUxpc3QiOltdfQ==
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Store externo (module-level) para el mensaje actualmente en streaming.
3
+ *
4
+ * Desacopla el texto del stream del array de `messages` de React: durante
5
+ * el streaming, el texto se mantiene acá y solo los componentes suscritos
6
+ * (vía `useStreamingMessage` / `useSyncExternalStore`) re-renderizan cuando
7
+ * cambia. El array `messages` no se muta en cada token, evitando ráfagas
8
+ * de re-renders del padre y ejecuciones innecesarias de useEffects.
9
+ */
10
+
11
+ var snapshot = {
12
+ id: null,
13
+ text: ''
14
+ };
15
+ var listeners = new Set();
16
+ var emitChange = function emitChange() {
17
+ listeners.forEach(function (listener) {
18
+ listener();
19
+ });
20
+ };
21
+ export var streamingStore = {
22
+ /** Inicia una nueva sesión de streaming para el mensaje con este id. */start: function start(id) {
23
+ snapshot = {
24
+ id: id,
25
+ text: ''
26
+ };
27
+ emitChange();
28
+ },
29
+ /** Setea el texto del mensaje en streaming. Solo aplica si el id coincide. */setText: function setText(id, text) {
30
+ if (snapshot.id !== id) {
31
+ snapshot = {
32
+ id: id,
33
+ text: text
34
+ };
35
+ } else if (snapshot.text !== text) {
36
+ snapshot = {
37
+ id: id,
38
+ text: text
39
+ };
40
+ } else {
41
+ return;
42
+ }
43
+ emitChange();
44
+ },
45
+ /** Limpia el estado de streaming (fin de stream, error o aprobación). */clear: function clear() {
46
+ if (snapshot.id == null && snapshot.text === '') return;
47
+ snapshot = {
48
+ id: null,
49
+ text: ''
50
+ };
51
+ emitChange();
52
+ },
53
+ /** API para useSyncExternalStore. */subscribe: function subscribe(listener) {
54
+ listeners.add(listener);
55
+ return function () {
56
+ listeners["delete"](listener);
57
+ };
58
+ },
59
+ /** Snapshot referencialmente estable mientras no haya cambios. */getSnapshot: function getSnapshot() {
60
+ return snapshot;
61
+ },
62
+ /** Server snapshot (SSR): siempre vacío. */getServerSnapshot: function getServerSnapshot() {
63
+ return {
64
+ id: null,
65
+ text: ''
66
+ };
67
+ }
68
+ };
69
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJzbmFwc2hvdCIsImlkIiwidGV4dCIsImxpc3RlbmVycyIsIlNldCIsImVtaXRDaGFuZ2UiLCJmb3JFYWNoIiwibGlzdGVuZXIiLCJzdHJlYW1pbmdTdG9yZSIsInN0YXJ0Iiwic2V0VGV4dCIsImNsZWFyIiwic3Vic2NyaWJlIiwiYWRkIiwiZ2V0U25hcHNob3QiLCJnZXRTZXJ2ZXJTbmFwc2hvdCJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9ob29rcy91c2VTdHJlYW1pbmdNZXNzYWdlL3N0cmVhbWluZ1N0b3JlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogU3RvcmUgZXh0ZXJubyAobW9kdWxlLWxldmVsKSBwYXJhIGVsIG1lbnNhamUgYWN0dWFsbWVudGUgZW4gc3RyZWFtaW5nLlxuICpcbiAqIERlc2Fjb3BsYSBlbCB0ZXh0byBkZWwgc3RyZWFtIGRlbCBhcnJheSBkZSBgbWVzc2FnZXNgIGRlIFJlYWN0OiBkdXJhbnRlXG4gKiBlbCBzdHJlYW1pbmcsIGVsIHRleHRvIHNlIG1hbnRpZW5lIGFjw6EgeSBzb2xvIGxvcyBjb21wb25lbnRlcyBzdXNjcml0b3NcbiAqICh2w61hIGB1c2VTdHJlYW1pbmdNZXNzYWdlYCAvIGB1c2VTeW5jRXh0ZXJuYWxTdG9yZWApIHJlLXJlbmRlcml6YW4gY3VhbmRvXG4gKiBjYW1iaWEuIEVsIGFycmF5IGBtZXNzYWdlc2Agbm8gc2UgbXV0YSBlbiBjYWRhIHRva2VuLCBldml0YW5kbyByw6FmYWdhc1xuICogZGUgcmUtcmVuZGVycyBkZWwgcGFkcmUgeSBlamVjdWNpb25lcyBpbm5lY2VzYXJpYXMgZGUgdXNlRWZmZWN0cy5cbiAqL1xuXG50eXBlIFN0cmVhbWluZ1NuYXBzaG90ID0ge1xuICBpZDogc3RyaW5nIHwgbnVsbFxuICB0ZXh0OiBzdHJpbmdcbn1cblxubGV0IHNuYXBzaG90OiBTdHJlYW1pbmdTbmFwc2hvdCA9IHsgaWQ6IG51bGwsIHRleHQ6ICcnIH1cbmNvbnN0IGxpc3RlbmVycyA9IG5ldyBTZXQ8KCkgPT4gdm9pZD4oKVxuXG5jb25zdCBlbWl0Q2hhbmdlID0gKCkgPT4ge1xuICBsaXN0ZW5lcnMuZm9yRWFjaChsaXN0ZW5lciA9PiB7XG4gICAgbGlzdGVuZXIoKVxuICB9KVxufVxuXG5leHBvcnQgY29uc3Qgc3RyZWFtaW5nU3RvcmUgPSB7XG4gIC8qKiBJbmljaWEgdW5hIG51ZXZhIHNlc2nDs24gZGUgc3RyZWFtaW5nIHBhcmEgZWwgbWVuc2FqZSBjb24gZXN0ZSBpZC4gKi9cbiAgc3RhcnQoaWQ6IHN0cmluZykge1xuICAgIHNuYXBzaG90ID0geyBpZCwgdGV4dDogJycgfVxuICAgIGVtaXRDaGFuZ2UoKVxuICB9LFxuICAvKiogU2V0ZWEgZWwgdGV4dG8gZGVsIG1lbnNhamUgZW4gc3RyZWFtaW5nLiBTb2xvIGFwbGljYSBzaSBlbCBpZCBjb2luY2lkZS4gKi9cbiAgc2V0VGV4dChpZDogc3RyaW5nLCB0ZXh0OiBzdHJpbmcpIHtcbiAgICBpZiAoc25hcHNob3QuaWQgIT09IGlkKSB7XG4gICAgICBzbmFwc2hvdCA9IHsgaWQsIHRleHQgfVxuICAgIH0gZWxzZSBpZiAoc25hcHNob3QudGV4dCAhPT0gdGV4dCkge1xuICAgICAgc25hcHNob3QgPSB7IGlkLCB0ZXh0IH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGVtaXRDaGFuZ2UoKVxuICB9LFxuICAvKiogTGltcGlhIGVsIGVzdGFkbyBkZSBzdHJlYW1pbmcgKGZpbiBkZSBzdHJlYW0sIGVycm9yIG8gYXByb2JhY2nDs24pLiAqL1xuICBjbGVhcigpIHtcbiAgICBpZiAoc25hcHNob3QuaWQgPT0gbnVsbCAmJiBzbmFwc2hvdC50ZXh0ID09PSAnJykgcmV0dXJuXG4gICAgc25hcHNob3QgPSB7IGlkOiBudWxsLCB0ZXh0OiAnJyB9XG4gICAgZW1pdENoYW5nZSgpXG4gIH0sXG4gIC8qKiBBUEkgcGFyYSB1c2VTeW5jRXh0ZXJuYWxTdG9yZS4gKi9cbiAgc3Vic2NyaWJlKGxpc3RlbmVyOiAoKSA9PiB2b2lkKSB7XG4gICAgbGlzdGVuZXJzLmFkZChsaXN0ZW5lcilcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgbGlzdGVuZXJzLmRlbGV0ZShsaXN0ZW5lcilcbiAgICB9XG4gIH0sXG4gIC8qKiBTbmFwc2hvdCByZWZlcmVuY2lhbG1lbnRlIGVzdGFibGUgbWllbnRyYXMgbm8gaGF5YSBjYW1iaW9zLiAqL1xuICBnZXRTbmFwc2hvdCgpOiBTdHJlYW1pbmdTbmFwc2hvdCB7XG4gICAgcmV0dXJuIHNuYXBzaG90XG4gIH0sXG4gIC8qKiBTZXJ2ZXIgc25hcHNob3QgKFNTUik6IHNpZW1wcmUgdmFjw61vLiAqL1xuICBnZXRTZXJ2ZXJTbmFwc2hvdCgpOiBTdHJlYW1pbmdTbmFwc2hvdCB7XG4gICAgcmV0dXJuIHsgaWQ6IG51bGwsIHRleHQ6ICcnIH1cbiAgfSxcbn1cblxuZXhwb3J0IHR5cGUgeyBTdHJlYW1pbmdTbmFwc2hvdCB9XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFPQSxJQUFJQSxRQUEyQixHQUFHO0VBQUVDLEVBQUUsRUFBRSxJQUFJO0VBQUVDLElBQUksRUFBRTtBQUFHLENBQUM7QUFDeEQsSUFBTUMsU0FBUyxHQUFHLElBQUlDLEdBQUcsQ0FBYSxDQUFDO0FBRXZDLElBQU1DLFVBQVUsR0FBRyxTQUFiQSxVQUFVQSxDQUFBLEVBQVM7RUFDdkJGLFNBQVMsQ0FBQ0csT0FBTyxDQUFDLFVBQUFDLFFBQVEsRUFBSTtJQUM1QkEsUUFBUSxDQUFDLENBQUM7RUFDWixDQUFDLENBQUM7QUFDSixDQUFDO0FBRUQsT0FBTyxJQUFNQyxjQUFjLEdBQUc7RUFDNUIsd0VBQ0FDLEtBQUssV0FBTEEsS0FBS0EsQ0FBQ1IsRUFBVSxFQUFFO0lBQ2hCRCxRQUFRLEdBQUc7TUFBRUMsRUFBRSxFQUFGQSxFQUFFO01BQUVDLElBQUksRUFBRTtJQUFHLENBQUM7SUFDM0JHLFVBQVUsQ0FBQyxDQUFDO0VBQ2QsQ0FBQztFQUNELDhFQUNBSyxPQUFPLFdBQVBBLE9BQU9BLENBQUNULEVBQVUsRUFBRUMsSUFBWSxFQUFFO0lBQ2hDLElBQUlGLFFBQVEsQ0FBQ0MsRUFBRSxLQUFLQSxFQUFFLEVBQUU7TUFDdEJELFFBQVEsR0FBRztRQUFFQyxFQUFFLEVBQUZBLEVBQUU7UUFBRUMsSUFBSSxFQUFKQTtNQUFLLENBQUM7SUFDekIsQ0FBQyxNQUFNLElBQUlGLFFBQVEsQ0FBQ0UsSUFBSSxLQUFLQSxJQUFJLEVBQUU7TUFDakNGLFFBQVEsR0FBRztRQUFFQyxFQUFFLEVBQUZBLEVBQUU7UUFBRUMsSUFBSSxFQUFKQTtNQUFLLENBQUM7SUFDekIsQ0FBQyxNQUFNO01BQ0w7SUFDRjtJQUNBRyxVQUFVLENBQUMsQ0FBQztFQUNkLENBQUM7RUFDRCx5RUFDQU0sS0FBSyxXQUFMQSxLQUFLQSxDQUFBLEVBQUc7SUFDTixJQUFJWCxRQUFRLENBQUNDLEVBQUUsSUFBSSxJQUFJLElBQUlELFFBQVEsQ0FBQ0UsSUFBSSxLQUFLLEVBQUUsRUFBRTtJQUNqREYsUUFBUSxHQUFHO01BQUVDLEVBQUUsRUFBRSxJQUFJO01BQUVDLElBQUksRUFBRTtJQUFHLENBQUM7SUFDakNHLFVBQVUsQ0FBQyxDQUFDO0VBQ2QsQ0FBQztFQUNELHFDQUNBTyxTQUFTLFdBQVRBLFNBQVNBLENBQUNMLFFBQW9CLEVBQUU7SUFDOUJKLFNBQVMsQ0FBQ1UsR0FBRyxDQUFDTixRQUFRLENBQUM7SUFDdkIsT0FBTyxZQUFNO01BQ1hKLFNBQVMsVUFBTyxDQUFDSSxRQUFRLENBQUM7SUFDNUIsQ0FBQztFQUNILENBQUM7RUFDRCxrRUFDQU8sV0FBVyxXQUFYQSxXQUFXQSxDQUFBLEVBQXNCO0lBQy9CLE9BQU9kLFFBQVE7RUFDakIsQ0FBQztFQUNELDRDQUNBZSxpQkFBaUIsV0FBakJBLGlCQUFpQkEsQ0FBQSxFQUFzQjtJQUNyQyxPQUFPO01BQUVkLEVBQUUsRUFBRSxJQUFJO01BQUVDLElBQUksRUFBRTtJQUFHLENBQUM7RUFDL0I7QUFDRixDQUFDIiwiaWdub3JlTGlzdCI6W119
@@ -1,18 +1,22 @@
1
- import { useCallback, useSyncExternalStore } from 'react';
2
- import { sessionStreamingText } from '../../store/sessions/sessionStreamingText';
1
+ import { useSyncExternalStore } from 'react';
2
+ import { streamingStore } from './streamingStore';
3
3
 
4
4
  /**
5
- * Devuelve el texto en streaming del mensaje `messageId` (placeholder id),
6
- * buscándolo entre todas las sesiones activas. El placeholder id es único por
7
- * stream, así que solo el componente de ese mensaje se re-renderiza cuando su
8
- * texto cambia; el resto del árbol no se ve afectado.
5
+ * Devuelve el texto actual del mensaje en streaming si el `id` coincide con
6
+ * el mensaje activo. Si no hay streaming activo o el id no coincide, devuelve
7
+ * una cadena vacía. Esto permite que solo el componente del mensaje en
8
+ * streaming se re-renderice, sin afectar al resto del árbol.
9
9
  */
10
10
  export var useStreamingMessage = function useStreamingMessage(messageId) {
11
- var getSnapshot = useCallback(function () {
12
- return sessionStreamingText.getTextByPlaceholder(messageId !== null && messageId !== void 0 ? messageId : null);
13
- }, [messageId]);
14
- return useSyncExternalStore(sessionStreamingText.subscribe, getSnapshot, function () {
15
- return '';
16
- });
11
+ var snapshot = useSyncExternalStore(streamingStore.subscribe, streamingStore.getSnapshot, streamingStore.getServerSnapshot);
12
+ if (!messageId) return '';
13
+ if (snapshot.id !== messageId) return '';
14
+ return snapshot.text;
17
15
  };
18
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJ1c2VDYWxsYmFjayIsInVzZVN5bmNFeHRlcm5hbFN0b3JlIiwic2Vzc2lvblN0cmVhbWluZ1RleHQiLCJ1c2VTdHJlYW1pbmdNZXNzYWdlIiwibWVzc2FnZUlkIiwiZ2V0U25hcHNob3QiLCJnZXRUZXh0QnlQbGFjZWhvbGRlciIsInN1YnNjcmliZSJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9ob29rcy91c2VTdHJlYW1pbmdNZXNzYWdlL3VzZVN0cmVhbWluZ01lc3NhZ2UudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgdXNlQ2FsbGJhY2ssIHVzZVN5bmNFeHRlcm5hbFN0b3JlIH0gZnJvbSAncmVhY3QnXG5pbXBvcnQgeyBzZXNzaW9uU3RyZWFtaW5nVGV4dCB9IGZyb20gJy4uLy4uL3N0b3JlL3Nlc3Npb25zL3Nlc3Npb25TdHJlYW1pbmdUZXh0J1xuXG4vKipcbiAqIERldnVlbHZlIGVsIHRleHRvIGVuIHN0cmVhbWluZyBkZWwgbWVuc2FqZSBgbWVzc2FnZUlkYCAocGxhY2Vob2xkZXIgaWQpLFxuICogYnVzY8OhbmRvbG8gZW50cmUgdG9kYXMgbGFzIHNlc2lvbmVzIGFjdGl2YXMuIEVsIHBsYWNlaG9sZGVyIGlkIGVzIMO6bmljbyBwb3JcbiAqIHN0cmVhbSwgYXPDrSBxdWUgc29sbyBlbCBjb21wb25lbnRlIGRlIGVzZSBtZW5zYWplIHNlIHJlLXJlbmRlcml6YSBjdWFuZG8gc3VcbiAqIHRleHRvIGNhbWJpYTsgZWwgcmVzdG8gZGVsIMOhcmJvbCBubyBzZSB2ZSBhZmVjdGFkby5cbiAqL1xuZXhwb3J0IGNvbnN0IHVzZVN0cmVhbWluZ01lc3NhZ2UgPSAobWVzc2FnZUlkOiBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkKTogc3RyaW5nID0+IHtcbiAgY29uc3QgZ2V0U25hcHNob3QgPSB1c2VDYWxsYmFjaygoKSA9PiBzZXNzaW9uU3RyZWFtaW5nVGV4dC5nZXRUZXh0QnlQbGFjZWhvbGRlcihtZXNzYWdlSWQgPz8gbnVsbCksIFttZXNzYWdlSWRdKVxuICByZXR1cm4gdXNlU3luY0V4dGVybmFsU3RvcmUoc2Vzc2lvblN0cmVhbWluZ1RleHQuc3Vic2NyaWJlLCBnZXRTbmFwc2hvdCwgKCkgPT4gJycpXG59XG4iXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLFdBQVcsRUFBRUMsb0JBQW9CLFFBQVEsT0FBTztBQUN6RCxTQUFTQyxvQkFBb0IsUUFBUSwyQ0FBMkM7O0FBRWhGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU8sSUFBTUMsbUJBQW1CLEdBQUcsU0FBdEJBLG1CQUFtQkEsQ0FBSUMsU0FBb0MsRUFBYTtFQUNuRixJQUFNQyxXQUFXLEdBQUdMLFdBQVcsQ0FBQztJQUFBLE9BQU1FLG9CQUFvQixDQUFDSSxvQkFBb0IsQ0FBQ0YsU0FBUyxhQUFUQSxTQUFTLGNBQVRBLFNBQVMsR0FBSSxJQUFJLENBQUM7RUFBQSxHQUFFLENBQUNBLFNBQVMsQ0FBQyxDQUFDO0VBQ2hILE9BQU9ILG9CQUFvQixDQUFDQyxvQkFBb0IsQ0FBQ0ssU0FBUyxFQUFFRixXQUFXLEVBQUU7SUFBQSxPQUFNLEVBQUU7RUFBQSxFQUFDO0FBQ3BGLENBQUMiLCJpZ25vcmVMaXN0IjpbXX0=
16
+
17
+ /** Devuelve el id del mensaje que está actualmente en streaming (o null). */
18
+ export var useStreamingMessageId = function useStreamingMessageId() {
19
+ var snapshot = useSyncExternalStore(streamingStore.subscribe, streamingStore.getSnapshot, streamingStore.getServerSnapshot);
20
+ return snapshot.id;
21
+ };
22
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJ1c2VTeW5jRXh0ZXJuYWxTdG9yZSIsInN0cmVhbWluZ1N0b3JlIiwidXNlU3RyZWFtaW5nTWVzc2FnZSIsIm1lc3NhZ2VJZCIsInNuYXBzaG90Iiwic3Vic2NyaWJlIiwiZ2V0U25hcHNob3QiLCJnZXRTZXJ2ZXJTbmFwc2hvdCIsImlkIiwidGV4dCIsInVzZVN0cmVhbWluZ01lc3NhZ2VJZCJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9ob29rcy91c2VTdHJlYW1pbmdNZXNzYWdlL3VzZVN0cmVhbWluZ01lc3NhZ2UudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgdXNlU3luY0V4dGVybmFsU3RvcmUgfSBmcm9tICdyZWFjdCdcbmltcG9ydCB7IHN0cmVhbWluZ1N0b3JlIH0gZnJvbSAnLi9zdHJlYW1pbmdTdG9yZSdcblxuLyoqXG4gKiBEZXZ1ZWx2ZSBlbCB0ZXh0byBhY3R1YWwgZGVsIG1lbnNhamUgZW4gc3RyZWFtaW5nIHNpIGVsIGBpZGAgY29pbmNpZGUgY29uXG4gKiBlbCBtZW5zYWplIGFjdGl2by4gU2kgbm8gaGF5IHN0cmVhbWluZyBhY3Rpdm8gbyBlbCBpZCBubyBjb2luY2lkZSwgZGV2dWVsdmVcbiAqIHVuYSBjYWRlbmEgdmFjw61hLiBFc3RvIHBlcm1pdGUgcXVlIHNvbG8gZWwgY29tcG9uZW50ZSBkZWwgbWVuc2FqZSBlblxuICogc3RyZWFtaW5nIHNlIHJlLXJlbmRlcmljZSwgc2luIGFmZWN0YXIgYWwgcmVzdG8gZGVsIMOhcmJvbC5cbiAqL1xuZXhwb3J0IGNvbnN0IHVzZVN0cmVhbWluZ01lc3NhZ2UgPSAobWVzc2FnZUlkOiBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkKTogc3RyaW5nID0+IHtcbiAgY29uc3Qgc25hcHNob3QgPSB1c2VTeW5jRXh0ZXJuYWxTdG9yZShcbiAgICBzdHJlYW1pbmdTdG9yZS5zdWJzY3JpYmUsXG4gICAgc3RyZWFtaW5nU3RvcmUuZ2V0U25hcHNob3QsXG4gICAgc3RyZWFtaW5nU3RvcmUuZ2V0U2VydmVyU25hcHNob3RcbiAgKVxuICBpZiAoIW1lc3NhZ2VJZCkgcmV0dXJuICcnXG4gIGlmIChzbmFwc2hvdC5pZCAhPT0gbWVzc2FnZUlkKSByZXR1cm4gJydcbiAgcmV0dXJuIHNuYXBzaG90LnRleHRcbn1cblxuLyoqIERldnVlbHZlIGVsIGlkIGRlbCBtZW5zYWplIHF1ZSBlc3TDoSBhY3R1YWxtZW50ZSBlbiBzdHJlYW1pbmcgKG8gbnVsbCkuICovXG5leHBvcnQgY29uc3QgdXNlU3RyZWFtaW5nTWVzc2FnZUlkID0gKCk6IHN0cmluZyB8IG51bGwgPT4ge1xuICBjb25zdCBzbmFwc2hvdCA9IHVzZVN5bmNFeHRlcm5hbFN0b3JlKFxuICAgIHN0cmVhbWluZ1N0b3JlLnN1YnNjcmliZSxcbiAgICBzdHJlYW1pbmdTdG9yZS5nZXRTbmFwc2hvdCxcbiAgICBzdHJlYW1pbmdTdG9yZS5nZXRTZXJ2ZXJTbmFwc2hvdFxuICApXG4gIHJldHVybiBzbmFwc2hvdC5pZFxufVxuIl0sIm1hcHBpbmdzIjoiQUFBQSxTQUFTQSxvQkFBb0IsUUFBUSxPQUFPO0FBQzVDLFNBQVNDLGNBQWMsUUFBUSxrQkFBa0I7O0FBRWpEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU8sSUFBTUMsbUJBQW1CLEdBQUcsU0FBdEJBLG1CQUFtQkEsQ0FBSUMsU0FBb0MsRUFBYTtFQUNuRixJQUFNQyxRQUFRLEdBQUdKLG9CQUFvQixDQUNuQ0MsY0FBYyxDQUFDSSxTQUFTLEVBQ3hCSixjQUFjLENBQUNLLFdBQVcsRUFDMUJMLGNBQWMsQ0FBQ00saUJBQ2pCLENBQUM7RUFDRCxJQUFJLENBQUNKLFNBQVMsRUFBRSxPQUFPLEVBQUU7RUFDekIsSUFBSUMsUUFBUSxDQUFDSSxFQUFFLEtBQUtMLFNBQVMsRUFBRSxPQUFPLEVBQUU7RUFDeEMsT0FBT0MsUUFBUSxDQUFDSyxJQUFJO0FBQ3RCLENBQUM7O0FBRUQ7QUFDQSxPQUFPLElBQU1DLHFCQUFxQixHQUFHLFNBQXhCQSxxQkFBcUJBLENBQUEsRUFBd0I7RUFDeEQsSUFBTU4sUUFBUSxHQUFHSixvQkFBb0IsQ0FDbkNDLGNBQWMsQ0FBQ0ksU0FBUyxFQUN4QkosY0FBYyxDQUFDSyxXQUFXLEVBQzFCTCxjQUFjLENBQUNNLGlCQUNqQixDQUFDO0VBQ0QsT0FBT0gsUUFBUSxDQUFDSSxFQUFFO0FBQ3BCLENBQUMiLCJpZ25vcmVMaXN0IjpbXX0=
package/lib/index.css CHANGED
@@ -2,7 +2,7 @@
2
2
  @tailwind components;
3
3
  @tailwind utilities;
4
4
 
5
- /* Streamdown classes are included via tailwind.config.js content */
5
+ /* Streamdown: estilos inyectados por MaiaStreamdown / ensureStreamdownStyles (ver streamdownStyles.ts) */
6
6
 
7
7
  @layer base {
8
8
  /* Prevent Tailwind from resetting link styles */
@@ -10,7 +10,7 @@
10
10
  color: revert;
11
11
  text-decoration: revert;
12
12
  }
13
-
13
+
14
14
  :root {
15
15
  --background: 0 0% 100%;
16
16
  --foreground: 222.2 84% 4.9%;
@@ -58,252 +58,19 @@
58
58
  }
59
59
 
60
60
  body {
61
- font-family: 'Work-Sans', -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
62
- "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
61
+ font-family:
62
+ 'Work-Sans',
63
+ -apple-system,
64
+ BlinkMacSystemFont,
65
+ 'Segoe UI',
66
+ 'Roboto',
67
+ 'Oxygen',
68
+ 'Ubuntu',
69
+ 'Cantarell',
70
+ 'Fira Sans',
71
+ 'Droid Sans',
72
+ 'Helvetica Neue',
63
73
  sans-serif;
64
74
  -webkit-font-smoothing: antialiased;
65
75
  -moz-osx-font-smoothing: grayscale;
66
76
  }
67
-
68
- /* Code blocks - github-light theme, fondo transparente */
69
- [data-streamdown="code-block"] {
70
- position: relative;
71
- margin: 1rem 0;
72
- background: transparent !important;
73
- border: none !important;
74
- border-radius: 0.75rem;
75
- overflow: hidden;
76
- }
77
-
78
- [data-streamdown="code-block"] > div {
79
- border: none !important;
80
- background: transparent !important;
81
- }
82
-
83
- [data-streamdown="code-block"] pre,
84
- [data-streamdown="code-block"] pre.shiki,
85
- .shiki {
86
- background-color: transparent !important;
87
- border-radius: 0 !important;
88
- padding: 1rem 1.25rem 1.25rem !important;
89
- border: none !important;
90
- margin: 0 !important;
91
- }
92
-
93
- /* Números de línea: 13px -> 12px */
94
- [data-streamdown="code-block"] pre code > span::before,
95
- [data-streamdown="code-block-body"] pre code > span::before {
96
- font-size: 12px !important;
97
- }
98
-
99
- /* Language label inside the block */
100
- [data-streamdown="code-block-language"] {
101
- display: block !important;
102
- color: #6e7681 !important;
103
- font-size: 0.75rem;
104
- font-weight: 500;
105
- padding: 0.75rem 1.25rem 0;
106
- text-transform: lowercase;
107
- letter-spacing: 0.02em;
108
- background: transparent !important;
109
- border: none !important;
110
- }
111
-
112
- /* Tables - scroll container: solo la tabla hace scroll horizontal, no todo el contenedor */
113
- [data-streamdown="table-wrapper"] {
114
- width: 100%;
115
- max-width: 100%;
116
- margin: 1rem 0;
117
- overflow-x: auto;
118
- overflow-y: visible;
119
- border-radius: 0.75rem;
120
- border: none !important;
121
- -webkit-overflow-scrolling: touch;
122
- }
123
-
124
- [data-streamdown="table-wrapper"] > div {
125
- border: none !important;
126
- }
127
-
128
- /* Tables - estilos claros con líneas horizontales */
129
- [data-streamdown="table"] {
130
- width: max-content;
131
- min-width: 100%;
132
- margin: 0 0 0.75rem 0;
133
- border-collapse: collapse;
134
- border-spacing: 0;
135
- background: transparent;
136
- overflow: hidden;
137
- border: none !important;
138
- }
139
-
140
- [data-streamdown="table"] thead {
141
- background: transparent;
142
- border-bottom: 1px solid #BFBFBF;
143
- }
144
-
145
- [data-streamdown="table"] th {
146
- color: #000;
147
- font-family: "Work Sans", sans-serif;
148
- font-size: 16px;
149
- font-style: normal;
150
- font-weight: 500;
151
- line-height: 26px;
152
- text-align: left;
153
- padding: 1rem 1.25rem;
154
- }
155
-
156
- [data-streamdown="table"] td {
157
- color: #000;
158
- font-family: "Work Sans", sans-serif;
159
- font-size: 16px;
160
- font-style: normal;
161
- font-weight: 400;
162
- line-height: 26px;
163
- padding: 1rem 1.25rem;
164
- border-bottom: 1px solid #D9D9D9;
165
- }
166
-
167
- [data-streamdown="table"] tbody tr:last-child td {
168
- border-bottom: none;
169
- }
170
-
171
- /* Mermaid diagrams */
172
- [data-streamdown="mermaid"] {
173
- margin: 1rem 0;
174
- overflow: visible;
175
- max-width: 100%;
176
- min-height: 500px;
177
- }
178
-
179
- [data-streamdown="mermaid"] svg {
180
- overflow: visible !important;
181
- min-height: 500px;
182
- max-width: 100%;
183
- }
184
-
185
- [data-streamdown="mermaid"] .node rect,
186
- [data-streamdown="mermaid"] .node polygon {
187
- rx: 8px;
188
- ry: 8px;
189
- }
190
-
191
- /* Edge labels (text on arrows) - prevent clipping */
192
- [data-streamdown="mermaid"] .edgeLabel {
193
- background-color: transparent !important;
194
- }
195
-
196
- [data-streamdown="mermaid"] .edgeLabel .label {
197
- background-color: #fce7f3 !important;
198
- padding: 2px 4px;
199
- }
200
-
201
-
202
- /* Dropdowns de copy/download (tablas, mermaid) - fondo blanco */
203
- [data-streamdown="table-wrapper"] div[class*="absolute"][class*="top-full"],
204
- [data-streamdown="mermaid-block"] div[class*="absolute"][class*="top-full"] {
205
- background: #fff !important;
206
- }
207
-
208
- /* Barra de acciones (code-block, mermaid) - fondo blanco */
209
- [data-streamdown="code-block-actions"],
210
- [data-streamdown="mermaid-block-actions"] {
211
- background: transparent !important;
212
- border-color: transparent !important;
213
- }
214
-
215
- /* Link Safety Modal - dark theme */
216
- /* Backdrop overlay */
217
- [data-streamdown="link-safety-modal"] {
218
- background: rgba(0, 0, 0, 0.7) !important;
219
- }
220
-
221
- /* Modal container */
222
- [data-streamdown="link-safety-modal"] > div {
223
- background: #1e1e2e !important;
224
- border: 1px solid #3d3d4d !important;
225
- border-radius: 0.75rem !important;
226
- box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5) !important;
227
- padding: 1.5rem !important;
228
- position: relative !important;
229
- }
230
-
231
- /* Botón de cerrar (X) - posicionarlo correctamente */
232
- [data-streamdown="link-safety-modal"] > div > button:first-child {
233
- position: absolute !important;
234
- top: 0.75rem !important;
235
- right: 0.75rem !important;
236
- color: #9ca3af !important;
237
- background: transparent !important;
238
- border: none !important;
239
- padding: 0.25rem !important;
240
- line-height: 1 !important;
241
- }
242
-
243
- [data-streamdown="link-safety-modal"] > div > button:first-child:hover {
244
- color: #ffffff !important;
245
- }
246
- [data-streamdown="link-safety-modal"] h2,
247
- [data-streamdown="link-safety-modal"] h3,
248
- [data-streamdown="link-safety-modal"] p,
249
- [data-streamdown="link-safety-modal"] span,
250
- [data-streamdown="link-safety-modal"] label {
251
- color: #e0e0e0 !important;
252
- }
253
-
254
- /* Título */
255
- [data-streamdown="link-safety-modal"] h2,
256
- [data-streamdown="link-safety-modal"] h3 {
257
- color: #ffffff !important;
258
- font-weight: 600 !important;
259
- }
260
-
261
- /* URL link */
262
- [data-streamdown="link-safety-modal"] a {
263
- color: #58a6ff !important;
264
- word-break: break-all;
265
- }
266
-
267
- /* Botón de cerrar (X) */
268
- [data-streamdown="link-safety-modal"] button[aria-label="Close"],
269
- [data-streamdown="link-safety-modal"] > div > button:first-child {
270
- color: #9ca3af !important;
271
- }
272
-
273
- [data-streamdown="link-safety-modal"] button[aria-label="Close"]:hover,
274
- [data-streamdown="link-safety-modal"] > div > button:first-child:hover {
275
- color: #ffffff !important;
276
- }
277
-
278
- /* Container de botones */
279
- [data-streamdown="link-safety-modal"] > div > div:last-child {
280
- display: flex;
281
- gap: 0.75rem;
282
- margin-top: 1rem;
283
- }
284
-
285
- /* Botón secundario (Copy link) */
286
- [data-streamdown="link-safety-modal"] > div > div:last-child button:first-of-type {
287
- background: #2d2d3d !important;
288
- color: #e0e0e0 !important;
289
- border: 1px solid #3d3d4d !important;
290
- border-radius: 0.5rem !important;
291
- padding: 0.5rem 1rem !important;
292
- }
293
-
294
- [data-streamdown="link-safety-modal"] > div > div:last-child button:first-of-type:hover {
295
- background: #3d3d4d !important;
296
- }
297
-
298
- /* Botón primario (Open link) */
299
- [data-streamdown="link-safety-modal"] > div > div:last-child button:last-of-type {
300
- background: #2563eb !important;
301
- color: #ffffff !important;
302
- border: none !important;
303
- border-radius: 0.5rem !important;
304
- padding: 0.5rem 1rem !important;
305
- }
306
-
307
- [data-streamdown="link-safety-modal"] > div > div:last-child button:last-of-type:hover {
308
- background: #1d4ed8 !important;
309
- }