codexly-ui 0.12.40 → 0.12.41

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.
@@ -9036,6 +9036,12 @@ class ClxEditorComponent {
9036
9036
  * plug in its own picker (e.g. an ERP's product/variant image browser) without this library
9037
9037
  * needing to know about that app's catalog backend. Resolve to undefined/null to cancel. */
9038
9038
  imagePicker = input(undefined, ...(ngDevMode ? [{ debugName: "imagePicker" }] : /* istanbul ignore next */ []));
9039
+ /** Adds an extra toolbar button (only rendered when provided) that inserts a raw HTML block at
9040
+ * the cursor — e.g. an ERP's own "insert product card" flow, where the result is a whole
9041
+ * <table> block, not a single <img>, so imagePicker's fixed <img>-only output doesn't fit. The
9042
+ * returned html is inserted as-is via insertHTML, no sanitization beyond what
9043
+ * insertHTML/_sanitizePaste already does for pasted content. */
9044
+ blockPicker = input(undefined, ...(ngDevMode ? [{ debugName: "blockPicker" }] : /* istanbul ignore next */ []));
9039
9045
  // ── View ─────────────────────────────────────────────────────────────────
9040
9046
  _bodyEl;
9041
9047
  _sourceEl;
@@ -9254,6 +9260,20 @@ class ClxEditorComponent {
9254
9260
  const ref = this._modal.open(ClxEditorImageModalComponent, { size: 'sm' });
9255
9261
  ref.afterClosed().then((result) => insert(result));
9256
9262
  }
9263
+ _openBlockPicker() {
9264
+ const picker = this.blockPicker();
9265
+ if (!picker)
9266
+ return;
9267
+ picker.fn().then(result => {
9268
+ if (!result?.html)
9269
+ return;
9270
+ this._restoreRange();
9271
+ this._bodyEl.nativeElement.focus();
9272
+ document.execCommand('insertHTML', false, result.html);
9273
+ this._emitChange();
9274
+ this._tick.update(v => v + 1);
9275
+ });
9276
+ }
9257
9277
  // ── Range save/restore ────────────────────────────────────────────────────
9258
9278
  _saveRange() {
9259
9279
  const sel = window.getSelection();
@@ -9372,7 +9392,7 @@ class ClxEditorComponent {
9372
9392
  this._cdr.markForCheck();
9373
9393
  }
9374
9394
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ClxEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9375
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: ClxEditorComponent, isStandalone: true, selector: "clx-editor", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null }, statusMessage: { classPropertyName: "statusMessage", publicName: "statusMessage", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, imagePicker: { classPropertyName: "imagePicker", publicName: "imagePicker", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "flex flex-col gap-1.5" }, providers: [
9395
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: ClxEditorComponent, isStandalone: true, selector: "clx-editor", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null }, statusMessage: { classPropertyName: "statusMessage", publicName: "statusMessage", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, imagePicker: { classPropertyName: "imagePicker", publicName: "imagePicker", isSignal: true, isRequired: false, transformFunction: null }, blockPicker: { classPropertyName: "blockPicker", publicName: "blockPicker", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "flex flex-col gap-1.5" }, providers: [
9376
9396
  {
9377
9397
  provide: NG_VALUE_ACCESSOR,
9378
9398
  useExisting: forwardRef(() => ClxEditorComponent),
@@ -9478,6 +9498,25 @@ class ClxEditorComponent {
9478
9498
  </button>
9479
9499
 
9480
9500
  <div class="clx-editor-divider mx-1"></div>
9501
+
9502
+ <!-- Custom HTML block insert (e.g. an ERP's "insert product card" flow) -->
9503
+ @if (blockPicker(); as picker) {
9504
+ <button
9505
+ clx-button
9506
+ type="button"
9507
+ variant="ghost"
9508
+ [color]="_color()"
9509
+ size="xs"
9510
+ shape="rounded"
9511
+ [icon]="picker.icon"
9512
+ [iconOnly]="true"
9513
+ [title]="picker.title"
9514
+ (mousedown)="_saveRange()"
9515
+ (click)="_openBlockPicker()">
9516
+ </button>
9517
+
9518
+ <div class="clx-editor-divider mx-1"></div>
9519
+ }
9481
9520
  }
9482
9521
 
9483
9522
  <!-- HTML source toggle -->
@@ -9665,6 +9704,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
9665
9704
  </button>
9666
9705
 
9667
9706
  <div class="clx-editor-divider mx-1"></div>
9707
+
9708
+ <!-- Custom HTML block insert (e.g. an ERP's "insert product card" flow) -->
9709
+ @if (blockPicker(); as picker) {
9710
+ <button
9711
+ clx-button
9712
+ type="button"
9713
+ variant="ghost"
9714
+ [color]="_color()"
9715
+ size="xs"
9716
+ shape="rounded"
9717
+ [icon]="picker.icon"
9718
+ [iconOnly]="true"
9719
+ [title]="picker.title"
9720
+ (mousedown)="_saveRange()"
9721
+ (click)="_openBlockPicker()">
9722
+ </button>
9723
+
9724
+ <div class="clx-editor-divider mx-1"></div>
9725
+ }
9668
9726
  }
9669
9727
 
9670
9728
  <!-- HTML source toggle -->
@@ -9743,7 +9801,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
9743
9801
  <p [class]="_sizeCfg().hint + ' text-gray-400'">{{ hint() }}</p>
9744
9802
  }
9745
9803
  `, host: { class: 'flex flex-col gap-1.5' }, styles: [".clx-editor-body:empty:before{content:attr(data-placeholder);color:#9ca3af;pointer-events:none}.clx-editor-body:focus{outline:none}.clx-editor-body p{margin:0 0 .4em}.clx-editor-body p:last-child{margin-bottom:0}.clx-editor-body h1{font-size:1.5em;font-weight:700;margin:.5em 0}.clx-editor-body h2{font-size:1.25em;font-weight:600;margin:.5em 0}.clx-editor-body h3{font-size:1.1em;font-weight:600;margin:.5em 0}.clx-editor-body ul,.clx-editor-body ol{padding-left:1.5em;margin:.35em 0}.clx-editor-body li{margin:.1em 0}.clx-editor-body blockquote{border-left:3px solid #e2e8f0;padding-left:.75em;color:#64748b;margin:.4em 0}.clx-editor-body code{background:#f1f5f9;border-radius:3px;padding:.1em .3em;font-size:.875em;font-family:ui-monospace,monospace}.clx-editor-body a{color:#6366f1;text-decoration:underline}.clx-editor-body hr{border:none;border-top:1px solid #e2e8f0;margin:.6em 0}.clx-editor-color-btn{position:relative;overflow:hidden}.clx-editor-color-btn input[type=color]{position:absolute;inset:0;opacity:0;width:100%;height:100%;cursor:pointer;border:none;padding:0}.clx-editor-toolbar-select clx-select .flex.flex-col{gap:0!important}.clx-editor-source{width:100%;resize:none;border:none;outline:none;background:#0f172a;color:#e2e8f0;font-family:ui-monospace,Cascadia Code,Fira Code,monospace;font-size:.8125rem;line-height:1.6;padding:1rem;tab-size:2}\n"] }]
9746
- }], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], statusMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "statusMessage", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], imagePicker: [{ type: i0.Input, args: [{ isSignal: true, alias: "imagePicker", required: false }] }], _bodyEl: [{
9804
+ }], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], statusMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "statusMessage", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], imagePicker: [{ type: i0.Input, args: [{ isSignal: true, alias: "imagePicker", required: false }] }], blockPicker: [{ type: i0.Input, args: [{ isSignal: true, alias: "blockPicker", required: false }] }], _bodyEl: [{
9747
9805
  type: ViewChild,
9748
9806
  args: ['bodyEl', { static: false }]
9749
9807
  }], _sourceEl: [{