otimus-library 0.4.82 → 0.4.83

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,14 +1,18 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Component, Injectable, Input, Directive, EventEmitter, Output, ContentChildren, forwardRef, ChangeDetectionStrategy, ContentChild, ViewChildren, ViewChild, ViewEncapsulation, HostBinding, input } from '@angular/core';
2
+ import { Component, Injectable, Input, Directive, EventEmitter, Output, ContentChildren, forwardRef, ChangeDetectionStrategy, ContentChild, ViewChildren, ViewChild, ViewEncapsulation, HostBinding, input, inject, PLATFORM_ID, RendererFactory2, signal, ElementRef, ViewContainerRef, computed, viewChild, booleanAttribute } from '@angular/core';
3
3
  import * as i2$1 from '@angular/cdk/menu';
4
4
  import { CdkMenuModule } from '@angular/cdk/menu';
5
5
  import * as i1 from '@angular/common';
6
- import { CommonModule, DatePipe } from '@angular/common';
6
+ import { CommonModule, DatePipe, isPlatformBrowser } from '@angular/common';
7
7
  import { ComponentPortal, TemplatePortal } from '@angular/cdk/portal';
8
8
  import * as i2 from '@angular/forms';
9
9
  import { FormsModule, ReactiveFormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
10
10
  import * as i1$1 from '@angular/common/http';
11
11
  import * as i3 from '@angular/cdk/overlay';
12
+ import { Overlay, OverlayPositionBuilder } from '@angular/cdk/overlay';
13
+ import * as i1$2 from '@angular/router';
14
+ import { RouterModule } from '@angular/router';
15
+ import { filter } from 'rxjs';
12
16
  import * as i2$2 from '@angular/platform-browser';
13
17
  import * as i2$3 from '@angular/cdk/table';
14
18
  import { CdkTableModule } from '@angular/cdk/table';
@@ -1699,6 +1703,51 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
1699
1703
  type: Input
1700
1704
  }] } });
1701
1705
 
