codexly-ui 0.15.1 → 0.15.3

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.
@@ -16583,8 +16583,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
16583
16583
  * using column/row units, supports drag-to-reorder (via Angular CDK's CdkDropList/CdkDrag — no
16584
16584
  * new dependency, @angular/cdk is already pulled in by ClxProfileComponent/ClxWidgetCardComponent's
16585
16585
  * overlay usage) and resize-by-dragging a corner handle. Persistence is the caller's job: listen
16586
- * to (layoutChange) and save the resulting ClxGridItem[] (e.g. to rp_dashboard_layouts.layout). */
16586
+ * to (layoutChange) and save the resulting ClxGridItem[] (e.g. to rp_dashboard_layouts.layout).
16587
+ *
16588
+ * Responsive: `columns` is the desktop column count; the grid itself halves it under 1024px and
16589
+ * collapses to a single column under 640px (both breakpoints measured off its own host width via
16590
+ * ResizeObserver, not the viewport — correct inside a narrow sidebar-pushed layout too). Below
16591
+ * 640px, pointer-drag reorder/resize is replaced by an up/down reorder button pair per item —
16592
+ * CdkDrag's pointer events are unreliable with real fingers on a dense grid, and a 1-column layout
16593
+ * has nothing to resize width-wise anyway. */
16587
16594
  class ClxDashboardGridComponent {
16595
+ _themeSvc = inject(ClxThemeService);
16596
+ _isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
16588
16597
  items = input.required(...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
16589
16598
  columns = input(4, ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
16590
16599
  rowHeight = input(92, ...(ngDevMode ? [{ debugName: "rowHeight" }] : /* istanbul ignore next */ []));
@@ -16593,8 +16602,48 @@ class ClxDashboardGridComponent {
16593
16602
  layoutChange = output();
16594
16603
  itemResize = output();
16595
16604
  _itemTemplate = contentChild(ClxGridItemDirective, ...(ngDevMode ? [{ debugName: "_itemTemplate" }] : /* istanbul ignore next */ []));
16596
- _gridCols = computed(() => `repeat(${this.columns()}, minmax(0, 1fr))`, ...(ngDevMode ? [{ debugName: "_gridCols" }] : /* istanbul ignore next */ []));
16605
+ _container = viewChild('container', ...(ngDevMode ? [{ debugName: "_container" }] : /* istanbul ignore next */ []));
16606
+ _hostWidth = signal(1280, ...(ngDevMode ? [{ debugName: "_hostWidth" }] : /* istanbul ignore next */ []));
16607
+ _resizeObserver;
16608
+ /** Below 640px: single column, no drag/resize (reorder buttons instead). 640-1024px: half the
16609
+ * desktop column count (min 2). 1024px+: the full `columns()` count. */
16610
+ _isCompact = computed(() => this._hostWidth() < 640, ...(ngDevMode ? [{ debugName: "_isCompact" }] : /* istanbul ignore next */ []));
16611
+ _effectiveColumns = computed(() => {
16612
+ const w = this._hostWidth();
16613
+ if (w < 640)
16614
+ return 1;
16615
+ if (w < 1024)
16616
+ return Math.max(2, Math.floor(this.columns() / 2));
16617
+ return this.columns();
16618
+ }, ...(ngDevMode ? [{ debugName: "_effectiveColumns" }] : /* istanbul ignore next */ []));
16619
+ _gridCols = computed(() => `repeat(${this._effectiveColumns()}, minmax(0, 1fr))`, ...(ngDevMode ? [{ debugName: "_gridCols" }] : /* istanbul ignore next */ []));
16620
+ /** Editing gets a visibly distinct "canvas" — dashed border + dotted background + surface-2 tint
16621
+ * — so the grid reads as an editable panel, not bare page background with cards floating on it. */
16622
+ _containerClass = computed(() => {
16623
+ const radius = resolveContainerRadius(this._themeSvc.config().borderRadius);
16624
+ if (!this.editable())
16625
+ return `${radius} p-1`;
16626
+ return `${radius} p-4 border-2 border-dashed border-clx-border bg-clx-surface-2`;
16627
+ }, ...(ngDevMode ? [{ debugName: "_containerClass" }] : /* istanbul ignore next */ []));
16597
16628
  _resizing = null;
16629
+ constructor() {
16630
+ effect((onCleanup) => {
16631
+ const el = this._container()?.nativeElement;
16632
+ if (!this._isBrowser || !el)
16633
+ return;
16634
+ this._hostWidth.set(el.clientWidth);
16635
+ this._resizeObserver = new ResizeObserver(entries => {
16636
+ const width = entries[0]?.contentRect.width;
16637
+ if (width)
16638
+ this._hostWidth.set(width);
16639
+ });
16640
+ this._resizeObserver.observe(el);
16641
+ onCleanup(() => this._resizeObserver?.disconnect());
16642
+ });
16643
+ }
16644
+ ngOnDestroy() {
16645
+ this._resizeObserver?.disconnect();
16646
+ }
16598
16647
  _onDrop(event) {
16599
16648
  const next = [...this.items()];
16600
16649
  moveItemInArray(next, event.previousIndex, event.currentIndex);
@@ -16604,6 +16653,16 @@ class ClxDashboardGridComponent {
16604
16653
  // Reordering is handled by cdkDropListDropped above; this hook exists for future free-form
16605
16654
  // (x/y pixel) positioning if a consumer needs it — not required for a reorderable column grid.
16606
16655
  }
16656
+ /** Compact-mode reorder (touch-friendly alternative to CdkDrag) — swap item at `index` with its
16657
+ * neighbor `delta` positions away (-1 = up/earlier, 1 = down/later). */
16658
+ _moveBy(index, delta) {
16659
+ const next = [...this.items()];
16660
+ const target = index + delta;
16661
+ if (target < 0 || target >= next.length)
16662
+ return;
16663
+ [next[index], next[target]] = [next[target], next[index]];
16664
+ this.layoutChange.emit(next);
16665
+ }
16607
16666
  _startResize(event, item) {
16608
16667
  event.preventDefault();
16609
16668
  event.stopPropagation();
@@ -16635,88 +16694,120 @@ class ClxDashboardGridComponent {
16635
16694
  window.addEventListener('pointerup', onUp);
16636
16695
  }
16637
16696
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ClxDashboardGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
16638
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: ClxDashboardGridComponent, isStandalone: true, selector: "clx-dashboard-grid", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, rowHeight: { classPropertyName: "rowHeight", publicName: "rowHeight", isSignal: true, isRequired: false, transformFunction: null }, gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { layoutChange: "layoutChange", itemResize: "itemResize" }, host: { classAttribute: "block w-full" }, queries: [{ propertyName: "_itemTemplate", first: true, predicate: ClxGridItemDirective, descendants: true, isSignal: true }], ngImport: i0, template: `
16639
- <div
16640
- cdkDropList
16641
- [cdkDropListDisabled]="!editable()"
16642
- (cdkDropListDropped)="_onDrop($event)"
16643
- class="grid w-full"
16644
- [style.grid-template-columns]="_gridCols()"
16645
- [style.grid-auto-rows.px]="rowHeight()"
16646
- [style.gap.px]="gap()">
16647
- @for (item of items(); track item.id) {
16648
- <div
16649
- cdkDrag
16650
- [cdkDragDisabled]="!editable()"
16651
- [cdkDragData]="item"
16652
- (cdkDragMoved)="_onDragMoved($event)"
16653
- class="relative min-w-0"
16654
- [class.cursor-grab]="editable()"
16655
- [style.grid-column]="'span ' + item.w"
16656
- [style.grid-row]="'span ' + item.h">
16657
-
16658
- <ng-container
16659
- [ngTemplateOutlet]="_itemTemplate()?.templateRef ?? null"
16660
- [ngTemplateOutletContext]="{ $implicit: item }">
16661
- </ng-container>
16662
-
16663
- @if (editable()) {
16664
- <div
16665
- class="absolute -right-1 -bottom-1 w-3.5 h-3.5 rounded bg-clx-primary border-2 border-clx-surface shadow cursor-nwse-resize"
16666
- (pointerdown)="_startResize($event, item)">
16667
- </div>
16668
- }
16669
- </div>
16670
- }
16697
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: ClxDashboardGridComponent, isStandalone: true, selector: "clx-dashboard-grid", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, rowHeight: { classPropertyName: "rowHeight", publicName: "rowHeight", isSignal: true, isRequired: false, transformFunction: null }, gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { layoutChange: "layoutChange", itemResize: "itemResize" }, host: { classAttribute: "block w-full" }, queries: [{ propertyName: "_itemTemplate", first: true, predicate: ClxGridItemDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "_container", first: true, predicate: ["container"], descendants: true, isSignal: true }], ngImport: i0, template: `
16698
+ <div #container [class]="_containerClass()">
16699
+ <div
16700
+ cdkDropList
16701
+ [cdkDropListDisabled]="!editable() || _isCompact()"
16702
+ (cdkDropListDropped)="_onDrop($event)"
16703
+ class="grid w-full"
16704
+ [style.grid-template-columns]="_gridCols()"
16705
+ [style.grid-auto-rows.px]="rowHeight()"
16706
+ [style.gap.px]="gap()">
16707
+ @for (item of items(); track item.id; let i = $index) {
16708
+ <div
16709
+ cdkDrag
16710
+ [cdkDragDisabled]="!editable() || _isCompact()"
16711
+ [cdkDragData]="item"
16712
+ (cdkDragMoved)="_onDragMoved($event)"
16713
+ class="relative min-w-0"
16714
+ [class.cursor-grab]="editable() && !_isCompact()"
16715
+ [style.grid-column]="_isCompact() ? 'span 1' : 'span ' + item.w"
16716
+ [style.grid-row]="_isCompact() ? 'span 1' : 'span ' + item.h">
16717
+
16718
+ <ng-container
16719
+ [ngTemplateOutlet]="_itemTemplate()?.templateRef ?? null"
16720
+ [ngTemplateOutletContext]="{ $implicit: item }">
16721
+ </ng-container>
16722
+
16723
+ @if (editable() && !_isCompact()) {
16724
+ <div
16725
+ class="absolute -right-1 -bottom-1 w-3.5 h-3.5 rounded bg-clx-primary border-2 border-clx-surface shadow cursor-nwse-resize z-10"
16726
+ (pointerdown)="_startResize($event, item)">
16727
+ </div>
16728
+ }
16729
+
16730
+ @if (editable() && _isCompact()) {
16731
+ <div class="absolute top-2 right-2 z-10 flex flex-col rounded-lg overflow-hidden border border-clx-border bg-clx-surface shadow-sm">
16732
+ <button type="button" class="w-7 h-7 flex items-center justify-center disabled:opacity-30"
16733
+ [disabled]="i === 0" (click)="_moveBy(i, -1)" aria-label="Mover arriba">
16734
+ <span clx-icon name="keyboard_arrow_up" size="sm"></span>
16735
+ </button>
16736
+ <div class="h-px bg-clx-border-soft"></div>
16737
+ <button type="button" class="w-7 h-7 flex items-center justify-center disabled:opacity-30"
16738
+ [disabled]="i === items().length - 1" (click)="_moveBy(i, 1)" aria-label="Mover abajo">
16739
+ <span clx-icon name="keyboard_arrow_down" size="sm"></span>
16740
+ </button>
16741
+ </div>
16742
+ }
16743
+ </div>
16744
+ }
16745
+ </div>
16671
16746
  </div>
16672
- `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1$2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1$2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
16747
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1$2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1$2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: ClxIconComponent, selector: "span[clx-icon]", inputs: ["name", "size", "color", "fill"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
16673
16748
  }
16674
16749
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ClxDashboardGridComponent, decorators: [{
16675
16750
  type: Component,
16676
16751
  args: [{
16677
16752
  selector: 'clx-dashboard-grid',
16678
16753
  standalone: true,
16679
- imports: [NgTemplateOutlet, DragDropModule],
16754
+ imports: [NgTemplateOutlet, DragDropModule, ClxIconComponent],
16680
16755
  encapsulation: ViewEncapsulation.None,
16681
16756
  changeDetection: ChangeDetectionStrategy.OnPush,
16682
16757
  host: { class: 'block w-full' },
16683
16758
  template: `
16684
- <div
16685
- cdkDropList
16686
- [cdkDropListDisabled]="!editable()"
16687
- (cdkDropListDropped)="_onDrop($event)"
16688
- class="grid w-full"
16689
- [style.grid-template-columns]="_gridCols()"
16690
- [style.grid-auto-rows.px]="rowHeight()"
16691
- [style.gap.px]="gap()">
16692
- @for (item of items(); track item.id) {
16693
- <div
16694
- cdkDrag
16695
- [cdkDragDisabled]="!editable()"
16696
- [cdkDragData]="item"
16697
- (cdkDragMoved)="_onDragMoved($event)"
16698
- class="relative min-w-0"
16699
- [class.cursor-grab]="editable()"
16700
- [style.grid-column]="'span ' + item.w"
16701
- [style.grid-row]="'span ' + item.h">
16702
-
16703
- <ng-container
16704
- [ngTemplateOutlet]="_itemTemplate()?.templateRef ?? null"
16705
- [ngTemplateOutletContext]="{ $implicit: item }">
16706
- </ng-container>
16707
-
16708
- @if (editable()) {
16709
- <div
16710
- class="absolute -right-1 -bottom-1 w-3.5 h-3.5 rounded bg-clx-primary border-2 border-clx-surface shadow cursor-nwse-resize"
16711
- (pointerdown)="_startResize($event, item)">
16712
- </div>
16713
- }
16714
- </div>
16715
- }
16759
+ <div #container [class]="_containerClass()">
16760
+ <div
16761
+ cdkDropList
16762
+ [cdkDropListDisabled]="!editable() || _isCompact()"
16763
+ (cdkDropListDropped)="_onDrop($event)"
16764
+ class="grid w-full"
16765
+ [style.grid-template-columns]="_gridCols()"
16766
+ [style.grid-auto-rows.px]="rowHeight()"
16767
+ [style.gap.px]="gap()">
16768
+ @for (item of items(); track item.id; let i = $index) {
16769
+ <div
16770
+ cdkDrag
16771
+ [cdkDragDisabled]="!editable() || _isCompact()"
16772
+ [cdkDragData]="item"
16773
+ (cdkDragMoved)="_onDragMoved($event)"
16774
+ class="relative min-w-0"
16775
+ [class.cursor-grab]="editable() && !_isCompact()"
16776
+ [style.grid-column]="_isCompact() ? 'span 1' : 'span ' + item.w"
16777
+ [style.grid-row]="_isCompact() ? 'span 1' : 'span ' + item.h">
16778
+
16779
+ <ng-container
16780
+ [ngTemplateOutlet]="_itemTemplate()?.templateRef ?? null"
16781
+ [ngTemplateOutletContext]="{ $implicit: item }">
16782
+ </ng-container>
16783
+
16784
+ @if (editable() && !_isCompact()) {
16785
+ <div
16786
+ class="absolute -right-1 -bottom-1 w-3.5 h-3.5 rounded bg-clx-primary border-2 border-clx-surface shadow cursor-nwse-resize z-10"
16787
+ (pointerdown)="_startResize($event, item)">
16788
+ </div>
16789
+ }
16790
+
16791
+ @if (editable() && _isCompact()) {
16792
+ <div class="absolute top-2 right-2 z-10 flex flex-col rounded-lg overflow-hidden border border-clx-border bg-clx-surface shadow-sm">
16793
+ <button type="button" class="w-7 h-7 flex items-center justify-center disabled:opacity-30"
16794
+ [disabled]="i === 0" (click)="_moveBy(i, -1)" aria-label="Mover arriba">
16795
+ <span clx-icon name="keyboard_arrow_up" size="sm"></span>
16796
+ </button>
16797
+ <div class="h-px bg-clx-border-soft"></div>
16798
+ <button type="button" class="w-7 h-7 flex items-center justify-center disabled:opacity-30"
16799
+ [disabled]="i === items().length - 1" (click)="_moveBy(i, 1)" aria-label="Mover abajo">
16800
+ <span clx-icon name="keyboard_arrow_down" size="sm"></span>
16801
+ </button>
16802
+ </div>
16803
+ }
16804
+ </div>
16805
+ }
16806
+ </div>
16716
16807
  </div>
16717
16808
  `,
16718
16809
  }]
16719
- }], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], rowHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowHeight", required: false }] }], gap: [{ type: i0.Input, args: [{ isSignal: true, alias: "gap", required: false }] }], editable: [{ type: i0.Input, args: [{ isSignal: true, alias: "editable", required: false }] }], layoutChange: [{ type: i0.Output, args: ["layoutChange"] }], itemResize: [{ type: i0.Output, args: ["itemResize"] }], _itemTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => ClxGridItemDirective), { isSignal: true }] }] } });
16810
+ }], ctorParameters: () => [], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], rowHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowHeight", required: false }] }], gap: [{ type: i0.Input, args: [{ isSignal: true, alias: "gap", required: false }] }], editable: [{ type: i0.Input, args: [{ isSignal: true, alias: "editable", required: false }] }], layoutChange: [{ type: i0.Output, args: ["layoutChange"] }], itemResize: [{ type: i0.Output, args: ["itemResize"] }], _itemTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => ClxGridItemDirective), { isSignal: true }] }], _container: [{ type: i0.ViewChild, args: ['container', { isSignal: true }] }] } });
16720
16811
 
16721
16812
  const PRODUCT_TAG_LABEL = {
16722
16813
  'new': 'Nuevo',