@basis-ng/primitives 0.0.1-alpha.97 → 0.0.1-alpha.99

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,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { signal, inject, RendererFactory2, PLATFORM_ID, Injectable, input, ElementRef, Component, TemplateRef, Directive, computed, model, linkedSignal, output, effect, contentChildren, contentChild, forwardRef, HostListener, afterRenderEffect, ViewEncapsulation, ChangeDetectorRef, Pipe } from '@angular/core';
3
- import { isPlatformBrowser, NgClass, NgStyle, CommonModule } from '@angular/common';
3
+ import { isPlatformBrowser, NgClass, NgStyle, CommonModule, NgTemplateOutlet } from '@angular/common';
4
4
  import { NgModel, NG_VALUE_ACCESSOR, ControlContainer } from '@angular/forms';
5
5
  import * as i1 from '@angular/cdk/overlay';
6
6
  import { CdkConnectedOverlay, Overlay, CdkOverlayOrigin } from '@angular/cdk/overlay';
@@ -2925,6 +2925,18 @@ class Utils {
2925
2925
  clearTimeout(this.debounceTimers.get(key));
2926
2926
  this.debounceTimers.delete(key);
2927
2927
  }
2928
+ /**
2929
+ * Generates a simple UUID.
2930
+ *
2931
+ * @returns A string representing a UUID.
2932
+ */
2933
+ generateUUID() {
2934
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
2935
+ const r = (Math.random() * 16) | 0; // Random integer between 0 and 15
2936
+ const v = c === 'x' ? r : (r & 0x3) | 0x8; // Version 4 UUID
2937
+ return v.toString(16);
2938
+ });
2939
+ }
2928
2940
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Utils, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2929
2941
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Utils, providedIn: 'root' });
2930
2942
  }
@@ -3538,6 +3550,155 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImpor
3538
3550
  }]
3539
3551
  }] });
3540
3552
 