1706
+ class OcBreadcrumbComponent {
1707
+ constructor() {
1708
+ this.ocItems = [];
1709
+ this.ocCrumbClick = new EventEmitter();
1710
+ }
1711
+ isLast(index) {
1712
+ return index === this.ocItems.length - 1;
1713
+ }
1714
+ onCrumbClick(event, item, last) {
1715
+ if (last) {
1716
+ event.preventDefault();
1717
+ return;
1718
+ }
1719
+ this.ocCrumbClick.emit(item);
1720
+ }
1721
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: OcBreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1722
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: OcBreadcrumbComponent, isStandalone: true, selector: "oc-breadcrumb", inputs: { ocItems: "ocItems" }, outputs: { ocCrumbClick: "ocCrumbClick" }, ngImport: i0, template: "<nav\n class=\"oc-breadcrumb\"\n aria-label=\"breadcrumb\"\n>\n <ol class=\"oc-breadcrumb-list\">\n @for (item of ocItems; track $index; let i = $index) {\n @let last = isLast(i);\n <li\n class=\"oc-breadcrumb-item\"\n [class.is-last]=\"last\"\n >\n @if (last || !item.route) {\n <span\n class=\"oc-breadcrumb-crumb\"\n [class.is-last]=\"last\"\n [attr.aria-current]=\"last ? 'page' : null\"\n >\n @if (item.icon) {\n <span class=\"material-symbols-outlined oc-breadcrumb-icon\">{{ item.icon }}</span>\n }\n <span class=\"oc-breadcrumb-label\">{{ item.label }}</span>\n </span>\n } @else {\n <a\n class=\"oc-breadcrumb-crumb\"\n [routerLink]=\"item.route\"\n [queryParams]=\"item.queryParams\"\n (click)=\"onCrumbClick($event, item, last)\"\n >\n @if (item.icon) {\n <span class=\"material-symbols-outlined oc-breadcrumb-icon\">{{ item.icon }}</span>\n }\n <span class=\"oc-breadcrumb-label\">{{ item.label }}</span>\n </a>\n }\n\n @if (!last) {\n <span\n class=\"material-symbols-outlined oc-breadcrumb-separator\"\n aria-hidden=\"true\"\n >keyboard_arrow_right</span\n >\n }\n </li>\n }\n </ol>\n</nav>\n", styles: [":host{display:block}.oc-breadcrumb{display:block;width:100%}.oc-breadcrumb-list{display:flex;flex-wrap:wrap;align-items:center;gap:2px;list-style:none;margin:0;padding:0}.oc-breadcrumb-item{display:inline-flex;align-items:center;gap:2px;min-width:0}.oc-breadcrumb-crumb{display:inline-flex;align-items:center;gap:4px;padding:4px 6px;border-radius:6px;color:#8f9596;font-size:.875rem;font-weight:400;line-height:1.2;text-decoration:none;transition:background-color .18s ease,color .18s ease}a.oc-breadcrumb-crumb{cursor:pointer}a.oc-breadcrumb-crumb:hover{background-color:#f7f7f7;color:#353535}a.oc-breadcrumb-crumb:focus-visible{outline:2px solid #8850be;outline-offset:2px}.oc-breadcrumb-crumb.is-last{color:#353535;font-weight:500;cursor:default;pointer-events:none}.oc-breadcrumb-icon{font-size:1rem;line-height:1;flex-shrink:0}.oc-breadcrumb-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.oc-breadcrumb-separator{font-size:1.125rem;line-height:1;color:#d1d5db;-webkit-user-select:none;user-select:none;flex-shrink:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }] }); }
1723
+ }
1724
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: OcBreadcrumbComponent, decorators: [{
1725
+ type: Component,
1726
+ args: [{ selector: 'oc-breadcrumb', standalone: true, imports: [CommonModule, RouterModule], template: "<nav\n class=\"oc-breadcrumb\"\n aria-label=\"breadcrumb\"\n>\n <ol class=\"oc-breadcrumb-list\">\n @for (item of ocItems; track $index; let i = $index) {\n @let last = isLast(i);\n <li\n class=\"oc-breadcrumb-item\"\n [class.is-last]=\"last\"\n >\n @if (last || !item.route) {\n <span\n class=\"oc-breadcrumb-crumb\"\n [class.is-last]=\"last\"\n [attr.aria-current]=\"last ? 'page' : null\"\n >\n @if (item.icon) {\n <span class=\"material-symbols-outlined oc-breadcrumb-icon\">{{ item.icon }}</span>\n }\n <span class=\"oc-breadcrumb-label\">{{ item.label }}</span>\n </span>\n } @else {\n <a\n class=\"oc-breadcrumb-crumb\"\n [routerLink]=\"item.route\"\n [queryParams]=\"item.queryParams\"\n (click)=\"onCrumbClick($event, item, last)\"\n >\n @if (item.icon) {\n <span class=\"material-symbols-outlined oc-breadcrumb-icon\">{{ item.icon }}</span>\n }\n <span class=\"oc-breadcrumb-label\">{{ item.label }}</span>\n </a>\n }\n\n @if (!last) {\n <span\n class=\"material-symbols-outlined oc-breadcrumb-separator\"\n aria-hidden=\"true\"\n >keyboard_arrow_right</span\n >\n }\n </li>\n }\n </ol>\n</nav>\n", styles: [":host{display:block}.oc-breadcrumb{display:block;width:100%}.oc-breadcrumb-list{display:flex;flex-wrap:wrap;align-items:center;gap:2px;list-style:none;margin:0;padding:0}.oc-breadcrumb-item{display:inline-flex;align-items:center;gap:2px;min-width:0}.oc-breadcrumb-crumb{display:inline-flex;align-items:center;gap:4px;padding:4px 6px;border-radius:6px;color:#8f9596;font-size:.875rem;font-weight:400;line-height:1.2;text-decoration:none;transition:background-color .18s ease,color .18s ease}a.oc-breadcrumb-crumb{cursor:pointer}a.oc-breadcrumb-crumb:hover{background-color:#f7f7f7;color:#353535}a.oc-breadcrumb-crumb:focus-visible{outline:2px solid #8850be;outline-offset:2px}.oc-breadcrumb-crumb.is-last{color:#353535;font-weight:500;cursor:default;pointer-events:none}.oc-breadcrumb-icon{font-size:1rem;line-height:1;flex-shrink:0}.oc-breadcrumb-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.oc-breadcrumb-separator{font-size:1.125rem;line-height:1;color:#d1d5db;-webkit-user-select:none;user-select:none;flex-shrink:0}\n"] }]
1727
+ }], propDecorators: { ocItems: [{
1728
+ type: Input
1729
+ }], ocCrumbClick: [{
1730
+ type: Output
1731
+ }] } });
1732
+
1733
+ /**
1734
+ * @deprecated
1735
+ * `OcMenuComponent` está depreciado e não deve ser usado em código novo.
1736
+ *
1737
+ * Motivo: o componente não implementa o principal comportamento esperado de um
1738
+ * "menu" (abertura por contexto / botão direito, navegação por teclado
1739
+ * compatível com WAI-ARIA, ancoragem via CDK overlay, gestão de foco).
1740
+ *
1741
+ * Substituto atual: **use `OcDropdownImports`** (`oc-dropdown` + `oc-dropdown-menu-content` +
1742
+ * `oc-dropdown-menu-item`) para menus acionados por botão/hover. Veja
1743
+ * `Components/OcDropdown` no Storybook.
1744
+ *
1745
+ * Um novo `oc-menu` será introduzido no futuro com suporte real a context menu, com estilo e usabilidade aprimorada.
1746
+ * Quando chegar, este componente sera removido
1747
+ *
1748
+ * Os usos atuais continuam funcionando — este aviso serve apenas para guiar
1749
+ * novos desenvolvimentos.
1750
+ */
1702
1751
  class OcMenuComponent {
1703
1752
  constructor(renderer) {
1704
1753
  this.renderer = renderer;
@@ -1746,7 +1795,7 @@ class OcMenuComponent {
1746
1795
  }
1747
1796
  changeCheckbox(name, checked) {
1748
1797
  let foundItem;
1749
- this.ocMenu.forEach(item => {
1798
+ this.ocMenu.forEach((item) => {
1750
1799
  if (item.name === name && typeof checked === 'boolean') {
1751
1800
  item.checked = checked;
1752
1801
  foundItem = item;
@@ -2289,6 +2338,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
2289
2338
  type: Output
2290
2339
  }] } });
2291
2340
 
2341
+ class OcDividerComponent {
2342
+ constructor() {
2343
+ this.orientation = input('horizontal', ...(ngDevMode ? [{ debugName: "orientation" }] : []));
2344
+ }
2345
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: OcDividerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2346
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.9", type: OcDividerComponent, isStandalone: true, selector: "oc-divider", inputs: { orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "separator" }, properties: { "attr.aria-orientation": "orientation()", "attr.data-orientation": "orientation()" } }, ngImport: i0, template: '', isInline: true, styles: ["oc-divider{display:block;background-color:#d1d5db}oc-divider[data-orientation=horizontal]{width:100%;height:1px;margin:4px 0}oc-divider[data-orientation=vertical]{display:inline-block;width:1px;height:100%;margin:0 4px;align-self:stretch}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
2347
+ }
2348
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: OcDividerComponent, decorators: [{
2349
+ type: Component,
2350
+ args: [{ selector: 'oc-divider', template: '', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
2351
+ role: 'separator',
2352
+ '[attr.aria-orientation]': 'orientation()',
2353
+ '[attr.data-orientation]': 'orientation()',
2354
+ }, styles: ["oc-divider{display:block;background-color:#d1d5db}oc-divider[data-orientation=horizontal]{width:100%;height:1px;margin:4px 0}oc-divider[data-orientation=vertical]{display:inline-block;width:1px;height:100%;margin:0 4px;align-self:stretch}\n"] }]
2355
+ }], propDecorators: { orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }] } });
2356
+
2292
2357
  class OcDrawerComponent {
2293
2358
  constructor(elRef, styleThemeService, cdr) {
2294
2359
  this.elRef = elRef;
@@ -2379,6 +2444,393 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
2379
2444
  type: Input
2380
2445
  }] } });
