@ship-ui/core 0.22.15 → 0.22.17

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 (69) hide show
  1. package/assets/mcp/components.json +213 -47
  2. package/bin/src/subset.ts +6 -6
  3. package/bin/src/utilities.ts +14 -14
  4. package/fesm2022/ship-ui-core-ship-a11y-keybindings.mjs +12 -86
  5. package/fesm2022/ship-ui-core-ship-a11y-keybindings.mjs.map +1 -1
  6. package/fesm2022/ship-ui-core-ship-accordion.mjs +4 -3
  7. package/fesm2022/ship-ui-core-ship-accordion.mjs.map +1 -1
  8. package/fesm2022/ship-ui-core-ship-alert.mjs +1 -4
  9. package/fesm2022/ship-ui-core-ship-alert.mjs.map +1 -1
  10. package/fesm2022/ship-ui-core-ship-blueprint.mjs +17 -11
  11. package/fesm2022/ship-ui-core-ship-blueprint.mjs.map +1 -1
  12. package/fesm2022/ship-ui-core-ship-checkbox.mjs +3 -2
  13. package/fesm2022/ship-ui-core-ship-checkbox.mjs.map +1 -1
  14. package/fesm2022/ship-ui-core-ship-color-picker.mjs +66 -62
  15. package/fesm2022/ship-ui-core-ship-color-picker.mjs.map +1 -1
  16. package/fesm2022/ship-ui-core-ship-datepicker.mjs +24 -16
  17. package/fesm2022/ship-ui-core-ship-datepicker.mjs.map +1 -1
  18. package/fesm2022/ship-ui-core-ship-dialog.mjs +4 -0
  19. package/fesm2022/ship-ui-core-ship-dialog.mjs.map +1 -1
  20. package/fesm2022/ship-ui-core-ship-editor.mjs +0 -42
  21. package/fesm2022/ship-ui-core-ship-editor.mjs.map +1 -1
  22. package/fesm2022/ship-ui-core-ship-form-field.mjs +0 -1
  23. package/fesm2022/ship-ui-core-ship-form-field.mjs.map +1 -1
  24. package/fesm2022/ship-ui-core-ship-kbd.mjs +0 -6
  25. package/fesm2022/ship-ui-core-ship-kbd.mjs.map +1 -1
  26. package/fesm2022/ship-ui-core-ship-list-item-swipe.mjs +241 -0
  27. package/fesm2022/ship-ui-core-ship-list-item-swipe.mjs.map +1 -0
  28. package/fesm2022/ship-ui-core-ship-menu.mjs +7 -10
  29. package/fesm2022/ship-ui-core-ship-menu.mjs.map +1 -1
  30. package/fesm2022/ship-ui-core-ship-popover.mjs +5 -20
  31. package/fesm2022/ship-ui-core-ship-popover.mjs.map +1 -1
  32. package/fesm2022/ship-ui-core-ship-radio.mjs +3 -2
  33. package/fesm2022/ship-ui-core-ship-radio.mjs.map +1 -1
  34. package/fesm2022/ship-ui-core-ship-range-slider.mjs +7 -9
  35. package/fesm2022/ship-ui-core-ship-range-slider.mjs.map +1 -1
  36. package/fesm2022/ship-ui-core-ship-select.mjs.map +1 -1
  37. package/fesm2022/ship-ui-core-ship-sidenav.mjs +2 -2
  38. package/fesm2022/ship-ui-core-ship-sidenav.mjs.map +1 -1
  39. package/fesm2022/ship-ui-core-ship-sortable.mjs +262 -68
  40. package/fesm2022/ship-ui-core-ship-sortable.mjs.map +1 -1
  41. package/fesm2022/ship-ui-core-ship-spotlight.mjs +0 -11
  42. package/fesm2022/ship-ui-core-ship-spotlight.mjs.map +1 -1
  43. package/fesm2022/ship-ui-core-ship-stepper.mjs +1 -1
  44. package/fesm2022/ship-ui-core-ship-stepper.mjs.map +1 -1
  45. package/fesm2022/ship-ui-core-ship-table.mjs +426 -23
  46. package/fesm2022/ship-ui-core-ship-table.mjs.map +1 -1
  47. package/fesm2022/ship-ui-core-ship-toggle.mjs +3 -2
  48. package/fesm2022/ship-ui-core-ship-toggle.mjs.map +1 -1
  49. package/fesm2022/ship-ui-core-ship-tree.mjs +1 -9
  50. package/fesm2022/ship-ui-core-ship-tree.mjs.map +1 -1
  51. package/fesm2022/ship-ui-core.mjs +37 -53
  52. package/fesm2022/ship-ui-core.mjs.map +1 -1
  53. package/package.json +5 -1
  54. package/types/ship-ui-core-ship-a11y-keybindings.d.ts +0 -55
  55. package/types/ship-ui-core-ship-accordion.d.ts +7 -7
  56. package/types/ship-ui-core-ship-blueprint.d.ts +2 -1
  57. package/types/ship-ui-core-ship-checkbox.d.ts +2 -3
  58. package/types/ship-ui-core-ship-color-picker.d.ts +1 -25
  59. package/types/ship-ui-core-ship-datepicker.d.ts +2 -3
  60. package/types/ship-ui-core-ship-editor.d.ts +10 -10
  61. package/types/ship-ui-core-ship-list-item-swipe.d.ts +25 -0
  62. package/types/ship-ui-core-ship-menu.d.ts +1 -2
  63. package/types/ship-ui-core-ship-radio.d.ts +2 -3
  64. package/types/ship-ui-core-ship-range-slider.d.ts +6 -6
  65. package/types/ship-ui-core-ship-sortable.d.ts +31 -9
  66. package/types/ship-ui-core-ship-table.d.ts +12 -1
  67. package/types/ship-ui-core-ship-toggle.d.ts +2 -3
  68. package/types/ship-ui-core-ship-tree.d.ts +20 -25
  69. package/types/ship-ui-core.d.ts +17 -24
