orbiq-neural-ui-kit 1.1.31 → 1.1.32

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.
@@ -490,7 +490,7 @@ class NeuralButtonComponent {
490
490
  const t = this.theme();
491
491
  const s = this.size();
492
492
  const solidClasses = {
493
- gray: 'text-ink-base bg-surface-gray-10 hover:bg-surface-gray-9 active:bg-surface-gray-8',
493
+ gray: 'text-white bg-ink-gray-8 hover:bg-ink-gray-9 active:bg-surface-gray-8',
494
494
  blue: 'text-ink-base bg-surface-blue-6 hover:bg-surface-blue-7 active:bg-surface-blue-8',
495
495
  green: 'text-ink-base bg-surface-green-7 hover:bg-surface-green-8 active:bg-surface-green-9',
496
496
  red: 'text-ink-base dark:text-ink-red-9 bg-surface-red-7 hover:bg-surface-red-8 active:bg-surface-red-9',
@@ -8271,8 +8271,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
8271
8271
  }] } });
8272
8272
 
8273
8273
  class NeuralDialogComponent {
8274
- dialog;
8275
- viewContainerRef;
8276
8274
  // ── Public API (sin cambios de compatibilidad) ──────────────────────────────
8277
8275
  openModel = model(false, /* @ts-ignore */
8278
8276
  ...(ngDevMode ? [{ debugName: "openModel" }] : /* istanbul ignore next */ []));
@@ -8296,60 +8294,24 @@ class NeuralDialogComponent {
8296
8294
  ...(ngDevMode ? [{ debugName: "showCloseButton" }] : /* istanbul ignore next */ []));
8297
8295
  bare = input(false, /* @ts-ignore */
8298
8296
  ...(ngDevMode ? [{ debugName: "bare" }] : /* istanbul ignore next */ []));
8299
- // Mantenidos por compatibilidad con el modo bare=false aunque ya no se usan en bare=true
8300
8297
  hasTitleSlot = input(false, /* @ts-ignore */
8301
8298
  ...(ngDevMode ? [{ debugName: "hasTitleSlot" }] : /* istanbul ignore next */ []));
8302
8299
  hasActionsSlot = input(false, /* @ts-ignore */
8303
8300
  ...(ngDevMode ? [{ debugName: "hasActionsSlot" }] : /* istanbul ignore next */ []));
8304
8301
  hasDefaultSlot = input(false, /* @ts-ignore */
8305
8302
  ...(ngDevMode ? [{ debugName: "hasDefaultSlot" }] : /* istanbul ignore next */ []));
8306
- dialogTemplate;
8307
- dialogRef = null;
8308
8303
  internalActionsState = {};
8309
- constructor(dialog, viewContainerRef) {
8310
- this.dialog = dialog;
8311
- this.viewContainerRef = viewContainerRef;
8304
+ constructor() {
8312
8305
  effect(() => {
8313
- const isOpen = this.openModel();
8314
- // El CDK Portal SOLO se gestiona en modo bare=false.
8315
- // En bare=true, el @if del template reacciona al signal directamente.
8316
- if (!this.bare()) {
8317
- if (isOpen && !this.dialogRef && this.dialogTemplate) {
8318
- this.openDialog();
8319
- }
8320
- else if (!isOpen && this.dialogRef) {
8321
- this.dialogRef.close();
8322
- this.dialogRef = null;
8323
- }
8324
- }
8306
+ // Manejar foco y escape de forma nativa en el futuro si es necesario.
8307
+ // El ngIf maneja el montaje y desmontaje.
8325
8308
  });
8326
8309
  }
8327
- openDialog() {
8328
- this.dialogRef = this.dialog.open(this.dialogTemplate, {
8329
- disableClose: !this.dismissible(),
8330
- backdropClass: 'bg-black-overlay-200',
8331
- panelClass: ['w-full', 'h-full', 'bg-transparent', 'shadow-none'],
8332
- hasBackdrop: true,
8333
- viewContainerRef: this.viewContainerRef,
8334
- });
8335
- this.dialogRef.closed.subscribe(() => {
8336
- this.dialogRef = null;
8337
- if (this.openModel()) {
8338
- this.openModel.set(false);
8339
- }
8340
- });
8341
- }
8342
- /** Cierra el modal en modo bare=false (CDK) */
8310
+ /** Cierra el modal */
8343
8311
  close() {
8344
- if (this.bare()) {
8345
- // bare=true: simplemente cerramos el signal
8346
- this.openModel.set(false);
8347
- }
8348
- else if (this.dialogRef) {
8349
- this.dialogRef.close();
8350
- }
8312
+ this.openModel.set(false);
8351
8313
  }
8352
- /** Alias para cerrar desde el template bare=true (keydown.escape) */
8314
+ /** Alias para cerrar desde el template */
8353
8315
  closeBare() {
8354
8316
  if (this.dismissible()) {
8355
8317
  this.openModel.set(false);
@@ -8359,15 +8321,13 @@ class NeuralDialogComponent {
8359
8321
  const target = event.target;
8360
8322
  const isOverlay = target.classList.contains('dialog-scroll-container') ||
8361
8323
  target.classList.contains('min-h-screen') ||
8362
- target.classList.contains('dialog-backdrop'); // clic en backdrop manual (bare=true)
8324
+ target.classList.contains('dialog-backdrop');
8363
8325
  if (isOverlay && this.dismissible()) {
8364
8326
  this.close();
8365
8327
  }
8366
8328
  }
8367
8329
  ngOnDestroy() {
8368
- if (this.dialogRef) {
8369
- this.dialogRef.close();
8370
- }
8330
+ this.close();
8371
8331
  }
8372
8332
  // ── Computed ────────────────────────────────────────────────────────────────
8373
8333
  sizeClass = computed(() => {
@@ -8438,16 +8398,6 @@ class NeuralDialogComponent {
8438
8398
  return pt ? { paddingTop: pt } : {};
8439
8399
  }, /* @ts-ignore */
8440
8400
  ...(ngDevMode ? [{ debugName: "dialogPositionStyles" }] : /* istanbul ignore next */ []));
8441
- showHeader = computed(() => {
8442
- if (this.bare())
8443
- return false;
8444
- if (this.hasTitleSlot())
8445
- return true;
8446
- if (this.title())
8447
- return true;
8448
- return false;
8449
- }, /* @ts-ignore */
8450
- ...(ngDevMode ? [{ debugName: "showHeader" }] : /* istanbul ignore next */ []));
8451
8401
  reactiveActions = computed(() => {
8452
8402
  if (this.bare())
8453
8403
  return [];
@@ -8475,283 +8425,142 @@ class NeuralDialogComponent {
8475
8425
  this.internalActionsState[action.label] = false;
8476
8426
  }
8477
8427
  }
8478
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NeuralDialogComponent, deps: [{ token: i1$3.Dialog }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component });
8479
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: NeuralDialogComponent, isStandalone: true, selector: "neural-dialog", inputs: { openModel: { classPropertyName: "openModel", publicName: "openModel", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, paddingTop: { classPropertyName: "paddingTop", publicName: "paddingTop", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, dismissible: { classPropertyName: "dismissible", publicName: "dismissible", isSignal: true, isRequired: false, transformFunction: null }, showCloseButton: { classPropertyName: "showCloseButton", publicName: "showCloseButton", isSignal: true, isRequired: false, transformFunction: null }, bare: { classPropertyName: "bare", publicName: "bare", isSignal: true, isRequired: false, transformFunction: null }, hasTitleSlot: { classPropertyName: "hasTitleSlot", publicName: "hasTitleSlot", isSignal: true, isRequired: false, transformFunction: null }, hasActionsSlot: { classPropertyName: "hasActionsSlot", publicName: "hasActionsSlot", isSignal: true, isRequired: false, transformFunction: null }, hasDefaultSlot: { classPropertyName: "hasDefaultSlot", publicName: "hasDefaultSlot", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { openModel: "openModelChange" }, viewQueries: [{ propertyName: "dialogTemplate", first: true, predicate: ["dialogTemplate"], descendants: true }], ngImport: i0, template: `
8480
- <!--
8481
- MODO bare=true: Renderizado directo con @if.
8482
- Angular mantiene el árbol de vistas del componente padre, lo que permite que
8483
- <ng-content> proyecte correctamente los nodos del consumidor.
8484
- NOTA: El CDK Dialog Portal crea una EmbeddedView desconectada donde <ng-content>
8485
- no recibe proyección, resultando en height:0. Este modo evita ese bug.
8486
- -->
8487
- @if (bare() && openModel()) {
8488
- <div
8489
- class="fixed inset-0 z-[1000] overflow-y-auto dialog-scroll-container"
8490
- (click)="onContainerClick($event)"
8491
- (keydown.escape)="closeBare()"
8492
- tabindex="-1"
8493
- >
8494
- <!-- Backdrop manual con transición sincronizada -->
8428
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NeuralDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8429
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: NeuralDialogComponent, isStandalone: true, selector: "neural-dialog", inputs: { openModel: { classPropertyName: "openModel", publicName: "openModel", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, paddingTop: { classPropertyName: "paddingTop", publicName: "paddingTop", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, dismissible: { classPropertyName: "dismissible", publicName: "dismissible", isSignal: true, isRequired: false, transformFunction: null }, showCloseButton: { classPropertyName: "showCloseButton", publicName: "showCloseButton", isSignal: true, isRequired: false, transformFunction: null }, bare: { classPropertyName: "bare", publicName: "bare", isSignal: true, isRequired: false, transformFunction: null }, hasTitleSlot: { classPropertyName: "hasTitleSlot", publicName: "hasTitleSlot", isSignal: true, isRequired: false, transformFunction: null }, hasActionsSlot: { classPropertyName: "hasActionsSlot", publicName: "hasActionsSlot", isSignal: true, isRequired: false, transformFunction: null }, hasDefaultSlot: { classPropertyName: "hasDefaultSlot", publicName: "hasDefaultSlot", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { openModel: "openModelChange" }, ngImport: i0, template: `
8430
+ @if (openModel()) {
8431
+ <div class="fixed inset-0 z-[1000] overflow-y-auto dialog-scroll-container" (click)="onContainerClick($event)" (keydown.escape)="closeBare()" tabindex="-1">
8495
8432
  <div class="fixed inset-0 bg-black-overlay-200 transition-opacity duration-150 dialog-backdrop"></div>
8496
-
8497
- <!-- Contenedor posicionado -->
8498
- <div
8499
- class="relative flex min-h-screen flex-col items-center px-4 py-4 text-center"
8500
- [class]="dialogPositionClasses()"
8501
- [style]="dialogPositionStyles()"
8502
- >
8503
- <div
8504
- class="my-8 inline-block w-full transform overflow-hidden rounded-7 bg-surface-elevation-1 text-start align-middle shadow-xl dialog-content focus-visible:outline-none"
8505
- [class]="sizeClass()"
8506
- >
8507
- <!-- ng-content proyecta correctamente aquí porque estamos en el árbol de vistas del padre -->
8508
- <ng-content></ng-content>
8509
- </div>
8510
- </div>
8511
- </div>
8512
- }
8513
-
8514
- <!--
8515
- MODO bare=false: CDK Dialog Portal.
8516
- No usa <ng-content> — el contenido se genera desde @Input() (title, message, actions).
8517
- El CDK Portal funciona correctamente aquí porque no hay proyección de nodos externos.
8518
- -->
8519
- @if (!bare()) {
8520
- <ng-template #dialogTemplate>
8521
- <div
8522
- class="fixed inset-0 z-50 overflow-y-auto dialog-scroll-container"
8523
- (click)="onContainerClick($event)"
8524
- >
8525
- <div
8526
- class="flex min-h-screen flex-col items-center px-4 py-4 text-center"
8527
- [class]="dialogPositionClasses()"
8528
- [style]="dialogPositionStyles()"
8529
- >
8530
- <div
8531
- class="my-8 inline-block w-full transform overflow-hidden rounded-7 bg-surface-elevation-1 text-start align-middle shadow-xl dialog-content focus-visible:outline-none"
8532
- [class]="sizeClass()"
8533
- >
8433
+
8434
+ <div class="relative flex min-h-screen flex-col items-center px-4 py-4 text-center" [class]="dialogPositionClasses()" [style]="dialogPositionStyles()">
8435
+ <div class="my-8 inline-block w-full transform overflow-hidden rounded-7 bg-surface-elevation-1 text-start align-middle shadow-xl dialog-content focus-visible:outline-none" [class]="sizeClass()">
8436
+
8437
+ @if (bare()) {
8438
+ <ng-content></ng-content>
8439
+ } @else {
8440
+ <!-- Diseño estándar con Header y Body -->
8534
8441
  <div class="bg-surface-elevation-1 px-4 pb-6 pt-5 sm:px-6">
8535
8442
  <div class="flex">
8536
- <div class="w-full flex-1">
8537
- @if (showHeader()) {
8538
- <div class="mb-6 flex items-center justify-between">
8539
- <div class="flex items-center space-x-2 flex-1">
8540
- @if (icon()) {
8541
- <div
8542
- class="flex h-7 w-7 flex-shrink-0 items-center justify-center rounded-full"
8543
- [class]="dialogIconBgClasses()"
8544
- >
8545
- <span [class]="iconName() + ' size-4 ' + dialogIconClasses()" aria-hidden="true"></span>
8546
- </div>
8547
- }
8548
- <header class="flex-1">
8549
- @if (title()) {
8550
- <h3 class="text-2xl-semibold leading-6 text-ink-gray-8">
8551
- {{ title() }}
8552
- </h3>
8553
- }
8554
- </header>
8555
- </div>
8556
- @if (showCloseButton()) {
8557
- <neural-button variant="ghost" label="Close" (click)="close()">
8558
- <span icon class="lucide-x size-4 text-ink-gray-9"></span>
8559
- </neural-button>
8560
- }
8561
- </div>
8562
- }
8563
-
8564
- @if (message()) {
8565
- <p class="text-p-base text-ink-gray-7">
8566
- {{ message() }}
8567
- </p>
8443
+ @if (icon()) {
8444
+ <div class="mx-auto flex size-10 shrink-0 items-center justify-center rounded-full sm:mx-0 sm:size-10" [class]="dialogIconBgClasses()">
8445
+ <span icon [class]="(iconName() || '') + ' size-5 ' + dialogIconClasses()"></span>
8446
+ </div>
8447
+ }
8448
+ <header class="flex-1" [class.ml-4]="icon()">
8449
+ @if (hasTitleSlot()) {
8450
+ <ng-content select="[title]"></ng-content>
8451
+ } @else if (title()) {
8452
+ <h3 class="text-2xl-semibold leading-6 text-ink-gray-8">{{ title() }}</h3>
8568
8453
  }
8569
- </div>
8454
+ </header>
8455
+ @if (showCloseButton()) {
8456
+ <neural-button variant="ghost" [iconOnly]="true" icon="lucide-x" (clicked)="closeBare()" class="-mt-2 -mr-2"></neural-button>
8457
+ }
8458
+ </div>
8459
+
8460
+ <div [class]="icon() ? 'ml-14 mt-2' : 'mt-3'">
8461
+ @if (hasDefaultSlot()) {
8462
+ <ng-content></ng-content>
8463
+ } @else if (message()) {
8464
+ <p class="text-p-base text-ink-gray-7">{{ message() }}</p>
8465
+ }
8570
8466
  </div>
8571
8467
  </div>
8572
-
8573
- @if (reactiveActions().length) {
8574
- <div class="px-4 pb-7 pt-4 sm:px-6">
8575
- <div [class]="isSingleActionFullWidth() ? '' : 'flex justify-end gap-2'">
8576
- @for (action of reactiveActions(); track action.label) {
8577
- <neural-button
8578
- class="w-full sm:w-auto"
8579
- [disabled]="action.disabled || false"
8580
- [loading]="action.loading || false"
8581
- [variant]="action.variant || 'solid'"
8582
- [theme]="action.theme || 'gray'"
8583
- (click)="onActionClick(action)"
8584
- >
8585
- {{ action.label }}
8586
- @if (action.icon) {
8587
- <span icon [class]="action.icon + ' size-4'"></span>
8588
- }
8589
- </neural-button>
8590
- }
8591
- </div>
8468
+
8469
+ <!-- Acciones Footer -->
8470
+ @if (reactiveActions().length || hasActionsSlot()) {
8471
+ <div class="px-4 pb-7 pt-4 sm:px-6 bg-surface-gray-1 border-t border-outline-gray-2">
8472
+ @if (hasActionsSlot()) {
8473
+ <ng-content select="[actions]"></ng-content>
8474
+ } @else {
8475
+ <div [class]="isSingleActionFullWidth() ? '' : 'flex justify-end gap-2'">
8476
+ @for (action of reactiveActions(); track action.label) {
8477
+ <neural-button class="w-full sm:w-auto" [disabled]="action.disabled || false" [loading]="action.loading || false" [variant]="action.variant || 'solid'" [theme]="action.theme || 'gray'" (clicked)="onActionClick(action)">
8478
+ {{ action.label }}
8479
+ @if (action.icon) { <span icon [class]="action.icon + ' size-4'"></span> }
8480
+ </neural-button>
8481
+ }
8482
+ </div>
8483
+ }
8592
8484
  </div>
8593
8485
  }
8594
-
8595
- @if (showCloseButton() && !showHeader()) {
8596
- <neural-button
8597
- class="absolute right-4 top-4 z-10"
8598
- variant="ghost"
8599
- label="Close"
8600
- (click)="close()"
8601
- >
8602
- <span icon class="lucide-x size-4 text-ink-gray-9"></span>
8603
- </neural-button>
8604
- }
8605
- </div>
8486
+ }
8606
8487
  </div>
8607
8488
  </div>
8608
- </ng-template>
8489
+ </div>
8609
8490
  }
8610
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: NeuralButtonComponent, selector: "neural-button", inputs: ["variant", "theme", "size", "type", "disabled", "loading", "icon", "iconLeft", "iconRight", "iconOnly"], outputs: ["clicked"] }] });
8491
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: NeuralButtonComponent, selector: "neural-button", inputs: ["variant", "theme", "size", "type", "disabled", "loading", "icon", "iconLeft", "iconRight", "iconOnly"], outputs: ["clicked"] }] });
8611
8492
  }
8612
8493
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NeuralDialogComponent, decorators: [{
8613
8494
  type: Component,
8614
8495
  args: [{
8615
8496
  selector: 'neural-dialog',
8616
8497
  standalone: true,
8617
- imports: [CommonModule, DialogModule, NeuralButtonComponent],
8498
+ imports: [CommonModule, NeuralButtonComponent],
8618
8499
  template: `
8619
- <!--
8620
- MODO bare=true: Renderizado directo con @if.
8621
- Angular mantiene el árbol de vistas del componente padre, lo que permite que
8622
- <ng-content> proyecte correctamente los nodos del consumidor.
8623
- NOTA: El CDK Dialog Portal crea una EmbeddedView desconectada donde <ng-content>
8624
- no recibe proyección, resultando en height:0. Este modo evita ese bug.
8625
- -->
8626
- @if (bare() && openModel()) {
8627
- <div
8628
- class="fixed inset-0 z-[1000] overflow-y-auto dialog-scroll-container"
8629
- (click)="onContainerClick($event)"
8630
- (keydown.escape)="closeBare()"
8631
- tabindex="-1"
8632
- >
8633
- <!-- Backdrop manual con transición sincronizada -->
8500
+ @if (openModel()) {
8501
+ <div class="fixed inset-0 z-[1000] overflow-y-auto dialog-scroll-container" (click)="onContainerClick($event)" (keydown.escape)="closeBare()" tabindex="-1">
8634
8502
  <div class="fixed inset-0 bg-black-overlay-200 transition-opacity duration-150 dialog-backdrop"></div>
8635
-
8636
- <!-- Contenedor posicionado -->
8637
- <div
8638
- class="relative flex min-h-screen flex-col items-center px-4 py-4 text-center"
8639
- [class]="dialogPositionClasses()"
8640
- [style]="dialogPositionStyles()"
8641
- >
8642
- <div
8643
- class="my-8 inline-block w-full transform overflow-hidden rounded-7 bg-surface-elevation-1 text-start align-middle shadow-xl dialog-content focus-visible:outline-none"
8644
- [class]="sizeClass()"
8645
- >
8646
- <!-- ng-content proyecta correctamente aquí porque estamos en el árbol de vistas del padre -->
8647
- <ng-content></ng-content>
8648
- </div>
8649
- </div>
8650
- </div>
8651
- }
8652
-
8653
- <!--
8654
- MODO bare=false: CDK Dialog Portal.
8655
- No usa <ng-content> — el contenido se genera desde @Input() (title, message, actions).
8656
- El CDK Portal funciona correctamente aquí porque no hay proyección de nodos externos.
8657
- -->
8658
- @if (!bare()) {
8659
- <ng-template #dialogTemplate>
8660
- <div
8661
- class="fixed inset-0 z-50 overflow-y-auto dialog-scroll-container"
8662
- (click)="onContainerClick($event)"
8663
- >
8664
- <div
8665
- class="flex min-h-screen flex-col items-center px-4 py-4 text-center"
8666
- [class]="dialogPositionClasses()"
8667
- [style]="dialogPositionStyles()"
8668
- >
8669
- <div
8670
- class="my-8 inline-block w-full transform overflow-hidden rounded-7 bg-surface-elevation-1 text-start align-middle shadow-xl dialog-content focus-visible:outline-none"
8671
- [class]="sizeClass()"
8672
- >
8503
+
8504
+ <div class="relative flex min-h-screen flex-col items-center px-4 py-4 text-center" [class]="dialogPositionClasses()" [style]="dialogPositionStyles()">
8505
+ <div class="my-8 inline-block w-full transform overflow-hidden rounded-7 bg-surface-elevation-1 text-start align-middle shadow-xl dialog-content focus-visible:outline-none" [class]="sizeClass()">
8506
+
8507
+ @if (bare()) {
8508
+ <ng-content></ng-content>
8509
+ } @else {
8510
+ <!-- Diseño estándar con Header y Body -->
8673
8511
  <div class="bg-surface-elevation-1 px-4 pb-6 pt-5 sm:px-6">
8674
8512
  <div class="flex">
8675
- <div class="w-full flex-1">
8676
- @if (showHeader()) {
8677
- <div class="mb-6 flex items-center justify-between">
8678
- <div class="flex items-center space-x-2 flex-1">
8679
- @if (icon()) {
8680
- <div
8681
- class="flex h-7 w-7 flex-shrink-0 items-center justify-center rounded-full"
8682
- [class]="dialogIconBgClasses()"
8683
- >
8684
- <span [class]="iconName() + ' size-4 ' + dialogIconClasses()" aria-hidden="true"></span>
8685
- </div>
8686
- }
8687
- <header class="flex-1">
8688
- @if (title()) {
8689
- <h3 class="text-2xl-semibold leading-6 text-ink-gray-8">
8690
- {{ title() }}
8691
- </h3>
8692
- }
8693
- </header>
8694
- </div>
8695
- @if (showCloseButton()) {
8696
- <neural-button variant="ghost" label="Close" (click)="close()">
8697
- <span icon class="lucide-x size-4 text-ink-gray-9"></span>
8698
- </neural-button>
8699
- }
8700
- </div>
8701
- }
8702
-
8703
- @if (message()) {
8704
- <p class="text-p-base text-ink-gray-7">
8705
- {{ message() }}
8706
- </p>
8513
+ @if (icon()) {
8514
+ <div class="mx-auto flex size-10 shrink-0 items-center justify-center rounded-full sm:mx-0 sm:size-10" [class]="dialogIconBgClasses()">
8515
+ <span icon [class]="(iconName() || '') + ' size-5 ' + dialogIconClasses()"></span>
8516
+ </div>
8517
+ }
8518
+ <header class="flex-1" [class.ml-4]="icon()">
8519
+ @if (hasTitleSlot()) {
8520
+ <ng-content select="[title]"></ng-content>
8521
+ } @else if (title()) {
8522
+ <h3 class="text-2xl-semibold leading-6 text-ink-gray-8">{{ title() }}</h3>
8707
8523
  }
8708
- </div>
8524
+ </header>
8525
+ @if (showCloseButton()) {
8526
+ <neural-button variant="ghost" [iconOnly]="true" icon="lucide-x" (clicked)="closeBare()" class="-mt-2 -mr-2"></neural-button>
8527
+ }
8528
+ </div>
8529
+
8530
+ <div [class]="icon() ? 'ml-14 mt-2' : 'mt-3'">
8531
+ @if (hasDefaultSlot()) {
8532
+ <ng-content></ng-content>
8533
+ } @else if (message()) {
8534
+ <p class="text-p-base text-ink-gray-7">{{ message() }}</p>
8535
+ }
8709
8536
  </div>
8710
8537
  </div>
8711
-
8712
- @if (reactiveActions().length) {
8713
- <div class="px-4 pb-7 pt-4 sm:px-6">
8714
- <div [class]="isSingleActionFullWidth() ? '' : 'flex justify-end gap-2'">
8715
- @for (action of reactiveActions(); track action.label) {
8716
- <neural-button
8717
- class="w-full sm:w-auto"
8718
- [disabled]="action.disabled || false"
8719
- [loading]="action.loading || false"
8720
- [variant]="action.variant || 'solid'"
8721
- [theme]="action.theme || 'gray'"
8722
- (click)="onActionClick(action)"
8723
- >
8724
- {{ action.label }}
8725
- @if (action.icon) {
8726
- <span icon [class]="action.icon + ' size-4'"></span>
8727
- }
8728
- </neural-button>
8729
- }
8730
- </div>
8538
+
8539
+ <!-- Acciones Footer -->
8540
+ @if (reactiveActions().length || hasActionsSlot()) {
8541
+ <div class="px-4 pb-7 pt-4 sm:px-6 bg-surface-gray-1 border-t border-outline-gray-2">
8542
+ @if (hasActionsSlot()) {
8543
+ <ng-content select="[actions]"></ng-content>
8544
+ } @else {
8545
+ <div [class]="isSingleActionFullWidth() ? '' : 'flex justify-end gap-2'">
8546
+ @for (action of reactiveActions(); track action.label) {
8547
+ <neural-button class="w-full sm:w-auto" [disabled]="action.disabled || false" [loading]="action.loading || false" [variant]="action.variant || 'solid'" [theme]="action.theme || 'gray'" (clicked)="onActionClick(action)">
8548
+ {{ action.label }}
8549
+ @if (action.icon) { <span icon [class]="action.icon + ' size-4'"></span> }
8550
+ </neural-button>
8551
+ }
8552
+ </div>
8553
+ }
8731
8554
  </div>
8732
8555
  }
8733
-
8734
- @if (showCloseButton() && !showHeader()) {
8735
- <neural-button
8736
- class="absolute right-4 top-4 z-10"
8737
- variant="ghost"
8738
- label="Close"
8739
- (click)="close()"
8740
- >
8741
- <span icon class="lucide-x size-4 text-ink-gray-9"></span>
8742
- </neural-button>
8743
- }
8744
- </div>
8556
+ }
8745
8557
  </div>
8746
8558
  </div>
8747
- </ng-template>
8559
+ </div>
8748
8560
  }
8749
8561
  `
8750
8562
  }]
8751
- }], ctorParameters: () => [{ type: i1$3.Dialog }, { type: i0.ViewContainerRef }], propDecorators: { openModel: [{ type: i0.Input, args: [{ isSignal: true, alias: "openModel", required: false }] }, { type: i0.Output, args: ["openModelChange"] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], paddingTop: [{ type: i0.Input, args: [{ isSignal: true, alias: "paddingTop", required: false }] }], actions: [{ type: i0.Input, args: [{ isSignal: true, alias: "actions", required: false }] }], dismissible: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissible", required: false }] }], showCloseButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCloseButton", required: false }] }], bare: [{ type: i0.Input, args: [{ isSignal: true, alias: "bare", required: false }] }], hasTitleSlot: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasTitleSlot", required: false }] }], hasActionsSlot: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasActionsSlot", required: false }] }], hasDefaultSlot: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasDefaultSlot", required: false }] }], dialogTemplate: [{
8752
- type: ViewChild,
8753
- args: ['dialogTemplate']
8754
- }] } });
8563
+ }], ctorParameters: () => [], propDecorators: { openModel: [{ type: i0.Input, args: [{ isSignal: true, alias: "openModel", required: false }] }, { type: i0.Output, args: ["openModelChange"] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], paddingTop: [{ type: i0.Input, args: [{ isSignal: true, alias: "paddingTop", required: false }] }], actions: [{ type: i0.Input, args: [{ isSignal: true, alias: "actions", required: false }] }], dismissible: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissible", required: false }] }], showCloseButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCloseButton", required: false }] }], bare: [{ type: i0.Input, args: [{ isSignal: true, alias: "bare", required: false }] }], hasTitleSlot: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasTitleSlot", required: false }] }], hasActionsSlot: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasActionsSlot", required: false }] }], hasDefaultSlot: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasDefaultSlot", required: false }] }] } });
8755
8564
 
