minahil 0.1.21 → 0.1.22

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Component, EventEmitter, HostListener, ViewChildren, Output, Input, Injectable, NgModule, forwardRef, ViewEncapsulation, Directive, InjectionToken, inject, ElementRef } from '@angular/core';
2
+ import { Component, EventEmitter, HostListener, ViewChildren, Output, Input, Injectable, NgModule, forwardRef, ViewEncapsulation, InjectionToken, inject, ElementRef, Directive } from '@angular/core';
3
3
  import * as i1 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
5
  import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
@@ -2330,283 +2330,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
2330
2330
  type: Output
2331
2331
  }] } });
2332
2332
 
2333
- class BKTooltipDirective {
2334
- el;
2335
- renderer;
2336
- tooltipContent = '';
2337
- tooltipPosition = 'right';
2338
- tooltipElement = null;
2339
- constructor(el, renderer) {
2340
- this.el = el;
2341
- this.renderer = renderer;
2342
- }
2343
- ngOnInit() {
2344
- this.createTooltip();
2345
- }
2346
- ngOnChanges(changes) {
2347
- if (changes['tooltipContent'] && !changes['tooltipContent'].firstChange) {
2348
- this.updateTooltipContent();
2349
- }
2350
- }
2351
- ngOnDestroy() {
2352
- this.removeTooltip();
2353
- }
2354
- updateTooltipContent() {
2355
- // If tooltip doesn't exist yet and content is now available, create it
2356
- if (!this.tooltipElement && !this.isTooltipContentEmpty()) {
2357
- this.createTooltip();
2358
- return;
2359
- }
2360
- if (!this.tooltipElement)
2361
- return;
2362
- if (this.isTooltipContentEmpty())
2363
- return;
2364
- // remove old .text nodes
2365
- Array.from(this.tooltipElement.querySelectorAll('.text')).forEach((el) => this.renderer.removeChild(this.tooltipElement, el));
2366
- this.appendContent();
2367
- }
2368
- appendContent() {
2369
- if (!this.tooltipElement)
2370
- return;
2371
- const contentLines = Array.isArray(this.tooltipContent)
2372
- ? this.tooltipContent
2373
- : [this.tooltipContent];
2374
- contentLines.forEach((line) => {
2375
- const div = this.renderer.createElement('div');
2376
- this.renderer.addClass(div, 'text');
2377
- if (line?.trim().startsWith('<')) {
2378
- div.innerHTML = line;
2379
- }
2380
- else {
2381
- const text = this.renderer.createText(line ?? '');
2382
- this.renderer.appendChild(div, text);
2383
- }
2384
- this.renderer.appendChild(this.tooltipElement, div);
2385
- });
2386
- }
2387
- onMouseEnter() {
2388
- if (this.tooltipElement) {
2389
- this.setTooltipPosition();
2390
- this.setStyle(this.tooltipElement, {
2391
- visibility: 'visible',
2392
- opacity: '1',
2393
- });
2394
- this.renderer.setStyle(document.body, 'overflow-x', 'hidden'); // ✅ temporarily lock horizontal scroll
2395
- }
2396
- }
2397
- onMouseLeave() {
2398
- if (this.tooltipElement) {
2399
- this.setStyle(this.tooltipElement, {
2400
- visibility: 'hidden',
2401
- opacity: '0',
2402
- });
2403
- this.renderer.removeStyle(document.body, 'overflow-x'); // ✅ restore scroll when tooltip hides
2404
- }
2405
- }
2406
- onWindowChange() {
2407
- if (this.tooltipElement?.style.visibility === 'visible') {
2408
- this.setTooltipPosition();
2409
- }
2410
- }
2411
- isTooltipContentEmpty() {
2412
- if (typeof this.tooltipContent === 'string') {
2413
- return !this.tooltipContent.trim();
2414
- }
2415
- else if (Array.isArray(this.tooltipContent)) {
2416
- return this.tooltipContent.length === 0 || this.tooltipContent.every((line) => !line.trim());
2417
- }
2418
- return true;
2419
- }
2420
- createTooltip() {
2421
- if (this.isTooltipContentEmpty())
2422
- return;
2423
- this.tooltipElement = this.renderer.createElement('div');
2424
- this.renderer.addClass(this.tooltipElement, 'bk-tooltip-content');
2425
- // Add content
2426
- const contentLines = Array.isArray(this.tooltipContent)
2427
- ? this.tooltipContent
2428
- : [this.tooltipContent];
2429
- contentLines.forEach((line) => {
2430
- const div = this.renderer.createElement('div');
2431
- this.renderer.addClass(div, 'text');
2432
- // this.renderer.appendChild(div, this.renderer.createText(line));
2433
- // Check if the line contains HTML
2434
- if (line.trim().startsWith('<')) {
2435
- div.innerHTML = line;
2436
- }
2437
- else {
2438
- const text = this.renderer.createText(line);
2439
- this.renderer.appendChild(div, text);
2440
- }
2441
- this.renderer.appendChild(this.tooltipElement, div);
2442
- });
2443
- // Add triangle
2444
- const triangle = this.renderer.createElement('div');
2445
- this.renderer.addClass(triangle, 'bk-tooltip-triangle');
2446
- this.renderer.appendChild(this.tooltipElement, triangle);
2447
- // Set base styles
2448
- this.setStyle(this.tooltipElement, {
2449
- position: 'fixed',
2450
- visibility: 'hidden',
2451
- opacity: '0',
2452
- zIndex: '9999',
2453
- transition: 'opacity 0.3s ease, visibility 0.3s ease',
2454
- });
2455
- this.renderer.appendChild(document.body, this.tooltipElement);
2456
- }
2457
- setTooltipPosition() {
2458
- if (!this.tooltipElement)
2459
- return;
2460
- const hostRect = this.el.nativeElement.getBoundingClientRect();
2461
- const tooltipRect = this.tooltipElement.getBoundingClientRect();
2462
- const triangle = this.tooltipElement.querySelector('.bk-tooltip-triangle');
2463
- const padding = 10;
2464
- let top = 0, left = 0;
2465
- // Position logic — using viewport-relative coords (getBoundingClientRect)
2466
- // since the tooltip uses position: fixed (no scroll offset needed)
2467
- switch (this.tooltipPosition) {
2468
- case 'right':
2469
- case 'left':
2470
- top = hostRect.top + hostRect.height / 2;
2471
- left =
2472
- this.tooltipPosition === 'right'
2473
- ? hostRect.right + padding
2474
- : hostRect.left - tooltipRect.width - padding;
2475
- // Auto flip if out of viewport
2476
- if (this.tooltipPosition === 'right' && left + tooltipRect.width > window.innerWidth) {
2477
- left = hostRect.left - tooltipRect.width - padding;
2478
- }
2479
- else if (this.tooltipPosition === 'left' && left < 0) {
2480
- left = hostRect.right + padding;
2481
- }
2482
- this.setStyle(this.tooltipElement, {
2483
- transform: 'translateY(-50%)',
2484
- });
2485
- this.setTriangleStyles(triangle, this.tooltipPosition, left < hostRect.left);
2486
- break;
2487
- case 'top':
2488
- case 'bottom':
2489
- left = hostRect.left + hostRect.width / 2 - tooltipRect.width / 2;
2490
- top =
2491
- this.tooltipPosition === 'top'
2492
- ? hostRect.top - tooltipRect.height - padding
2493
- : hostRect.bottom + padding;
2494
- // Prevent overflow
2495
- left = Math.max(10, Math.min(left, window.innerWidth - tooltipRect.width - 10));
2496
- this.setStyle(this.tooltipElement, {
2497
- transform: 'translateX(0)',
2498
- });
2499
- this.setTriangleStyles(triangle, this.tooltipPosition);
2500
- break;
2501
- }
2502
- this.setStyle(this.tooltipElement, {
2503
- top: `${top}px`,
2504
- left: `${left}px`,
2505
- });
2506
- }
2507
- setTriangleStyles(triangle, position, flipped = false) {
2508
- if (!triangle)
2509
- return;
2510
- const base = {
2511
- top: '',
2512
- left: '',
2513
- right: '',
2514
- bottom: '',
2515
- transform: '',
2516
- borderColor: '',
2517
- };
2518
- let styles = { ...base };
2519
- switch (position) {
2520
- case 'right':
2521
- styles = flipped
2522
- ? {
2523
- left: '100%',
2524
- top: '50%',
2525
- transform: 'translateY(-50%) translateX(0)',
2526
- borderColor: 'transparent transparent transparent #1a1a1a',
2527
- }
2528
- : {
2529
- left: '-15px',
2530
- top: '50%',
2531
- transform: 'translateY(-50%)',
2532
- borderColor: 'transparent #1a1a1a transparent transparent',
2533
- };
2534
- break;
2535
- case 'left':
2536
- styles = flipped
2537
- ? {
2538
- left: '100%',
2539
- top: '50%',
2540
- transform: 'translateY(-50%) translateX(0)',
2541
- borderColor: 'transparent transparent transparent #1a1a1a',
2542
- }
2543
- : {
2544
- left: '-15px',
2545
- top: '50%',
2546
- transform: 'translateY(-50%)',
2547
- borderColor: 'transparent #1a1a1a transparent transparent',
2548
- };
2549
- break;
2550
- case 'top':
2551
- styles = {
2552
- bottom: '-15px',
2553
- left: '50%',
2554
- transform: 'translateX(-50%)',
2555
- borderColor: '#1a1a1a transparent transparent transparent',
2556
- };
2557
- break;
2558
- case 'bottom':
2559
- styles = {
2560
- top: '-15px',
2561
- left: '50%',
2562
- transform: 'translateX(-50%)',
2563
- borderColor: 'transparent transparent #1a1a1a transparent',
2564
- };
2565
- break;
2566
- }
2567
- this.setStyle(triangle, styles);
2568
- }
2569
- removeTooltip() {
2570
- if (this.tooltipElement) {
2571
- this.renderer.removeChild(document.body, this.tooltipElement);
2572
- this.tooltipElement = null;
2573
- }
2574
- }
2575
- // Utility function to apply multiple styles
2576
- setStyle(el, styles) {
2577
- Object.entries(styles).forEach(([prop, value]) => {
2578
- this.renderer.setStyle(el, prop, value);
2579
- });
2580
- }
2581
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BKTooltipDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
2582
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.16", type: BKTooltipDirective, isStandalone: true, selector: "[bkTooltip]", inputs: { tooltipContent: ["bkTooltip", "tooltipContent"], tooltipPosition: ["bkTooltipPosition", "tooltipPosition"] }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()", "window:scroll": "onWindowChange()", "window:resize": "onWindowChange()" } }, usesOnChanges: true, ngImport: i0 });
2583
- }
2584
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BKTooltipDirective, decorators: [{
2585
- type: Directive,
2586
- args: [{
2587
- selector: '[bkTooltip]',
2588
- standalone: true,
2589
- }]
2590
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { tooltipContent: [{
2591
- type: Input,
2592
- args: ['bkTooltip']
2593
- }], tooltipPosition: [{
2594
- type: Input,
2595
- args: ['bkTooltipPosition']
2596
- }], onMouseEnter: [{
2597
- type: HostListener,
2598
- args: ['mouseenter']
2599
- }], onMouseLeave: [{
2600
- type: HostListener,
2601
- args: ['mouseleave']
2602
- }], onWindowChange: [{
2603
- type: HostListener,
2604
- args: ['window:scroll']
2605
- }, {
2606
- type: HostListener,
2607
- args: ['window:resize']
2608
- }] } });
2609
-
2610
2333
  class CheckboxComponent {
2611
2334
  checkboxClass = '';
2612
2335
  label = '';
@@ -2647,19 +2370,19 @@ class CheckboxComponent {
2647
2370
  {
2648
2371
  provide: NG_VALUE_ACCESSOR,
2649
2372
  useExisting: forwardRef(() => CheckboxComponent),
2650
- multi: true,
2651
- },
2652
- ], ngImport: i0, template: "<div\n class=\"inline-flex items-center gap-2 cursor-pointer group outline-none\"\n (click)=\"toggle()\"\n (keydown.enter)=\"toggle()\"\n (keydown.space)=\"$event.preventDefault(); toggle()\"\n tabindex=\"0\"\n [attr.aria-disabled]=\"disabled\"\n>\n <div\n class=\"relative flex items-center justify-center border-2 transition-all duration-200 ease-in-out rounded group-focus-visible:ring-2 group-focus-visible:ring-blue-600 group-focus-visible:ring-offset-2\"\n [ngClass]=\"[\n checkboxClass,\n isChecked && !disabled ? 'bg-black border-black' : '',\n !isChecked && !disabled ? 'bg-white border-gray-300 group-hover:border-gray-400' : '',\n disabled && isChecked ? 'bg-gray-300 border-gray-300' : '',\n disabled && !isChecked ? 'bg-gray-100 border-gray-200' : '',\n disabled ? 'cursor-not-allowed' : '',\n ]\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"text-white pointer-events-none transition-opacity duration-200\"\n [class.opacity-0]=\"!isChecked\"\n [class.opacity-100]=\"isChecked\"\n >\n <polyline points=\"20 6 9 17 4 12\"></polyline>\n </svg>\n </div>\n @if (label) {\n <span\n [bkTooltip]=\"'test label'\"\n [bkTooltipPosition]=\"'top'\"\n [ngClass]=\"disabled ? 'text-gray-400' : ''\"\n class=\"font-medium text-xs text-[#1B223A] select-none {{ labelClass }}\"\n >\n {{ label }}\n </span>\n }\n</div>\n", styles: [".xsm{@apply size-[14px];}.sm{@apply size-[16px];}.md{@apply size-[18px];}.lg{@apply size-[20px];}.xsm svg{@apply size-[10.5px];}.sm svg{@apply size-[12px];}.md svg{@apply size-[13.5px];}.lg svg{@apply size-[14px];}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: BKTooltipDirective, selector: "[bkTooltip]", inputs: ["bkTooltip", "bkTooltipPosition"] }], encapsulation: i0.ViewEncapsulation.None });
2373
+ multi: true
2374
+ }
2375
+ ], ngImport: i0, template: "<div\r\n class=\"inline-flex items-center gap-2 cursor-pointer group outline-none\"\r\n (click)=\"toggle()\"\r\n (keydown.enter)=\"toggle()\"\r\n (keydown.space)=\"$event.preventDefault(); toggle()\"\r\n tabindex=\"0\"\r\n [attr.aria-disabled]=\"disabled\">\r\n <div\r\n class=\"relative flex items-center justify-center border-2 transition-all duration-200 ease-in-out rounded group-focus-visible:ring-2 group-focus-visible:ring-blue-600 group-focus-visible:ring-offset-2\"\r\n [ngClass]=\"[\r\n checkboxClass,\r\n isChecked && !disabled ? 'bg-black border-black' : '',\r\n !isChecked && !disabled ? 'bg-white border-gray-300 group-hover:border-gray-400' : '',\r\n disabled && isChecked ? 'bg-gray-300 border-gray-300' : '',\r\n disabled && !isChecked ? 'bg-gray-100 border-gray-200' : '',\r\n disabled ? 'cursor-not-allowed' : ''\r\n ]\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"3.5\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n class=\"text-white pointer-events-none transition-opacity duration-200\"\r\n [class.opacity-0]=\"!isChecked\"\r\n [class.opacity-100]=\"isChecked\"\r\n >\r\n <polyline points=\"20 6 9 17 4 12\"></polyline>\r\n </svg>\r\n </div>\r\n@if(label){\r\n <span\r\n [ngClass]=\"disabled ? 'text-gray-400' : ''\"\r\n class=\"font-medium text-xs text-[#1B223A] select-none {{labelClass}}\"\r\n >\r\n {{ label }}\r\n </span>\r\n}\r\n</div>\r\n", styles: [".xsm{@apply size-[14px];}.sm{@apply size-[16px];}.md{@apply size-[18px];}.lg{@apply size-[20px];}.xsm svg{@apply size-[10.5px];}.sm svg{@apply size-[12px];}.md svg{@apply size-[13.5px];}.lg svg{@apply size-[14px];}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], encapsulation: i0.ViewEncapsulation.None });
2653
2376
  }