@@ -7,7 +7,6 @@ import { ShipIcon } from '@ship-ui/core/ship-icon';
7
7
  import { ShipMenu } from '@ship-ui/core/ship-menu';
8
8
  import { ShipA11yKeybindingsService } from '@ship-ui/core/ship-a11y-keybindings';
9
9
 
10
- // Value Accessor Provider
11
10
  const SHIP_EDITOR_VALUE_ACCESSOR = {
12
11
  provide: NG_VALUE_ACCESSOR,
13
12
  useExisting: forwardRef(() => ShipEditor),
@@ -29,11 +28,8 @@ class ShipEditor {
29
28
  #maxHistorySize;
30
29
  #isInternalDOMUpdate;
31
30
  #typingTimeout;
32
- // Image layout overlay signals
33
31
  #selectedImage;
34
- // Selection backup for inserting links/images when modal is open
35
32
  #savedRange;
36
- // Track outer changes
37
33
  #isWriting;
38
34
  #lastFormat;
39
35
  constructor() {
@@ -42,7 +38,6 @@ class ShipEditor {
42
38
  this.#isBrowser = isPlatformBrowser(this.#platformId);
43
39
  this.#elementRef = inject(ElementRef);
44
40
  this.#keybindings = inject(ShipA11yKeybindingsService);
45
- // Elements
46
41
  this.editorRef = viewChild('editorRef', /* @ts-ignore */
47
42
  ...(ngDevMode ? [{ debugName: "editorRef" }] : /* istanbul ignore next */ []));
48
43
  this.codeEditorRef = viewChild('codeEditorRef', /* @ts-ignore */
@@ -53,7 +48,6 @@ class ShipEditor {
53
48
  ...(ngDevMode ? [{ debugName: "imageInput" }] : /* istanbul ignore next */ []));
54
49
  this.linkInput = viewChild('linkInput', /* @ts-ignore */
55
50
  ...(ngDevMode ? [{ debugName: "linkInput" }] : /* istanbul ignore next */ []));
56
- // Configuration inputs & model signals
57
51
  this.value = model('', /* @ts-ignore */
58
52
  ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
59
53
  this.format = input('html', /* @ts-ignore */
@@ -70,7 +64,6 @@ class ShipEditor {
70
64
  ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
71
65
  this.customCommands = input([], /* @ts-ignore */
72
66
  ...(ngDevMode ? [{ debugName: "customCommands" }] : /* istanbul ignore next */ []));
73
- // Slash commands state signals
74
67
  this.showSlashMenu = signal(false, /* @ts-ignore */
75
68
  ...(ngDevMode ? [{ debugName: "showSlashMenu" }] : /* istanbul ignore next */ []));
76
69
  this.slashSearchQuery = signal('', /* @ts-ignore */
@@ -183,7 +176,6 @@ class ShipEditor {
183
176
  cmd.id.toLowerCase().includes(query));
184
177
  }, /* @ts-ignore */
185
178
  ...(ngDevMode ? [{ debugName: "filteredCommands" }] : /* istanbul ignore next */ []));
186
- // Toolbar group configuration inputs
187
179
  this.showFormats = input(true, /* @ts-ignore */
188
180
  ...(ngDevMode ? [{ debugName: "showFormats" }] : /* istanbul ignore next */ []));
189
181
  this.showBlocks = input(true, /* @ts-ignore */
@@ -196,13 +188,11 @@ class ShipEditor {
196
188
  ...(ngDevMode ? [{ debugName: "showInsertions" }] : /* istanbul ignore next */ []));
197
189
  this.showHistory = input(true, /* @ts-ignore */
198
190
  ...(ngDevMode ? [{ debugName: "showHistory" }] : /* istanbul ignore next */ []));
199
- // File upload output hook & configuration
200
191
  this.customUpload = input(false, /* @ts-ignore */
201
192
  ...(ngDevMode ? [{ debugName: "customUpload" }] : /* istanbul ignore next */ []));
202
193
  this.imageUploadEnabled = input(true, /* @ts-ignore */
203
194
  ...(ngDevMode ? [{ debugName: "imageUploadEnabled" }] : /* istanbul ignore next */ []));
204
195
  this.imageUpload = output();
205
- // Image layout overlay signals
206
196
  this.#selectedImage = signal(null, /* @ts-ignore */
207
197
  ...(ngDevMode ? [{ debugName: "#selectedImage" }] : /* istanbul ignore next */ []));
208
198
  this.imgToolbarTop = signal(0, /* @ts-ignore */
@@ -213,7 +203,6 @@ class ShipEditor {
213
203
  ...(ngDevMode ? [{ debugName: "imgMode" }] : /* istanbul ignore next */ []));
214
204
  this.imgSize = signal('auto', /* @ts-ignore */
215
205
  ...(ngDevMode ? [{ debugName: "imgSize" }] : /* istanbul ignore next */ []));
216
- // Local state signals
217
206
  this.viewMode = signal('design', /* @ts-ignore */
218
207
  ...(ngDevMode ? [{ debugName: "viewMode" }] : /* istanbul ignore next */ []));
219
208
  this.isFocused = signal(false, /* @ts-ignore */
@@ -226,7 +215,6 @@ class ShipEditor {
226
215
  ...(ngDevMode ? [{ debugName: "rawCodeValue" }] : /* istanbul ignore next */ []));
227
216
  this.showBlockMenu = signal(false, /* @ts-ignore */
228
217
  ...(ngDevMode ? [{ debugName: "showBlockMenu" }] : /* istanbul ignore next */ []));
229
- // Toolbar active states
230
218
  this.isBold = signal(false, /* @ts-ignore */
231
219
  ...(ngDevMode ? [{ debugName: "isBold" }] : /* istanbul ignore next */ []));
232
220
  this.isItalic = signal(false, /* @ts-ignore */
@@ -243,28 +231,22 @@ class ShipEditor {
243
231
  ...(ngDevMode ? [{ debugName: "canUndo" }] : /* istanbul ignore next */ []));
244
232
  this.canRedo = signal(false, /* @ts-ignore */
245
233
  ...(ngDevMode ? [{ debugName: "canRedo" }] : /* istanbul ignore next */ []));
246
- // Selection backup for inserting links/images when modal is open
247
234
  this.#savedRange = null;
248
- // Text metrics signals
249
235
  this.charCount = signal(0, /* @ts-ignore */
250
236
  ...(ngDevMode ? [{ debugName: "charCount" }] : /* istanbul ignore next */ []));
251
237
  this.wordCount = signal(0, /* @ts-ignore */
252
238
  ...(ngDevMode ? [{ debugName: "wordCount" }] : /* istanbul ignore next */ []));
253
- // Form accessors callbacks
254
239
  this.onChange = () => { };
255
240
  this.onTouched = () => { };
256
- // Host CSS classes resolver
257
241
  this.hostClasses = shipComponentClasses('editor', {
258
242
  color: this.color,
259
243
  variant: this.variant,
260
244
  readonly: this.readonly,
261
245
  });
262
- // Track outer changes
263
246
  this.#isWriting = false;
264
247
  this.#lastFormat = null;
265
248
  // --- IMAGE FILE HANDLING & LAYOUT OVERLAYS ---
266
249
  this.selectedImage = this.#selectedImage.asReadonly();
267
- // Auto-focus link dialog input when opened
268
250
  effect(() => {
269
251
  if (this.showLinkModal()) {
270
252
  const linkInput = this.linkInput();
@@ -273,7 +255,6 @@ class ShipEditor {
273
255
  }
274
256
  }
275
257
  });
276
- // Auto-focus image dialog elements when opened based on configuration
277
258
  effect(() => {
278
259
  if (this.showImageModal()) {
279
260
  const uploadBtn = this.uploadBtn();
@@ -290,12 +271,9 @@ class ShipEditor {
290
271
  }
291
272
  }
292
273
  });
293
- // Keep DOM inside editor in sync with value model changes reactively (when written from parent)
294
274
  effect(() => {
295
275
  const val = this.value();
296
276
  const editor = this.editorRef()?.nativeElement;
297
- // If the DOM element itself has changed (re-created during HMR), we must reset
298
- // lastValueWrittenFromDOM to force content initialization onto the new element.
299
277
  if (editor && editor !== this.#lastEditorElement) {
300
278
  this.#lastEditorElement = editor;
301
279
  this.#lastValueWrittenFromDOM = undefined;
@@ -304,14 +282,12 @@ class ShipEditor {
304
282
  return;
305
283
  this.#syncModelToDOM(val);
306
284
  });
307
- // React to format changes by converting the model value to the new format reactively
308
285
  effect(() => {
309
286
  const fmt = this.format();
310
287
  const prev = this.#lastFormat;
311
288
  this.#lastFormat = fmt;
312
289
  if (prev !== null && prev !== fmt) {
313
290
  const val = this.value();
314
- // 1. Convert current value in prev format to HTML
315
291
  let html = '';
316
292
  if (prev === 'html' && typeof val === 'string') {
317
293
  html = val;
@@ -322,7 +298,6 @@ class ShipEditor {
322
298
  else if (prev === 'json' && Array.isArray(val)) {
323
299
  html = this.#jsonToHTML(val);
324
300
  }
325
- // 2. Convert HTML to the new format
326
301
  let newValue = '';
327
302
  if (fmt === 'html') {
328
303
  newValue = html;
@@ -333,7 +308,6 @@ class ShipEditor {
333
308
  else if (fmt === 'json') {
334
309
  newValue = this.#htmlToJSON(html);
335
310
  }
336
- // 3. Update the model and DOM
337
311
  this.#isWriting = true;
338
312
  this.value.set(newValue);
339
313
  this.#lastValueWrittenFromDOM = newValue;
@@ -359,7 +333,6 @@ class ShipEditor {
359
333
  this.#isWriting = false;
360
334
  }
361
335
  });
362
- // Recalculate metrics whenever raw content updates
363
336
  effect(() => {
364
337
  const val = this.value();
365
338
  const fmt = this.format();
@@ -384,7 +357,6 @@ class ShipEditor {
384
357
  this.charCount.set(text.length);
385
358
  this.wordCount.set(text === '' ? 0 : text.split(/\s+/).filter((w) => w.length > 0).length);
386
359
  });
387
- // Reinitialize toolbar tabindexes when visibility inputs change
388
360
  effect(() => {
389
361
  this.showFormats();
390
362
  this.showBlocks();
@@ -398,7 +370,6 @@ class ShipEditor {
398
370
  });
399
371
  }
400
372
  ngOnInit() {
401
- // Empty hook
402
373
  }
403
374
  ngAfterViewInit() {
404
375
  this.#syncModelToDOM(this.value());
@@ -409,7 +380,6 @@ class ShipEditor {
409
380
  clearTimeout(this.#typingTimeout);
410
381
  }
411
382
  }
412
- // --- CONTROL VALUE ACCESSOR ---
413
383
  writeValue(obj) {
414
384
  this.#isWriting = true;
415
385
  this.value.set(obj);
@@ -423,9 +393,7 @@ class ShipEditor {
423
393
  this.onTouched = fn;
424
394
  }
425
395
  setDisabledState(isDisabled) {
426
- // In Angular forms, this matches readonly
427
396
  }
428
- // --- MODEL TO DOM SYNCING ---
429
397
  #syncModelToDOM(val) {
430
398
  let html = '';
431
399
  if (val === null || val === undefined || val === '') {
@@ -446,7 +414,6 @@ class ShipEditor {
446
414
  html = '<p><br></p>';
447
415
  }
448
416
  const isNewValue = val !== this.#lastValueWrittenFromDOM;
449
- // Set code editor value
450
417
  if (this.format() === 'markdown' && typeof val === 'string') {
451
418
  this.rawCodeValue.set(val);
452
419
  }
@@ -456,11 +423,9 @@ class ShipEditor {
456
423
  else {
457
424
  this.rawCodeValue.set(html);
458
425
  }
459
- // Update WYSIWYG editor surface if in design mode
460
426
  const editor = this.editorRef()?.nativeElement;
461
427
  if (editor) {
462
428
  this.#lastValueWrittenFromDOM = val;
463
- // Avoid resetting selection if html content is equivalent
464
429
  const normalizedHTML = html === '<p><br></p>' ? '' : html;
465
430
  const currentNormalized = editor.innerHTML === '<p><br></p>' ? '' : editor.innerHTML;
466
431
  if (normalizedHTML !== currentNormalized) {
@@ -477,13 +442,11 @@ class ShipEditor {
477
442
  }
478
443
  this.#updateHistoryStates();
479
444
  }
480
- // --- DOM TO MODEL SYNCING ---
481
445
  #updateValueFromDOM() {
482
446
  const editor = this.editorRef()?.nativeElement;
483
447
  if (!editor)
484
448
  return;
485
449
  let html = editor.innerHTML;
486
- // Normalize empty editor contents to empty string or basic paragraph
487
450
  if (html === '' || html === '<br>' || html === '<p><br></p>') {
488
451
  html = '';
489
452
  }
@@ -510,11 +473,9 @@ class ShipEditor {
510
473
  }
511
474
  this.#isWriting = false;
512
475
  }
513
- // --- COMPONENT HANDLERS ---
514
476
  onDOMInput() {
515
477
  this.#ensureImagesFocusable();
516
478
  this.#updateValueFromDOM();
517
- // Debounce history save on typing (500ms) or save immediately on word/sentence boundaries
518
479
  const selection = window.getSelection();
519
480
  let saveImmediately = false;
520
481
  if (selection && selection.rangeCount > 0) {
@@ -568,13 +529,11 @@ class ShipEditor {
568
529
  this.onChange(parsed);
569
530
  }
570
531
  catch (e) {
571
- // invalid JSON, do not update model, let user fix it
572
532
  }
573
533
  }
574
534
  this.#isWriting = false;
575
535
  this.onTouched();
576
536
  }
577
- // --- SELECTION STATE & COMMANDS ---
578
537
  formatText(command, value = '') {
579
538
  if (this.readonly())
580
539
  return;
@@ -764,7 +723,6 @@ class ShipEditor {
764
723
  selection.addRange(newRange);
765
724
  }
766
725
  catch (e) {
767
- // Fallback
768
726
  }
769
727
  }
770
728
  this.#updateValueFromDOM();