2381
2446
 
2447
+ class OcDropdownService {
2448
+ constructor() {
2449
+ this.overlay = inject(Overlay);
2450
+ this.overlayPositionBuilder = inject(OverlayPositionBuilder);
2451
+ this.platformId = inject(PLATFORM_ID);
2452
+ this.rendererFactory = inject(RendererFactory2);
2453
+ this.focusedIndex = signal(-1, ...(ngDevMode ? [{ debugName: "focusedIndex" }] : []));
2454
+ this.unlisten = () => { };
2455
+ this.isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
2456
+ this.renderer = this.rendererFactory.createRenderer(null, null);
2457
+ }
2458
+ toggle(triggerElement, template, viewContainerRef) {
2459
+ if (this.isOpen()) {
2460
+ this.close();
2461
+ }
2462
+ else {
2463
+ this.open(triggerElement, template, viewContainerRef);
2464
+ }
2465
+ }
2466
+ open(triggerElement, template, viewContainerRef) {
2467
+ if (this.isOpen()) {
2468
+ this.close();
2469
+ }
2470
+ this.triggerElement = triggerElement;
2471
+ this.createOverlay(triggerElement);
2472
+ if (!this.overlayRef) {
2473
+ return;
2474
+ }
2475
+ this.portal = new TemplatePortal(template, viewContainerRef);
2476
+ this.overlayRef.attach(this.portal);
2477
+ setTimeout(() => {
2478
+ this.setupKeyboardNavigation();
2479
+ }, 0);
2480
+ this.outsideClickSubscription = this.overlayRef
2481
+ .outsidePointerEvents()
2482
+ .pipe(filter(event => !triggerElement.nativeElement.contains(event.target)))
2483
+ .subscribe(() => {
2484
+ this.close();
2485
+ });
2486
+ this.isOpen.set(true);
2487
+ }
2488
+ getTriggerElement() {
2489
+ return this.triggerElement;
2490
+ }
2491
+ close() {
2492
+ if (this.overlayRef?.hasAttached()) {
2493
+ this.overlayRef.detach();
2494
+ }
2495
+ this.focusedIndex.set(-1);
2496
+ this.unlisten();
2497
+ this.destroyOverlay();
2498
+ this.isOpen.set(false);
2499
+ this.triggerElement = undefined;
2500
+ }
2501
+ closeAndReturnTrigger() {
2502
+ const trigger = this.triggerElement;
2503
+ this.close();
2504
+ return trigger;
2505
+ }
2506
+ createOverlay(triggerElement) {
2507
+ if (this.overlayRef) {
2508
+ this.destroyOverlay();
2509
+ }
2510
+ const positionStrategy = this.overlayPositionBuilder
2511
+ .flexibleConnectedTo(triggerElement)
2512
+ .withPositions([
2513
+ {
2514
+ originX: 'start',
2515
+ originY: 'bottom',
2516
+ overlayX: 'start',
2517
+ overlayY: 'top',
2518
+ offsetY: 4,
2519
+ },
2520
+ {
2521
+ originX: 'start',
2522
+ originY: 'top',
2523
+ overlayX: 'start',
2524
+ overlayY: 'bottom',
2525
+ offsetY: -4,
2526
+ },
2527
+ ])
2528
+ .withPush(false);
2529
+ this.overlayRef = this.overlay.create({
2530
+ positionStrategy,
2531
+ hasBackdrop: false,
2532
+ scrollStrategy: this.overlay.scrollStrategies.reposition(),
2533
+ minWidth: 200,
2534
+ maxHeight: 400,
2535
+ });
2536
+ }
2537
+ destroyOverlay() {
2538
+ this.overlayRef?.dispose();
2539
+ this.overlayRef = undefined;
2540
+ this.outsideClickSubscription?.unsubscribe();
2541
+ }
2542
+ setupKeyboardNavigation() {
2543
+ if (!this.overlayRef?.hasAttached() || !isPlatformBrowser(this.platformId)) {
2544
+ return;
2545
+ }
2546
+ const dropdownElement = this.overlayRef.overlayElement.querySelector('[role="menu"]');
2547
+ if (!dropdownElement) {
2548
+ return;
2549
+ }
2550
+ this.unlisten = this.renderer.listen(dropdownElement, 'keydown', (event) => {
2551
+ const items = this.getDropdownItems();
2552
+ switch (event.key) {
2553
+ case 'ArrowDown':
2554
+ event.preventDefault();
2555
+ this.navigateItems(1, items);
2556
+ break;
2557
+ case 'ArrowUp':
2558
+ event.preventDefault();
2559
+ this.navigateItems(-1, items);
2560
+ break;
2561
+ case 'Enter':
2562
+ case ' ':
2563
+ event.preventDefault();
2564
+ this.selectFocusedItem(items);
2565
+ break;
2566
+ case 'Escape': {
2567
+ event.preventDefault();
2568
+ const triggerToFocus = this.closeAndReturnTrigger();
2569
+ triggerToFocus?.nativeElement.focus();
2570
+ break;
2571
+ }
2572
+ case 'Home':
2573
+ event.preventDefault();
2574
+ this.focusItemAtIndex(items, 0);
2575
+ break;
2576
+ case 'End':
2577
+ event.preventDefault();
2578
+ this.focusItemAtIndex(items, items.length - 1);
2579
+ break;
2580
+ }
2581
+ });
2582
+ dropdownElement.focus();
2583
+ }
2584
+ getDropdownItems() {
2585
+ if (!this.overlayRef?.hasAttached()) {
2586
+ return [];
2587
+ }
2588
+ const dropdownElement = this.overlayRef.overlayElement;
2589
+ return Array.from(dropdownElement.querySelectorAll('oc-dropdown-menu-item, [oc-dropdown-menu-item]')).filter(item => item.dataset['disabled'] === undefined);
2590
+ }
2591
+ navigateItems(direction, items) {
2592
+ if (items.length === 0) {
2593
+ return;
2594
+ }
2595
+ const currentIndex = this.focusedIndex();
2596
+ let nextIndex;
2597
+ if (currentIndex === -1) {
2598
+ nextIndex = direction > 0 ? 0 : items.length - 1;
2599
+ }
2600
+ else {
2601
+ nextIndex = currentIndex + direction;
2602
+ if (nextIndex < 0) {
2603
+ nextIndex = items.length - 1;
2604
+ }
2605
+ else if (nextIndex >= items.length) {
2606
+ nextIndex = 0;
2607
+ }
2608
+ }
2609
+ this.focusItemAtIndex(items, nextIndex);
2610
+ }
2611
+ focusItemAtIndex(items, index) {
2612
+ if (index >= 0 && index < items.length) {
2613
+ this.focusedIndex.set(index);
2614
+ this.updateItemFocus(items, index);
2615
+ }
2616
+ }
2617
+ selectFocusedItem(items) {
2618
+ const currentIndex = this.focusedIndex();
2619
+ if (currentIndex >= 0 && currentIndex < items.length) {
2620
+ const item = items[currentIndex];
2621
+ item.click();
2622
+ }
2623
+ }
2624
+ updateItemFocus(items, focusedIndex) {
2625
+ for (let index = 0; index < items.length; index++) {
2626
+ const item = items[index];
2627
+ if (index === focusedIndex) {
2628
+ item.focus();
2629
+ item.dataset['highlighted'] = '';
2630
+ }
2631
+ else {
2632
+ delete item.dataset['highlighted'];
2633
+ }
2634
+ }
2635
+ }
2636
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: OcDropdownService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2637
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: OcDropdownService, providedIn: 'root' }); }
2638
+ }
2639
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: OcDropdownService, decorators: [{
2640
+ type: Injectable,
2641
+ args: [{
2642
+ providedIn: 'root',
2643
+ }]
2644
+ }], ctorParameters: () => [] });
2645
+
2646
+ class OcDropdownDirective {
2647
+ constructor() {
2648
+ this.elementRef = inject(ElementRef);
2649
+ this.viewContainerRef = inject(ViewContainerRef);
2650
+ this.dropdownService = inject(OcDropdownService);
2651
+ this.isThisDropdownOpen = computed(() => this.dropdownService.isOpen() && this.dropdownService.getTriggerElement() === this.elementRef, ...(ngDevMode ? [{ debugName: "isThisDropdownOpen" }] : []));
2652
+ this.ocDropdownMenu = input(...(ngDevMode ? [undefined, { debugName: "ocDropdownMenu" }] : []));
2653
+ this.ocTrigger = input('click', ...(ngDevMode ? [{ debugName: "ocTrigger" }] : []));
2654
+ this.ocDisabled = input(false, ...(ngDevMode ? [{ debugName: "ocDisabled" }] : []));
2655
+ }
2656
+ ngOnInit() {
2657
+ const element = this.elementRef.nativeElement;
2658
+ if (!element.hasAttribute('aria-label') && !element.hasAttribute('aria-labelledby')) {
2659
+ const label = element.textContent?.trim();
2660
+ element.setAttribute('aria-label', label?.length ? label : 'Open menu');
2661
+ }
2662
+ }
2663
+ onClick(event) {
2664
+ if (this.ocTrigger() !== 'click') {
2665
+ return;
2666
+ }
2667
+ event.preventDefault();
2668
+ event.stopPropagation();
2669
+ this.toggleDropdown();
2670
+ }
2671
+ onKeydown(event) {
2672
+ if (event.key === 'Enter' || event.key === ' ') {
2673
+ event.preventDefault();
2674
+ event.stopPropagation();
2675
+ this.toggleDropdown();
2676
+ }
2677
+ else if (event.key === 'ArrowDown') {
2678
+ event.preventDefault();
2679
+ this.openDropdown();
2680
+ }
2681
+ }
2682
+ onHoverToggle(event) {
2683
+ if (this.ocTrigger() !== 'hover' || this.ocDisabled()) {
2684
+ return;
2685
+ }
2686
+ if (event.type === 'mouseenter') {
2687
+ this.openDropdown();
2688
+ }
2689
+ else if (event.type === 'mouseleave') {
2690
+ this.closeDropdown();
2691
+ }
2692
+ }
2693
+ toggleDropdown() {
2694
+ if (this.ocDisabled()) {
2695
+ return;
2696
+ }
2697
+ const menuContent = this.ocDropdownMenu();
2698
+ if (menuContent) {
2699
+ this.dropdownService.toggle(this.elementRef, menuContent.contentTemplate(), this.viewContainerRef);
2700
+ }
2701
+ }
2702
+ openDropdown() {
2703
+ if (this.ocDisabled()) {
2704
+ return;
2705
+ }
2706
+ const menuContent = this.ocDropdownMenu();
2707
+ if (menuContent && !this.dropdownService.isOpen()) {
2708
+ this.dropdownService.toggle(this.elementRef, menuContent.contentTemplate(), this.viewContainerRef);
2709
+ }
2710
+ }
2711
+ closeDropdown() {
2712
+ this.dropdownService.close();
2713
+ }
2714
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: OcDropdownDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2715
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.9", type: OcDropdownDirective, isStandalone: true, selector: "[oc-dropdown], [ocDropdown]", inputs: { ocDropdownMenu: { classPropertyName: "ocDropdownMenu", publicName: "ocDropdownMenu", isSignal: true, isRequired: false, transformFunction: null }, ocTrigger: { classPropertyName: "ocTrigger", publicName: "ocTrigger", isSignal: true, isRequired: false, transformFunction: null }, ocDisabled: { classPropertyName: "ocDisabled", publicName: "ocDisabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "onClick($event)", "mouseenter": "onHoverToggle($event)", "mouseleave": "onHoverToggle($event)", "keydown": "onKeydown($event)" }, properties: { "attr.tabindex": "0", "attr.role": "\"button\"", "attr.aria-haspopup": "\"menu\"", "attr.aria-expanded": "isThisDropdownOpen()", "attr.aria-disabled": "ocDisabled()" } }, exportAs: ["ocDropdown"], ngImport: i0 }); }
2716
+ }
2717
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: OcDropdownDirective, decorators: [{
2718
+ type: Directive,
2719
+ args: [{
2720
+ selector: '[oc-dropdown], [ocDropdown]',
2721
+ host: {
2722
+ '[attr.tabindex]': '0',
2723
+ '[attr.role]': '"button"',
2724
+ '[attr.aria-haspopup]': '"menu"',
2725
+ '[attr.aria-expanded]': 'isThisDropdownOpen()',
2726
+ '[attr.aria-disabled]': 'ocDisabled()',
2727
+ '(click)': 'onClick($event)',
2728
+ '(mouseenter)': 'onHoverToggle($event)',
2729
+ '(mouseleave)': 'onHoverToggle($event)',
2730
+ '(keydown)': 'onKeydown($event)',
2731
+ },
2732
+ exportAs: 'ocDropdown',
2733
+ }]
2734
+ }], propDecorators: { ocDropdownMenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "ocDropdownMenu", required: false }] }], ocTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "ocTrigger", required: false }] }], ocDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "ocDisabled", required: false }] }] } });
2735
+
2736
+ class OcDropdownMenuContentComponent {
2737
+ constructor() {
2738
+ this.contentTemplate = viewChild.required('contentTemplate');
2739
+ }
2740
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: OcDropdownMenuContentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2741
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.3.9", type: OcDropdownMenuContentComponent, isStandalone: true, selector: "oc-dropdown-menu-content", host: { properties: { "style.display": "\"none\"" } }, viewQueries: [{ propertyName: "contentTemplate", first: true, predicate: ["contentTemplate"], descendants: true, isSignal: true }], exportAs: ["ocDropdownMenuContent"], ngImport: i0, template: `
2742
+ <ng-template #contentTemplate>
2743
+ <div
2744
+ class="oc-dropdown-menu"
2745
+ role="menu"
2746
+ tabindex="-1"
2747
+ aria-orientation="vertical"
2748
+ >
2749
+ <ng-content />
2750
+ </div>
2751
+ </ng-template>
2752
+ `, isInline: true, styles: [".oc-dropdown-menu{box-sizing:border-box;min-width:200px;max-height:400px;padding:4px;overflow-y:auto;background-color:#fff;border:1px solid #d1d5db;border-radius:8px;box-shadow:0 8px 24px #1e08321f;outline:none}.oc-dropdown-menu:focus{outline:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
2753
+ }
2754
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: OcDropdownMenuContentComponent, decorators: [{
2755
+ type: Component,
2756
+ args: [{ selector: 'oc-dropdown-menu-content', template: `
2757
+ <ng-template #contentTemplate>
2758
+ <div
2759
+ class="oc-dropdown-menu"
2760
+ role="menu"
2761
+ tabindex="-1"
2762
+ aria-orientation="vertical"
2763
+ >
2764
+ <ng-content />
2765
+ </div>
2766
+ </ng-template>
2767
+ `, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
2768
+ '[style.display]': '"none"',
2769
+ }, exportAs: 'ocDropdownMenuContent', styles: [".oc-dropdown-menu{box-sizing:border-box;min-width:200px;max-height:400px;padding:4px;overflow-y:auto;background-color:#fff;border:1px solid #d1d5db;border-radius:8px;box-shadow:0 8px 24px #1e08321f;outline:none}.oc-dropdown-menu:focus{outline:none}\n"] }]
2770
+ }], propDecorators: { contentTemplate: [{ type: i0.ViewChild, args: ['contentTemplate', { isSignal: true }] }] } });
2771
+
2772
+ class OcDropdownMenuItemComponent {
2773
+ constructor() {
2774
+ this.dropdownService = inject(OcDropdownService);
2775
+ this.variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : []));
2776
+ this.inset = input(false, ...(ngDevMode ? [{ debugName: "inset", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
2777
+ this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
2778
+ }
2779
+ onClick(event) {
2780
+ if (this.disabled()) {
2781
+ event.preventDefault();
2782
+ event.stopPropagation();
2783
+ return;
2784
+ }
2785
+ setTimeout(() => {
2786
+ this.dropdownService.close();
2787
+ }, 0);
2788
+ }
2789
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: OcDropdownMenuItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2790
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.9", type: OcDropdownMenuItemComponent, isStandalone: true, selector: "oc-dropdown-menu-item, [oc-dropdown-menu-item]", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, inset: { classPropertyName: "inset", publicName: "inset", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "menuitem", "tabindex": "-1" }, listeners: { "click": "onClick($event)" }, properties: { "attr.data-disabled": "disabled() || null", "attr.data-variant": "variant()", "attr.data-inset": "inset() || null", "attr.aria-disabled": "disabled()" } }, exportAs: ["ocDropdownMenuItem"], ngImport: i0, template: `
2791
+ <ng-content />
2792
+ `, isInline: true, styles: ["oc-dropdown-menu-item,[oc-dropdown-menu-item]{display:flex;align-items:center;gap:8px;padding:6px 8px;color:#353535;font-size:.875rem;line-height:1.2;background-color:transparent;border-radius:4px;cursor:pointer;-webkit-user-select:none;user-select:none;outline:none;transition:background-color .15s ease,color .15s ease}oc-dropdown-menu-item:hover,oc-dropdown-menu-item:focus-visible,oc-dropdown-menu-item[data-highlighted],[oc-dropdown-menu-item]:hover,[oc-dropdown-menu-item]:focus-visible,[oc-dropdown-menu-item][data-highlighted]{background-color:#f8f9ff;color:#5505a2}oc-dropdown-menu-item[data-inset],[oc-dropdown-menu-item][data-inset]{padding-left:32px}oc-dropdown-menu-item[data-variant=destructive],[oc-dropdown-menu-item][data-variant=destructive]{color:#ed3a3a}oc-dropdown-menu-item[data-variant=destructive]:hover,oc-dropdown-menu-item[data-variant=destructive]:focus-visible,oc-dropdown-menu-item[data-variant=destructive][data-highlighted],[oc-dropdown-menu-item][data-variant=destructive]:hover,[oc-dropdown-menu-item][data-variant=destructive]:focus-visible,[oc-dropdown-menu-item][data-variant=destructive][data-highlighted]{background-color:#ed3a3a14;color:#ed3a3a}oc-dropdown-menu-item[data-disabled],oc-dropdown-menu-item[aria-disabled=true],[oc-dropdown-menu-item][data-disabled],[oc-dropdown-menu-item][aria-disabled=true]{cursor:not-allowed;opacity:.5;pointer-events:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
2793
+ }
2794
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: OcDropdownMenuItemComponent, decorators: [{
2795
+ type: Component,
2796
+ args: [{ selector: 'oc-dropdown-menu-item, [oc-dropdown-menu-item]', template: `
2797
+ <ng-content />
2798
+ `, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
2799
+ '[attr.data-disabled]': 'disabled() || null',
2800
+ '[attr.data-variant]': 'variant()',
2801
+ '[attr.data-inset]': 'inset() || null',
2802
+ '[attr.aria-disabled]': 'disabled()',
2803
+ '(click)': 'onClick($event)',
2804
+ role: 'menuitem',
2805
+ tabindex: '-1',
2806
+ }, exportAs: 'ocDropdownMenuItem', styles: ["oc-dropdown-menu-item,[oc-dropdown-menu-item]{display:flex;align-items:center;gap:8px;padding:6px 8px;color:#353535;font-size:.875rem;line-height:1.2;background-color:transparent;border-radius:4px;cursor:pointer;-webkit-user-select:none;user-select:none;outline:none;transition:background-color .15s ease,color .15s ease}oc-dropdown-menu-item:hover,oc-dropdown-menu-item:focus-visible,oc-dropdown-menu-item[data-highlighted],[oc-dropdown-menu-item]:hover,[oc-dropdown-menu-item]:focus-visible,[oc-dropdown-menu-item][data-highlighted]{background-color:#f8f9ff;color:#5505a2}oc-dropdown-menu-item[data-inset],[oc-dropdown-menu-item][data-inset]{padding-left:32px}oc-dropdown-menu-item[data-variant=destructive],[oc-dropdown-menu-item][data-variant=destructive]{color:#ed3a3a}oc-dropdown-menu-item[data-variant=destructive]:hover,oc-dropdown-menu-item[data-variant=destructive]:focus-visible,oc-dropdown-menu-item[data-variant=destructive][data-highlighted],[oc-dropdown-menu-item][data-variant=destructive]:hover,[oc-dropdown-menu-item][data-variant=destructive]:focus-visible,[oc-dropdown-menu-item][data-variant=destructive][data-highlighted]{background-color:#ed3a3a14;color:#ed3a3a}oc-dropdown-menu-item[data-disabled],oc-dropdown-menu-item[aria-disabled=true],[oc-dropdown-menu-item][data-disabled],[oc-dropdown-menu-item][aria-disabled=true]{cursor:not-allowed;opacity:.5;pointer-events:none}\n"] }]
2807
+ }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], inset: [{ type: i0.Input, args: [{ isSignal: true, alias: "inset", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
2808
+
2809
+ class OcDropdownMenuLabelComponent {
2810
+ constructor() {
2811
+ this.inset = input(false, ...(ngDevMode ? [{ debugName: "inset", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
2812
+ }
2813
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: OcDropdownMenuLabelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2814
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.9", type: OcDropdownMenuLabelComponent, isStandalone: true, selector: "oc-dropdown-menu-label", inputs: { inset: { classPropertyName: "inset", publicName: "inset", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-inset": "inset() || null" } }, ngImport: i0, template: `
2815
+ <ng-content />
2816
+ `, isInline: true, styles: ["oc-dropdown-menu-label{display:block;padding:6px 8px 4px;font-size:.6875rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:#8f9596}oc-dropdown-menu-label[data-inset]{padding-left:32px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
2817
+ }
2818
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: OcDropdownMenuLabelComponent, decorators: [{
2819
+ type: Component,
2820
+ args: [{ selector: 'oc-dropdown-menu-label', template: `
2821
+ <ng-content />
2822
+ `, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
2823
+ '[attr.data-inset]': 'inset() || null',
2824
+ }, styles: ["oc-dropdown-menu-label{display:block;padding:6px 8px 4px;font-size:.6875rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:#8f9596}oc-dropdown-menu-label[data-inset]{padding-left:32px}\n"] }]
2825
+ }], propDecorators: { inset: [{ type: i0.Input, args: [{ isSignal: true, alias: "inset", required: false }] }] } });
2826
+
2827
+ const OcDropdownImports = [
2828
+ OcDropdownDirective,
2829
+ OcDropdownMenuContentComponent,
2830
+ OcDropdownMenuItemComponent,
2831
+ OcDropdownMenuLabelComponent,
2832
+ ];
2833
+
2382
2834
  class OcFilterComponent {
2383
2835
  constructor(styleThemeService) {
2384
2836
  this.styleThemeService = styleThemeService;
@@ -2826,6 +3278,7 @@ class OcModalComponent {
2826
3278
  this.elRef = elRef;
2827
3279
  this.styleThemeService = styleThemeService;
2828
3280
  this.cdr = cdr;
3281
+ this.closeTimeout = null;
2829
3282
  this.ocClose = true;
2830
3283
  this.ocTitle = '';
2831
3284
  this.ocSize = 'medium';
@@ -2846,11 +3299,20 @@ class OcModalComponent {
2846
3299
  this.elRef.nativeElement.ownerDocument.body.classList.add('disabled-scroll');
2847
3300
  this.ocOnOpen.emit(this.isOpen);
2848
3301
  }
3302
+ ngOnDestroy() {
3303
+ if (this.closeTimeout) {
3304
+ clearTimeout(this.closeTimeout);
3305
+ }
3306
+ if (this.isOpen || this.closing) {
3307
+ this.elRef.nativeElement.ownerDocument.body.classList.remove('disabled-scroll');
3308
+ }
3309
+ }
2849
3310
  close() {
2850
3311
  this.closing = true;
2851
- setTimeout(() => {
3312
+ this.closeTimeout = setTimeout(() => {
2852
3313
  this.isOpen = false;
2853
3314
  this.closing = false;
3315
+ this.closeTimeout = null;
2854
3316
  if (this.ocOnClose) {
2855
3317
  this.ocOnClose.emit(this.isOpen);
2856
3318
  }
@@ -4116,5 +4578,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
4116
4578
  * Generated bundle index. Do not edit.
4117
4579
  */
4118
4580
 
4119
- export { OcAccordionComponent, OcAccordionItemComponent, OcAutocompleteComponent, OcBadgeComponent, OcButtonMenuComponent, OcCalendarComponent, OcCardComponent, OcChatComponent, OcChatErrorComponent, OcChatHeaderComponent, OcChatInputComponent, OcChatMessageComponent, OcChatMessageListComponent, OcChatToolProposalComponent, OcChatTypingIndicatorComponent, OcChatWelcomeComponent, OcCheckboxComponent, OcChipComponent, OcDateSelectComponent, OcDrawerComponent, OcDrawerFooterComponent, OcFilterComponent, OcInputComponent, OcKeyValueComponent, OcLogComponent, OcMenuComponent, OcMenuHorizComponent, OcMenuHorizDirective, OcMessageComponent, OcModalComponent, OcModalFooterComponent, OcNotFoundComponent, OcOverlayComponent, OcPaginationComponent, OcProfileComponent, OcProgressComponent, OcStepComponent, OcStepperComponent, OcTabComponent, OcTableComponent, OcTabsComponent, OcToastComponent, OcToastService, OcToggleComponent, OcTooltipDirective, OtimusLibraryComponent, OtimusLibraryService, StyleThemeService };
4581
+ export { OcAccordionComponent, OcAccordionItemComponent, OcAutocompleteComponent, OcBadgeComponent, OcBreadcrumbComponent, OcButtonMenuComponent, OcCalendarComponent, OcCardComponent, OcChatComponent, OcChatErrorComponent, OcChatHeaderComponent, OcChatInputComponent, OcChatMessageComponent, OcChatMessageListComponent, OcChatToolProposalComponent, OcChatTypingIndicatorComponent, OcChatWelcomeComponent, OcCheckboxComponent, OcChipComponent, OcDateSelectComponent, OcDividerComponent, OcDrawerComponent, OcDrawerFooterComponent, OcDropdownDirective, OcDropdownImports, OcDropdownMenuContentComponent, OcDropdownMenuItemComponent, OcDropdownMenuLabelComponent, OcDropdownService, OcFilterComponent, OcInputComponent, OcKeyValueComponent, OcLogComponent, OcMenuComponent, OcMenuHorizComponent, OcMenuHorizDirective, OcMessageComponent, OcModalComponent, OcModalFooterComponent, OcNotFoundComponent, OcOverlayComponent, OcPaginationComponent, OcProfileComponent, OcProgressComponent, OcStepComponent, OcStepperComponent, OcTabComponent, OcTableComponent, OcTabsComponent, OcToastComponent, OcToastService, OcToggleComponent, OcTooltipDirective, OtimusLibraryComponent, OtimusLibraryService, StyleThemeService };
4120
4582
  //# sourceMappingURL=otimus-library.mjs.map