@nuraly/lumenui 0.2.2 → 0.3.2
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/dist/cdn.js +1 -0
- package/dist/nuralyui.bundle.js +2467 -1857
- package/dist/nuralyui.bundle.js.gz +0 -0
- package/dist/src/components/canvas/bundle.js +569 -204
- package/dist/src/components/canvas/bundle.js.gz +0 -0
- package/dist/src/components/canvas/canvas.constants.d.ts +1 -1
- package/dist/src/components/canvas/canvas.constants.js +1 -1
- package/dist/src/components/canvas/workflow-canvas.component.d.ts +7 -0
- package/dist/src/components/canvas/workflow-canvas.component.js +46 -2
- package/dist/src/components/canvas/workflow-canvas.types.d.ts +8 -1
- package/dist/src/components/canvas/workflow-canvas.types.js +157 -0
- package/dist/src/components/chat-panel/bundle.js +216 -0
- package/dist/src/components/chat-panel/bundle.js.gz +0 -0
- package/dist/src/components/chat-panel/chat-panel.component.d.ts +85 -0
- package/dist/src/components/chat-panel/chat-panel.component.js +510 -0
- package/dist/src/components/chat-panel/chat-panel.style.d.ts +2 -0
- package/dist/src/components/chat-panel/chat-panel.style.js +127 -0
- package/dist/src/components/chat-panel/chat-panel.types.d.ts +54 -0
- package/dist/src/components/chat-panel/chat-panel.types.js +2 -0
- package/dist/src/components/chat-panel/index.d.ts +3 -0
- package/dist/src/components/chat-panel/index.js +2 -0
- package/dist/src/components/chatbot/bundle.js +1 -1
- package/dist/src/components/chatbot/bundle.js.gz +0 -0
- package/dist/src/components/chatbot/providers/workflow-socket-provider.js +1 -1
- package/dist/src/components/presence/bundle.js +69 -42
- package/dist/src/components/presence/bundle.js.gz +0 -0
- package/dist/src/components/presence/presence-chat.component.d.ts +2 -0
- package/dist/src/components/presence/presence-chat.component.js +12 -2
- package/dist/src/components/presence/presence.component.d.ts +30 -6
- package/dist/src/components/presence/presence.component.js +277 -30
- package/dist/src/components/presence/presence.types.d.ts +2 -0
- package/dist/src/components/toast/bundle.js +11 -9
- package/dist/src/components/toast/bundle.js.gz +0 -0
- package/dist/src/components/toast/toast.component.d.ts +8 -0
- package/dist/src/components/toast/toast.component.js +17 -7
- package/dist/src/components/video/bundle.js +13 -12
- package/dist/src/components/video/bundle.js.gz +0 -0
- package/dist/src/components/video/video.component.d.ts +15 -1
- package/dist/src/components/video/video.component.js +131 -3
- package/package.json +5 -10
- package/packages/common/dist/VERSIONS.md +1 -1
|
@@ -18,17 +18,22 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
18
18
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
19
19
|
});
|
|
20
20
|
};
|
|
21
|
-
import { LitElement, html, nothing } from 'lit';
|
|
21
|
+
import { LitElement, html, nothing, css } from 'lit';
|
|
22
22
|
import { customElement, property, state } from 'lit/decorators.js';
|
|
23
23
|
import { NuralyUIBaseMixin } from '@nuralyui/common/mixins';
|
|
24
24
|
import { styles } from './presence.style.js';
|
|
25
25
|
import './presence-avatars.component.js';
|
|
26
26
|
import './presence-chat.component.js';
|
|
27
|
+
const GROUP_CHAT_KEY = '__group__';
|
|
27
28
|
/**
|
|
28
29
|
* Top-level presence orchestrator.
|
|
29
30
|
*
|
|
30
|
-
* Owns the socket
|
|
31
|
-
*
|
|
31
|
+
* Owns the resource socket for viewer tracking, and uses the global messages
|
|
32
|
+
* socket (`.globalSocket`) for real-time chat.
|
|
33
|
+
*
|
|
34
|
+
* Two chat modes:
|
|
35
|
+
* - **Group chat**: One conversation per resource. Opened via the chat button.
|
|
36
|
+
* - **DM**: Private 1-on-1 conversation. Opened by clicking a viewer's avatar.
|
|
32
37
|
*
|
|
33
38
|
* @example
|
|
34
39
|
* ```html
|
|
@@ -36,9 +41,11 @@ import './presence-chat.component.js';
|
|
|
36
41
|
* namespace="/nk/apps/workflows/socket"
|
|
37
42
|
* socket-path="/__nk_socketio/"
|
|
38
43
|
* resource-id="workflow-abc123"
|
|
44
|
+
* resource-type="workflow"
|
|
45
|
+
* resource-name="My Workflow"
|
|
39
46
|
* user-id="user-xyz"
|
|
40
47
|
* .currentUser=${{ displayName, initials, color, avatarUrl }}
|
|
41
|
-
* .
|
|
48
|
+
* .globalSocket=${globalSocket}
|
|
42
49
|
* ></nr-presence>
|
|
43
50
|
* ```
|
|
44
51
|
*
|
|
@@ -47,31 +54,43 @@ import './presence-chat.component.js';
|
|
|
47
54
|
let NrPresenceElement = class NrPresenceElement extends NuralyUIBaseMixin(LitElement) {
|
|
48
55
|
constructor() {
|
|
49
56
|
super(...arguments);
|
|
50
|
-
/** Socket.io namespace */
|
|
57
|
+
/** Socket.io namespace for presence tracking */
|
|
51
58
|
this.namespace = '';
|
|
52
59
|
/** Socket.io path */
|
|
53
60
|
this.socketPath = '/__nk_socketio/';
|
|
54
61
|
/** The resource being viewed (workflow id, doc id, etc.) */
|
|
55
62
|
this.resourceId = '';
|
|
63
|
+
/** Resource type for group conversation (e.g. 'workflow', 'whiteboard') */
|
|
64
|
+
this.resourceType = '';
|
|
65
|
+
/** Resource name (used as group conversation name) */
|
|
66
|
+
this.resourceName = '';
|
|
56
67
|
/** Current user's id */
|
|
57
68
|
this.userId = '';
|
|
58
69
|
/** Current user object (shown first in avatar strip) */
|
|
59
70
|
this.currentUser = null;
|
|
60
71
|
/** Additional users to show (e.g. mocks for demo) */
|
|
61
72
|
this.extraUsers = [];
|
|
73
|
+
/** Global messages socket (from layout's /nk/messages connection) for real-time chat */
|
|
74
|
+
this.globalSocket = null;
|
|
62
75
|
this._viewers = [];
|
|
76
|
+
this._hasUnreadGroup = false;
|
|
63
77
|
this._socket = null;
|
|
78
|
+
this._connecting = false;
|
|
64
79
|
this._chats = new Map();
|
|
65
80
|
this._chatZ = 100;
|
|
66
81
|
this._drag = null;
|
|
67
82
|
this._boundDragMove = (e) => this._onDragMove(e);
|
|
68
83
|
this._boundDragEnd = () => this._onDragEnd();
|
|
69
84
|
this._boundEscape = (e) => this._onEscape(e);
|
|
85
|
+
this._boundOnMessage = (data) => this._onSocketMessage(data);
|
|
86
|
+
// ── Group chat ──
|
|
87
|
+
this._groupConversationId = null;
|
|
70
88
|
}
|
|
71
89
|
connectedCallback() {
|
|
72
90
|
super.connectedCallback();
|
|
73
91
|
document.addEventListener('keydown', this._boundEscape);
|
|
74
92
|
this._connect();
|
|
93
|
+
this._attachGlobalSocket();
|
|
75
94
|
}
|
|
76
95
|
disconnectedCallback() {
|
|
77
96
|
var _a;
|
|
@@ -81,11 +100,66 @@ let NrPresenceElement = class NrPresenceElement extends NuralyUIBaseMixin(LitEle
|
|
|
81
100
|
document.removeEventListener('mouseup', this._boundDragEnd);
|
|
82
101
|
(_a = this._socket) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
83
102
|
this._socket = null;
|
|
103
|
+
this._detachGlobalSocket();
|
|
104
|
+
}
|
|
105
|
+
updated(changed) {
|
|
106
|
+
if (changed.has('globalSocket')) {
|
|
107
|
+
this._detachGlobalSocket(changed.get('globalSocket'));
|
|
108
|
+
this._attachGlobalSocket();
|
|
109
|
+
}
|
|
110
|
+
// Resource socket may not have connected during connectedCallback if userId/
|
|
111
|
+
// resourceId/namespace were still empty (common during hydration). Retry when
|
|
112
|
+
// any of them becomes available.
|
|
113
|
+
if (!this._socket && (changed.has('userId') || changed.has('resourceId') || changed.has('namespace'))) {
|
|
114
|
+
if (this.userId && this.resourceId && this.namespace) {
|
|
115
|
+
this._connect();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
84
118
|
}
|
|
119
|
+
_attachGlobalSocket() {
|
|
120
|
+
if (this.globalSocket) {
|
|
121
|
+
this.globalSocket.on('nk:data', this._boundOnMessage);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
_detachGlobalSocket(old) {
|
|
125
|
+
const sock = old || this.globalSocket;
|
|
126
|
+
if (sock) {
|
|
127
|
+
sock.off('nk:data', this._boundOnMessage);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/** Handle incoming messages from the global /nk/messages socket */
|
|
131
|
+
_onSocketMessage(data) {
|
|
132
|
+
if (data.event !== 'message:new')
|
|
133
|
+
return;
|
|
134
|
+
const msg = data.data;
|
|
135
|
+
if (!(msg === null || msg === void 0 ? void 0 : msg.conversationId) || msg.senderId === this.userId)
|
|
136
|
+
return;
|
|
137
|
+
for (const [, chat] of this._chats) {
|
|
138
|
+
if (chat.conversationId === msg.conversationId) {
|
|
139
|
+
chat.messages = [...chat.messages, {
|
|
140
|
+
id: String(msg.id),
|
|
141
|
+
senderId: msg.senderId,
|
|
142
|
+
text: msg.content,
|
|
143
|
+
timestamp: new Date(msg.createdAt).getTime(),
|
|
144
|
+
me: false,
|
|
145
|
+
}];
|
|
146
|
+
this.requestUpdate();
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// If message is for our group conversation but panel is closed, show unread dot
|
|
151
|
+
if (this._groupConversationId && msg.conversationId === this._groupConversationId) {
|
|
152
|
+
this._hasUnreadGroup = true;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// ── Resource presence socket ──
|
|
85
156
|
_connect() {
|
|
86
157
|
return __awaiter(this, void 0, void 0, function* () {
|
|
158
|
+
if (this._socket || this._connecting)
|
|
159
|
+
return;
|
|
87
160
|
if (!this.userId || !this.resourceId || !this.namespace)
|
|
88
161
|
return;
|
|
162
|
+
this._connecting = true;
|
|
89
163
|
try {
|
|
90
164
|
const { io } = yield import('socket.io-client');
|
|
91
165
|
this._socket = io(this.namespace, {
|
|
@@ -108,24 +182,172 @@ let NrPresenceElement = class NrPresenceElement extends NuralyUIBaseMixin(LitEle
|
|
|
108
182
|
catch (e) {
|
|
109
183
|
console.error('[nr-presence] Connection failed:', e);
|
|
110
184
|
}
|
|
185
|
+
finally {
|
|
186
|
+
this._connecting = false;
|
|
187
|
+
}
|
|
111
188
|
});
|
|
112
189
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
this._chats.
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
190
|
+
_openGroupChat() {
|
|
191
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
192
|
+
var _a;
|
|
193
|
+
if (this._chats.has(GROUP_CHAT_KEY)) {
|
|
194
|
+
const c = this._chats.get(GROUP_CHAT_KEY);
|
|
195
|
+
c.minimized = false;
|
|
196
|
+
c.z = ++this._chatZ;
|
|
197
|
+
this._hasUnreadGroup = false;
|
|
198
|
+
this.requestUpdate();
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
const ix = window.innerWidth - 324;
|
|
202
|
+
const iy = 56;
|
|
203
|
+
this._chats.set(GROUP_CHAT_KEY, {
|
|
204
|
+
user: { displayName: this.resourceName || `${this.resourceType} chat`, color: '#7c3aed', initials: '#' },
|
|
205
|
+
conversationId: null, loading: true,
|
|
206
|
+
x: ix, y: iy, savedX: ix, savedY: iy,
|
|
207
|
+
z: ++this._chatZ, minimized: false, messages: [], draftText: '',
|
|
208
|
+
});
|
|
209
|
+
this._hasUnreadGroup = false;
|
|
210
|
+
this.requestUpdate();
|
|
211
|
+
try {
|
|
212
|
+
const res = yield fetch('/api/conversations/resource', {
|
|
213
|
+
method: 'POST',
|
|
214
|
+
headers: { 'Content-Type': 'application/json' },
|
|
215
|
+
body: JSON.stringify({
|
|
216
|
+
resourceType: this.resourceType,
|
|
217
|
+
resourceId: this.resourceId,
|
|
218
|
+
resourceName: this.resourceName,
|
|
219
|
+
}),
|
|
220
|
+
});
|
|
221
|
+
const data = yield res.json();
|
|
222
|
+
const chat = this._chats.get(GROUP_CHAT_KEY);
|
|
223
|
+
if (!chat || !data.conversationId) {
|
|
224
|
+
if (chat)
|
|
225
|
+
chat.loading = false;
|
|
226
|
+
this.requestUpdate();
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
chat.conversationId = data.conversationId;
|
|
230
|
+
this._groupConversationId = data.conversationId;
|
|
231
|
+
// Join the conversation room on the global socket
|
|
232
|
+
if ((_a = this.globalSocket) === null || _a === void 0 ? void 0 : _a.connected) {
|
|
233
|
+
this.globalSocket.emit('nk:conversation:join', { conversationId: data.conversationId });
|
|
234
|
+
}
|
|
235
|
+
// Load existing messages
|
|
236
|
+
yield this._loadMessages(chat);
|
|
237
|
+
}
|
|
238
|
+
catch (e) {
|
|
239
|
+
console.error('[nr-presence] Failed to open group chat:', e);
|
|
240
|
+
const chat = this._chats.get(GROUP_CHAT_KEY);
|
|
241
|
+
if (chat)
|
|
242
|
+
chat.loading = false;
|
|
243
|
+
}
|
|
244
|
+
this.requestUpdate();
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
// ── DM chat ──
|
|
248
|
+
_openDm(user) {
|
|
249
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
250
|
+
var _a;
|
|
251
|
+
const key = user.userId || user.displayName;
|
|
252
|
+
// Clicking your own avatar opens the group chat (notes to self in context)
|
|
253
|
+
if (key === this.userId) {
|
|
254
|
+
this._openGroupChat();
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
if (this._chats.has(key)) {
|
|
258
|
+
this._chats.get(key).z = ++this._chatZ;
|
|
259
|
+
this.requestUpdate();
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
const offset = [...this._chats.keys()].filter(k => k !== GROUP_CHAT_KEY).length;
|
|
263
|
+
const ix = window.innerWidth - 324 - (offset + 1) * 24;
|
|
264
|
+
const iy = 56 + (offset + 1) * 24;
|
|
122
265
|
this._chats.set(key, {
|
|
123
|
-
user,
|
|
266
|
+
user, conversationId: null, loading: true,
|
|
267
|
+
x: ix, y: iy, savedX: ix, savedY: iy,
|
|
124
268
|
z: ++this._chatZ, minimized: false, messages: [], draftText: '',
|
|
125
269
|
});
|
|
126
|
-
|
|
270
|
+
this.requestUpdate();
|
|
271
|
+
if (!user.userId)
|
|
272
|
+
return;
|
|
273
|
+
try {
|
|
274
|
+
const dmRes = yield fetch('/api/conversations/dm', {
|
|
275
|
+
method: 'POST',
|
|
276
|
+
headers: { 'Content-Type': 'application/json' },
|
|
277
|
+
body: JSON.stringify({ targetUserId: user.userId }),
|
|
278
|
+
});
|
|
279
|
+
const dm = yield dmRes.json();
|
|
280
|
+
const chat = this._chats.get(key);
|
|
281
|
+
if (!chat || !dm.conversationId) {
|
|
282
|
+
if (chat)
|
|
283
|
+
chat.loading = false;
|
|
284
|
+
this.requestUpdate();
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
chat.conversationId = dm.conversationId;
|
|
288
|
+
if ((_a = this.globalSocket) === null || _a === void 0 ? void 0 : _a.connected) {
|
|
289
|
+
this.globalSocket.emit('nk:conversation:join', { conversationId: dm.conversationId });
|
|
290
|
+
}
|
|
291
|
+
yield this._loadMessages(chat);
|
|
292
|
+
}
|
|
293
|
+
catch (e) {
|
|
294
|
+
console.error('[nr-presence] Failed to open DM:', e);
|
|
295
|
+
const chat = this._chats.get(key);
|
|
296
|
+
if (chat)
|
|
297
|
+
chat.loading = false;
|
|
298
|
+
}
|
|
299
|
+
this.requestUpdate();
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
// ── Shared helpers ──
|
|
303
|
+
_loadMessages(chat) {
|
|
304
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
305
|
+
var _a;
|
|
306
|
+
if (!chat.conversationId)
|
|
307
|
+
return;
|
|
308
|
+
try {
|
|
309
|
+
const res = yield fetch(`/api/conversations/${chat.conversationId}/messages`);
|
|
310
|
+
const data = yield res.json();
|
|
311
|
+
if ((_a = data.messages) === null || _a === void 0 ? void 0 : _a.length) {
|
|
312
|
+
chat.messages = data.messages.map((m) => ({
|
|
313
|
+
id: String(m.id),
|
|
314
|
+
senderId: m.sender_id,
|
|
315
|
+
text: m.content,
|
|
316
|
+
timestamp: new Date(m.created_at).getTime(),
|
|
317
|
+
me: m.sender_id === this.userId,
|
|
318
|
+
}));
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
catch (e) {
|
|
322
|
+
console.error('[nr-presence] Failed to load messages:', e);
|
|
323
|
+
}
|
|
324
|
+
chat.loading = false;
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
_sendMessage(key, text) {
|
|
328
|
+
var _a;
|
|
329
|
+
const chat = this._chats.get(key);
|
|
330
|
+
if (!(chat === null || chat === void 0 ? void 0 : chat.conversationId))
|
|
331
|
+
return;
|
|
332
|
+
// Optimistic local update
|
|
333
|
+
chat.messages = [...chat.messages, {
|
|
334
|
+
id: crypto.randomUUID(),
|
|
335
|
+
senderId: this.userId,
|
|
336
|
+
text,
|
|
337
|
+
timestamp: Date.now(),
|
|
338
|
+
me: true,
|
|
339
|
+
}];
|
|
127
340
|
this.requestUpdate();
|
|
341
|
+
// Send via global socket
|
|
342
|
+
if ((_a = this.globalSocket) === null || _a === void 0 ? void 0 : _a.connected) {
|
|
343
|
+
this.globalSocket.emit('nk:message:send', {
|
|
344
|
+
conversationId: chat.conversationId,
|
|
345
|
+
content: text,
|
|
346
|
+
type: 'text',
|
|
347
|
+
});
|
|
348
|
+
}
|
|
128
349
|
}
|
|
350
|
+
// ── Chat panel UI management ──
|
|
129
351
|
_closeChat(key) {
|
|
130
352
|
this._chats.delete(key);
|
|
131
353
|
this.requestUpdate();
|
|
@@ -189,9 +411,18 @@ let NrPresenceElement = class NrPresenceElement extends NuralyUIBaseMixin(LitEle
|
|
|
189
411
|
return html `
|
|
190
412
|
<nr-presence-avatars
|
|
191
413
|
.users=${allUsers}
|
|
192
|
-
@user-click=${(e) => this.
|
|
414
|
+
@user-click=${(e) => this._openDm(e.detail.user)}
|
|
193
415
|
></nr-presence-avatars>
|
|
194
416
|
|
|
417
|
+
${this.resourceType ? html `
|
|
418
|
+
<button class="group-chat-btn" title="Team chat" @click=${() => this._openGroupChat()}>
|
|
419
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
|
|
420
|
+
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
|
|
421
|
+
</svg>
|
|
422
|
+
${this._hasUnreadGroup ? html `<span class="unread-dot"></span>` : nothing}
|
|
423
|
+
</button>
|
|
424
|
+
` : nothing}
|
|
425
|
+
|
|
195
426
|
${[...this._chats.entries()].map(([key, c]) => {
|
|
196
427
|
const minIdx = minimizedList.findIndex(([k]) => k === key);
|
|
197
428
|
return html `
|
|
@@ -203,6 +434,7 @@ let NrPresenceElement = class NrPresenceElement extends NuralyUIBaseMixin(LitEle
|
|
|
203
434
|
.minimized=${c.minimized}
|
|
204
435
|
.minimizedIndex=${minIdx >= 0 ? minIdx : 0}
|
|
205
436
|
.messages=${c.messages}
|
|
437
|
+
.loading=${c.loading}
|
|
206
438
|
@focus=${() => { c.z = ++this._chatZ; this.requestUpdate(); }}
|
|
207
439
|
@drag-start=${(e) => this._onDragStart(key, e.detail.offsetX, e.detail.offsetY)}
|
|
208
440
|
@minimize=${() => { c.savedX = c.x; c.savedY = c.y; c.minimized = true; this.requestUpdate(); }}
|
|
@@ -215,25 +447,28 @@ let NrPresenceElement = class NrPresenceElement extends NuralyUIBaseMixin(LitEle
|
|
|
215
447
|
}}
|
|
216
448
|
@float=${() => { c.minimized = false; c.x = c.savedX; c.y = c.savedY; c.z = ++this._chatZ; this.requestUpdate(); }}
|
|
217
449
|
@close=${() => this._closeChat(key)}
|
|
218
|
-
@send=${(e) =>
|
|
219
|
-
c.messages = [...c.messages, {
|
|
220
|
-
id: crypto.randomUUID(),
|
|
221
|
-
senderId: this.userId,
|
|
222
|
-
text: e.detail.text,
|
|
223
|
-
timestamp: Date.now(),
|
|
224
|
-
me: true,
|
|
225
|
-
}];
|
|
226
|
-
this.requestUpdate();
|
|
227
|
-
}}
|
|
450
|
+
@send=${(e) => this._sendMessage(key, e.detail.text)}
|
|
228
451
|
></nr-presence-chat>
|
|
229
452
|
`;
|
|
230
453
|
})}
|
|
231
|
-
|
|
232
|
-
${this._chats.size === 0 ? nothing : nothing}
|
|
233
454
|
`;
|
|
234
455
|
}
|
|
235
456
|
};
|
|
236
|
-
NrPresenceElement.styles = styles
|
|
457
|
+
NrPresenceElement.styles = [styles, css `
|
|
458
|
+
.group-chat-btn {
|
|
459
|
+
display: flex; align-items: center; justify-content: center;
|
|
460
|
+
width: 28px; height: 28px; border-radius: 50%; border: 2px solid var(--bg, #fff);
|
|
461
|
+
background: var(--accent, #7c3aed); color: #fff; cursor: pointer;
|
|
462
|
+
margin-left: 4px; transition: transform 120ms, background 120ms;
|
|
463
|
+
position: relative;
|
|
464
|
+
}
|
|
465
|
+
.group-chat-btn:hover { transform: scale(1.1); background: var(--accent-hover, #6d28d9); }
|
|
466
|
+
.group-chat-btn svg { width: 14px; height: 14px; }
|
|
467
|
+
.unread-dot {
|
|
468
|
+
position: absolute; top: -2px; right: -2px; width: 8px; height: 8px;
|
|
469
|
+
border-radius: 50%; background: #ef4444; border: 2px solid var(--bg, #fff);
|
|
470
|
+
}
|
|
471
|
+
`];
|
|
237
472
|
NrPresenceElement.useShadowDom = true;
|
|
238
473
|
__decorate([
|
|
239
474
|
property({ type: String })
|
|
@@ -244,6 +479,12 @@ __decorate([
|
|
|
244
479
|
__decorate([
|
|
245
480
|
property({ type: String, attribute: 'resource-id' })
|
|
246
481
|
], NrPresenceElement.prototype, "resourceId", void 0);
|
|
482
|
+
__decorate([
|
|
483
|
+
property({ type: String, attribute: 'resource-type' })
|
|
484
|
+
], NrPresenceElement.prototype, "resourceType", void 0);
|
|
485
|
+
__decorate([
|
|
486
|
+
property({ type: String, attribute: 'resource-name' })
|
|
487
|
+
], NrPresenceElement.prototype, "resourceName", void 0);
|
|
247
488
|
__decorate([
|
|
248
489
|
property({ type: String, attribute: 'user-id' })
|
|
249
490
|
], NrPresenceElement.prototype, "userId", void 0);
|
|
@@ -253,9 +494,15 @@ __decorate([
|
|
|
253
494
|
__decorate([
|
|
254
495
|
property({ type: Array })
|
|
255
496
|
], NrPresenceElement.prototype, "extraUsers", void 0);
|
|
497
|
+
__decorate([
|
|
498
|
+
property({ type: Object })
|
|
499
|
+
], NrPresenceElement.prototype, "globalSocket", void 0);
|
|
256
500
|
__decorate([
|
|
257
501
|
state()
|
|
258
502
|
], NrPresenceElement.prototype, "_viewers", void 0);
|
|
503
|
+
__decorate([
|
|
504
|
+
state()
|
|
505
|
+
], NrPresenceElement.prototype, "_hasUnreadGroup", void 0);
|
|
259
506
|
NrPresenceElement = __decorate([
|
|
260
507
|
customElement('nr-presence')
|
|
261
508
|
], NrPresenceElement);
|
|
@@ -331,13 +331,13 @@ import{css as t,html as e,nothing as o,LitElement as s}from"lit";import{property
|
|
|
331
331
|
* @license
|
|
332
332
|
* Copyright 2023 Nuraly, Laabidi Aymen
|
|
333
333
|
* SPDX-License-Identifier: MIT
|
|
334
|
-
*/,d=t=>class extends t{constructor(){super(...arguments),this.handleSystemThemeChange=()=>{this.closest("[data-theme]")||document.documentElement.hasAttribute("data-theme")||this.requestUpdate()}}connectedCallback(){super.connectedCallback(),this.setupThemeObserver(),this.setupDesignSystemObserver(),this.setupSystemThemeListener()}disconnectedCallback(){var t,e,o;super.disconnectedCallback(),null===(t=this.themeObserver)||void 0===t||t.disconnect(),null===(e=this.designSystemObserver)||void 0===e||e.disconnect(),null===(o=this.mediaQuery)||void 0===o||o.removeEventListener("change",this.handleSystemThemeChange)}get currentTheme(){var t,e;const o=(null===(t=this.closest("[data-theme]"))||void 0===t?void 0:t.getAttribute("data-theme"))||document.documentElement.getAttribute("data-theme");return o||((null===(e=window.matchMedia)||void 0===e?void 0:e.call(window,"(prefers-color-scheme: dark)").matches)?"dark":"light")}get currentDesignSystem(){var t;const e=(null===(t=this.closest("[design-system]"))||void 0===t?void 0:t.getAttribute("design-system"))||document.documentElement.getAttribute("design-system");return"carbon"===e?e:"default"}setupThemeObserver(){this.themeObserver=new MutationObserver(()=>{this.requestUpdate()}),this.themeObserver.observe(document.documentElement,{attributes:!0,attributeFilter:["data-theme"]})}setupDesignSystemObserver(){this.designSystemObserver=new MutationObserver(()=>{this.requestUpdate()}),this.designSystemObserver.observe(document.documentElement,{attributes:!0,attributeFilter:["design-system"]})}setupSystemThemeListener(){window.matchMedia&&(this.mediaQuery=window.matchMedia("(prefers-color-scheme: dark)"),this.mediaQuery.addEventListener("change",this.handleSystemThemeChange))}},h=()=>{var t;return void 0!==globalThis.litElementVersions||"undefined"!=typeof process&&"development"===(null===(t=process.env)||void 0===t?void 0:t.NODE_ENV)||"undefined"!=typeof window&&("localhost"===window.location.hostname||"127.0.0.1"===window.location.hostname)},u=t=>class extends t{constructor(){super(...arguments),this.requiredComponents=[]}validateDependencies(){if(h())for(const t of this.requiredComponents)if(!this.isComponentAvailable(t))throw new Error(`Required component "${t}" is not registered. Please import and register the component before using ${this.tagName.toLowerCase()}. Example: import '@nuralyui/${t}';`)}validateDependenciesWithHandler(t){if(!h())return!0;let e=!0;for(const o of this.requiredComponents)if(!this.isComponentAvailable(o)){e=!1;const s=new Error(`Required component "${o}" is not registered. Please import and register the component before using ${this.tagName.toLowerCase()}.`);t?t(o,s):console.error(s.message)}return e}isComponentAvailable(t){return!!customElements.get(t)}getMissingDependencies(){return this.requiredComponents.filter(t=>!this.isComponentAvailable(t))}areDependenciesAvailable(){return this.requiredComponents.every(t=>this.isComponentAvailable(t))}addRequiredComponent(t){this.requiredComponents.includes(t)||this.requiredComponents.push(t)}removeRequiredComponent(t){const e=this.requiredComponents.indexOf(t);e>-1&&this.requiredComponents.splice(e,1)}},m=t=>class extends t{dispatchCustomEvent(t,e){this.dispatchEvent(new CustomEvent(t,{detail:e,bubbles:!0,composed:!0}))}dispatchEventWithMetadata(t,e){var o;const s=Object.assign(Object.assign({},e),{timestamp:Date.now(),componentName:(null===(o=this.tagName)||void 0===o?void 0:o.toLowerCase())||"unknown"});this.dispatchCustomEvent(t,s)}dispatchInputEvent(t,e){const o=Object.assign({target:e.target||this,value:e.value,originalEvent:e.originalEvent},e);this.dispatchCustomEvent(t,o)}dispatchFocusEvent(t,e){const o=Object.assign({target:e.target||this,value:e.value,focused:e.focused,cursorPosition:e.cursorPosition,selectedText:e.selectedText},e);this.dispatchCustomEvent(t,o)}dispatchValidationEvent(t,e){var o;const s=Object.assign({target:e.target||this,value:e.value,isValid:null!==(o=e.isValid)&&void 0!==o&&o,error:e.error},e);this.dispatchCustomEvent(t,s)}dispatchActionEvent(t,e){const o=Object.assign({target:e.target||this,action:e.action,previousValue:e.previousValue,newValue:e.newValue},e);this.dispatchCustomEvent(t,o)}isReadonlyKeyAllowed(t){if(t.ctrlKey||t.metaKey){return["KeyA","KeyC"].includes(t.code)}return["Tab","Escape","ArrowLeft","ArrowRight","ArrowUp","ArrowDown","Home","End","PageUp","PageDown"].includes(t.key)}isActivationKey(t){return"Enter"===t.key||" "===t.key}},
|
|
334
|
+
*/,d=t=>class extends t{constructor(){super(...arguments),this.handleSystemThemeChange=()=>{this.closest("[data-theme]")||document.documentElement.hasAttribute("data-theme")||this.requestUpdate()}}connectedCallback(){super.connectedCallback(),this.setupThemeObserver(),this.setupDesignSystemObserver(),this.setupSystemThemeListener()}disconnectedCallback(){var t,e,o;super.disconnectedCallback(),null===(t=this.themeObserver)||void 0===t||t.disconnect(),null===(e=this.designSystemObserver)||void 0===e||e.disconnect(),null===(o=this.mediaQuery)||void 0===o||o.removeEventListener("change",this.handleSystemThemeChange)}get currentTheme(){var t,e;const o=(null===(t=this.closest("[data-theme]"))||void 0===t?void 0:t.getAttribute("data-theme"))||document.documentElement.getAttribute("data-theme");return o||((null===(e=window.matchMedia)||void 0===e?void 0:e.call(window,"(prefers-color-scheme: dark)").matches)?"dark":"light")}get currentDesignSystem(){var t;const e=(null===(t=this.closest("[design-system]"))||void 0===t?void 0:t.getAttribute("design-system"))||document.documentElement.getAttribute("design-system");return"carbon"===e?e:"default"}setupThemeObserver(){this.themeObserver=new MutationObserver(()=>{this.requestUpdate()}),this.themeObserver.observe(document.documentElement,{attributes:!0,attributeFilter:["data-theme"]})}setupDesignSystemObserver(){this.designSystemObserver=new MutationObserver(()=>{this.requestUpdate()}),this.designSystemObserver.observe(document.documentElement,{attributes:!0,attributeFilter:["design-system"]})}setupSystemThemeListener(){window.matchMedia&&(this.mediaQuery=window.matchMedia("(prefers-color-scheme: dark)"),this.mediaQuery.addEventListener("change",this.handleSystemThemeChange))}},h=()=>{var t;return void 0!==globalThis.litElementVersions||"undefined"!=typeof process&&"development"===(null===(t=process.env)||void 0===t?void 0:t.NODE_ENV)||"undefined"!=typeof window&&("localhost"===window.location.hostname||"127.0.0.1"===window.location.hostname)},u=t=>class extends t{constructor(){super(...arguments),this.requiredComponents=[]}validateDependencies(){if(h())for(const t of this.requiredComponents)if(!this.isComponentAvailable(t))throw new Error(`Required component "${t}" is not registered. Please import and register the component before using ${this.tagName.toLowerCase()}. Example: import '@nuralyui/${t}';`)}validateDependenciesWithHandler(t){if(!h())return!0;let e=!0;for(const o of this.requiredComponents)if(!this.isComponentAvailable(o)){e=!1;const s=new Error(`Required component "${o}" is not registered. Please import and register the component before using ${this.tagName.toLowerCase()}.`);t?t(o,s):console.error(s.message)}return e}isComponentAvailable(t){return!!customElements.get(t)}getMissingDependencies(){return this.requiredComponents.filter(t=>!this.isComponentAvailable(t))}areDependenciesAvailable(){return this.requiredComponents.every(t=>this.isComponentAvailable(t))}addRequiredComponent(t){this.requiredComponents.includes(t)||this.requiredComponents.push(t)}removeRequiredComponent(t){const e=this.requiredComponents.indexOf(t);e>-1&&this.requiredComponents.splice(e,1)}},m=t=>class extends t{dispatchCustomEvent(t,e){this.dispatchEvent(new CustomEvent(t,{detail:e,bubbles:!0,composed:!0}))}dispatchEventWithMetadata(t,e){var o;const s=Object.assign(Object.assign({},e),{timestamp:Date.now(),componentName:(null===(o=this.tagName)||void 0===o?void 0:o.toLowerCase())||"unknown"});this.dispatchCustomEvent(t,s)}dispatchInputEvent(t,e){const o=Object.assign({target:e.target||this,value:e.value,originalEvent:e.originalEvent},e);this.dispatchCustomEvent(t,o)}dispatchFocusEvent(t,e){const o=Object.assign({target:e.target||this,value:e.value,focused:e.focused,cursorPosition:e.cursorPosition,selectedText:e.selectedText},e);this.dispatchCustomEvent(t,o)}dispatchValidationEvent(t,e){var o;const s=Object.assign({target:e.target||this,value:e.value,isValid:null!==(o=e.isValid)&&void 0!==o&&o,error:e.error},e);this.dispatchCustomEvent(t,s)}dispatchActionEvent(t,e){const o=Object.assign({target:e.target||this,action:e.action,previousValue:e.previousValue,newValue:e.newValue},e);this.dispatchCustomEvent(t,o)}isReadonlyKeyAllowed(t){if(t.ctrlKey||t.metaKey){return["KeyA","KeyC"].includes(t.code)}return["Tab","Escape","ArrowLeft","ArrowRight","ArrowUp","ArrowDown","Home","End","PageUp","PageDown"].includes(t.key)}isActivationKey(t){return"Enter"===t.key||" "===t.key}},p=new Set,f=new Map;
|
|
335
335
|
/**
|
|
336
336
|
* @license
|
|
337
337
|
* Copyright 2023 Nuraly, Laabidi Aymen
|
|
338
338
|
* SPDX-License-Identifier: MIT
|
|
339
339
|
*/
|
|
340
|
-
const b=t=>{class e extends t{constructor(){super(...arguments),this.t=null}createRenderRoot(){return this.constructor.useShadowDom?super.createRenderRoot():this}connectedCallback(){const t=this.constructor.useShadowDom;if(!t&&null===this.t)for(this.t=[];this.firstChild;)this.t.push(this.removeChild(this.firstChild));if(super.connectedCallback(),!t){const t=this.constructor,e=this.tagName.toLowerCase(),o=t.styles;if(o){const t=v(o);t&&function(t,e,o){var s;if(!
|
|
340
|
+
const b=t=>{class e extends t{constructor(){super(...arguments),this.t=null}createRenderRoot(){return this.constructor.useShadowDom?super.createRenderRoot():this}connectedCallback(){const t=this.constructor.useShadowDom;if(!t&&null===this.t)for(this.t=[];this.firstChild;)this.t.push(this.removeChild(this.firstChild));if(super.connectedCallback(),!t){const t=this.constructor,e=this.tagName.toLowerCase(),o=t.styles;if(o){const t=v(o);t&&function(t,e,o){var s;if(!f.has(t)){const o=new CSSStyleSheet;o.replaceSync(e),f.set(t,o)}const i=f.get(t),r=`doc:${t}`;if(p.has(r)||(document.adoptedStyleSheets=[...document.adoptedStyleSheets,i],p.add(r)),o){let e=o;for(;e;){const o=e.getRootNode();if(!(o instanceof ShadowRoot))break;{const r=`shadow:${((null===(s=o.host)||void 0===s?void 0:s.tagName)||"").toLowerCase()}:${t}`;p.has(r)||(o.adoptedStyleSheets=[...o.adoptedStyleSheets,i],p.add(r)),e=o.host}}}}(e,t,this)}}}get lightChildren(){return this.t?this.t.filter(t=>!(t instanceof Element&&t.hasAttribute("slot"))):[]}lightChildrenNamed(t){return this.t?this.t.filter(e=>e instanceof Element&&e.getAttribute("slot")===t):[]}}return e.useShadowDom=!1,e};function v(t){return Array.isArray(t)?t.map(t=>v(t)).filter(Boolean).join("\n"):t&&"string"==typeof t.cssText?t.cssText:"string"==typeof t?t:""}
|
|
341
341
|
/**
|
|
342
342
|
* @license
|
|
343
343
|
* Copyright 2023 Nuraly, Laabidi Aymen
|
|
@@ -349,32 +349,34 @@ const b=t=>{class e extends t{constructor(){super(...arguments),this.t=null}crea
|
|
|
349
349
|
* SPDX-License-Identifier: MIT
|
|
350
350
|
*/
|
|
351
351
|
var x=function(t,e,o,s){for(var i,r=arguments.length,n=r<3?e:null===s?s=Object.getOwnPropertyDescriptor(e,o):s,a=t.length-1;a>=0;a--)(i=t[a])&&(n=(r<3?i(n):r>3?i(e,o,n):i(e,o))||n);return r>3&&n&&Object.defineProperty(e,o,n),n};let k=class extends((t=>u(d(m(b(t)))))(s)){constructor(){super(...arguments),this.requiredComponents=["nr-icon","nr-button"],this.position="top-right",this.maxToasts=5,this.defaultDuration=5e3,this.animation="fade",this.stack=!0,this.autoDismiss=!0,this.toasts=[],this.timeouts=new Map}show(t){var e,o,s;const i="string"==typeof t?{text:t}:t,r={id:this.generateId(),timestamp:Date.now(),text:i.text,content:i.content,type:i.type||"default",duration:null!==(e=i.duration)&&void 0!==e?e:this.defaultDuration,autoDismiss:null!==(o=i.autoDismiss)&&void 0!==o?o:this.autoDismiss,closable:null===(s=i.closable)||void 0===s||s,icon:i.icon||this.getDefaultIcon(i.type),customClass:i.customClass,button:i.button,onClose:i.onClose,onClick:i.onClick};if(this.stack?this.toasts.length>=this.maxToasts&&this.removeToast(this.toasts[0].id):this.clearAll(),this.toasts=[...this.toasts,r],this.emitToastEvent("nr-toast-show",r,"show"),r.autoDismiss&&r.duration&&r.duration>0){const t=window.setTimeout(()=>{this.removeToast(r.id)},r.duration);this.timeouts.set(r.id,t)}return r.id}success(t,e){return this.show({text:t,type:"success",duration:e})}error(t,e){return this.show({text:t,type:"error",duration:e})}warning(t,e){return this.show({text:t,type:"warning",duration:e})}info(t,e){return this.show({text:t,type:"info",duration:e})}removeToast(t){const e=this.toasts.find(e=>e.id===t);if(!e)return;e.removing=!0,this.requestUpdate();const o=this.timeouts.get(t);o&&(clearTimeout(o),this.timeouts.delete(t)),setTimeout(()=>{var o;this.toasts=this.toasts.filter(e=>e.id!==t),this.emitToastEvent("nr-toast-close",e,"close"),null===(o=e.onClose)||void 0===o||o.call(e)},300)}clearAll(){this.toasts.forEach(t=>{const e=this.timeouts.get(t.id);e&&clearTimeout(e)}),this.timeouts.clear(),this.toasts=[]}handleToastClick(t){var e;this.emitToastEvent("nr-toast-click",t,"click"),null===(e=t.onClick)||void 0===e||e.call(t)}handleCloseClick(t,e){t.stopPropagation(),this.removeToast(e.id)}getDefaultIcon(t){switch(t){case"success":return"check-circle";case"error":return"x-circle";case"warning":return"alert-triangle";case"info":return"info";default:return""}}generateId(){return`toast-${Date.now()}-${Math.random().toString(36).substr(2,9)}`}getAnimationClass(t){const e=t.removing?"out":"in";return`toast--${this.animation}-${e}`}emitToastEvent(t,e,o){this.dispatchEvent(new CustomEvent(t,{detail:{toast:e,action:o},bubbles:!0,composed:!0}))}disconnectedCallback(){super.disconnectedCallback(),this.clearAll()}render(){return e`
|
|
352
|
-
<div class="toast-container">
|
|
352
|
+
<div class="toast-container" part="container">
|
|
353
353
|
${a(this.toasts,t=>t.id,t=>this.renderToast(t))}
|
|
354
354
|
</div>
|
|
355
355
|
`}renderToast(t){const s={toast:!0,[`toast--${t.type}`]:!0,[this.getAnimationClass(t)]:!0,[t.customClass||""]:!!t.customClass};return e`
|
|
356
356
|
<div
|
|
357
357
|
class=${c(s)}
|
|
358
|
+
part="toast toast-${t.type}"
|
|
358
359
|
@click=${()=>this.handleToastClick(t)}
|
|
359
360
|
role="alert"
|
|
360
361
|
aria-live="polite"
|
|
361
362
|
>
|
|
362
363
|
${t.icon?e`
|
|
363
|
-
<div class="toast__icon">
|
|
364
|
+
<div class="toast__icon" part="icon">
|
|
364
365
|
<nr-icon name=${t.icon} size="medium"></nr-icon>
|
|
365
366
|
</div>
|
|
366
367
|
`:o}
|
|
367
|
-
|
|
368
|
-
<div class="toast__content">
|
|
368
|
+
|
|
369
|
+
<div class="toast__content" part="content">
|
|
369
370
|
${t.content?t.content:e`
|
|
370
|
-
<div class="toast__text">${t.text}</div>
|
|
371
|
+
<div class="toast__text" part="text">${t.text}</div>
|
|
371
372
|
${t.button?this.renderButton(t.button):o}
|
|
372
373
|
`}
|
|
373
374
|
</div>
|
|
374
|
-
|
|
375
|
+
|
|
375
376
|
${t.closable?e`
|
|
376
377
|
<button
|
|
377
378
|
class="toast__close"
|
|
379
|
+
part="close"
|
|
378
380
|
@click=${e=>this.handleCloseClick(e,t)}
|
|
379
381
|
aria-label="Close notification"
|
|
380
382
|
type="button"
|
|
@@ -384,7 +386,7 @@ var x=function(t,e,o,s){for(var i,r=arguments.length,n=r<3?e:null===s?s=Object.g
|
|
|
384
386
|
`:o}
|
|
385
387
|
</div>
|
|
386
388
|
`}renderButton(t){return e`
|
|
387
|
-
<div class="toast__button">
|
|
389
|
+
<div class="toast__button" part="button">
|
|
388
390
|
<nr-button
|
|
389
391
|
type=${t.type||"default"}
|
|
390
392
|
size=${t.size||"small"}
|
|
Binary file
|
|
@@ -69,6 +69,14 @@ declare const NrToastElement_base: (new (...args: any[]) => import("@nuralyui/co
|
|
|
69
69
|
* @cssproperty --nuraly-toast-error-background - Error toast background
|
|
70
70
|
* @cssproperty --nuraly-toast-warning-background - Warning toast background
|
|
71
71
|
* @cssproperty --nuraly-toast-info-background - Info toast background
|
|
72
|
+
*
|
|
73
|
+
* @csspart container - The root list wrapper holding all visible toasts
|
|
74
|
+
* @csspart toast - An individual toast element
|
|
75
|
+
* @csspart icon - The leading icon container (when an icon is set)
|
|
76
|
+
* @csspart content - The content area (text or custom html)
|
|
77
|
+
* @csspart text - The text node (when not using custom content)
|
|
78
|
+
* @csspart button - The action button wrapper (when a button is configured)
|
|
79
|
+
* @csspart close - The close (×) button (when closable)
|
|
72
80
|
*/
|
|
73
81
|
export declare class NrToastElement extends NrToastElement_base {
|
|
74
82
|
static useShadowDom: boolean;
|
|
@@ -80,6 +80,14 @@ import { DEFAULT_TOAST_DURATION, DEFAULT_MAX_TOASTS, EMPTY_STRING } from './toas
|
|
|
80
80
|
* @cssproperty --nuraly-toast-error-background - Error toast background
|
|
81
81
|
* @cssproperty --nuraly-toast-warning-background - Warning toast background
|
|
82
82
|
* @cssproperty --nuraly-toast-info-background - Info toast background
|
|
83
|
+
*
|
|
84
|
+
* @csspart container - The root list wrapper holding all visible toasts
|
|
85
|
+
* @csspart toast - An individual toast element
|
|
86
|
+
* @csspart icon - The leading icon container (when an icon is set)
|
|
87
|
+
* @csspart content - The content area (text or custom html)
|
|
88
|
+
* @csspart text - The text node (when not using custom content)
|
|
89
|
+
* @csspart button - The action button wrapper (when a button is configured)
|
|
90
|
+
* @csspart close - The close (×) button (when closable)
|
|
83
91
|
*/
|
|
84
92
|
let NrToastElement = class NrToastElement extends NuralyUIBaseMixin(LitElement) {
|
|
85
93
|
constructor() {
|
|
@@ -272,7 +280,7 @@ let NrToastElement = class NrToastElement extends NuralyUIBaseMixin(LitElement)
|
|
|
272
280
|
}
|
|
273
281
|
render() {
|
|
274
282
|
return html `
|
|
275
|
-
<div class="toast-container">
|
|
283
|
+
<div class="toast-container" part="container">
|
|
276
284
|
${repeat(this.toasts, toast => toast.id, toast => this.renderToast(toast))}
|
|
277
285
|
</div>
|
|
278
286
|
`;
|
|
@@ -287,28 +295,30 @@ let NrToastElement = class NrToastElement extends NuralyUIBaseMixin(LitElement)
|
|
|
287
295
|
return html `
|
|
288
296
|
<div
|
|
289
297
|
class=${classMap(classes)}
|
|
298
|
+
part="toast toast-${toast.type}"
|
|
290
299
|
@click=${() => this.handleToastClick(toast)}
|
|
291
300
|
role="alert"
|
|
292
301
|
aria-live="polite"
|
|
293
302
|
>
|
|
294
303
|
${toast.icon ? html `
|
|
295
|
-
<div class="toast__icon">
|
|
304
|
+
<div class="toast__icon" part="icon">
|
|
296
305
|
<nr-icon name=${toast.icon} size="medium"></nr-icon>
|
|
297
306
|
</div>
|
|
298
307
|
` : nothing}
|
|
299
|
-
|
|
300
|
-
<div class="toast__content">
|
|
308
|
+
|
|
309
|
+
<div class="toast__content" part="content">
|
|
301
310
|
${toast.content
|
|
302
311
|
? toast.content
|
|
303
312
|
: html `
|
|
304
|
-
<div class="toast__text">${toast.text}</div>
|
|
313
|
+
<div class="toast__text" part="text">${toast.text}</div>
|
|
305
314
|
${toast.button ? this.renderButton(toast.button) : nothing}
|
|
306
315
|
`}
|
|
307
316
|
</div>
|
|
308
|
-
|
|
317
|
+
|
|
309
318
|
${toast.closable ? html `
|
|
310
319
|
<button
|
|
311
320
|
class="toast__close"
|
|
321
|
+
part="close"
|
|
312
322
|
@click=${(e) => this.handleCloseClick(e, toast)}
|
|
313
323
|
aria-label="Close notification"
|
|
314
324
|
type="button"
|
|
@@ -325,7 +335,7 @@ let NrToastElement = class NrToastElement extends NuralyUIBaseMixin(LitElement)
|
|
|
325
335
|
button.onClick(e);
|
|
326
336
|
};
|
|
327
337
|
return html `
|
|
328
|
-
<div class="toast__button">
|
|
338
|
+
<div class="toast__button" part="button">
|
|
329
339
|
<nr-button
|
|
330
340
|
type=${button.type || 'default'}
|
|
331
341
|
size=${button.size || 'small'}
|