8756
8565
  class NeuralAwesomeBarComponent {
8757
8566
  searchInput;
@@ -8851,14 +8660,23 @@ class NeuralAwesomeBarComponent {
8851
8660
  (ngModelChange)="onQueryChange($event)"
8852
8661
  (keydown)="handleKeydown($event)"
8853
8662
  />
8854
- @if (query()) {
8855
- <button
8856
- class="flex items-center justify-center size-6 rounded-md hover:bg-surface-gray-2 transition-colors ml-2"
8857
- (click)="clearQuery()"
8858
- >
8859
- <i class="lucide-x size-4 text-ink-gray-5"></i>
8663
+ <div class="flex items-center gap-1 ml-3 text-ink-gray-4">
8664
+ @if (query()) {
8665
+ <button class="flex items-center justify-center size-7 rounded hover:bg-surface-gray-2 transition-colors text-ink-gray-5 hover:text-ink-gray-7" (click)="clearQuery()">
8666
+ <i class="lucide-delete size-4"></i>
8667
+ </button>
8668
+ <div class="w-px h-4 bg-outline-gray-2 mx-1"></div>
8669
+ }
8670
+ <button class="flex items-center justify-center size-7 rounded hover:bg-surface-gray-2 transition-colors text-ink-gray-5 hover:text-ink-gray-7">
8671
+ <i class="lucide-settings size-4"></i>
8860
8672
  </button>
8861
- }
8673
+ <button class="flex items-center justify-center size-7 rounded hover:bg-surface-gray-2 transition-colors text-ink-gray-5 hover:text-ink-gray-7">
8674
+ <i class="lucide-maximize-2 size-4"></i>
8675
+ </button>
8676
+ <button class="flex items-center justify-center size-7 rounded hover:bg-surface-gray-2 transition-colors text-ink-gray-5 hover:text-ink-gray-7" (click)="openModel.set(false)">
8677
+ <i class="lucide-x size-4"></i>
8678
+ </button>
8679
+ </div>
8862
8680
  </div>
8863
8681
 
8864
8682
  <!-- Filters (Chips) -->
@@ -8910,12 +8728,17 @@ class NeuralAwesomeBarComponent {
8910
8728
  <!-- Empty State -->
8911
8729
  <div class="flex flex-col items-center justify-center py-16 px-4 text-center">
8912
8730
  <div class="size-16 rounded-full bg-surface-gray-2 flex items-center justify-center mb-4">
8913
- <i class="lucide-search size-8 text-ink-gray-4"></i>
8731
+ <i class="lucide-clipboard-search size-8 text-ink-gray-4"></i>
8914
8732
  </div>
8915
8733
  <h3 class="text-base font-semibold text-ink-gray-9 mb-1">Buscar por cualquier cosa</h3>
8916
- <p class="text-sm text-ink-gray-5 max-w-sm">
8917
- Escribe para buscar a través de módulos, clientes, productos y configuraciones.
8734
+ <p class="text-sm text-ink-gray-5 max-w-sm mb-4">
8735
+ Use ampersand to match multiple terms (ej. Marie&amp;John)
8918
8736
  </p>
8737
+ <div class="flex items-center gap-1.5 text-xs text-ink-gray-5">
8738
+ <kbd class="px-1.5 py-0.5 rounded border border-outline-gray-3 bg-surface-base font-sans text-[10px] text-ink-gray-7 shadow-sm">⌘</kbd>
8739
+ <kbd class="px-1.5 py-0.5 rounded border border-outline-gray-3 bg-surface-base font-sans text-[10px] text-ink-gray-7 shadow-sm">K</kbd>
8740
+ <span>to open Awesome Bar</span>
8741
+ </div>
8919
8742
  </div>
8920
8743
  } @else {
8921
8744
  <!-- Results Projection -->
@@ -8971,14 +8794,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
8971
8794
  (ngModelChange)="onQueryChange($event)"
8972
8795
  (keydown)="handleKeydown($event)"
8973
8796
  />
8974
- @if (query()) {
8975
- <button
8976
- class="flex items-center justify-center size-6 rounded-md hover:bg-surface-gray-2 transition-colors ml-2"
8977
- (click)="clearQuery()"
8978
- >
8979
- <i class="lucide-x size-4 text-ink-gray-5"></i>
8797
+ <div class="flex items-center gap-1 ml-3 text-ink-gray-4">
8798
+ @if (query()) {
8799
+ <button class="flex items-center justify-center size-7 rounded hover:bg-surface-gray-2 transition-colors text-ink-gray-5 hover:text-ink-gray-7" (click)="clearQuery()">
8800
+ <i class="lucide-delete size-4"></i>
8801
+ </button>
8802
+ <div class="w-px h-4 bg-outline-gray-2 mx-1"></div>
8803
+ }
8804
+ <button class="flex items-center justify-center size-7 rounded hover:bg-surface-gray-2 transition-colors text-ink-gray-5 hover:text-ink-gray-7">
8805
+ <i class="lucide-settings size-4"></i>
8980
8806
  </button>
8981
- }
8807
+ <button class="flex items-center justify-center size-7 rounded hover:bg-surface-gray-2 transition-colors text-ink-gray-5 hover:text-ink-gray-7">
8808
+ <i class="lucide-maximize-2 size-4"></i>
8809
+ </button>
8810
+ <button class="flex items-center justify-center size-7 rounded hover:bg-surface-gray-2 transition-colors text-ink-gray-5 hover:text-ink-gray-7" (click)="openModel.set(false)">
8811
+ <i class="lucide-x size-4"></i>
8812
+ </button>
8813
+ </div>
8982
8814
  </div>
8983
8815
 
8984
8816
  <!-- Filters (Chips) -->
@@ -9030,12 +8862,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
9030
8862
  <!-- Empty State -->
9031
8863
  <div class="flex flex-col items-center justify-center py-16 px-4 text-center">
9032
8864
  <div class="size-16 rounded-full bg-surface-gray-2 flex items-center justify-center mb-4">
9033
- <i class="lucide-search size-8 text-ink-gray-4"></i>
8865
+ <i class="lucide-clipboard-search size-8 text-ink-gray-4"></i>
9034
8866
  </div>
9035
8867
  <h3 class="text-base font-semibold text-ink-gray-9 mb-1">Buscar por cualquier cosa</h3>
9036
- <p class="text-sm text-ink-gray-5 max-w-sm">
9037
- Escribe para buscar a través de módulos, clientes, productos y configuraciones.
8868
+ <p class="text-sm text-ink-gray-5 max-w-sm mb-4">
8869
+ Use ampersand to match multiple terms (ej. Marie&amp;John)
9038
8870
  </p>
8871
+ <div class="flex items-center gap-1.5 text-xs text-ink-gray-5">
8872
+ <kbd class="px-1.5 py-0.5 rounded border border-outline-gray-3 bg-surface-base font-sans text-[10px] text-ink-gray-7 shadow-sm">⌘</kbd>
8873
+ <kbd class="px-1.5 py-0.5 rounded border border-outline-gray-3 bg-surface-base font-sans text-[10px] text-ink-gray-7 shadow-sm">K</kbd>
8874
+ <span>to open Awesome Bar</span>
8875
+ </div>
9039
8876
  </div>
9040
8877
  } @else {
9041
8878
  <!-- Results Projection -->