@nuraly/lumenui 0.3.4 → 0.3.6

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 (80) hide show
  1. package/dist/nuralyui.bundle.js +2581 -1483
  2. package/dist/nuralyui.bundle.js.gz +0 -0
  3. package/dist/src/components/button/bundle.js +130 -39
  4. package/dist/src/components/button/bundle.js.gz +0 -0
  5. package/dist/src/components/button/button.component.js +7 -4
  6. package/dist/src/components/button/button.style.js +92 -2
  7. package/dist/src/components/canvas/base-canvas.component.d.ts +8 -0
  8. package/dist/src/components/canvas/base-canvas.component.js +75 -3
  9. package/dist/src/components/canvas/bundle.js +2546 -1200
  10. package/dist/src/components/canvas/bundle.js.gz +0 -0
  11. package/dist/src/components/canvas/controllers/collaboration.controller.d.ts +24 -11
  12. package/dist/src/components/canvas/controllers/collaboration.controller.js +176 -120
  13. package/dist/src/components/canvas/controllers/selection.controller.js +20 -0
  14. package/dist/src/components/canvas/interfaces/collaboration.interface.d.ts +8 -0
  15. package/dist/src/components/canvas/templates/index.d.ts +1 -0
  16. package/dist/src/components/canvas/templates/index.js +2 -0
  17. package/dist/src/components/canvas/templates/lock-overlay.template.d.ts +20 -0
  18. package/dist/src/components/canvas/templates/lock-overlay.template.js +33 -0
  19. package/dist/src/components/canvas/workflow-canvas.component.js +52 -24
  20. package/dist/src/components/canvas/workflow-canvas.style.js +62 -1
  21. package/dist/src/components/canvas/workflow-canvas.types.js +50 -4
  22. package/dist/src/components/chat-panel/bundle.js +10 -10
  23. package/dist/src/components/chat-panel/bundle.js.gz +0 -0
  24. package/dist/src/components/chat-panel/chat-panel.component.js +8 -8
  25. package/dist/src/components/chatbot/bundle.js +454 -289
  26. package/dist/src/components/chatbot/bundle.js.gz +0 -0
  27. package/dist/src/components/chatbot/chatbot.style.js +162 -21
  28. package/dist/src/components/chatbot/chatbot.types.d.ts +1 -0
  29. package/dist/src/components/chatbot/core/chatbot-core.controller.js +13 -7
  30. package/dist/src/components/chatbot/providers/workflow-socket-provider.js +1 -2
  31. package/dist/src/components/chatbot/templates/input-box.template.js +58 -30
  32. package/dist/src/components/chatbot/templates/message.template.js +41 -31
  33. package/dist/src/components/chatbot/templates/thread-sidebar.template.js +38 -39
  34. package/dist/src/components/colorpicker/bundle.js +15 -10
  35. package/dist/src/components/colorpicker/bundle.js.gz +0 -0
  36. package/dist/src/components/colorpicker/color-picker.component.js +15 -10
  37. package/dist/src/components/datepicker/bundle.js +10 -10
  38. package/dist/src/components/datepicker/bundle.js.gz +0 -0
  39. package/dist/src/components/datepicker/datepicker.component.js +14 -22
  40. package/dist/src/components/dropdown/bundle.js +13 -12
  41. package/dist/src/components/dropdown/bundle.js.gz +0 -0
  42. package/dist/src/components/dropdown/dropdown.component.js +10 -9
  43. package/dist/src/components/file-upload/bundle.js +15 -14
  44. package/dist/src/components/file-upload/bundle.js.gz +0 -0
  45. package/dist/src/components/file-upload/file-upload.component.js +15 -14
  46. package/dist/src/components/icon/bundle.js +7 -7
  47. package/dist/src/components/icon/bundle.js.gz +0 -0
  48. package/dist/src/components/icon/icon-paths.js +15 -0
  49. package/dist/src/components/iconpicker/bundle.js +214 -122
  50. package/dist/src/components/iconpicker/bundle.js.gz +0 -0
  51. package/dist/src/components/iconpicker/icon-picker.component.js +4 -4
  52. package/dist/src/components/menu/bundle.js +5 -2
  53. package/dist/src/components/menu/bundle.js.gz +0 -0
  54. package/dist/src/components/menu/menu.component.js +5 -2
  55. package/dist/src/components/modal/bundle.js +16 -13
  56. package/dist/src/components/modal/bundle.js.gz +0 -0
  57. package/dist/src/components/modal/modal.component.js +16 -13
  58. package/dist/src/components/panel/bundle.js +28 -28
  59. package/dist/src/components/panel/bundle.js.gz +0 -0
  60. package/dist/src/components/popconfirm/bundle.js +135 -41
  61. package/dist/src/components/popconfirm/bundle.js.gz +0 -0
  62. package/dist/src/components/popconfirm/popconfirm.component.d.ts +15 -119
  63. package/dist/src/components/popconfirm/popconfirm.component.js +158 -162
  64. package/dist/src/components/popconfirm/popconfirm.style.js +94 -0
  65. package/dist/src/components/presence/bundle.js +2 -1
  66. package/dist/src/components/presence/bundle.js.gz +0 -0
  67. package/dist/src/components/presence/presence.component.js +2 -1
  68. package/dist/src/components/table/bundle.js +3 -2
  69. package/dist/src/components/table/bundle.js.gz +0 -0
  70. package/dist/src/components/table/table.component.js +3 -2
  71. package/dist/src/components/tabs/bundle.js +3 -3
  72. package/dist/src/components/tabs/bundle.js.gz +0 -0
  73. package/dist/src/components/timepicker/bundle.js +3 -3
  74. package/dist/src/components/timepicker/bundle.js.gz +0 -0
  75. package/package.json +1 -1
  76. package/packages/common/dist/VERSIONS.md +1 -1
  77. package/packages/common/dist/shared/controllers/dropdown.controller.d.ts +4 -0
  78. package/packages/common/dist/shared/controllers/dropdown.controller.d.ts.map +1 -1
  79. package/packages/common/dist/shared/controllers/dropdown.controller.js +29 -3
  80. package/packages/common/dist/shared/controllers/dropdown.controller.js.map +1 -1