2654
2377
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CheckboxComponent, decorators: [{
2655
2378
  type: Component,
2656
- args: [{ selector: 'brickclay-checkbox', standalone: true, imports: [CommonModule, BKTooltipDirective], encapsulation: ViewEncapsulation.None, providers: [
2379
+ args: [{ selector: 'brickclay-checkbox', standalone: true, imports: [CommonModule], encapsulation: ViewEncapsulation.None, providers: [
2657
2380
  {
2658
2381
  provide: NG_VALUE_ACCESSOR,
2659
2382
  useExisting: forwardRef(() => CheckboxComponent),
2660
- multi: true,
2661
- },
2662
- ], template: "<div\n class=\"inline-flex items-center gap-2 cursor-pointer group outline-none\"\n (click)=\"toggle()\"\n (keydown.enter)=\"toggle()\"\n (keydown.space)=\"$event.preventDefault(); toggle()\"\n tabindex=\"0\"\n [attr.aria-disabled]=\"disabled\"\n>\n <div\n class=\"relative flex items-center justify-center border-2 transition-all duration-200 ease-in-out rounded group-focus-visible:ring-2 group-focus-visible:ring-blue-600 group-focus-visible:ring-offset-2\"\n [ngClass]=\"[\n checkboxClass,\n isChecked && !disabled ? 'bg-black border-black' : '',\n !isChecked && !disabled ? 'bg-white border-gray-300 group-hover:border-gray-400' : '',\n disabled && isChecked ? 'bg-gray-300 border-gray-300' : '',\n disabled && !isChecked ? 'bg-gray-100 border-gray-200' : '',\n disabled ? 'cursor-not-allowed' : '',\n ]\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"text-white pointer-events-none transition-opacity duration-200\"\n [class.opacity-0]=\"!isChecked\"\n [class.opacity-100]=\"isChecked\"\n >\n <polyline points=\"20 6 9 17 4 12\"></polyline>\n </svg>\n </div>\n @if (label) {\n <span\n [bkTooltip]=\"'test label'\"\n [bkTooltipPosition]=\"'top'\"\n [ngClass]=\"disabled ? 'text-gray-400' : ''\"\n class=\"font-medium text-xs text-[#1B223A] select-none {{ labelClass }}\"\n >\n {{ label }}\n </span>\n }\n</div>\n", styles: [".xsm{@apply size-[14px];}.sm{@apply size-[16px];}.md{@apply size-[18px];}.lg{@apply size-[20px];}.xsm svg{@apply size-[10.5px];}.sm svg{@apply size-[12px];}.md svg{@apply size-[13.5px];}.lg svg{@apply size-[14px];}\n"] }]
2383
+ multi: true
2384
+ }
2385
+ ], template: "<div\r\n class=\"inline-flex items-center gap-2 cursor-pointer group outline-none\"\r\n (click)=\"toggle()\"\r\n (keydown.enter)=\"toggle()\"\r\n (keydown.space)=\"$event.preventDefault(); toggle()\"\r\n tabindex=\"0\"\r\n [attr.aria-disabled]=\"disabled\">\r\n <div\r\n class=\"relative flex items-center justify-center border-2 transition-all duration-200 ease-in-out rounded group-focus-visible:ring-2 group-focus-visible:ring-blue-600 group-focus-visible:ring-offset-2\"\r\n [ngClass]=\"[\r\n checkboxClass,\r\n isChecked && !disabled ? 'bg-black border-black' : '',\r\n !isChecked && !disabled ? 'bg-white border-gray-300 group-hover:border-gray-400' : '',\r\n disabled && isChecked ? 'bg-gray-300 border-gray-300' : '',\r\n disabled && !isChecked ? 'bg-gray-100 border-gray-200' : '',\r\n disabled ? 'cursor-not-allowed' : ''\r\n ]\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"3.5\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n class=\"text-white pointer-events-none transition-opacity duration-200\"\r\n [class.opacity-0]=\"!isChecked\"\r\n [class.opacity-100]=\"isChecked\"\r\n >\r\n <polyline points=\"20 6 9 17 4 12\"></polyline>\r\n </svg>\r\n </div>\r\n@if(label){\r\n <span\r\n [ngClass]=\"disabled ? 'text-gray-400' : ''\"\r\n class=\"font-medium text-xs text-[#1B223A] select-none {{labelClass}}\"\r\n >\r\n {{ label }}\r\n </span>\r\n}\r\n</div>\r\n", styles: [".xsm{@apply size-[14px];}.sm{@apply size-[16px];}.md{@apply size-[18px];}.lg{@apply size-[20px];}.xsm svg{@apply size-[10.5px];}.sm svg{@apply size-[12px];}.md svg{@apply size-[13.5px];}.lg svg{@apply size-[14px];}\n"] }]
2663
2386
  }], propDecorators: { checkboxClass: [{
2664
2387
  type: Input
2665
2388
  }], label: [{
@@ -3811,133 +3534,410 @@ class BkDialogClose {
3811
3534
  this._dialogRef = getClosestDialog(this._elementRef, this._dialogService.openDialogsRef);
3812
3535
  }
3813
3536
  }
3814
- ngOnChanges(changes) {
3815
- const proxiedChange = changes['_bkDialogClose'] || changes['dialogResult'];
3816
- if (proxiedChange) {
3817
- this.dialogResult = proxiedChange.currentValue;
3537
+ ngOnChanges(changes) {
3538
+ const proxiedChange = changes['_bkDialogClose'] || changes['dialogResult'];
3539
+ if (proxiedChange) {
3540
+ this.dialogResult = proxiedChange.currentValue;
3541
+ }
3542
+ }
3543
+ _onButtonClick(_event) {
3544
+ this._dialogRef?.close(this.dialogResult);
3545
+ }
3546
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkDialogClose, deps: [], target: i0.ɵɵFactoryTarget.Directive });
3547
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.16", type: BkDialogClose, isStandalone: true, selector: "[bk-dialog-close], [bkDialogClose]", inputs: { ariaLabel: ["aria-label", "ariaLabel"], type: "type", dialogResult: ["bk-dialog-close", "dialogResult"], _bkDialogClose: ["bkDialogClose", "_bkDialogClose"] }, host: { listeners: { "click": "_onButtonClick($event)" }, properties: { "attr.aria-label": "ariaLabel || null", "attr.type": "type" } }, exportAs: ["bkDialogClose"], usesOnChanges: true, ngImport: i0 });
3548
+ }
3549
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkDialogClose, decorators: [{
3550
+ type: Directive,
3551
+ args: [{
3552
+ selector: '[bk-dialog-close], [bkDialogClose]',
3553
+ standalone: true,
3554
+ exportAs: 'bkDialogClose',
3555
+ host: {
3556
+ '(click)': '_onButtonClick($event)',
3557
+ '[attr.aria-label]': 'ariaLabel || null',
3558
+ '[attr.type]': 'type',
3559
+ },
3560
+ }]
3561
+ }], propDecorators: { ariaLabel: [{
3562
+ type: Input,
3563
+ args: ['aria-label']
3564
+ }], type: [{
3565
+ type: Input
3566
+ }], dialogResult: [{
3567
+ type: Input,
3568
+ args: ['bk-dialog-close']
3569
+ }], _bkDialogClose: [{
3570
+ type: Input,
3571
+ args: ['bkDialogClose']
3572
+ }] } });
3573
+
3574
+ /**
3575
+ * BkDialogModule
3576
+ *
3577
+ * Optional NgModule wrapper for projects that prefer module-based usage.
3578
+ *
3579
+ * Architecture Decision:
3580
+ * ─────────────────────
3581
+ * Follows the exact same pattern as Angular Material's `MatDialogModule`
3582
+ * and `@brickclay-org/ui`'s `CalendarModule`:
3583
+ *
3584
+ * • All components/directives are **standalone**.
3585
+ * • This module simply imports + re-exports them for convenience.
3586
+ * • `DialogService` is `providedIn: 'root'`, so it does NOT need to
3587
+ * be listed in `providers` here — it is tree-shakeable and available
3588
+ * app-wide automatically.
3589
+ *
3590
+ * Two usage styles:
3591
+ *
3592
+ * ───────── Module-based (NgModule) ─────────
3593
+ * ```ts
3594
+ * import { BkDialogModule } from '@shared/components/dialog';
3595
+ *
3596
+ * @NgModule({ imports: [BkDialogModule] })
3597
+ * export class FuelCostModule {}
3598
+ * ```
3599
+ *
3600
+ * ───────── Standalone ──────────────────────
3601
+ * ```ts
3602
+ * @Component({
3603
+ * standalone: true,
3604
+ * imports: [BkDialogContent, BkDialogActions, BkDialogClose],
3605
+ * })
3606
+ * export class MyDialog {}
3607
+ * ```
3608
+ *
3609
+ * @see https://github.com/angular/components/blob/main/src/material/dialog/dialog-module.ts
3610
+ */
3611
+ class BkDialogModule {
3612
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkDialogModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
3613
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.16", ngImport: i0, type: BkDialogModule, imports: [
3614
+ // ── CDK foundations ──────────────────────────────────────────────
3615
+ DialogModule,
3616
+ OverlayModule,
3617
+ PortalModule,
3618
+ // ── Our standalone pieces ───────────────────────────────────────
3619
+ DialogContainerComponent,
3620
+ BkDialogTitle,
3621
+ BkDialogContent,
3622
+ BkDialogActions,
3623
+ BkDialogClose], exports: [
3624
+ // ── Public API for template usage ───────────────────────────────
3625
+ // Consumers import BkDialogModule and get these directives in
3626
+ // their templates automatically — just like MatDialogModule.
3627
+ BkDialogTitle,
3628
+ BkDialogContent,
3629
+ BkDialogActions,
3630
+ BkDialogClose] });
3631
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkDialogModule, imports: [
3632
+ // ── CDK foundations ──────────────────────────────────────────────
3633
+ DialogModule,
3634
+ OverlayModule,
3635
+ PortalModule] });
3636
+ }
3637
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkDialogModule, decorators: [{
3638
+ type: NgModule,
3639
+ args: [{
3640
+ imports: [
3641
+ // ── CDK foundations ──────────────────────────────────────────────
3642
+ DialogModule,
3643
+ OverlayModule,
3644
+ PortalModule,
3645
+ // ── Our standalone pieces ───────────────────────────────────────
3646
+ DialogContainerComponent,
3647
+ BkDialogTitle,
3648
+ BkDialogContent,
3649
+ BkDialogActions,
3650
+ BkDialogClose,
3651
+ ],
3652
+ exports: [
3653
+ // ── Public API for template usage ───────────────────────────────
3654
+ // Consumers import BkDialogModule and get these directives in
3655
+ // their templates automatically — just like MatDialogModule.
3656
+ BkDialogTitle,
3657
+ BkDialogContent,
3658
+ BkDialogActions,
3659
+ BkDialogClose,
3660
+ ],
3661
+ }]
3662
+ }] });
3663
+
3664
+ class BKTooltipDirective {
3665
+ el;
3666
+ renderer;
3667
+ tooltipContent = '';
3668
+ tooltipPosition = 'right';
3669
+ tooltipElement = null;
3670
+ constructor(el, renderer) {
3671
+ this.el = el;
3672
+ this.renderer = renderer;
3673
+ }
3674
+ ngOnInit() {
3675
+ this.createTooltip();
3676
+ }
3677
+ ngOnChanges(changes) {
3678
+ if (changes['tooltipContent'] && !changes['tooltipContent'].firstChange) {
3679
+ this.updateTooltipContent();
3680
+ }
3681
+ }
3682
+ ngOnDestroy() {
3683
+ this.removeTooltip();
3684
+ }
3685
+ updateTooltipContent() {
3686
+ // If tooltip doesn't exist yet and content is now available, create it
3687
+ if (!this.tooltipElement && !this.isTooltipContentEmpty()) {
3688
+ this.createTooltip();
3689
+ return;
3690
+ }
3691
+ if (!this.tooltipElement)
3692
+ return;
3693
+ if (this.isTooltipContentEmpty())
3694
+ return;
3695
+ // remove old .text nodes
3696
+ Array.from(this.tooltipElement.querySelectorAll('.text')).forEach((el) => this.renderer.removeChild(this.tooltipElement, el));
3697
+ this.appendContent();
3698
+ }
3699
+ appendContent() {
3700
+ if (!this.tooltipElement)
3701
+ return;
3702
+ const contentLines = Array.isArray(this.tooltipContent)
3703
+ ? this.tooltipContent
3704
+ : [this.tooltipContent];
3705
+ contentLines.forEach((line) => {
3706
+ const div = this.renderer.createElement('div');
3707
+ this.renderer.addClass(div, 'text');
3708
+ if (line?.trim().startsWith('<')) {
3709
+ div.innerHTML = line;
3710
+ }
3711
+ else {
3712
+ const text = this.renderer.createText(line ?? '');
3713
+ this.renderer.appendChild(div, text);
3714
+ }
3715
+ this.renderer.appendChild(this.tooltipElement, div);
3716
+ });
3717
+ }
3718
+ onMouseEnter() {
3719
+ if (this.tooltipElement) {
3720
+ this.setTooltipPosition();
3721
+ this.setStyle(this.tooltipElement, {
3722
+ visibility: 'visible',
3723
+ opacity: '1',
3724
+ });
3725
+ this.renderer.setStyle(document.body, 'overflow-x', 'hidden'); // ✅ temporarily lock horizontal scroll
3726
+ }
3727
+ }
3728
+ onMouseLeave() {
3729
+ if (this.tooltipElement) {
3730
+ this.setStyle(this.tooltipElement, {
3731
+ visibility: 'hidden',
3732
+ opacity: '0',
3733
+ });
3734
+ this.renderer.removeStyle(document.body, 'overflow-x'); // ✅ restore scroll when tooltip hides
3735
+ }
3736
+ }
3737
+ onWindowChange() {
3738
+ if (this.tooltipElement?.style.visibility === 'visible') {
3739
+ this.setTooltipPosition();
3740
+ }
3741
+ }
3742
+ isTooltipContentEmpty() {
3743
+ if (typeof this.tooltipContent === 'string') {
3744
+ return !this.tooltipContent.trim();
3745
+ }
3746
+ else if (Array.isArray(this.tooltipContent)) {
3747
+ return this.tooltipContent.length === 0 || this.tooltipContent.every((line) => !line.trim());
3748
+ }
3749
+ return true;
3750
+ }
3751
+ createTooltip() {
3752
+ if (this.isTooltipContentEmpty())
3753
+ return;
3754
+ this.tooltipElement = this.renderer.createElement('div');
3755
+ this.renderer.addClass(this.tooltipElement, 'bk-tooltip-content');
3756
+ // Add content
3757
+ const contentLines = Array.isArray(this.tooltipContent)
3758
+ ? this.tooltipContent
3759
+ : [this.tooltipContent];
3760
+ contentLines.forEach((line) => {
3761
+ const div = this.renderer.createElement('div');
3762
+ this.renderer.addClass(div, 'text');
3763
+ // this.renderer.appendChild(div, this.renderer.createText(line));
3764
+ // Check if the line contains HTML
3765
+ if (line.trim().startsWith('<')) {
3766
+ div.innerHTML = line;
3767
+ }
3768
+ else {
3769
+ const text = this.renderer.createText(line);
3770
+ this.renderer.appendChild(div, text);
3771
+ }
3772
+ this.renderer.appendChild(this.tooltipElement, div);
3773
+ });
3774
+ // Add triangle
3775
+ const triangle = this.renderer.createElement('div');
3776
+ this.renderer.addClass(triangle, 'bk-tooltip-triangle');
3777
+ this.renderer.appendChild(this.tooltipElement, triangle);
3778
+ // Set base styles
3779
+ this.setStyle(this.tooltipElement, {
3780
+ position: 'fixed',
3781
+ visibility: 'hidden',
3782
+ opacity: '0',
3783
+ zIndex: '9999',
3784
+ transition: 'opacity 0.3s ease, visibility 0.3s ease',
3785
+ });
3786
+ this.renderer.appendChild(document.body, this.tooltipElement);
3787
+ }
3788
+ setTooltipPosition() {
3789
+ if (!this.tooltipElement)
3790
+ return;
3791
+ const hostRect = this.el.nativeElement.getBoundingClientRect();
3792
+ const tooltipRect = this.tooltipElement.getBoundingClientRect();
3793
+ const triangle = this.tooltipElement.querySelector('.bk-tooltip-triangle');
3794
+ const padding = 10;
3795
+ let top = 0, left = 0;
3796
+ // Position logic — using viewport-relative coords (getBoundingClientRect)
3797
+ // since the tooltip uses position: fixed (no scroll offset needed)
3798
+ switch (this.tooltipPosition) {
3799
+ case 'right':
3800
+ case 'left':
3801
+ top = hostRect.top + hostRect.height / 2;
3802
+ left =
3803
+ this.tooltipPosition === 'right'
3804
+ ? hostRect.right + padding
3805
+ : hostRect.left - tooltipRect.width - padding;
3806
+ // Auto flip if out of viewport
3807
+ if (this.tooltipPosition === 'right' && left + tooltipRect.width > window.innerWidth) {
3808
+ left = hostRect.left - tooltipRect.width - padding;
3809
+ }
3810
+ else if (this.tooltipPosition === 'left' && left < 0) {
3811
+ left = hostRect.right + padding;
3812
+ }
3813
+ this.setStyle(this.tooltipElement, {
3814
+ transform: 'translateY(-50%)',
3815
+ });
3816
+ this.setTriangleStyles(triangle, this.tooltipPosition, left < hostRect.left);
3817
+ break;
3818
+ case 'top':
3819
+ case 'bottom':
3820
+ left = hostRect.left + hostRect.width / 2 - tooltipRect.width / 2;
3821
+ top =
3822
+ this.tooltipPosition === 'top'
3823
+ ? hostRect.top - tooltipRect.height - padding
3824
+ : hostRect.bottom + padding;
3825
+ // Prevent overflow
3826
+ left = Math.max(10, Math.min(left, window.innerWidth - tooltipRect.width - 10));
3827
+ this.setStyle(this.tooltipElement, {
3828
+ transform: 'translateX(0)',
3829
+ });
3830
+ this.setTriangleStyles(triangle, this.tooltipPosition);
3831
+ break;
3832
+ }
3833
+ this.setStyle(this.tooltipElement, {
3834
+ top: `${top}px`,
3835
+ left: `${left}px`,
3836
+ });
3837
+ }
3838
+ setTriangleStyles(triangle, position, flipped = false) {
3839
+ if (!triangle)
3840
+ return;
3841
+ const base = {
3842
+ top: '',
3843
+ left: '',
3844
+ right: '',
3845
+ bottom: '',
3846
+ transform: '',
3847
+ borderColor: '',
3848
+ };
3849
+ let styles = { ...base };
3850
+ switch (position) {
3851
+ case 'right':
3852
+ styles = flipped
3853
+ ? {
3854
+ left: '100%',
3855
+ top: '50%',
3856
+ transform: 'translateY(-50%) translateX(0)',
3857
+ borderColor: 'transparent transparent transparent #1a1a1a',
3858
+ }
3859
+ : {
3860
+ left: '-15px',
3861
+ top: '50%',
3862
+ transform: 'translateY(-50%)',
3863
+ borderColor: 'transparent #1a1a1a transparent transparent',
3864
+ };
3865
+ break;
3866
+ case 'left':
3867
+ styles = flipped
3868
+ ? {
3869
+ left: '100%',
3870
+ top: '50%',
3871
+ transform: 'translateY(-50%) translateX(0)',
3872
+ borderColor: 'transparent transparent transparent #1a1a1a',
3873
+ }
3874
+ : {
3875
+ left: '-15px',
3876
+ top: '50%',
3877
+ transform: 'translateY(-50%)',
3878
+ borderColor: 'transparent #1a1a1a transparent transparent',
3879
+ };
3880
+ break;
3881
+ case 'top':
3882
+ styles = {
3883
+ bottom: '-15px',
3884
+ left: '50%',
3885
+ transform: 'translateX(-50%)',
3886
+ borderColor: '#1a1a1a transparent transparent transparent',
3887
+ };
3888
+ break;
3889
+ case 'bottom':
3890
+ styles = {
3891
+ top: '-15px',
3892
+ left: '50%',
3893
+ transform: 'translateX(-50%)',
3894
+ borderColor: 'transparent transparent #1a1a1a transparent',
3895
+ };
3896
+ break;
3818
3897
  }
3898
+ this.setStyle(triangle, styles);
3819
3899
  }
3820
- _onButtonClick(_event) {
3821
- this._dialogRef?.close(this.dialogResult);
3900
+ removeTooltip() {
3901
+ if (this.tooltipElement) {
3902
+ this.renderer.removeChild(document.body, this.tooltipElement);
3903
+ this.tooltipElement = null;
3904
+ }
3822
3905
  }
3823
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkDialogClose, deps: [], target: i0.ɵɵFactoryTarget.Directive });
3824
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.16", type: BkDialogClose, isStandalone: true, selector: "[bk-dialog-close], [bkDialogClose]", inputs: { ariaLabel: ["aria-label", "ariaLabel"], type: "type", dialogResult: ["bk-dialog-close", "dialogResult"], _bkDialogClose: ["bkDialogClose", "_bkDialogClose"] }, host: { listeners: { "click": "_onButtonClick($event)" }, properties: { "attr.aria-label": "ariaLabel || null", "attr.type": "type" } }, exportAs: ["bkDialogClose"], usesOnChanges: true, ngImport: i0 });
3906
+ // Utility function to apply multiple styles
3907
+ setStyle(el, styles) {
3908
+ Object.entries(styles).forEach(([prop, value]) => {
3909
+ this.renderer.setStyle(el, prop, value);
3910
+ });
3911
+ }
3912
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BKTooltipDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
3913
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.16", type: BKTooltipDirective, isStandalone: true, selector: "[bkTooltip]", inputs: { tooltipContent: ["bkTooltip", "tooltipContent"], tooltipPosition: ["bkTooltipPosition", "tooltipPosition"] }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()", "window:scroll": "onWindowChange()", "window:resize": "onWindowChange()" } }, usesOnChanges: true, ngImport: i0 });
3825
3914
  }