3553
+ /**
3554
+ * Directive that toggles a connected popover via click or hover interactions.
3555
+ */
3556
+ class PopoverTrigger {
3557
+ /** Reference to the trigger host element. */
3558
+ el = inject(ElementRef);
3559
+ /** Reactive open state of the associated popover. */
3560
+ active = signal(false, ...(ngDevMode ? [{ debugName: "active" }] : []));
3561
+ /** Interaction mode that determines whether the popover opens on click or hover.
3562
+ *
3563
+ * @defaultValue 'click'
3564
+ */
3565
+ mode = input('click', ...(ngDevMode ? [{ debugName: "mode" }] : []));
3566
+ /** Whether clicking outside the popover should close it when managed by a parent component.
3567
+ *
3568
+ * @defaultValue true
3569
+ */
3570
+ closeOnOutsideClick = input(true, ...(ngDevMode ? [{ debugName: "closeOnOutsideClick" }] : []));
3571
+ /** Disables trigger interactions when true.
3572
+ *
3573
+ * @defaultValue false
3574
+ */
3575
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
3576
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: PopoverTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive });
3577
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.2.3", type: PopoverTrigger, isStandalone: true, selector: "[bPopoverTrigger]", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, closeOnOutsideClick: { classPropertyName: "closeOnOutsideClick", publicName: "closeOnOutsideClick", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "(mode() === \"click\" && !disabled()) && active.set(!active())", "mouseenter": "(mode() === \"hover\" && !disabled()) && active.set(true)" } }, ngImport: i0 });
3578
+ }
3579
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: PopoverTrigger, decorators: [{
3580
+ type: Directive,
3581
+ args: [{
3582
+ selector: '[bPopoverTrigger]',
3583
+ host: {
3584
+ '(click)': '(mode() === "click" && !disabled()) && active.set(!active())',
3585
+ '(mouseenter)': '(mode() === "hover" && !disabled()) && active.set(true)',
3586
+ },
3587
+ }]
3588
+ }] });
3589
+
3590
+ /**
3591
+ * Renders the projected popover content and positions it relative to an anchor using CSS anchor positioning.
3592
+ */
3593
+ class PopoverContent {
3594
+ /**
3595
+ * Requested anchor-relative position of the popover.
3596
+ */
3597
+ position = input.required(...(ngDevMode ? [{ debugName: "position" }] : []));
3598
+ /**
3599
+ * Reference to the host DOM element for direct native access when needed.
3600
+ */
3601
+ el = inject(ElementRef);
3602
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: PopoverContent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3603
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.3", type: PopoverContent, isStandalone: true, selector: "b-popover-content", inputs: { position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "style.position-area": "position()", "animate.enter": "'b-popover-entering'", "animate.leave": "'b-popover-leaving'" } }, ngImport: i0, template: ` <ng-content /> `, isInline: true, styles: [":host{position:absolute;position-anchor:var(--anchor-name);position-try-fallbacks:flip-block,flip-inline}\n"] });
3604
+ }
3605
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: PopoverContent, decorators: [{
3606
+ type: Component,
3607
+ args: [{ selector: 'b-popover-content', imports: [], template: ` <ng-content /> `, host: {
3608
+ '[style.position-area]': 'position()',
3609
+ '[animate.enter]': "'b-popover-entering'",
3610
+ '[animate.leave]': "'b-popover-leaving'",
3611
+ }, styles: [":host{position:absolute;position-anchor:var(--anchor-name);position-try-fallbacks:flip-block,flip-inline}\n"] }]
3612
+ }] });
3613
+
3614
+ /**
3615
+ * Hosts trigger and content projections and manages showing and positioning popover content relative to its trigger.
3616
+ */
3617
+ class Popover {
3618
+ /** Utility service used to generate a unique anchor name. */
3619
+ utils = inject(Utils);
3620
+ /** Reference to the host DOM element for event boundary checks. */
3621
+ el = inject(ElementRef);
3622
+ /** Reactive signal indicating whether the popover is currently active (open). */
3623
+ active = computed(() => this.trigger()?.active(), ...(ngDevMode ? [{ debugName: "active" }] : []));
3624
+ /** Unique anchor CSS name used to link trigger and content via anchor positioning. */
3625
+ anchorName = signal('--' + this.utils.generateUUID(), ...(ngDevMode ? [{ debugName: "anchorName" }] : []));
3626
+ /** Mode of the trigger (e.g. hover or click) used to determine interaction behavior. */
3627
+ triggerMode = computed(() => this.trigger()?.mode(), ...(ngDevMode ? [{ debugName: "triggerMode" }] : []));
3628
+ /**
3629
+ * Whether a click outside the popover should close it.
3630
+ *
3631
+ * @defaultValue true
3632
+ */
3633
+ closeOnOutsideClick = input(true, ...(ngDevMode ? [{ debugName: "closeOnOutsideClick" }] : []));
3634
+ /** Content child reference to the popover trigger directive instance. */
3635
+ trigger = contentChild(PopoverTrigger, ...(ngDevMode ? [{ debugName: "trigger" }] : []));
3636
+ /** Content child reference to the projected popover content component. */
3637
+ content = contentChild(PopoverContent, ...(ngDevMode ? [{ debugName: "content" }] : []));
3638
+ /** Template reference for inline content projected with the 'popoverContent' identifier. */
3639
+ contentTplRef = contentChild('popoverContent', ...(ngDevMode ? [{ debugName: "contentTplRef" }] : []));
3640
+ /**
3641
+ * Lifecycle hook that initializes the trigger element with its anchor name.
3642
+ */
3643
+ ngOnInit() {
3644
+ this.setTriggerAnchorName();
3645
+ }
3646
+ /**
3647
+ * Creates a reactive effect that syncs content anchor and registers outside click listeners when active.
3648
+ */
3649
+ constructor() {
3650
+ effect(onCleanup => {
3651
+ if (this.active()) {
3652
+ this.setContentAnchorName();
3653
+ if (this.closeOnOutsideClick()) {
3654
+ const handler = (event) => {
3655
+ if (!this.el.nativeElement.contains(event.target)) {
3656
+ this.trigger()?.active.set(false);
3657
+ }
3658
+ };
3659
+ document.addEventListener('click', handler, true);
3660
+ onCleanup(() => document.removeEventListener('click', handler, true));
3661
+ }
3662
+ }
3663
+ });
3664
+ }
3665
+ /**
3666
+ * Applies the generated anchor name to the content element for CSS anchor positioning.
3667
+ */
3668
+ setContentAnchorName() {
3669
+ this.content()?.el.nativeElement.style.setProperty('--anchor-name', this.anchorName());
3670
+ }
3671
+ /**
3672
+ * Applies the generated anchor name to the trigger element to associate it with the content.
3673
+ */
3674
+ setTriggerAnchorName() {
3675
+ this.trigger()?.el.nativeElement.style.setProperty('anchor-name', this.anchorName());
3676
+ }
3677
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Popover, deps: [], target: i0.ɵɵFactoryTarget.Component });
3678
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.3", type: Popover, isStandalone: true, selector: "b-popover", inputs: { closeOnOutsideClick: { classPropertyName: "closeOnOutsideClick", publicName: "closeOnOutsideClick", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mouseleave": "triggerMode() === \"hover\" && trigger()?.active.set(false)" } }, queries: [{ propertyName: "trigger", first: true, predicate: PopoverTrigger, descendants: true, isSignal: true }, { propertyName: "content", first: true, predicate: PopoverContent, descendants: true, isSignal: true }, { propertyName: "contentTplRef", first: true, predicate: ["popoverContent"], descendants: true, isSignal: true }], ngImport: i0, template: `
3679
+ <ng-content />
3680
+ @if (active()) {
3681
+ <ng-container *ngTemplateOutlet="contentTplRef()" />
3682
+ }
3683
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
3684
+ }
3685
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Popover, decorators: [{
3686
+ type: Component,
3687
+ args: [{
3688
+ selector: 'b-popover',
3689
+ imports: [NgTemplateOutlet],
3690
+ template: `
3691
+ <ng-content />
3692
+ @if (active()) {
3693
+ <ng-container *ngTemplateOutlet="contentTplRef()" />
3694
+ }
3695
+ `,
3696
+ host: {
3697
+ '(mouseleave)': 'triggerMode() === "hover" && trigger()?.active.set(false)',
3698
+ },
3699
+ }]
3700
+ }], ctorParameters: () => [] });
3701
+
3541
3702
  /*
3542
3703
  * Public API Surface of basis-ng
3543
3704
  */
@@ -3547,5 +3708,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImpor
3547
3708
  * Generated bundle index. Do not edit.
3548
3709
  */
3549
3710
 
3550
- export { Alert, Badge, Button, ButtonGroup, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, ColorPicker, CommandComponent, CommandOptionsComponent, ConnectedOverlay, Dialog, DialogManager, Drawer, Input, InputGroup, LazyContentDirective, Menu, MenuGroup, MenuItem, MenuItemCheckbox, MenuItemRadio, MenuLabel, MenuTriggerDirective, Option, Otp, OtpDigitDirective, OverlayOrigin, Range, ResponsiveManager, RowComponent, RowItemComponent, Select, SelectContent, SelectFilter, SelectTrigger, SelectValue, Sheet, Spinner, SwitchComponent, Tab, TableComponent, Tabs, TextareaComponent, ThemeManager, Tooltip, TooltipContent, TooltipTrigger, TranslatePipe, TranslationManager, Tree, TreeNode };
3711
+ export { Alert, Badge, Button, ButtonGroup, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, ColorPicker, CommandComponent, CommandOptionsComponent, ConnectedOverlay, Dialog, DialogManager, Drawer, Input, InputGroup, LazyContentDirective, Menu, MenuGroup, MenuItem, MenuItemCheckbox, MenuItemRadio, MenuLabel, MenuTriggerDirective, Option, Otp, OtpDigitDirective, OverlayOrigin, Popover, PopoverContent, PopoverTrigger, Range, ResponsiveManager, RowComponent, RowItemComponent, Select, SelectContent, SelectFilter, SelectTrigger, SelectValue, Sheet, Spinner, SwitchComponent, Tab, TableComponent, Tabs, TextareaComponent, ThemeManager, Tooltip, TooltipContent, TooltipTrigger, TranslatePipe, TranslationManager, Tree, TreeNode };
3551
3712
  //# sourceMappingURL=basis-ng-primitives.mjs.map