@@ -18,52 +18,17 @@ 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 { html, LitElement } from 'lit';
21
+ import { html, LitElement, render, nothing } from 'lit';
22
22
  import { customElement, property, state } from 'lit/decorators.js';
23
+ import { classMap } from 'lit/directives/class-map.js';
23
24
  import { styles } from './popconfirm.style.js';
24
25
  import { NuralyUIBaseMixin } from '@nuralyui/common/mixins';
25
26
  /**
26
27
  * # Popconfirm Component
27
28
  *
28
- * A pop-up confirmation dialog triggered by user interaction. It provides a simple and
29
- * compact way to ask for user confirmation before performing an action.
30
- *
31
- * ## Features
32
- * - Customizable title and description
33
- * - Configurable OK and Cancel buttons
34
- * - Multiple placement options (12 positions)
35
- * - Custom icons with predefined options
36
- * - Async confirmation support
37
- * - Multiple trigger modes (click, hover, focus)
38
- * - Theme-aware styling
39
- * - Keyboard accessibility
40
- *
41
- * ## Usage
42
- * ```html
43
- * <!-- Basic popconfirm -->
44
- * <nr-popconfirm
45
- * title="Are you sure delete this task?"
46
- * ok-text="Yes"
47
- * cancel-text="No">
48
- * <button slot="trigger">Delete</button>
49
- * </nr-popconfirm>
50
- *
51
- * <!-- With description -->
52
- * <nr-popconfirm
53
- * title="Delete the task"
54
- * description="Are you sure you want to delete this task? This action cannot be undone."
55
- * ok-type="danger">
56
- * <button slot="trigger">Delete</button>
57
- * </nr-popconfirm>
58
- *
59
- * <!-- Custom icon -->
60
- * <nr-popconfirm
61
- * title="Change status?"
62
- * icon="question-circle"
63
- * icon-color="#1890ff">
64
- * <button slot="trigger">Change Status</button>
65
- * </nr-popconfirm>
66
- * ```
29
+ * A pop-up confirmation dialog triggered by user interaction. The panel is rendered
30
+ * into a body-level portal so it escapes ancestor stacking contexts and is not
31
+ * hidden when the trigger's ancestors are toggled with `display: none`.
67
32
  *
68
33
  * @element nr-popconfirm
69
34
  * @fires nr-confirm - Fired when user confirms the action
@@ -77,71 +42,26 @@ import { NuralyUIBaseMixin } from '@nuralyui/common/mixins';
77
42
  let NrPopconfirmElement = class NrPopconfirmElement extends NuralyUIBaseMixin(LitElement) {
78
43
  constructor() {
79
44
  super(...arguments);
80
- this.requiredComponents = ['nr-dropdown', 'nr-icon', 'nr-button', 'nr-label'];
81
- /**
82
- * Title of the confirmation box
83
- */
45
+ this.requiredComponents = ['nr-icon', 'nr-button', 'nr-label'];
84
46
  this.title = '';
85
- /**
86
- * Description of the confirmation box (optional)
87
- */
88
47
  this.description = '';
89
- /**
90
- * Text of the OK button
91
- */
92
48
  this.okText = 'OK';
93
- /**
94
- * Text of the Cancel button
95
- */
96
49
  this.cancelText = 'Cancel';
97
- /**
98
- * Button type of the OK button
99
- */
100
50
  this.okType = "primary" /* PopconfirmButtonType.Primary */;
101
- /**
102
- * Show cancel button
103
- */
104
51
  this.showCancel = true;
105
- /**
106
- * Icon name for the confirmation box
107
- */
108
52
  this.icon = "exclamation-circle" /* PopconfirmIcon.Warning */;
109
- /**
110
- * Custom icon color
111
- */
112
53
  this.iconColor = '';
113
- /**
114
- * Placement of the popconfirm
115
- */
116
54
  this.placement = "top" /* PopconfirmPlacement.Top */;
117
- /**
118
- * Trigger mode
119
- */
120
55
  this.trigger = "click" /* PopconfirmTrigger.Click */;
121
- /**
122
- * Whether the popconfirm is disabled
123
- */
124
56
  this.disabled = false;
125
- /**
126
- * Whether to show arrow
127
- */
128
57
  this.arrow = true;
129
- /**
130
- * Whether the popconfirm is open
131
- */
132
58
  this.open = false;