3826
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkDialogClose, decorators: [{
3915
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BKTooltipDirective, decorators: [{
3827
3916
  type: Directive,
3828
3917
  args: [{
3829
- selector: '[bk-dialog-close], [bkDialogClose]',
3918
+ selector: '[bkTooltip]',
3830
3919
  standalone: true,
3831
- exportAs: 'bkDialogClose',
3832
- host: {
3833
- '(click)': '_onButtonClick($event)',
3834
- '[attr.aria-label]': 'ariaLabel || null',
3835
- '[attr.type]': 'type',
3836
- },
3837
3920
  }]
3838
- }], propDecorators: { ariaLabel: [{
3839
- type: Input,
3840
- args: ['aria-label']
3841
- }], type: [{
3842
- type: Input
3843
- }], dialogResult: [{
3921
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { tooltipContent: [{
3844
3922
  type: Input,
3845
- args: ['bk-dialog-close']
3846
- }], _bkDialogClose: [{
3923
+ args: ['bkTooltip']
3924
+ }], tooltipPosition: [{
3847
3925
  type: Input,
3848
- args: ['bkDialogClose']
3926
+ args: ['bkTooltipPosition']
3927
+ }], onMouseEnter: [{
3928
+ type: HostListener,
3929
+ args: ['mouseenter']
3930
+ }], onMouseLeave: [{
3931
+ type: HostListener,
3932
+ args: ['mouseleave']
3933
+ }], onWindowChange: [{
3934
+ type: HostListener,
3935
+ args: ['window:scroll']
3936
+ }, {
3937
+ type: HostListener,
3938
+ args: ['window:resize']
3849
3939
  }] } });
3850
3940
 
3851
- /**
3852
- * BkDialogModule
3853
- *
3854
- * Optional NgModule wrapper for projects that prefer module-based usage.
3855
- *
3856
- * Architecture Decision:
3857
- * ─────────────────────
3858
- * Follows the exact same pattern as Angular Material's `MatDialogModule`
3859
- * and `@brickclay-org/ui`'s `CalendarModule`:
3860
- *
3861
- * • All components/directives are **standalone**.
3862
- * • This module simply imports + re-exports them for convenience.
3863
- * • `DialogService` is `providedIn: 'root'`, so it does NOT need to
3864
- * be listed in `providers` here — it is tree-shakeable and available
3865
- * app-wide automatically.
3866
- *
3867
- * Two usage styles:
3868
- *
3869
- * ───────── Module-based (NgModule) ─────────
3870
- * ```ts
3871
- * import { BkDialogModule } from '@shared/components/dialog';
3872
- *
3873
- * @NgModule({ imports: [BkDialogModule] })
3874
- * export class FuelCostModule {}
3875
- * ```
3876
- *
3877
- * ───────── Standalone ──────────────────────
3878
- * ```ts
3879
- * @Component({
3880
- * standalone: true,
3881
- * imports: [BkDialogContent, BkDialogActions, BkDialogClose],
3882
- * })
3883
- * export class MyDialog {}
3884
- * ```
3885
- *
3886
- * @see https://github.com/angular/components/blob/main/src/material/dialog/dialog-module.ts
3887
- */
3888
- class BkDialogModule {
3889
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkDialogModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
3890
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.16", ngImport: i0, type: BkDialogModule, imports: [
3891
- // ── CDK foundations ──────────────────────────────────────────────
3892
- DialogModule,
3893
- OverlayModule,
3894
- PortalModule,
3895
- // ── Our standalone pieces ───────────────────────────────────────
3896
- DialogContainerComponent,
3897
- BkDialogTitle,
3898
- BkDialogContent,
3899
- BkDialogActions,
3900
- BkDialogClose], exports: [
3901
- // ── Public API for template usage ───────────────────────────────
3902
- // Consumers import BkDialogModule and get these directives in
3903
- // their templates automatically — just like MatDialogModule.
3904
- BkDialogTitle,
3905
- BkDialogContent,
3906
- BkDialogActions,
3907
- BkDialogClose] });
3908
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkDialogModule, imports: [
3909
- // ── CDK foundations ──────────────────────────────────────────────
3910
- DialogModule,
3911
- OverlayModule,
3912
- PortalModule] });
3913
- }
3914
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkDialogModule, decorators: [{
3915
- type: NgModule,
3916
- args: [{
3917
- imports: [
3918
- // ── CDK foundations ──────────────────────────────────────────────
3919
- DialogModule,
3920
- OverlayModule,
3921
- PortalModule,
3922
- // ── Our standalone pieces ───────────────────────────────────────
3923
- DialogContainerComponent,
3924
- BkDialogTitle,
3925
- BkDialogContent,
3926
- BkDialogActions,
3927
- BkDialogClose,
3928
- ],
3929
- exports: [
3930
- // ── Public API for template usage ───────────────────────────────
3931
- // Consumers import BkDialogModule and get these directives in
3932
- // their templates automatically — just like MatDialogModule.
3933
- BkDialogTitle,
3934
- BkDialogContent,
3935
- BkDialogActions,
3936
- BkDialogClose,
3937
- ],
3938
- }]
3939
- }] });
3940
-
3941
3941
  /*
3942
3942
  * Public API Surface of brickclay-lib
3943
3943
  */