codexly-ui 0.12.36 → 0.12.38

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.
@@ -5015,8 +5015,16 @@ class ClxCheckboxComponent {
5015
5015
  _handleBlur() {
5016
5016
  this._onTouched();
5017
5017
  }
5018
+ /** The host's (click) toggles the checkbox for any click inside it — including clicks on a link
5019
+ * projected via ng-content (e.g. "Acepto los <a>Términos</a>"), which would otherwise both
5020
+ * navigate AND flip the checkbox. Stops propagation only when the click originated on (or
5021
+ * inside) an <a>, so the rest of the projected text still toggles normally. */
5022
+ _onLabelClick(event) {
5023
+ if (event.target?.closest('a'))
5024
+ event.stopPropagation();
5025
+ }
5018
5026
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ClxCheckboxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5019
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: ClxCheckboxComponent, isStandalone: true, selector: "clx-checkbox", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "checkbox" }, listeners: { "click": "_toggle()", "keydown.space": "_onSpace($event)" }, properties: { "style.cursor": "_disabled() ? \"not-allowed\" : \"pointer\"", "style.pointer-events": "_disabled() ? \"none\" : null", "attr.aria-checked": "_checked()", "attr.tabindex": "_disabled() ? -1 : 0" }, classAttribute: "inline-flex items-center gap-2 select-none" }, providers: [
5027
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: ClxCheckboxComponent, isStandalone: true, selector: "clx-checkbox", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "checkbox" }, listeners: { "click": "_toggle()", "keydown.space": "_onSpace($event)" }, properties: { "style.cursor": "_disabled() ? \"not-allowed\" : \"pointer\"", "style.pointer-events": "_disabled() ? \"none\" : null", "attr.aria-checked": "_checked()", "attr.tabindex": "_disabled() ? -1 : 0" }, classAttribute: "inline-flex items-start gap-2 select-none" }, providers: [
5020
5028
  {
5021
5029
  provide: NG_VALUE_ACCESSOR,
5022
5030
  useExisting: forwardRef(() => ClxCheckboxComponent),
@@ -5040,6 +5048,10 @@ class ClxCheckboxComponent {
5040
5048
  </div>
5041
5049
  @if (label()) {
5042
5050
  <span [class]="_labelClass()">{{ label() }}</span>
5051
+ } @else {
5052
+ <span [class]="_labelClass()" (click)="_onLabelClick($event)">
5053
+ <ng-content></ng-content>
5054
+ </span>
5043
5055
  }
5044
5056
  `, isInline: true, dependencies: [{ kind: "component", type: ClxIconComponent, selector: "span[clx-icon]", inputs: ["name", "size", "color", "fill"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
5045
5057
  }
@@ -5074,12 +5086,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
5074
5086
  </div>
5075
5087
  @if (label()) {
5076
5088
  <span [class]="_labelClass()">{{ label() }}</span>
5089
+ } @else {
5090
+ <span [class]="_labelClass()" (click)="_onLabelClick($event)">
5091
+ <ng-content></ng-content>
5092
+ </span>
5077
5093
  }
5078
5094
  `,
5079
5095
  encapsulation: ViewEncapsulation.None,
5080
5096
  changeDetection: ChangeDetectionStrategy.OnPush,
5081
5097
  host: {
5082
- class: 'inline-flex items-center gap-2 select-none',
5098
+ class: 'inline-flex items-start gap-2 select-none',
5083
5099
  '[style.cursor]': '_disabled() ? "not-allowed" : "pointer"',
5084
5100
  '[style.pointer-events]': '_disabled() ? "none" : null',
5085
5101
  role: 'checkbox',
@@ -9020,6 +9036,12 @@ class ClxEditorComponent {
9020
9036
  * plug in its own picker (e.g. an ERP's product/variant image browser) without this library
9021
9037
  * needing to know about that app's catalog backend. Resolve to undefined/null to cancel. */
9022
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 "poster" template resolved against a chosen product/variant, where
9041
+ * the result is a whole <table> block, not a single <img>, so imagePicker's fixed <img>-only
9042
+ * output doesn't fit. The returned html is inserted as-is via insertHTML, no sanitization beyond
9043
+ * what insertHTML/_sanitizePaste already does for pasted content. */
9044
+ blockPicker = input(undefined, ...(ngDevMode ? [{ debugName: "blockPicker" }] : /* istanbul ignore next */ []));
9023
9045
  // ── View ─────────────────────────────────────────────────────────────────
9024
9046
  _bodyEl;
9025
9047
  _sourceEl;
@@ -9238,6 +9260,20 @@ class ClxEditorComponent {
9238
9260
  const ref = this._modal.open(ClxEditorImageModalComponent, { size: 'sm' });
9239
9261
  ref.afterClosed().then((result) => insert(result));
9240
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
+ }
9241
9277
  // ── Range save/restore ────────────────────────────────────────────────────
9242
9278
  _saveRange() {
9243
9279
  const sel = window.getSelection();
@@ -9356,7 +9392,7 @@ class ClxEditorComponent {
9356
9392
  this._cdr.markForCheck();
9357
9393
  }
9358
9394
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ClxEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9359
- 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: [
9360
9396
  {
9361
9397
  provide: NG_VALUE_ACCESSOR,
9362
9398
  useExisting: forwardRef(() => ClxEditorComponent),
@@ -9462,6 +9498,25 @@ class ClxEditorComponent {
9462
9498
  </button>
9463
9499
 
9464
9500
  <div class="clx-editor-divider mx-1"></div>
9501
+
9502
+ <!-- Custom HTML block insert (e.g. an ERP's "insert poster" 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
+ }
9465
9520
  }
9466
9521
 
9467
9522
  <!-- HTML source toggle -->
@@ -9649,6 +9704,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
9649
9704
  </button>
9650
9705
 
9651
9706
  <div class="clx-editor-divider mx-1"></div>
9707
+
9708
+ <!-- Custom HTML block insert (e.g. an ERP's "insert poster" 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
+ }
9652
9726
  }
9653
9727
 
9654
9728
  <!-- HTML source toggle -->
@@ -9727,7 +9801,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
9727
9801
  <p [class]="_sizeCfg().hint + ' text-gray-400'">{{ hint() }}</p>
9728
9802
  }
9729
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"] }]
9730
- }], 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: [{
9731
9805
  type: ViewChild,
9732
9806
  args: ['bodyEl', { static: false }]
9733
9807
  }], _sourceEl: [{