133
- /**
134
- * Loading state for OK button (for async operations)
135
- */
136
59
  this.okLoading = false;
137
- /**
138
- * Bound event handlers for cleanup
139
- */
60
+ this._portalHost = null;
61
+ this._portalRoot = null;
140
62
  this._boundHandleOutsideClick = null;
141
63
  this._boundHandleKeydown = null;
142
- /**
143
- * Handle trigger click to toggle popconfirm
144
- */
64
+ this._boundReposition = null;
145
65
  this.handleTriggerClick = (e) => {
146
66
  if (this.disabled)
147
67
  return;
@@ -153,9 +73,6 @@ let NrPopconfirmElement = class NrPopconfirmElement extends NuralyUIBaseMixin(Li
153
73
  this.openPopconfirm();
154
74
  }
155
75
  };
156
- /**
157
- * Handle confirm button click
158
- */
159
76
  this.handleConfirm = (e) => __awaiter(this, void 0, void 0, function* () {
160
77
  e.stopPropagation();
161
78
  const confirmEvent = new CustomEvent('nr-confirm', {
@@ -165,9 +82,7 @@ let NrPopconfirmElement = class NrPopconfirmElement extends NuralyUIBaseMixin(Li
165
82
  detail: { originalEvent: e },
166
83
  });
167
84
  const dispatched = this.dispatchEvent(confirmEvent);
168
- // If event is not prevented, close the popconfirm
169
85
  if (dispatched && !confirmEvent.defaultPrevented) {
170
- // Check if the event handler returns a promise
171
86
  const handler = this.onConfirm;
172
87
  if (handler && typeof handler === 'function') {
173
88
  const result = handler(e);
@@ -189,9 +104,6 @@ let NrPopconfirmElement = class NrPopconfirmElement extends NuralyUIBaseMixin(Li
189
104
  this.closePopconfirm();
190
105
  }
191
106
  });
192
- /**
193
- * Handle cancel button click
194
- */
195
107
  this.handleCancel = (e) => {
196
108
  e.stopPropagation();
197
109
  this.dispatchEvent(new CustomEvent('nr-cancel', {
@@ -202,17 +114,11 @@ let NrPopconfirmElement = class NrPopconfirmElement extends NuralyUIBaseMixin(Li
202
114
  this.closePopconfirm();
203
115
  };
204
116
  }
205
- /**
206
- * Reference to the dropdown element
207
- */
208
- get dropdownElement() {
209
- var _a;
210
- return (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('nr-dropdown');
211
- }
212
117
  connectedCallback() {
213
118
  super.connectedCallback();
214
119
  this._boundHandleOutsideClick = this.handleOutsideClick.bind(this);
215
120
  this._boundHandleKeydown = this.handleKeydown.bind(this);
121
+ this._boundReposition = () => this.reposition();
216
122
  document.addEventListener('click', this._boundHandleOutsideClick, true);
217
123
  document.addEventListener('keydown', this._boundHandleKeydown);
218
124
  }
@@ -224,67 +130,171 @@ let NrPopconfirmElement = class NrPopconfirmElement extends NuralyUIBaseMixin(Li
224
130
  if (this._boundHandleKeydown) {
225
131
  document.removeEventListener('keydown', this._boundHandleKeydown);
226
132
  }
133
+ this._detachViewportListeners();
134
+ this._teardownPortal();
135
+ }
136
+ updated(changed) {
137
+ super.updated(changed);
138
+ if (changed.has('open')) {
139
+ if (this.open) {
140
+ this._attachViewportListeners();
141
+ }
142
+ else {
143
+ this._detachViewportListeners();
144
+ }
145
+ }
146
+ this._renderPortal();
147
+ }
148
+ _ensurePortal() {
149
+ if (this._portalRoot)
150
+ return this._portalRoot;
151
+ const host = document.createElement('div');
152
+ host.setAttribute('data-nr-popconfirm-portal', '');
153
+ host.style.position = 'fixed';
154
+ host.style.top = '0';
155
+ host.style.left = '0';
156
+ host.style.width = '0';
157
+ host.style.height = '0';
158
+ host.style.zIndex = '2147483000';
159
+ document.body.appendChild(host);
160
+ this._portalHost = host;
161
+ this._portalRoot = host.attachShadow({ mode: 'open' });
162
+ return this._portalRoot;
163
+ }
164
+ _teardownPortal() {
165
+ if (this._portalRoot) {
166
+ render(nothing, this._portalRoot);
167
+ }
168
+ if (this._portalHost && this._portalHost.parentNode) {
169
+ this._portalHost.parentNode.removeChild(this._portalHost);
170
+ }
171
+ this._portalHost = null;
172
+ this._portalRoot = null;
173
+ }
174
+ _attachViewportListeners() {
175
+ if (!this._boundReposition)
176
+ return;
177
+ window.addEventListener('scroll', this._boundReposition, true);
178
+ window.addEventListener('resize', this._boundReposition);
179
+ }
180
+ _detachViewportListeners() {
181
+ if (!this._boundReposition)
182
+ return;
183
+ window.removeEventListener('scroll', this._boundReposition, true);
184
+ window.removeEventListener('resize', this._boundReposition);
185
+ }
186
+ _renderPortal() {
187
+ if (!this.open) {
188
+ if (this._portalRoot) {
189
+ render(nothing, this._portalRoot);
190
+ }
191
+ return;
192
+ }
193
+ const root = this._ensurePortal();
194
+ render(this._renderPortalTemplate(), root);
195
+ requestAnimationFrame(() => this.reposition());
196
+ }
197
+ _renderPortalTemplate() {
198
+ const placementClass = `popconfirm-panel--${this.placement}`;
199
+ return html `
200
+ <style>${styles.cssText}</style>
201
+ <div
202
+ class="popconfirm-panel ${classMap({ [placementClass]: true, 'popconfirm-panel--with-arrow': this.arrow })}"
203
+ part="panel"
204
+ role="dialog"
205
+ @click=${(e) => e.stopPropagation()}>
206
+ ${this.arrow ? html `<div class="popconfirm-arrow" part="arrow"></div>` : nothing}
207
+ ${this.renderContent()}
208
+ </div>
209
+ `;
210
+ }
211
+ reposition() {
212
+ if (!this.open || !this._portalRoot)
213
+ return;
214
+ const panel = this._portalRoot.querySelector('.popconfirm-panel');
215
+ if (!panel)
216
+ return;
217
+ const triggerRect = this.getBoundingClientRect();
218
+ const panelRect = panel.getBoundingClientRect();
219
+ const offset = 8;
220
+ const placement = this.placement || "top" /* PopconfirmPlacement.Top */;
221
+ let top = 0;
222
+ let left = 0;
223
+ if (placement.startsWith('top')) {
224
+ top = triggerRect.top - panelRect.height - offset;
225
+ }
226
+ else if (placement.startsWith('bottom')) {
227
+ top = triggerRect.bottom + offset;
228
+ }
229
+ else if (placement.startsWith('left')) {
230
+ left = triggerRect.left - panelRect.width - offset;
231
+ }
232
+ else if (placement.startsWith('right')) {
233
+ left = triggerRect.right + offset;
234
+ }
235
+ if (placement === "top" /* PopconfirmPlacement.Top */ || placement === "bottom" /* PopconfirmPlacement.Bottom */) {
236
+ left = triggerRect.left + (triggerRect.width - panelRect.width) / 2;
237
+ }
238
+ else if (placement === "left" /* PopconfirmPlacement.Left */ || placement === "right" /* PopconfirmPlacement.Right */) {
239
+ top = triggerRect.top + (triggerRect.height - panelRect.height) / 2;
240
+ }
241
+ else if (placement.endsWith('-start')) {
242
+ if (placement.startsWith('top') || placement.startsWith('bottom')) {
243
+ left = triggerRect.left;
244
+ }
245
+ else {
246
+ top = triggerRect.top;
247
+ }
248
+ }
249
+ else if (placement.endsWith('-end')) {
250
+ if (placement.startsWith('top') || placement.startsWith('bottom')) {
251
+ left = triggerRect.right - panelRect.width;
252
+ }
253
+ else {
254
+ top = triggerRect.bottom - panelRect.height;
255
+ }
256
+ }
257
+ const vw = window.innerWidth;
258
+ const vh = window.innerHeight;
259
+ left = Math.max(8, Math.min(left, vw - panelRect.width - 8));
260
+ top = Math.max(8, Math.min(top, vh - panelRect.height - 8));
261
+ panel.style.top = `${top}px`;
262
+ panel.style.left = `${left}px`;
227
263
  }
228
- /**
229
- * Open the popconfirm
230
- */
231
264
  openPopconfirm() {
232
265
  this.open = true;
233
- if (this.dropdownElement) {
234
- this.dropdownElement.show();
235
- }
236
266
  this.dispatchEvent(new CustomEvent('nr-open-change', {
237
267
  bubbles: true,
238
268
  composed: true,
239
269
  detail: { open: true },
240
270
  }));
241
271
  }
242
- /**
243
- * Handle clicks outside the popconfirm to close it
244
- */
272
+ closePopconfirm() {
273
+ this.open = false;
274
+ this.dispatchEvent(new CustomEvent('nr-open-change', {
275
+ bubbles: true,
276
+ composed: true,
277
+ detail: { open: false },
278
+ }));
279
+ }
245
280
  handleOutsideClick(e) {
246
281
  if (!this.open)
247
282
  return;
248
283
  const path = e.composedPath();
249
- if (!path.includes(this)) {
250
- this.closePopconfirm();
251
- }
284
+ if (path.includes(this))
285
+ return;
286
+ if (this._portalHost && path.includes(this._portalHost))
287
+ return;
288
+ this.closePopconfirm();
252
289
  }
253
- /**
254
- * Handle escape key to close popconfirm
255
- */
256
290
  handleKeydown(e) {
257
291
  if (e.key === 'Escape' && this.open) {
258
292
  this.closePopconfirm();
259
293
  }
260
294
  }
261
- /**
262
- * Close the popconfirm
263
- */
264
- closePopconfirm() {
265
- this.open = false;
266
- if (this.dropdownElement) {
267
- this.dropdownElement.hide();
268
- }
269
- this.dispatchEvent(new CustomEvent('nr-open-change', {
270
- bubbles: true,
271
- composed: true,
272
- detail: { open: false },
273
- }));
274
- }
275
- /**
276
- * Get icon color based on icon type
277
- */
278
295
  getIconColor() {
279
- if (this.iconColor) {
280
- return this.iconColor;
281
- }
282
- // Return empty string to use CSS class colors
283
- return '';
296
+ return this.iconColor || '';
284
297
  }
285
- /**
286
- * Get icon class based on icon type
287
- */
288
298
  getIconClass() {
289
299
  const iconColorMap = {
290
300
  ["exclamation-circle" /* PopconfirmIcon.Warning */]: 'warning',
@@ -293,14 +303,10 @@ let NrPopconfirmElement = class NrPopconfirmElement extends NuralyUIBaseMixin(Li
293
303
  ["close-circle" /* PopconfirmIcon.Error */]: 'error',
294
304
  ["check-circle" /* PopconfirmIcon.Success */]: 'success',
295
305
  };
296
- if (this.iconColor) {
306
+ if (this.iconColor)
297
307
  return 'custom';
298
- }
299
308
  return iconColorMap[this.icon] || 'warning';
300
309
  }
301
- /**
302
- * Render the popconfirm content
303
- */
304
310
  renderContent() {
305
311
  const iconClass = this.getIconClass();
306
312
  const iconColor = this.getIconColor();
@@ -346,19 +352,9 @@ let NrPopconfirmElement = class NrPopconfirmElement extends NuralyUIBaseMixin(Li
346
352
  }
347
353
  render() {
348
354
  return html `
349
- <nr-dropdown
350
- .open=${this.open}
351
- .placement=${this.placement}
352
- trigger="manual"
353
- ?disabled=${this.disabled}
354
- ?arrow=${this.arrow}
355
- .closeOnOutsideClick=${false}
356
- .closeOnEscape=${false}>
357
- <div slot="trigger" part="trigger" @click=${this.handleTriggerClick}>
358
- <slot name="trigger"></slot>
359
- </div>
360
- <div slot="content">${this.renderContent()}</div>
361
- </nr-dropdown>
355
+ <div class="popconfirm-trigger" part="trigger" @click=${this.handleTriggerClick}>
356
+ <slot name="trigger"></slot>
357
+ </div>
362
358
  `;
363
359
  }
364
360
  };
@@ -4,6 +4,100 @@ export const styles = css `
4
4
  display: inline-block;
5
5
  }
6
6
 
7
+ .popconfirm-trigger {
8
+ display: inline-block;
9
+ cursor: pointer;
10
+ }
11
+
12
+ .popconfirm-panel {
13
+ position: fixed;
14
+ top: 0;
15
+ left: 0;
16
+ z-index: 2147483000;
17
+ background: #ffffff;
18
+ border: 1px solid #e0e0e0;
19
+ border-radius: 6px;
20
+ box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
21
+ box-sizing: border-box;
22
+ min-width: 200px;
23
+ max-width: 400px;
24
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
25
+ }
26
+
27
+ .popconfirm-arrow {
28
+ position: absolute;
29
+ width: 8px;
30
+ height: 8px;
31
+ background: #ffffff;
32
+ border: 1px solid #e0e0e0;
33
+ transform: rotate(45deg);
34
+ pointer-events: none;
35
+ }
36
+
37
+ .popconfirm-panel--top .popconfirm-arrow,
38
+ .popconfirm-panel--top-start .popconfirm-arrow,
39
+ .popconfirm-panel--top-end .popconfirm-arrow {
40
+ bottom: -5px;
41
+ border-top: none;
42
+ border-left: none;
43
+ }
44
+
45
+ .popconfirm-panel--bottom .popconfirm-arrow,
46
+ .popconfirm-panel--bottom-start .popconfirm-arrow,
47
+ .popconfirm-panel--bottom-end .popconfirm-arrow {
48
+ top: -5px;
49
+ border-bottom: none;
50
+ border-right: none;
51
+ }
52
+
53
+ .popconfirm-panel--left .popconfirm-arrow,
54
+ .popconfirm-panel--left-start .popconfirm-arrow,
55
+ .popconfirm-panel--left-end .popconfirm-arrow {
56
+ right: -5px;
57
+ border-bottom: none;
58
+ border-left: none;
59
+ }
60
+
61
+ .popconfirm-panel--right .popconfirm-arrow,
62
+ .popconfirm-panel--right-start .popconfirm-arrow,
63
+ .popconfirm-panel--right-end .popconfirm-arrow {
64
+ left: -5px;
65
+ border-top: none;
66
+ border-right: none;
67
+ }
68
+
69
+ .popconfirm-panel--top .popconfirm-arrow,
70
+ .popconfirm-panel--bottom .popconfirm-arrow {
71
+ left: 50%;
72
+ margin-left: -4px;
73
+ }
74
+
75
+ .popconfirm-panel--top-start .popconfirm-arrow,
76
+ .popconfirm-panel--bottom-start .popconfirm-arrow {
77
+ left: 12px;
78
+ }
79
+
80
+ .popconfirm-panel--top-end .popconfirm-arrow,
81
+ .popconfirm-panel--bottom-end .popconfirm-arrow {
82
+ right: 12px;
83
+ }
84
+
85
+ .popconfirm-panel--left .popconfirm-arrow,
86
+ .popconfirm-panel--right .popconfirm-arrow {
87
+ top: 50%;
88
+ margin-top: -4px;
89
+ }
90
+
91
+ .popconfirm-panel--left-start .popconfirm-arrow,
92
+ .popconfirm-panel--right-start .popconfirm-arrow {
93
+ top: 12px;
94
+ }
95
+
96
+ .popconfirm-panel--left-end .popconfirm-arrow,
97
+ .popconfirm-panel--right-end .popconfirm-arrow {
98
+ bottom: 12px;
99
+ }
100
+
7
101
  .popconfirm-content {
8
102
  display: flex;
9
103
  flex-direction: column;
@@ -507,11 +507,12 @@ const y=t`
507
507
  var $=function(t,e,i,s){for(var n,r=arguments.length,o=r<3?e:null===s?s=Object.getOwnPropertyDescriptor(e,i):s,a=t.length-1;a>=0;a--)(n=t[a])&&(o=(r<3?n(o):r>3?n(e,i,o):n(e,i))||o);return r>3&&o&&Object.defineProperty(e,i,o),o},z=function(t,e,i,s){return new(i||(i=Promise))(function(n,r){function o(t){try{c(s.next(t))}catch(t){r(t)}}function a(t){try{c(s.throw(t))}catch(t){r(t)}}function c(t){var e;t.done?n(t.value):(e=t.value,e instanceof i?e:new i(function(t){t(e)})).then(o,a)}c((s=s.apply(t,e||[])).next())})};const S="__group__";let C=class extends(v(s)){constructor(){super(...arguments),this.namespace="",this.socketPath="/__nk_socketio/",this.resourceId="",this.resourceType="",this.resourceName="",this.userId="",this.currentUser=null,this.extraUsers=[],this.globalSocket=null,this._viewers=[],this._hasUnreadGroup=!1,this._socket=null,this._connecting=!1,this._chats=new Map,this._chatZ=100,this._drag=null,this._boundDragMove=t=>this._onDragMove(t),this._boundDragEnd=()=>this._onDragEnd(),this._boundEscape=t=>this._onEscape(t),this._boundOnMessage=t=>this._onSocketMessage(t),this._groupConversationId=null}connectedCallback(){super.connectedCallback(),document.addEventListener("keydown",this._boundEscape),this._connect(),this._attachGlobalSocket()}disconnectedCallback(){var t;super.disconnectedCallback(),document.removeEventListener("keydown",this._boundEscape),document.removeEventListener("mousemove",this._boundDragMove),document.removeEventListener("mouseup",this._boundDragEnd),null===(t=this._socket)||void 0===t||t.disconnect(),this._socket=null,this._detachGlobalSocket()}updated(t){t.has("globalSocket")&&(this._detachGlobalSocket(t.get("globalSocket")),this._attachGlobalSocket()),!this._socket&&(t.has("userId")||t.has("resourceId")||t.has("namespace"))&&this.userId&&this.resourceId&&this.namespace&&this._connect()}_attachGlobalSocket(){this.globalSocket&&this.globalSocket.on("nk:data",this._boundOnMessage)}_detachGlobalSocket(t){const e=t||this.globalSocket;e&&e.off("nk:data",this._boundOnMessage)}_onSocketMessage(t){if("message:new"!==t.event)return;const e=t.data;if((null==e?void 0:e.conversationId)&&e.senderId!==this.userId){for(const[,t]of this._chats)if(t.conversationId===e.conversationId)return t.messages=[...t.messages,{id:String(e.id),senderId:e.senderId,text:e.content,timestamp:new Date(e.createdAt).getTime(),me:!1}],void this.requestUpdate();this._groupConversationId&&e.conversationId===this._groupConversationId&&(this._hasUnreadGroup=!0)}}_connect(){return z(this,void 0,void 0,function*(){if(!this._socket&&!this._connecting&&this.userId&&this.resourceId&&this.namespace){this._connecting=!0;try{const{io:t}=yield import("socket.io-client");this._socket=t(this.namespace,{path:this.socketPath,query:{i:JSON.stringify({userId:this.userId,resourceId:this.resourceId})}}),this._socket.on("nk:data",t=>{var e;const i=t.event;"presence:viewers"!==i&&"presence:joined"!==i&&"presence:left"!==i||(this._viewers=(null===(e=t.data)||void 0===e?void 0:e.viewers)||[],this.dispatchEvent(new CustomEvent("presence-changed",{detail:{viewers:this._viewers},bubbles:!0,composed:!0})))})}catch(t){console.error("[nr-presence] Connection failed:",t)}finally{this._connecting=!1}}})}_openGroupChat(){return z(this,void 0,void 0,function*(){var t;if(this._chats.has(S)){const t=this._chats.get(S);return t.minimized=!1,t.z=++this._chatZ,this._hasUnreadGroup=!1,void this.requestUpdate()}const e=window.innerWidth-324;this._chats.set(S,{user:{displayName:this.resourceName||`${this.resourceType} chat`,color:"#7c3aed",initials:"#"},conversationId:null,loading:!0,x:e,y:56,savedX:e,savedY:56,z:++this._chatZ,minimized:!1,messages:[],draftText:""}),this._hasUnreadGroup=!1,this.requestUpdate();try{const e=yield fetch("/api/conversations/resource",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({resourceType:this.resourceType,resourceId:this.resourceId,resourceName:this.resourceName})}),i=yield e.json(),s=this._chats.get(S);if(!s||!i.conversationId)return s&&(s.loading=!1),void this.requestUpdate();s.conversationId=i.conversationId,this._groupConversationId=i.conversationId,(null===(t=this.globalSocket)||void 0===t?void 0:t.connected)&&this.globalSocket.emit("nk:conversation:join",{conversationId:i.conversationId}),yield this._loadMessages(s)}catch(t){console.error("[nr-presence] Failed to open group chat:",t);const e=this._chats.get(S);e&&(e.loading=!1)}this.requestUpdate()})}_openDm(t){return z(this,void 0,void 0,function*(){var e;const i=t.userId||t.displayName;if(i===this.userId)return void this._openGroupChat();if(this._chats.has(i))return this._chats.get(i).z=++this._chatZ,void this.requestUpdate();const s=[...this._chats.keys()].filter(t=>t!==S).length,n=window.innerWidth-324-24*(s+1),r=56+24*(s+1);if(this._chats.set(i,{user:t,conversationId:null,loading:!0,x:n,y:r,savedX:n,savedY:r,z:++this._chatZ,minimized:!1,messages:[],draftText:""}),this.requestUpdate(),t.userId){try{const s=yield fetch("/api/conversations/dm",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({targetUserId:t.userId})}),n=yield s.json(),r=this._chats.get(i);if(!r||!n.conversationId)return r&&(r.loading=!1),void this.requestUpdate();r.conversationId=n.conversationId,(null===(e=this.globalSocket)||void 0===e?void 0:e.connected)&&this.globalSocket.emit("nk:conversation:join",{conversationId:n.conversationId}),yield this._loadMessages(r)}catch(t){console.error("[nr-presence] Failed to open DM:",t);const e=this._chats.get(i);e&&(e.loading=!1)}this.requestUpdate()}})}_loadMessages(t){return z(this,void 0,void 0,function*(){var e;if(t.conversationId){try{const i=yield fetch(`/api/conversations/${t.conversationId}/messages`),s=yield i.json();(null===(e=s.messages)||void 0===e?void 0:e.length)&&(t.messages=s.messages.map(t=>({id:String(t.id),senderId:t.sender_id,text:t.content,timestamp:new Date(t.created_at).getTime(),me:t.sender_id===this.userId})))}catch(t){console.error("[nr-presence] Failed to load messages:",t)}t.loading=!1}})}_sendMessage(t,e){var i;const s=this._chats.get(t);(null==s?void 0:s.conversationId)&&(s.messages=[...s.messages,{id:crypto.randomUUID(),senderId:this.userId,text:e,timestamp:Date.now(),me:!0}],this.requestUpdate(),(null===(i=this.globalSocket)||void 0===i?void 0:i.connected)&&this.globalSocket.emit("nk:message:send",{conversationId:s.conversationId,content:e,type:"text"}))}_closeChat(t){this._chats.delete(t),this.requestUpdate()}_onEscape(t){if("Escape"!==t.key||0===this._chats.size)return;let e="",i=-1;for(const[t,s]of this._chats)s.z>i&&(i=s.z,e=t);if(!e)return;const s=this._chats.get(e);s.minimized?this._closeChat(e):(s.savedX=s.x,s.savedY=s.y,s.minimized=!0,this.requestUpdate())}_onDragStart(t,e,i){const s=this._chats.get(t);s&&(s.z=++this._chatZ,this._drag={userId:t,ox:e,oy:i},document.addEventListener("mousemove",this._boundDragMove),document.addEventListener("mouseup",this._boundDragEnd))}_onDragMove(t){if(!this._drag)return;const e=this._chats.get(this._drag.userId);e&&(e.x=Math.max(0,Math.min(window.innerWidth-300,t.clientX-this._drag.ox)),e.y=Math.max(0,Math.min(window.innerHeight-60,t.clientY-this._drag.oy)),this.requestUpdate())}_onDragEnd(){this._drag=null,document.removeEventListener("mousemove",this._boundDragMove),document.removeEventListener("mouseup",this._boundDragEnd)}render(){const t=this.currentUser,s=[...t?[t]:[],...this._viewers.filter(e=>!t||e.userId!==t.userId),...this.extraUsers],n=[...this._chats.entries()].filter(([,t])=>t.minimized);return e`
508
508
  <nr-presence-avatars
509
509
  .users=${s}
510
+ part="avatars"
510
511
  @user-click=${t=>this._openDm(t.detail.user)}
511
512
  ></nr-presence-avatars>
512
513
 
513
514
  ${this.resourceType?e`
514
- <button class="group-chat-btn" title="Team chat" @click=${()=>this._openGroupChat()}>
515
+ <button class="group-chat-btn" part="group-chat-button" title="Team chat" @click=${()=>this._openGroupChat()}>
515
516
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
516
517
  <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
517
518
  </svg>
@@ -411,11 +411,12 @@ let NrPresenceElement = class NrPresenceElement extends NuralyUIBaseMixin(LitEle
411
411
  return html `
412
412
  <nr-presence-avatars
413
413
  .users=${allUsers}
414
+ part="avatars"
414
415
  @user-click=${(e) => this._openDm(e.detail.user)}
415
416
  ></nr-presence-avatars>
416
417
 
417
418
  ${this.resourceType ? html `
418
- <button class="group-chat-btn" title="Team chat" @click=${() => this._openGroupChat()}>
419
+ <button class="group-chat-btn" part="group-chat-button" title="Team chat" @click=${() => this._openGroupChat()}>
419
420
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
420
421
  <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
422
  </svg>
@@ -939,7 +939,7 @@ var E=function(t,e,i,n){for(var o,s=arguments.length,r=s<3?e:null===n?n=Object.g
939
939
  <button @click=${d.onCancelSelection}>Cancel</button>
940
940
  </div>
941
941
  `):this.withFilter?e`
942
- <div class="filter-container">
942
+ <div class="filter-container" part="filter">
943
943
  ${function(t){return e`
944
944
  <div class="filter-container">
945
945
  ${t.showInput?e`
@@ -960,7 +960,8 @@ var E=function(t,e,i,n){for(var o,s=arguments.length,r=s<3?e:null===n?n=Object.g
960
960
  </div>
961
961
  `:i}
962
962
 
963
- <div class="table-content-wrapper ${this.fixedHeader?"fixed-header":""}"
963
+ <div class="table-content-wrapper ${this.fixedHeader?"fixed-header":""}"
964
+ part="wrapper"
964
965
  style="${(null===(t=this.scrollConfig)||void 0===t?void 0:t.y)?`${this.fixedHeader?"height":"max-height"}: ${"number"==typeof this.scrollConfig.y?this.scrollConfig.y+"px":this.scrollConfig.y};`:""}
965
966
  ${(null===(n=this.scrollConfig)||void 0===n?void 0:n.x)?`${this.fixedHeader?"width":"max-width"}: ${"number"==typeof this.scrollConfig.x?this.scrollConfig.x+"px":this.scrollConfig.x};`:""}">
966
967
  ${P({headers:this.headers,rows:this.displayedRows,expandable:this.expandable&&!this.selectionMode?this.expandable:void 0,expansionRenderer:this.selectionMode?void 0:this.expansionRenderer,selectionMode:this.selectionMode&&!this.withFilter?this.selectionMode:void 0,selectedItems:this.selectedItems,currentPage:this.currentPage,itemPerPage:this.selectedItemPerPage,sortAttribute:this.sortAttribute,expand:this.expand,columnFilters:this.columnFilters,activeFilterColumn:this.activeFilterColumn,loading:this.loading,host:this,clickable:this.clickable,onCheckAll:()=>{const t=(this.currentPage-1)*this.selectedItemPerPage,e=Math.min(t+this.selectedItemPerPage,this.selectedItems.length),i=this.selectedItems.slice(t,e),n=i.every(t=>t)&&i.length>0;this._handleCheckAll({detail:{isEveryItemChecked:n}})},onCheckOne:(t,e)=>this._handleCheckOne({detail:{index:e,value:t.detail.checked}}),onSelectOne:t=>this._handleSelectOne({detail:{index:t}}),onUpdateSort:t=>this._handleSortOrder({detail:{index:t}}),onShowExpandedContent:t=>this._showExpandedContent(t),onToggleColumnFilter:t=>this.filterController.toggleColumnFilterDropdown(t),onApplyColumnFilter:(t,e)=>this.filterController.applyColumnFilter(t,e),onClearColumnFilter:t=>this.filterController.clearColumnFilter(t),onRowClick:(t,e)=>{this.clickable&&this.dispatchEvent(new CustomEvent("nr-row-click",{detail:{row:t,index:e},bubbles:!0,composed:!0}))}})}
@@ -255,7 +255,7 @@ let HyTable = class HyTable extends NuralyUIBaseMixin(LitElement) {
255
255
  })
256
256
  : this.withFilter
257
257
  ? html `
258
- <div class="filter-container">
258
+ <div class="filter-container" part="filter">
259
259
  ${renderFilterTemplate({
260
260
  showInput: this.showFilterInput,
261
261
  value: this.filterValue,
@@ -266,7 +266,8 @@ let HyTable = class HyTable extends NuralyUIBaseMixin(LitElement) {
266
266
  `
267
267
  : nothing}
268
268
 
269
- <div class="table-content-wrapper ${this.fixedHeader ? 'fixed-header' : ''}"
269
+ <div class="table-content-wrapper ${this.fixedHeader ? 'fixed-header' : ''}"
270
+ part="wrapper"
270
271
  style="${((_a = this.scrollConfig) === null || _a === void 0 ? void 0 : _a.y) ? `${this.fixedHeader ? 'height' : 'max-height'}: ${typeof this.scrollConfig.y === 'number' ? this.scrollConfig.y + 'px' : this.scrollConfig.y};` : ''}
271
272
  ${((_b = this.scrollConfig) === null || _b === void 0 ? void 0 : _b.x) ? `${this.fixedHeader ? 'width' : 'max-width'}: ${typeof this.scrollConfig.x === 'number' ? this.scrollConfig.x + 'px' : this.scrollConfig.x};` : ''}">
272
273
  ${renderContentTemplate({