@uni-design-system/uni-angular 7.2.0 → 7.3.0

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,7 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
- import { signal, computed, linkedSignal, resource, Injectable, inject, DestroyRef, InjectionToken, input, ChangeDetectionStrategy, Component, contentChildren, output, Renderer2, ElementRef, Directive, model, effect, viewChild, afterNextRender, ViewChild, booleanAttribute, viewChildren } from '@angular/core';
2
+ import { signal, computed, linkedSignal, resource, Injectable, inject, DestroyRef, InjectionToken, input, ChangeDetectionStrategy, Component, contentChildren, output, Renderer2, ElementRef, Directive, model, effect, viewChild, afterNextRender, ViewChild, afterRenderEffect, booleanAttribute, viewChildren } from '@angular/core';
3
3
  import { injectGlobal, css, keyframes } from '@emotion/css';
4
- import { UniThemes, LightTheme, toTypefaces, createThemeFromPalette, Z_INDEX, fadeIn, fadeOut, expandFadeIn, collapseFadeOut, removeInputPlatformStyling, ShapeRadii, generatePalette, emitThemeFile, emitDtcgTokens } from '@uni-design-system/uni-core';
4
+ import { UniThemes, LightTheme, toTypefaces, createThemeFromPalette, Z_INDEX, fadeIn, fadeOut, EXPAND_DEFAULT_SPEED, expandDuration, expandFadeIn, collapseFadeOut, removeInputPlatformStyling, ShapeRadii, generatePalette, emitThemeFile, emitDtcgTokens } from '@uni-design-system/uni-core';
5
5
  import { NgClass, NgTemplateOutlet, CommonModule } from '@angular/common';
6
6
 
7
7
  let nextUniqueId = 0;
@@ -3308,6 +3308,13 @@ class UniDropdownComponent extends BaseComponent {
3308
3308
  popoverId = uniqueId('uni-dropdown');
3309
3309
  paddingVertical = input(...(ngDevMode ? [undefined, { debugName: "paddingVertical" }] : /* istanbul ignore next */ []));
3310
3310
  paddingHorizontal = input(...(ngDevMode ? [undefined, { debugName: "paddingHorizontal" }] : /* istanbul ignore next */ []));
3311
+ // Per-instance panel-chrome overrides; undefined falls back to the theme's
3312
+ // `dropdown` options, so hosts like uni-menu can restyle their panel
3313
+ // without forking the shared dropdown entry.
3314
+ border = input(...(ngDevMode ? [undefined, { debugName: "border" }] : /* istanbul ignore next */ []));
3315
+ borderRadius = input(...(ngDevMode ? [undefined, { debugName: "borderRadius" }] : /* istanbul ignore next */ []));
3316
+ shadow = input(...(ngDevMode ? [undefined, { debugName: "shadow" }] : /* istanbul ignore next */ []));
3317
+ color = input(...(ngDevMode ? [undefined, { debugName: "color" }] : /* istanbul ignore next */ []));
3311
3318
  dropdownShowing = output();
3312
3319
  dropdownHiding = output();
3313
3320
  dropdownRef;
@@ -3432,17 +3439,17 @@ class UniDropdownComponent extends BaseComponent {
3432
3439
  }
3433
3440
  }
3434
3441
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniDropdownComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
3435
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.12", type: UniDropdownComponent, isStandalone: true, selector: "uni-dropdown", inputs: { trigger: { classPropertyName: "trigger", publicName: "trigger", isSignal: true, isRequired: true, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "offset", isSignal: true, isRequired: false, transformFunction: null }, ariaHasPopup: { classPropertyName: "ariaHasPopup", publicName: "ariaHasPopup", isSignal: true, isRequired: false, transformFunction: null }, paddingVertical: { classPropertyName: "paddingVertical", publicName: "paddingVertical", isSignal: true, isRequired: false, transformFunction: null }, paddingHorizontal: { classPropertyName: "paddingHorizontal", publicName: "paddingHorizontal", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dropdownShowing: "dropdownShowing", dropdownHiding: "dropdownHiding" }, providers: [{ provide: COMPONENT_NAME, useValue: 'dropdown' }], viewQueries: [{ propertyName: "dropdownRef", first: true, predicate: ["dropdown"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: `
3442
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.12", type: UniDropdownComponent, isStandalone: true, selector: "uni-dropdown", inputs: { trigger: { classPropertyName: "trigger", publicName: "trigger", isSignal: true, isRequired: true, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "offset", isSignal: true, isRequired: false, transformFunction: null }, ariaHasPopup: { classPropertyName: "ariaHasPopup", publicName: "ariaHasPopup", isSignal: true, isRequired: false, transformFunction: null }, paddingVertical: { classPropertyName: "paddingVertical", publicName: "paddingVertical", isSignal: true, isRequired: false, transformFunction: null }, paddingHorizontal: { classPropertyName: "paddingHorizontal", publicName: "paddingHorizontal", isSignal: true, isRequired: false, transformFunction: null }, border: { classPropertyName: "border", publicName: "border", isSignal: true, isRequired: false, transformFunction: null }, borderRadius: { classPropertyName: "borderRadius", publicName: "borderRadius", isSignal: true, isRequired: false, transformFunction: null }, shadow: { classPropertyName: "shadow", publicName: "shadow", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dropdownShowing: "dropdownShowing", dropdownHiding: "dropdownHiding" }, providers: [{ provide: COMPONENT_NAME, useValue: 'dropdown' }], viewQueries: [{ propertyName: "dropdownRef", first: true, predicate: ["dropdown"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: `
3436
3443
  <!-- 1. The native 'popover' attribute brings it to the top layer with native light-dismiss -->
3437
3444
  <div #dropdown popover="auto" [id]="popoverId" [class]="dropdownClass()">
3438
3445
  <div
3439
3446
  box-layout
3440
- [border]="componentOptions().border"
3441
- [borderRadius]="componentOptions().borderRadius"
3447
+ [border]="border() ?? componentOptions().border"
3448
+ [borderRadius]="borderRadius() ?? componentOptions().borderRadius"
3442
3449
  [paddingVertical]="paddingVertical()"
3443
3450
  [paddingHorizontal]="paddingHorizontal()"
3444
- [color]="componentOptions().color"
3445
- [shadow]="componentOptions().shadow"
3451
+ [color]="color() ?? componentOptions().color"
3452
+ [shadow]="shadow() ?? componentOptions().shadow"
3446
3453
  >
3447
3454
  <ng-content></ng-content>
3448
3455
  </div>
@@ -3460,12 +3467,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
3460
3467
  <div #dropdown popover="auto" [id]="popoverId" [class]="dropdownClass()">
3461
3468
  <div
3462
3469
  box-layout
3463
- [border]="componentOptions().border"
3464
- [borderRadius]="componentOptions().borderRadius"
3470
+ [border]="border() ?? componentOptions().border"
3471
+ [borderRadius]="borderRadius() ?? componentOptions().borderRadius"
3465
3472
  [paddingVertical]="paddingVertical()"
3466
3473
  [paddingHorizontal]="paddingHorizontal()"
3467
- [color]="componentOptions().color"
3468
- [shadow]="componentOptions().shadow"
3474
+ [color]="color() ?? componentOptions().color"
3475
+ [shadow]="shadow() ?? componentOptions().shadow"
3469
3476
  >
3470
3477
  <ng-content></ng-content>
3471
3478
  </div>
@@ -3473,13 +3480,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
3473
3480
  `,
3474
3481
  providers: [{ provide: COMPONENT_NAME, useValue: 'dropdown' }],
3475
3482
  }]
3476
- }], propDecorators: { trigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "trigger", required: true }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], offset: [{ type: i0.Input, args: [{ isSignal: true, alias: "offset", required: false }] }], ariaHasPopup: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaHasPopup", required: false }] }], paddingVertical: [{ type: i0.Input, args: [{ isSignal: true, alias: "paddingVertical", required: false }] }], paddingHorizontal: [{ type: i0.Input, args: [{ isSignal: true, alias: "paddingHorizontal", required: false }] }], dropdownShowing: [{ type: i0.Output, args: ["dropdownShowing"] }], dropdownHiding: [{ type: i0.Output, args: ["dropdownHiding"] }], dropdownRef: [{
3483
+ }], propDecorators: { trigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "trigger", required: true }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], offset: [{ type: i0.Input, args: [{ isSignal: true, alias: "offset", required: false }] }], ariaHasPopup: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaHasPopup", required: false }] }], paddingVertical: [{ type: i0.Input, args: [{ isSignal: true, alias: "paddingVertical", required: false }] }], paddingHorizontal: [{ type: i0.Input, args: [{ isSignal: true, alias: "paddingHorizontal", required: false }] }], border: [{ type: i0.Input, args: [{ isSignal: true, alias: "border", required: false }] }], borderRadius: [{ type: i0.Input, args: [{ isSignal: true, alias: "borderRadius", required: false }] }], shadow: [{ type: i0.Input, args: [{ isSignal: true, alias: "shadow", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], dropdownShowing: [{ type: i0.Output, args: ["dropdownShowing"] }], dropdownHiding: [{ type: i0.Output, args: ["dropdownHiding"] }], dropdownRef: [{
3477
3484
  type: ViewChild,
3478
3485
  args: ['dropdown', { static: true }]
3479
3486
  }] } });
3480
3487
 
3481
- class UniExpandComponent {
3488
+ class UniExpandComponent extends BaseComponent {
3482
3489
  collapsed = model(true, ...(ngDevMode ? [{ debugName: "collapsed" }] : /* istanbul ignore next */ []));
3490
+ /**
3491
+ * Exact per-instance duration in seconds. Bypasses size-aware scaling —
3492
+ * an explicit number means the consumer wants that number. Omitted, the
3493
+ * duration derives from the `expand` theme options' `transitionSpeed`
3494
+ * scaled by content height (see `duration`).
3495
+ */
3496
+ transitionSpeed = input(...(ngDevMode ? [undefined, { debugName: "transitionSpeed" }] : /* istanbul ignore next */ []));
3483
3497
  /** Referenced by the controlling toggle's aria-controls. */
3484
3498
  regionId = uniqueId('uni-expand');
3485
3499
  /**
@@ -3488,12 +3502,49 @@ class UniExpandComponent {
3488
3502
  * animations only after the first render, i.e. on real state changes.
3489
3503
  */
3490
3504
  ready = signal(false, ...(ngDevMode ? [{ debugName: "ready" }] : /* istanbul ignore next */ []));
3505
+ contentRef = viewChild('content', ...(ngDevMode ? [{ debugName: "contentRef" }] : /* istanbul ignore next */ []));
3506
+ /**
3507
+ * Last observed content height. Retained after collapse (the observer
3508
+ * disconnects but the signal keeps its value) so the leave animation and
3509
+ * the next reveal are timed to the real size. Until the first measurement
3510
+ * lands — one frame into the very first reveal — the duration falls back
3511
+ * to the unscaled token; CSS remaps animation progress when
3512
+ * `animation-duration` updates, so the retime is imperceptible that early.
3513
+ */
3514
+ contentHeight = signal(undefined, ...(ngDevMode ? [{ debugName: "contentHeight" }] : /* istanbul ignore next */ []));
3491
3515
  constructor() {
3516
+ super();
3492
3517
  afterNextRender(() => this.ready.set(true));
3518
+ afterRenderEffect((onCleanup) => {
3519
+ const content = this.contentRef()?.nativeElement;
3520
+ if (!content)
3521
+ return;
3522
+ const observer = new ResizeObserver(() => this.contentHeight.set(content.scrollHeight));
3523
+ observer.observe(content);
3524
+ onCleanup(() => observer.disconnect());
3525
+ });
3493
3526
  }
3494
3527
  toggle() {
3495
3528
  this.collapsed.update((collapsed) => !collapsed);
3496
3529
  }
3530
+ /**
3531
+ * The resolved duration in seconds: the `transitionSpeed` input verbatim,
3532
+ * or the `expand` theme options' `transitionSpeed` scaled by content height
3533
+ * (`expandDuration` — √-of-height, clamped) so short regions stay snappy
3534
+ * and tall ones aren't rushed. The public sync hook: Expand Area binds this
3535
+ * to its toggle so the chevron rotates on the region's clock, and consumers
3536
+ * can bind adjacent styling the same way
3537
+ * (`[style.transition-duration]="expand.duration() + 's'"`).
3538
+ */
3539
+ duration = computed(() => {
3540
+ const override = this.transitionSpeed();
3541
+ if (override !== undefined)
3542
+ return override;
3543
+ const speed = this.componentOptions().transitionSpeed ?? EXPAND_DEFAULT_SPEED;
3544
+ const height = this.contentHeight();
3545
+ return height === undefined ? speed : expandDuration(height, speed);
3546
+ }, ...(ngDevMode ? [{ debugName: "duration" }] : /* istanbul ignore next */ []));
3547
+ cssDuration = computed(() => `${this.duration()}s`, ...(ngDevMode ? [{ debugName: "cssDuration" }] : /* istanbul ignore next */ []));
3497
3548
  /**
3498
3549
  * A custom element is `display: inline` by default, which would lay the
3499
3550
  * animated grid out as a block-in-inline box and distort the revealed
@@ -3519,23 +3570,29 @@ class UniExpandComponent {
3519
3570
  * decorations that legitimately paint outside the region (focus rings,
3520
3571
  * offset outlines). Angular removes a leaving node on the next frame when it
3521
3572
  * detects no animation, so nothing hangs when the guard strips them.
3573
+ *
3574
+ * The classes carry the default duration; the animated div's
3575
+ * `[style.animation-duration]` binding overrides it with the resolved
3576
+ * `duration`, so the classes stay static while timing tracks the theme and
3577
+ * the content's size through signals alone.
3522
3578
  */
3523
3579
  expandAnimation = css(motionSafe({
3524
3580
  overflow: 'hidden',
3525
- animation: `${this.expand} ease-in 350ms`,
3581
+ animation: `${this.expand} ease-in-out ${EXPAND_DEFAULT_SPEED}s`,
3526
3582
  }));
3527
3583
  collapseAnimation = css(motionSafe({
3528
3584
  overflow: 'hidden',
3529
- animation: `${this.collapse} ease-in 350ms`,
3585
+ animation: `${this.collapse} ease-in-out ${EXPAND_DEFAULT_SPEED}s`,
3530
3586
  }));
3531
3587
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniExpandComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3532
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: UniExpandComponent, isStandalone: true, selector: "uni-expand", inputs: { collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { collapsed: "collapsedChange" }, host: { properties: { "attr.id": "regionId", "class": "hostClassName" } }, ngImport: i0, template: `@if (!collapsed()) {
3588
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: UniExpandComponent, isStandalone: true, selector: "uni-expand", inputs: { collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null }, transitionSpeed: { classPropertyName: "transitionSpeed", publicName: "transitionSpeed", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { collapsed: "collapsedChange" }, host: { properties: { "attr.id": "regionId", "class": "hostClassName" } }, providers: [{ provide: COMPONENT_NAME, useValue: 'expand' }], viewQueries: [{ propertyName: "contentRef", first: true, predicate: ["content"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `@if (!collapsed()) {
3533
3589
  <div
3534
3590
  [animate.enter]="ready() ? expandAnimation : ''"
3535
3591
  [animate.leave]="collapseAnimation"
3536
3592
  [class]="expandClassName"
3593
+ [style.animation-duration]="cssDuration()"
3537
3594
  >
3538
- <div [class]="contentClassName">
3595
+ <div #content [class]="contentClassName">
3539
3596
  <ng-content></ng-content>
3540
3597
  </div>
3541
3598
  </div>
@@ -3547,13 +3604,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
3547
3604
  changeDetection: ChangeDetectionStrategy.OnPush,
3548
3605
  selector: 'uni-expand',
3549
3606
  imports: [],
3607
+ providers: [{ provide: COMPONENT_NAME, useValue: 'expand' }],
3550
3608
  template: `@if (!collapsed()) {
3551
3609
  <div
3552
3610
  [animate.enter]="ready() ? expandAnimation : ''"
3553
3611
  [animate.leave]="collapseAnimation"
3554
3612
  [class]="expandClassName"
3613
+ [style.animation-duration]="cssDuration()"
3555
3614
  >
3556
- <div [class]="contentClassName">
3615
+ <div #content [class]="contentClassName">
3557
3616
  <ng-content></ng-content>
3558
3617
  </div>
3559
3618
  </div>
@@ -3563,7 +3622,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
3563
3622
  '[class]': 'hostClassName',
3564
3623
  },
3565
3624
  }]
3566
- }], ctorParameters: () => [], propDecorators: { collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }, { type: i0.Output, args: ["collapsedChange"] }] } });
3625
+ }], ctorParameters: () => [], propDecorators: { collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }, { type: i0.Output, args: ["collapsedChange"] }], transitionSpeed: [{ type: i0.Input, args: [{ isSignal: true, alias: "transitionSpeed", required: false }] }], contentRef: [{ type: i0.ViewChild, args: ['content', { isSignal: true }] }] } });
3567
3626
 
3568
3627
  /**
3569
3628
  * UniExpandComponent Barrel File
@@ -3571,182 +3630,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
3571
3630
  * This file exports all public-facing elements of the expand component.
3572
3631
  */
3573
3632
 
3574
- class UniTooltipComponent extends BaseComponent {
3575
- elRef = inject(ElementRef);
3576
- renderer = inject(Renderer2);
3577
- timer = useTimer();
3578
- isMouseInside = signal(false, ...(ngDevMode ? [{ debugName: "isMouseInside" }] : /* istanbul ignore next */ []));
3579
- /** Whether the bubble is currently shown (or fading out). */
3580
- visible = signal(false, ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
3581
- tooltipId = uniqueId('uni-tooltip');
3582
- anchorName = newAnchorName();
3583
- hoverDelay = input(500, ...(ngDevMode ? [{ debugName: "hoverDelay" }] : /* istanbul ignore next */ []));
3584
- label = input.required(...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
3585
- placement = input('top', ...(ngDevMode ? [{ debugName: "placement" }] : /* istanbul ignore next */ []));
3586
- inlineText = input(false, ...(ngDevMode ? [{ debugName: "inlineText" }] : /* istanbul ignore next */ []));
3587
- /** @deprecated The tooltip renders in the native top layer; ignored. */
3588
- appendToBody = input(false, ...(ngDevMode ? [{ debugName: "appendToBody" }] : /* istanbul ignore next */ []));
3589
- tipRef = viewChild.required('tip');
3590
- constructor() {
3591
- super();
3592
- effect(() => {
3593
- const timerActive = this.timer.isActive();
3594
- const mouseInside = this.isMouseInside();
3595
- // If the timer finished and the mouse is still inside, show tooltip
3596
- if (!timerActive && mouseInside) {
3597
- this.showTooltip();
3598
- }
3599
- // If the mouse left and the timer is not running, hide tooltip
3600
- else if (!mouseInside) {
3601
- this.hideTooltip();
3602
- }
3603
- });
3604
- // A tooltip must be reachable by keyboard (WCAG 1.4.13): when the
3605
- // projected content has no focusable element, the host itself joins
3606
- // the tab sequence. The bubble is always in the DOM, so the describedby
3607
- // relationship is wired once, on the element that receives focus.
3608
- afterNextRender(() => {
3609
- const host = this.elRef.nativeElement;
3610
- if (!host.querySelector(FOCUSABLE_SELECTOR) && !host.matches(FOCUSABLE_SELECTOR)) {
3611
- this.renderer.setAttribute(host, 'tabindex', '0');
3612
- }
3613
- this.renderer.setAttribute(resolveFocusTarget(host), 'aria-describedby', this.tooltipId);
3614
- });
3615
- }
3616
- onFocusIn(event) {
3617
- // Only keyboard-driven focus shows the tooltip immediately; mouse
3618
- // interaction keeps the hover-delay behavior.
3619
- if (event.target.matches(':focus-visible')) {
3620
- this.showTooltip();
3621
- }
3622
- }
3623
- onFocusOut() {
3624
- if (!this.isMouseInside()) {
3625
- this.hideTooltip();
3626
- }
3627
- }
3628
- onEscape(event) {
3629
- if (this.visible()) {
3630
- // Dismiss only the tooltip, not an enclosing dialog/popover
3631
- event.stopPropagation();
3632
- this.hideTooltip();
3633
- }
3634
- }
3635
- toggleTooltip() {
3636
- if (this.visible()) {
3637
- this.hideTooltip();
3638
- }
3639
- else {
3640
- this.showTooltip();
3641
- }
3642
- }
3643
- mouseenter() {
3644
- this.isMouseInside.set(true);
3645
- this.timer.start(this.hoverDelay());
3646
- }
3647
- mouseleave() {
3648
- this.isMouseInside.set(false);
3649
- this.timer.stop();
3650
- }
3651
- showTooltip() {
3652
- if (this.visible())
3653
- return;
3654
- const tip = this.tipRef().nativeElement;
3655
- tip.showPopover();
3656
- this.renderer.setAttribute(tip, 'fade', 'in');
3657
- this.visible.set(true);
3658
- }
3659
- hideTooltip() {
3660
- if (!this.visible())
3661
- return;
3662
- this.renderer.setAttribute(this.tipRef().nativeElement, 'fade', 'out');
3663
- }
3664
- onAnimationEnd(event) {
3665
- if (event.animationName.includes(this.tooltipFadeOut)) {
3666
- this.tipRef().nativeElement.hidePopover();
3667
- this.visible.set(false);
3668
- }
3669
- }
3670
- className = computed(() => css({
3671
- display: 'inline-flex',
3672
- anchorName: this.anchorName,
3673
- }, this.inlineText() && {
3674
- cursor: 'help',
3675
- textDecoration: 'underline',
3676
- textDecorationStyle: 'dotted',
3677
- }), ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
3678
- tooltipFadeIn = keyframes({ ...fadeIn });
3679
- tooltipFadeOut = keyframes({ ...fadeOut });
3680
- tooltipClassName = computed(() => css([
3681
- {
3682
- ...this.theme.colorPair(this.componentOptions().color),
3683
- ...this.theme.radius(this.componentOptions().borderRadius),
3684
- ...this.theme.boxShadow(this.componentOptions().shadow),
3685
- ...this.theme.typeface(this.componentOptions().typeface),
3686
- border: 'none',
3687
- padding: 5,
3688
- width: 'max-content',
3689
- ...anchorStyles(this.anchorName, this.placement(), { mainAxis: 6 }),
3690
- '&[fade="in"]': {
3691
- animation: `${this.tooltipFadeIn} ease-in 350ms`,
3692
- },
3693
- '&[fade="out"]': {
3694
- animation: `${this.tooltipFadeOut} ease-in 350ms`,
3695
- },
3696
- },
3697
- ]), ...(ngDevMode ? [{ debugName: "tooltipClassName" }] : /* istanbul ignore next */ []));
3698
- arrowClassName = computed(() => css({
3699
- ...this.theme.colorPair(this.componentOptions().color),
3700
- ...anchorArrowStyles(this.placement()),
3701
- }), ...(ngDevMode ? [{ debugName: "arrowClassName" }] : /* istanbul ignore next */ []));
3702
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniTooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3703
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.12", type: UniTooltipComponent, isStandalone: true, selector: "uni-tooltip", inputs: { hoverDelay: { classPropertyName: "hoverDelay", publicName: "hoverDelay", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, inlineText: { classPropertyName: "inlineText", publicName: "inlineText", isSignal: true, isRequired: false, transformFunction: null }, appendToBody: { classPropertyName: "appendToBody", publicName: "appendToBody", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "toggleTooltip()", "mouseenter": "mouseenter()", "mouseleave": "mouseleave()", "focusin": "onFocusIn($event)", "focusout": "onFocusOut()", "keydown.escape": "onEscape($event)" }, properties: { "class": "className()" } }, providers: [{ provide: COMPONENT_NAME, useValue: 'tooltip' }], viewQueries: [{ propertyName: "tipRef", first: true, predicate: ["tip"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `<ng-content></ng-content
3704
- ><span
3705
- #tip
3706
- popover="manual"
3707
- role="tooltip"
3708
- [id]="tooltipId"
3709
- [class]="tooltipClassName()"
3710
- (mouseenter)="isMouseInside.set(true)"
3711
- (mouseleave)="isMouseInside.set(false)"
3712
- (animationend)="onAnimationEnd($event)"
3713
- >{{ label() }}<span [class]="arrowClassName()"></span
3714
- ></span>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
3715
- }
3716
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniTooltipComponent, decorators: [{
3717
- type: Component,
3718
- args: [{
3719
- selector: 'uni-tooltip',
3720
- imports: [],
3721
- // The bubble lives declaratively in the template as a manual popover: the
3722
- // top layer escapes any overflow context (which made appendToBody obsolete)
3723
- // and native CSS anchor positioning keeps it attached to the host.
3724
- template: `<ng-content></ng-content
3725
- ><span
3726
- #tip
3727
- popover="manual"
3728
- role="tooltip"
3729
- [id]="tooltipId"
3730
- [class]="tooltipClassName()"
3731
- (mouseenter)="isMouseInside.set(true)"
3732
- (mouseleave)="isMouseInside.set(false)"
3733
- (animationend)="onAnimationEnd($event)"
3734
- >{{ label() }}<span [class]="arrowClassName()"></span
3735
- ></span>`,
3736
- providers: [{ provide: COMPONENT_NAME, useValue: 'tooltip' }],
3737
- changeDetection: ChangeDetectionStrategy.OnPush,
3738
- host: {
3739
- '[class]': 'className()',
3740
- '(click)': 'toggleTooltip()',
3741
- '(mouseenter)': 'mouseenter()',
3742
- '(mouseleave)': 'mouseleave()',
3743
- '(focusin)': 'onFocusIn($event)',
3744
- '(focusout)': 'onFocusOut()',
3745
- '(keydown.escape)': 'onEscape($event)',
3746
- },
3747
- }]
3748
- }], ctorParameters: () => [], propDecorators: { hoverDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "hoverDelay", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], inlineText: [{ type: i0.Input, args: [{ isSignal: true, alias: "inlineText", required: false }] }], appendToBody: [{ type: i0.Input, args: [{ isSignal: true, alias: "appendToBody", required: false }] }], tipRef: [{ type: i0.ViewChild, args: ['tip', { isSignal: true }] }] } });
3749
-
3750
3633
  /**
3751
3634
  * Trigger for a {@link UniExpandComponent} region.
3752
3635
  *
@@ -3765,13 +3648,19 @@ class UniExpandToggleComponent {
3765
3648
  label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : /* istanbul ignore next */ []));
3766
3649
  /** Muted qualifier beside the label ("for POs & custom orders"). Needs `label`. */
3767
3650
  sublabel = input(...(ngDevMode ? [undefined, { debugName: "sublabel" }] : /* istanbul ignore next */ []));
3651
+ /**
3652
+ * Rotation duration in seconds. Expand Area binds the region's resolved
3653
+ * `duration` here so chevron and reveal share one clock even when the
3654
+ * region is size-scaled or overridden per instance.
3655
+ */
3656
+ transitionSpeed = input(...(ngDevMode ? [undefined, { debugName: "transitionSpeed" }] : /* istanbul ignore next */ []));
3657
+ /** Fallback clock when no `transitionSpeed` is bound: the `expand` theme options' `transitionSpeed`. */
3658
+ expandOptions = inject(ThemeService).getComponentOptions('expand');
3659
+ speed = computed(() => this.transitionSpeed() ?? this.expandOptions().transitionSpeed ?? EXPAND_DEFAULT_SPEED, ...(ngDevMode ? [{ debugName: "speed" }] : /* istanbul ignore next */ []));
3768
3660
  /**
3769
3661
  * The glyph rotates, never the host.
3770
3662
  *
3771
- * The host is the tooltip's positioning box `uni-tooltip` puts its
3772
- * `anchor-name` on its own element, nested inside ours — so rotating the
3773
- * host swings the anchor through the turn and the bubble visibly bobs. The
3774
- * host is also taller than the glyph (an inline-level box reserves baseline
3663
+ * The host is taller than the glyph (an inline-level box reserves baseline
3775
3664
  * descender space), so spinning it about its own centre walks the glyph
3776
3665
  * off-centre. `uni-icon` is a centred square sized to the glyph, which makes
3777
3666
  * it the only box here that rotates symmetrically. It also keeps a label
@@ -3780,7 +3669,9 @@ class UniExpandToggleComponent {
3780
3669
  glyphStyles = computed(() => ({
3781
3670
  '& uni-icon': {
3782
3671
  flexShrink: 0,
3783
- ...motionSafe({ transition: 'transform 350ms ease-in-out' }),
3672
+ ...motionSafe({
3673
+ transition: `transform ${this.speed()}s ease-in-out`,
3674
+ }),
3784
3675
  transform: this.collapsed() ? 'rotate(-180deg)' : 'rotate(0)',
3785
3676
  },
3786
3677
  }), ...(ngDevMode ? [{ debugName: "glyphStyles" }] : /* istanbul ignore next */ []));
@@ -3817,7 +3708,7 @@ class UniExpandToggleComponent {
3817
3708
  this.collapsed.update((collapsed) => !collapsed);
3818
3709
  }
3819
3710
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniExpandToggleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3820
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: UniExpandToggleComponent, isStandalone: true, selector: "uni-expand-toggle", inputs: { collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null }, ariaControls: { classPropertyName: "ariaControls", publicName: "ariaControls", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, sublabel: { classPropertyName: "sublabel", publicName: "sublabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { collapsed: "collapsedChange" }, host: { properties: { "class": "className()", "attr.toggled": "collapsed() || null" } }, ngImport: i0, template: `
3711
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: UniExpandToggleComponent, isStandalone: true, selector: "uni-expand-toggle", inputs: { collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null }, ariaControls: { classPropertyName: "ariaControls", publicName: "ariaControls", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, sublabel: { classPropertyName: "sublabel", publicName: "sublabel", isSignal: true, isRequired: false, transformFunction: null }, transitionSpeed: { classPropertyName: "transitionSpeed", publicName: "transitionSpeed", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { collapsed: "collapsedChange" }, host: { properties: { "class": "className()", "attr.toggled": "collapsed() || null" } }, ngImport: i0, template: `
3821
3712
  @if (label()) {
3822
3713
  <button
3823
3714
  type="button"
@@ -3835,25 +3726,23 @@ class UniExpandToggleComponent {
3835
3726
  </span>
3836
3727
  </button>
3837
3728
  } @else {
3838
- <uni-tooltip [label]="collapsed() ? 'Expand' : 'Collapse'" placement="right">
3839
- <button
3840
- icon-button
3841
- iconName="chevronUp"
3842
- (click)="toggle()"
3843
- [attr.aria-expanded]="!collapsed()"
3844
- [attr.aria-controls]="ariaControls() || null"
3845
- >
3846
- {{ collapsed() ? 'Expand' : 'Collapse' }}
3847
- </button>
3848
- </uni-tooltip>
3729
+ <button
3730
+ icon-button
3731
+ iconName="chevronUp"
3732
+ (click)="toggle()"
3733
+ [attr.aria-expanded]="!collapsed()"
3734
+ [attr.aria-controls]="ariaControls() || null"
3735
+ >
3736
+ {{ collapsed() ? 'Expand' : 'Collapse' }}
3737
+ </button>
3849
3738
  }
3850
- `, isInline: true, dependencies: [{ kind: "component", type: UniIconComponent, selector: "uni-icon", inputs: ["color", "name", "size"] }, { kind: "component", type: UniIconButtonComponent, selector: "button[uni-icon-button], button[icon-button]", inputs: ["ariaLabel", "iconName", "symbolName", "variant", "size", "disable", "loading", "opticalSize"] }, { kind: "component", type: UniTextComponent, selector: "[uni-text]", inputs: ["uni-text", "typeface", "color", "display", "align", "nowrap", "maxWidth", "ellipsis"] }, { kind: "component", type: UniTooltipComponent, selector: "uni-tooltip", inputs: ["hoverDelay", "label", "placement", "inlineText", "appendToBody"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3739
+ `, isInline: true, dependencies: [{ kind: "component", type: UniIconComponent, selector: "uni-icon", inputs: ["color", "name", "size"] }, { kind: "component", type: UniIconButtonComponent, selector: "button[uni-icon-button], button[icon-button]", inputs: ["ariaLabel", "iconName", "symbolName", "variant", "size", "disable", "loading", "opticalSize"] }, { kind: "component", type: UniTextComponent, selector: "[uni-text]", inputs: ["uni-text", "typeface", "color", "display", "align", "nowrap", "maxWidth", "ellipsis"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3851
3740
  }
3852
3741
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniExpandToggleComponent, decorators: [{
3853
3742
  type: Component,
3854
3743
  args: [{
3855
3744
  selector: 'uni-expand-toggle',
3856
- imports: [UniIconComponent, UniIconButtonComponent, UniTextComponent, UniTooltipComponent],
3745
+ imports: [UniIconComponent, UniIconButtonComponent, UniTextComponent],
3857
3746
  template: `
3858
3747
  @if (label()) {
3859
3748
  <button
@@ -3872,17 +3761,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
3872
3761
  </span>
3873
3762
  </button>
3874
3763
  } @else {
3875
- <uni-tooltip [label]="collapsed() ? 'Expand' : 'Collapse'" placement="right">
3876
- <button
3877
- icon-button
3878
- iconName="chevronUp"
3879
- (click)="toggle()"
3880
- [attr.aria-expanded]="!collapsed()"
3881
- [attr.aria-controls]="ariaControls() || null"
3882
- >
3883
- {{ collapsed() ? 'Expand' : 'Collapse' }}
3884
- </button>
3885
- </uni-tooltip>
3764
+ <button
3765
+ icon-button
3766
+ iconName="chevronUp"
3767
+ (click)="toggle()"
3768
+ [attr.aria-expanded]="!collapsed()"
3769
+ [attr.aria-controls]="ariaControls() || null"
3770
+ >
3771
+ {{ collapsed() ? 'Expand' : 'Collapse' }}
3772
+ </button>
3886
3773
  }
3887
3774
  `,
3888
3775
  host: {
@@ -3891,7 +3778,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
3891
3778
  },
3892
3779
  changeDetection: ChangeDetectionStrategy.OnPush,
3893
3780
  }]
3894
- }], propDecorators: { collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }, { type: i0.Output, args: ["collapsedChange"] }], ariaControls: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaControls", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], sublabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sublabel", required: false }] }] } });
3781
+ }], propDecorators: { collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }, { type: i0.Output, args: ["collapsedChange"] }], ariaControls: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaControls", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], sublabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sublabel", required: false }] }], transitionSpeed: [{ type: i0.Input, args: [{ isSignal: true, alias: "transitionSpeed", required: false }] }] } });
3895
3782
 
3896
3783
  class UniExpandAreaComponent {
3897
3784
  title = input.required(...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
@@ -3927,6 +3814,7 @@ class UniExpandAreaComponent {
3927
3814
  style="display: inline-flex; margin: -2px"
3928
3815
  [collapsed]="initCollapsed()"
3929
3816
  [ariaControls]="expand.regionId"
3817
+ [transitionSpeed]="expand.duration()"
3930
3818
  />
3931
3819
  </div>
3932
3820
 
@@ -3936,7 +3824,7 @@ class UniExpandAreaComponent {
3936
3824
  </div>
3937
3825
  </uni-expand>
3938
3826
  </div>
3939
- `, isInline: true, dependencies: [{ kind: "component", type: UniBoxComponent, selector: "[uni-box-layout], [box-layout]", inputs: ["color", "backgroundColor", "borderRadius", "borderRadiusLeft", "borderRadiusRight", "borderRadiusTop", "borderRadiusBottom", "padding", "paddingHorizontal", "paddingVertical", "paddingLeft", "paddingRight", "paddingTop", "paddingBottom", "border", "borderTop", "borderBottom", "borderLeft", "borderRight", "dashBorder", "alignSelf", "alignItems", "alignContent", "justifyContent", "grow", "display", "position", "inset", "height", "minHeight", "maxHeight", "width", "minWidth", "maxWidth", "ignoreDir", "gridArea", "gridColumn", "gridRow", "overflow", "elevation", "shadow", "gap", "fullWidth", "fullHeight", "flexDirection", "textAlign", "wrapItems", "zIndex"] }, { kind: "component", type: UniTextComponent, selector: "[uni-text]", inputs: ["uni-text", "typeface", "color", "display", "align", "nowrap", "maxWidth", "ellipsis"] }, { kind: "component", type: UniExpandToggleComponent, selector: "uni-expand-toggle", inputs: ["collapsed", "ariaControls", "label", "sublabel"], outputs: ["collapsedChange"] }, { kind: "component", type: UniExpandComponent, selector: "uni-expand", inputs: ["collapsed"], outputs: ["collapsedChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3827
+ `, isInline: true, dependencies: [{ kind: "component", type: UniBoxComponent, selector: "[uni-box-layout], [box-layout]", inputs: ["color", "backgroundColor", "borderRadius", "borderRadiusLeft", "borderRadiusRight", "borderRadiusTop", "borderRadiusBottom", "padding", "paddingHorizontal", "paddingVertical", "paddingLeft", "paddingRight", "paddingTop", "paddingBottom", "border", "borderTop", "borderBottom", "borderLeft", "borderRight", "dashBorder", "alignSelf", "alignItems", "alignContent", "justifyContent", "grow", "display", "position", "inset", "height", "minHeight", "maxHeight", "width", "minWidth", "maxWidth", "ignoreDir", "gridArea", "gridColumn", "gridRow", "overflow", "elevation", "shadow", "gap", "fullWidth", "fullHeight", "flexDirection", "textAlign", "wrapItems", "zIndex"] }, { kind: "component", type: UniTextComponent, selector: "[uni-text]", inputs: ["uni-text", "typeface", "color", "display", "align", "nowrap", "maxWidth", "ellipsis"] }, { kind: "component", type: UniExpandToggleComponent, selector: "uni-expand-toggle", inputs: ["collapsed", "ariaControls", "label", "sublabel", "transitionSpeed"], outputs: ["collapsedChange"] }, { kind: "component", type: UniExpandComponent, selector: "uni-expand", inputs: ["collapsed", "transitionSpeed"], outputs: ["collapsedChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3940
3828
  }
3941
3829
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniExpandAreaComponent, decorators: [{
3942
3830
  type: Component,
@@ -3968,6 +3856,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
3968
3856
  style="display: inline-flex; margin: -2px"
3969
3857
  [collapsed]="initCollapsed()"
3970
3858
  [ariaControls]="expand.regionId"
3859
+ [transitionSpeed]="expand.duration()"
3971
3860
  />
3972
3861
  </div>
3973
3862
 
@@ -4274,32 +4163,61 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
4274
4163
  * This file exports all public-facing elements of the json-view component.
4275
4164
  */
4276
4165
 
4277
- class UniMenuItemComponent extends UniBoxComponent {
4166
+ const isDivider = (item) => 'divider' in item;
4167
+
4168
+ class UniMenuItemComponent {
4169
+ theme = inject(ThemeService);
4278
4170
  _elementRef = inject(ElementRef);
4279
- display = input('flex', ...(ngDevMode ? [{ debugName: "display" }] : /* istanbul ignore next */ []));
4280
- flexDirection = input('row', ...(ngDevMode ? [{ debugName: "flexDirection" }] : /* istanbul ignore next */ []));
4281
- alignItems = input('center', ...(ngDevMode ? [{ debugName: "alignItems" }] : /* istanbul ignore next */ []));
4282
- paddingHorizontal = input('md', ...(ngDevMode ? [{ debugName: "paddingHorizontal" }] : /* istanbul ignore next */ []));
4283
- gap = input('md', ...(ngDevMode ? [{ debugName: "gap" }] : /* istanbul ignore next */ []));
4284
4171
  label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : /* istanbul ignore next */ []));
4285
4172
  template = input(...(ngDevMode ? [undefined, { debugName: "template" }] : /* istanbul ignore next */ []));
4286
4173
  context = input(...(ngDevMode ? [undefined, { debugName: "context" }] : /* istanbul ignore next */ []));
4287
4174
  symbolName = input(...(ngDevMode ? [undefined, { debugName: "symbolName" }] : /* istanbul ignore next */ []));
4288
4175
  active = input(...(ngDevMode ? [undefined, { debugName: "active" }] : /* istanbul ignore next */ []));
4289
- hoverColor = input('primary-container', ...(ngDevMode ? [{ debugName: "hoverColor" }] : /* istanbul ignore next */ []));
4176
+ /** Tone routed through the theme's `menuItem` variants (e.g. 'warn'). */
4177
+ variant = input(...(ngDevMode ? [undefined, { debugName: "variant" }] : /* istanbul ignore next */ []));
4178
+ /** Per-instance override of the theme's `menuItem.hoverColor`. */
4179
+ hoverColor = input(...(ngDevMode ? [undefined, { debugName: "hoverColor" }] : /* istanbul ignore next */ []));
4290
4180
  disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
4291
- menuItemClassName = computed(() => css([
4292
- {
4293
- cursor: 'pointer',
4294
- transition: 'all 0.35s ease',
4295
- height: 38,
4296
- // Roving focus highlights items the same way hover does
4297
- '&:hover, &:focus': {
4298
- ...this.theme.colorPair(this.hoverColor()),
4299
- outline: 'none',
4181
+ options = computed(() => this.theme.getComponentOptions('menuItem')(), ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
4182
+ activeSymbol = computed(() => this.options().activeSymbol, ...(ngDevMode ? [{ debugName: "activeSymbol" }] : /* istanbul ignore next */ []));
4183
+ /** Typography comes from the host's themed typeface; the span only lays out. */
4184
+ LabelClassName = css({ display: 'block', whiteSpace: 'nowrap' });
4185
+ menuItemClassName = computed(() => {
4186
+ const options = this.options();
4187
+ const variant = this.variant();
4188
+ const variantStyle = variant
4189
+ ? this.theme.component('menuItem')().variants?.[variant]
4190
+ : undefined;
4191
+ const transitionSpeed = options.transitionSpeed ?? 0;
4192
+ return css([
4193
+ {
4194
+ display: 'flex',
4195
+ flexDirection: 'row',
4196
+ alignItems: 'center',
4197
+ boxSizing: 'border-box',
4198
+ cursor: 'pointer',
4199
+ height: options.height,
4200
+ ...this.theme.horizontalPadding(options.paddingHorizontal),
4201
+ ...this.theme.gap(options.gap),
4202
+ ...this.theme.radius(options.borderRadius),
4203
+ ...this.theme.typeface(options.typeface),
4204
+ ...this.theme.color(options.textColor),
4205
+ // Roving focus highlights items the same way hover does
4206
+ '&:hover, &:focus': {
4207
+ ...this.theme.colorPair(this.hoverColor() ?? options.hoverColor),
4208
+ outline: 'none',
4209
+ },
4210
+ '&[aria-disabled="true"]': {
4211
+ color: this.theme.colors()['on-disabled-surface'],
4212
+ pointerEvents: 'none',
4213
+ },
4300
4214
  },
4301
- },
4302
- ]), ...(ngDevMode ? [{ debugName: "menuItemClassName" }] : /* istanbul ignore next */ []));
4215
+ transitionSpeed > 0 && { transition: `all ${transitionSpeed}s ease` },
4216
+ // Variant tones override the base look; a same-key '&:hover, &:focus'
4217
+ // in the variant replaces the default hover pair outright.
4218
+ { ...variantStyle },
4219
+ ]);
4220
+ }, ...(ngDevMode ? [{ debugName: "menuItemClassName" }] : /* istanbul ignore next */ []));
4303
4221
  /** Host element, used by Menu for roving-focus bookkeeping. */
4304
4222
  get host() {
4305
4223
  return this._elementRef.nativeElement;
@@ -4307,21 +4225,22 @@ class UniMenuItemComponent extends UniBoxComponent {
4307
4225
  focus() {
4308
4226
  this._elementRef.nativeElement.focus();
4309
4227
  }
4310
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniMenuItemComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
4311
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: UniMenuItemComponent, isStandalone: true, selector: "[uni-menu-item], [menu-item]", inputs: { display: { classPropertyName: "display", publicName: "display", isSignal: true, isRequired: false, transformFunction: null }, flexDirection: { classPropertyName: "flexDirection", publicName: "flexDirection", isSignal: true, isRequired: false, transformFunction: null }, alignItems: { classPropertyName: "alignItems", publicName: "alignItems", isSignal: true, isRequired: false, transformFunction: null }, paddingHorizontal: { classPropertyName: "paddingHorizontal", publicName: "paddingHorizontal", isSignal: true, isRequired: false, transformFunction: null }, gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, template: { classPropertyName: "template", publicName: "template", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null }, symbolName: { classPropertyName: "symbolName", publicName: "symbolName", isSignal: true, isRequired: false, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, hoverColor: { classPropertyName: "hoverColor", publicName: "hoverColor", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "menuitem", "tabindex": "-1" }, properties: { "attr.aria-disabled": "disabled() ? 'true' : null", "attr.aria-current": "active() ? 'true' : null", "class": "menuItemClassName()" } }, usesInheritance: true, ngImport: i0, template: "@let tpl = template();\n@let symbol = symbolName();\n@if (symbol) {\n <uni-symbol [name]=\"symbol\"></uni-symbol>\n}\n<div box-layout [grow]=\"1\">\n @if (tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"context()\"></ng-container>\n } @else {\n <span uni-text=\"label\" display=\"block\" [nowrap]=\"true\">\n {{ label() }}\n </span>\n }\n</div>\n@if (active()) {\n <uni-symbol name=\"check\"></uni-symbol>\n}\n", styles: [":host.disabled{color:#ddd;pointer-events:none}\n"], dependencies: [{ kind: "component", type: UniTextComponent, selector: "[uni-text]", inputs: ["uni-text", "typeface", "color", "display", "align", "nowrap", "maxWidth", "ellipsis"] }, { kind: "component", type: UniSymbolComponent, selector: "uni-symbol", inputs: ["name", "fill", "weight", "grade", "opticalSize"] }, { kind: "component", type: UniBoxComponent, selector: "[uni-box-layout], [box-layout]", inputs: ["color", "backgroundColor", "borderRadius", "borderRadiusLeft", "borderRadiusRight", "borderRadiusTop", "borderRadiusBottom", "padding", "paddingHorizontal", "paddingVertical", "paddingLeft", "paddingRight", "paddingTop", "paddingBottom", "border", "borderTop", "borderBottom", "borderLeft", "borderRight", "dashBorder", "alignSelf", "alignItems", "alignContent", "justifyContent", "grow", "display", "position", "inset", "height", "minHeight", "maxHeight", "width", "minWidth", "maxWidth", "ignoreDir", "gridArea", "gridColumn", "gridRow", "overflow", "elevation", "shadow", "gap", "fullWidth", "fullHeight", "flexDirection", "textAlign", "wrapItems", "zIndex"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4228
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniMenuItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4229
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: UniMenuItemComponent, isStandalone: true, selector: "[uni-menu-item], [menu-item]", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, template: { classPropertyName: "template", publicName: "template", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null }, symbolName: { classPropertyName: "symbolName", publicName: "symbolName", isSignal: true, isRequired: false, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, hoverColor: { classPropertyName: "hoverColor", publicName: "hoverColor", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "menuitem", "tabindex": "-1" }, properties: { "attr.aria-disabled": "disabled() ? 'true' : null", "attr.aria-current": "active() ? 'true' : null", "class": "menuItemClassName()" } }, ngImport: i0, template: "@let tpl = template();\n@let symbol = symbolName();\n@if (symbol) {\n <uni-symbol [name]=\"symbol\"></uni-symbol>\n}\n<div box-layout [grow]=\"1\">\n @if (tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"context()\"></ng-container>\n } @else {\n <span [class]=\"LabelClassName\">{{ label() }}</span>\n }\n</div>\n@let activeSym = activeSymbol();\n@if (active() && activeSym) {\n <uni-symbol [name]=\"activeSym\"></uni-symbol>\n}\n", dependencies: [{ kind: "component", type: UniSymbolComponent, selector: "uni-symbol", inputs: ["name", "fill", "weight", "grade", "opticalSize"] }, { kind: "component", type: UniBoxComponent, selector: "[uni-box-layout], [box-layout]", inputs: ["color", "backgroundColor", "borderRadius", "borderRadiusLeft", "borderRadiusRight", "borderRadiusTop", "borderRadiusBottom", "padding", "paddingHorizontal", "paddingVertical", "paddingLeft", "paddingRight", "paddingTop", "paddingBottom", "border", "borderTop", "borderBottom", "borderLeft", "borderRight", "dashBorder", "alignSelf", "alignItems", "alignContent", "justifyContent", "grow", "display", "position", "inset", "height", "minHeight", "maxHeight", "width", "minWidth", "maxWidth", "ignoreDir", "gridArea", "gridColumn", "gridRow", "overflow", "elevation", "shadow", "gap", "fullWidth", "fullHeight", "flexDirection", "textAlign", "wrapItems", "zIndex"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4312
4230
  }
4313
4231
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniMenuItemComponent, decorators: [{
4314
4232
  type: Component,
4315
- args: [{ selector: '[uni-menu-item], [menu-item]', imports: [UniTextComponent, UniSymbolComponent, UniBoxComponent, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, host: {
4233
+ args: [{ selector: '[uni-menu-item], [menu-item]', imports: [UniSymbolComponent, UniBoxComponent, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, host: {
4316
4234
  role: 'menuitem',
4317
4235
  tabindex: '-1',
4318
4236
  '[attr.aria-disabled]': "disabled() ? 'true' : null",
4319
4237
  '[attr.aria-current]': "active() ? 'true' : null",
4320
4238
  '[class]': 'menuItemClassName()',
4321
- }, template: "@let tpl = template();\n@let symbol = symbolName();\n@if (symbol) {\n <uni-symbol [name]=\"symbol\"></uni-symbol>\n}\n<div box-layout [grow]=\"1\">\n @if (tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"context()\"></ng-container>\n } @else {\n <span uni-text=\"label\" display=\"block\" [nowrap]=\"true\">\n {{ label() }}\n </span>\n }\n</div>\n@if (active()) {\n <uni-symbol name=\"check\"></uni-symbol>\n}\n", styles: [":host.disabled{color:#ddd;pointer-events:none}\n"] }]
4322
- }], propDecorators: { display: [{ type: i0.Input, args: [{ isSignal: true, alias: "display", required: false }] }], flexDirection: [{ type: i0.Input, args: [{ isSignal: true, alias: "flexDirection", required: false }] }], alignItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "alignItems", required: false }] }], paddingHorizontal: [{ type: i0.Input, args: [{ isSignal: true, alias: "paddingHorizontal", required: false }] }], gap: [{ type: i0.Input, args: [{ isSignal: true, alias: "gap", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], template: [{ type: i0.Input, args: [{ isSignal: true, alias: "template", required: false }] }], context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: false }] }], symbolName: [{ type: i0.Input, args: [{ isSignal: true, alias: "symbolName", required: false }] }], active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }], hoverColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "hoverColor", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
4239
+ }, template: "@let tpl = template();\n@let symbol = symbolName();\n@if (symbol) {\n <uni-symbol [name]=\"symbol\"></uni-symbol>\n}\n<div box-layout [grow]=\"1\">\n @if (tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"context()\"></ng-container>\n } @else {\n <span [class]=\"LabelClassName\">{{ label() }}</span>\n }\n</div>\n@let activeSym = activeSymbol();\n@if (active() && activeSym) {\n <uni-symbol [name]=\"activeSym\"></uni-symbol>\n}\n" }]
4240
+ }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], template: [{ type: i0.Input, args: [{ isSignal: true, alias: "template", required: false }] }], context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: false }] }], symbolName: [{ type: i0.Input, args: [{ isSignal: true, alias: "symbolName", required: false }] }], active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], hoverColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "hoverColor", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
4323
4241
 
4324
4242
  class UniMenuComponent {
4243
+ theme = inject(ThemeService);
4325
4244
  // Modern Signal Inputs for perfect Zoneless tracking
4326
4245
  menuItems = input.required(...(ngDevMode ? [{ debugName: "menuItems" }] : /* istanbul ignore next */ []));
4327
4246
  activeItem = input(...(ngDevMode ? [undefined, { debugName: "activeItem" }] : /* istanbul ignore next */ []));
@@ -4329,6 +4248,21 @@ class UniMenuComponent {
4329
4248
  // Modern Signal Output
4330
4249
  menuItemClicked = output();
4331
4250
  TriggerClassName = css({ display: 'inline-block' });
4251
+ /** Type guard for the template: dividers render as separators, not items. */
4252
+ isDivider = isDivider;
4253
+ menuOptions = computed(() => this.theme.getComponentOptions('menu')(), ...(ngDevMode ? [{ debugName: "menuOptions" }] : /* istanbul ignore next */ []));
4254
+ menuClassName = computed(() => css({ minWidth: this.menuOptions().minWidth }), ...(ngDevMode ? [{ debugName: "menuClassName" }] : /* istanbul ignore next */ []));
4255
+ dividerClassName = computed(() => {
4256
+ const { dividerBorder, dividerSpacing } = this.menuOptions();
4257
+ // Read spacing directly: getSpacing('none') yields the string 'none',
4258
+ // which is invalid as a margin and must resolve to 0 instead.
4259
+ const spacing = this.theme.spacing()[dividerSpacing ?? 'none'];
4260
+ return css({
4261
+ ...this.theme.borderTop(dividerBorder),
4262
+ marginBlock: spacing,
4263
+ marginInline: spacing,
4264
+ });
4265
+ }, ...(ngDevMode ? [{ debugName: "dividerClassName" }] : /* istanbul ignore next */ []));
4332
4266
  itemComponents = viewChildren(UniMenuItemComponent, ...(ngDevMode ? [{ debugName: "itemComponents" }] : /* istanbul ignore next */ []));
4333
4267
  dropdownComponent = viewChild(UniDropdownComponent, ...(ngDevMode ? [{ debugName: "dropdownComponent" }] : /* istanbul ignore next */ []));
4334
4268
  /** Which item receives focus when the menu opens (ArrowUp opens onto the last item). */
@@ -4340,7 +4274,7 @@ class UniMenuComponent {
4340
4274
  });
4341
4275
  }, ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
4342
4276
  handleMenuItemClick(item, dropdown) {
4343
- if (item.action) {
4277
+ if (!isDivider(item) && item.action) {
4344
4278
  item.action();
4345
4279
  }
4346
4280
  this.menuItemClicked.emit(item);
@@ -4437,7 +4371,12 @@ class UniMenuComponent {
4437
4371
  [trigger]="trigger"
4438
4372
  [placement]="placement()"
4439
4373
  ariaHasPopup="menu"
4440
- paddingVertical="xs"
4374
+ [color]="menuOptions().color"
4375
+ [border]="menuOptions().border"
4376
+ [borderRadius]="menuOptions().borderRadius"
4377
+ [shadow]="menuOptions().shadow"
4378
+ [paddingVertical]="menuOptions().paddingVertical"
4379
+ [paddingHorizontal]="menuOptions().paddingHorizontal"
4441
4380
  #dropdown
4442
4381
  (dropdownShowing)="onOpened()"
4443
4382
  >
@@ -4445,23 +4384,29 @@ class UniMenuComponent {
4445
4384
  the focused item (menu-item hosts carry tabindex="-1"), and
4446
4385
  Enter/Space activation is dispatched from onMenuKeydown. -->
4447
4386
  <!-- eslint-disable-next-line @angular-eslint/template/interactive-supports-focus -->
4448
- <div role="menu" (keydown)="onMenuKeydown($event, dropdown)">
4387
+ <div role="menu" [class]="menuClassName()" (keydown)="onMenuKeydown($event, dropdown)">
4449
4388
  @for (item of menuItems(); track item) {
4450
- <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->
4451
- <div
4452
- menu-item
4453
- [label]="item.label"
4454
- [symbolName]="item.symbolName"
4455
- [active]="activeItem() === item"
4456
- [template]="item.template"
4457
- [context]="item.context"
4458
- (click)="handleMenuItemClick(item, dropdown)"
4459
- ></div>
4389
+ @if (isDivider(item)) {
4390
+ <div role="separator" [class]="dividerClassName()"></div>
4391
+ } @else {
4392
+ <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events -->
4393
+ <div
4394
+ menu-item
4395
+ [label]="item.label"
4396
+ [symbolName]="item.symbolName"
4397
+ [active]="activeItem() === item"
4398
+ [template]="item.template"
4399
+ [context]="item.context"
4400
+ [variant]="item.variant"
4401
+ [disabled]="item.disabled ?? false"
4402
+ (click)="handleMenuItemClick(item, dropdown)"
4403
+ ></div>
4404
+ }
4460
4405
  }
4461
4406
  </div>
4462
4407
  </uni-dropdown>
4463
4408
  }
4464
- `, isInline: true, dependencies: [{ kind: "component", type: UniMenuItemComponent, selector: "[uni-menu-item], [menu-item]", inputs: ["display", "flexDirection", "alignItems", "paddingHorizontal", "gap", "label", "template", "context", "symbolName", "active", "hoverColor", "disabled"] }, { kind: "component", type: UniDropdownComponent, selector: "uni-dropdown", inputs: ["trigger", "placement", "offset", "ariaHasPopup", "paddingVertical", "paddingHorizontal"], outputs: ["dropdownShowing", "dropdownHiding"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4409
+ `, isInline: true, dependencies: [{ kind: "component", type: UniMenuItemComponent, selector: "[uni-menu-item], [menu-item]", inputs: ["label", "template", "context", "symbolName", "active", "variant", "hoverColor", "disabled"] }, { kind: "component", type: UniDropdownComponent, selector: "uni-dropdown", inputs: ["trigger", "placement", "offset", "ariaHasPopup", "paddingVertical", "paddingHorizontal", "border", "borderRadius", "shadow", "color"], outputs: ["dropdownShowing", "dropdownHiding"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4465
4410
  }
4466
4411
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniMenuComponent, decorators: [{
4467
4412
  type: Component,
@@ -4482,7 +4427,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
4482
4427
  [trigger]="trigger"
4483
4428
  [placement]="placement()"
4484
4429
  ariaHasPopup="menu"
4485
- paddingVertical="xs"
4430
+ [color]="menuOptions().color"
4431
+ [border]="menuOptions().border"
4432
+ [borderRadius]="menuOptions().borderRadius"
4433
+ [shadow]="menuOptions().shadow"
4434
+ [paddingVertical]="menuOptions().paddingVertical"
4435
+ [paddingHorizontal]="menuOptions().paddingHorizontal"
4486
4436
  #dropdown
4487
4437
  (dropdownShowing)="onOpened()"
4488
4438
  >
@@ -4490,18 +4440,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
4490
4440
  the focused item (menu-item hosts carry tabindex="-1"), and
4491
4441
  Enter/Space activation is dispatched from onMenuKeydown. -->
4492
4442
  <!-- eslint-disable-next-line @angular-eslint/template/interactive-supports-focus -->
4493
- <div role="menu" (keydown)="onMenuKeydown($event, dropdown)">
4443
+ <div role="menu" [class]="menuClassName()" (keydown)="onMenuKeydown($event, dropdown)">
4494
4444
  @for (item of menuItems(); track item) {
4495
- <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->
4496
- <div
4497
- menu-item
4498
- [label]="item.label"
4499
- [symbolName]="item.symbolName"
4500
- [active]="activeItem() === item"
4501
- [template]="item.template"
4502
- [context]="item.context"
4503
- (click)="handleMenuItemClick(item, dropdown)"
4504
- ></div>
4445
+ @if (isDivider(item)) {
4446
+ <div role="separator" [class]="dividerClassName()"></div>
4447
+ } @else {
4448
+ <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events -->
4449
+ <div
4450
+ menu-item
4451
+ [label]="item.label"
4452
+ [symbolName]="item.symbolName"
4453
+ [active]="activeItem() === item"
4454
+ [template]="item.template"
4455
+ [context]="item.context"
4456
+ [variant]="item.variant"
4457
+ [disabled]="item.disabled ?? false"
4458
+ (click)="handleMenuItemClick(item, dropdown)"
4459
+ ></div>
4460
+ }
4505
4461
  }
4506
4462
  </div>
4507
4463
  </uni-dropdown>
@@ -4657,7 +4613,7 @@ class UniMultiSelectDropdownComponent extends BaseComponent {
4657
4613
  });
4658
4614
  }
4659
4615
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniMultiSelectDropdownComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
4660
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: UniMultiSelectDropdownComponent, isStandalone: true, selector: "uni-multi-select-dropdown", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, dirty: { classPropertyName: "dirty", publicName: "dirty", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedBy: { classPropertyName: "ariaDescribedBy", publicName: "ariaDescribedBy", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touched: "touchedChange" }, host: { properties: { "class": "className" } }, providers: [{ provide: COMPONENT_NAME, useValue: 'multiSelectDropdown' }], usesInheritance: true, ngImport: i0, template: "<button\n [class]=\"triggerClass\"\n #trigger\n [style.cursor]=\"disabled() ? 'default' : 'pointer'\"\n [attr.aria-required]=\"required() ? true : null\"\n [attr.aria-invalid]=\"showError() ? true : null\"\n [attr.aria-describedby]=\"ariaDescribedBy() || null\"\n (click)=\"!disabled() && touched.set(true)\"\n>\n <uni-input-box [error]=\"showError()\" [disabled]=\"disabled()\">\n <div\n row-layout\n alignItems=\"center\"\n justifyContent=\"space-between\"\n [fullWidth]=\"true\"\n [minWidth]=\"0\"\n paddingLeft=\"sm\"\n >\n <span uni-text\n display=\"block\"\n [typeface]=\"componentOptions().textRole\"\n [color]=\"textColor()\"\n [ellipsis]=\"true\"\n [style.flex-grow]=\"1\"\n >{{ selectedLabelsText() }}</span>\n <uni-symbol name=\"keyboard_arrow_down\" [style.flex-shrink]=\"0\"></uni-symbol>\n </div>\n </uni-input-box>\n</button>\n<uni-dropdown\n #dropdown\n [trigger]=\"trigger\"\n ariaHasPopup=\"dialog\"\n (dropdownShowing)=\"$event && searchInput.focus()\"\n (dropdownHiding)=\"$event && trigger.focus()\"\n>\n <div box-layout gap=\"xs\" padding=\"xs\">\n <input\n #searchInput\n type=\"text\"\n [class]=\"searchInputClass()\"\n [value]=\"query()\"\n (input)=\"handleQueryInput($event)\"\n placeholder=\"Search...\"\n aria-label=\"Filter options\"\n (click)=\"$event.stopPropagation()\"\n [disabled]=\"disabled()\"\n />\n </div>\n\n <uni-divider [border]=\"componentOptions().dividerBorder\" />\n\n <div stack-layout gap=\"xs\" padding=\"xs\">\n @for (option of filteredOptions(); track option.value) {\n <uni-checkbox\n [label]=\"option.label\"\n [checked]=\"isOptionSelected(option)()\"\n (checkedChange)=\"toggleOption(option, $event)\"\n variant=\"primary\"\n [disabled]=\"disabled()\"\n >\n </uni-checkbox>\n }\n </div>\n\n <uni-divider [border]=\"componentOptions().dividerBorder\" />\n\n <div row-layout gap=\"xs\" justifyContent=\"space-around\" padding=\"xs\">\n <button text-button (click)=\"dropdown.hideDropdown()\" size=\"sm\" variant=\"ghost\">Done</button>\n </div>\n</uni-dropdown>\n", dependencies: [{ kind: "component", type: UniCheckboxComponent, selector: "uni-checkbox", inputs: ["checked", "disabled", "touched", "invalid", "dirty", "required", "ariaDescribedBy", "label", "indeterminate"], outputs: ["checkedChange", "touchedChange", "indeterminateChange"] }, { kind: "component", type: UniBoxComponent, selector: "[uni-box-layout], [box-layout]", inputs: ["color", "backgroundColor", "borderRadius", "borderRadiusLeft", "borderRadiusRight", "borderRadiusTop", "borderRadiusBottom", "padding", "paddingHorizontal", "paddingVertical", "paddingLeft", "paddingRight", "paddingTop", "paddingBottom", "border", "borderTop", "borderBottom", "borderLeft", "borderRight", "dashBorder", "alignSelf", "alignItems", "alignContent", "justifyContent", "grow", "display", "position", "inset", "height", "minHeight", "maxHeight", "width", "minWidth", "maxWidth", "ignoreDir", "gridArea", "gridColumn", "gridRow", "overflow", "elevation", "shadow", "gap", "fullWidth", "fullHeight", "flexDirection", "textAlign", "wrapItems", "zIndex"] }, { kind: "component", type: UniDropdownComponent, selector: "uni-dropdown", inputs: ["trigger", "placement", "offset", "ariaHasPopup", "paddingVertical", "paddingHorizontal"], outputs: ["dropdownShowing", "dropdownHiding"] }, { kind: "component", type: UniStackComponent, selector: "[uni-stack-layout], [stack-layout]", inputs: ["display", "flexDirection", "minHeight"] }, { kind: "component", type: UniDividerComponent, selector: "uni-divider", inputs: ["orientation", "border"] }, { kind: "component", type: UniButtonComponent, selector: "button[uni-text-button], button[text-button]", inputs: ["disable", "loading", "fullWidth", "symbolLeft", "symbolRight"] }, { kind: "component", type: UniTextComponent, selector: "[uni-text]", inputs: ["uni-text", "typeface", "color", "display", "align", "nowrap", "maxWidth", "ellipsis"] }, { kind: "component", type: UniSymbolComponent, selector: "uni-symbol", inputs: ["name", "fill", "weight", "grade", "opticalSize"] }, { kind: "component", type: UniRowComponent, selector: "[uni-row-layout], [row-layout]", inputs: ["display", "flexDirection", "minWidth"] }, { kind: "component", type: UniInputBoxComponent, selector: "uni-input-box", inputs: ["disabled", "error", "minWidth", "height"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4616
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: UniMultiSelectDropdownComponent, isStandalone: true, selector: "uni-multi-select-dropdown", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, dirty: { classPropertyName: "dirty", publicName: "dirty", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedBy: { classPropertyName: "ariaDescribedBy", publicName: "ariaDescribedBy", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touched: "touchedChange" }, host: { properties: { "class": "className" } }, providers: [{ provide: COMPONENT_NAME, useValue: 'multiSelectDropdown' }], usesInheritance: true, ngImport: i0, template: "<button\n [class]=\"triggerClass\"\n #trigger\n [style.cursor]=\"disabled() ? 'default' : 'pointer'\"\n [attr.aria-required]=\"required() ? true : null\"\n [attr.aria-invalid]=\"showError() ? true : null\"\n [attr.aria-describedby]=\"ariaDescribedBy() || null\"\n (click)=\"!disabled() && touched.set(true)\"\n>\n <uni-input-box [error]=\"showError()\" [disabled]=\"disabled()\">\n <div\n row-layout\n alignItems=\"center\"\n justifyContent=\"space-between\"\n [fullWidth]=\"true\"\n [minWidth]=\"0\"\n paddingLeft=\"sm\"\n >\n <span uni-text\n display=\"block\"\n [typeface]=\"componentOptions().textRole\"\n [color]=\"textColor()\"\n [ellipsis]=\"true\"\n [style.flex-grow]=\"1\"\n >{{ selectedLabelsText() }}</span>\n <uni-symbol name=\"keyboard_arrow_down\" [style.flex-shrink]=\"0\"></uni-symbol>\n </div>\n </uni-input-box>\n</button>\n<uni-dropdown\n #dropdown\n [trigger]=\"trigger\"\n ariaHasPopup=\"dialog\"\n (dropdownShowing)=\"$event && searchInput.focus()\"\n (dropdownHiding)=\"$event && trigger.focus()\"\n>\n <div box-layout gap=\"xs\" padding=\"xs\">\n <input\n #searchInput\n type=\"text\"\n [class]=\"searchInputClass()\"\n [value]=\"query()\"\n (input)=\"handleQueryInput($event)\"\n placeholder=\"Search...\"\n aria-label=\"Filter options\"\n (click)=\"$event.stopPropagation()\"\n [disabled]=\"disabled()\"\n />\n </div>\n\n <uni-divider [border]=\"componentOptions().dividerBorder\" />\n\n <div stack-layout gap=\"xs\" padding=\"xs\">\n @for (option of filteredOptions(); track option.value) {\n <uni-checkbox\n [label]=\"option.label\"\n [checked]=\"isOptionSelected(option)()\"\n (checkedChange)=\"toggleOption(option, $event)\"\n variant=\"primary\"\n [disabled]=\"disabled()\"\n >\n </uni-checkbox>\n }\n </div>\n\n <uni-divider [border]=\"componentOptions().dividerBorder\" />\n\n <div row-layout gap=\"xs\" justifyContent=\"space-around\" padding=\"xs\">\n <button text-button (click)=\"dropdown.hideDropdown()\" size=\"sm\" variant=\"ghost\">Done</button>\n </div>\n</uni-dropdown>\n", dependencies: [{ kind: "component", type: UniCheckboxComponent, selector: "uni-checkbox", inputs: ["checked", "disabled", "touched", "invalid", "dirty", "required", "ariaDescribedBy", "label", "indeterminate"], outputs: ["checkedChange", "touchedChange", "indeterminateChange"] }, { kind: "component", type: UniBoxComponent, selector: "[uni-box-layout], [box-layout]", inputs: ["color", "backgroundColor", "borderRadius", "borderRadiusLeft", "borderRadiusRight", "borderRadiusTop", "borderRadiusBottom", "padding", "paddingHorizontal", "paddingVertical", "paddingLeft", "paddingRight", "paddingTop", "paddingBottom", "border", "borderTop", "borderBottom", "borderLeft", "borderRight", "dashBorder", "alignSelf", "alignItems", "alignContent", "justifyContent", "grow", "display", "position", "inset", "height", "minHeight", "maxHeight", "width", "minWidth", "maxWidth", "ignoreDir", "gridArea", "gridColumn", "gridRow", "overflow", "elevation", "shadow", "gap", "fullWidth", "fullHeight", "flexDirection", "textAlign", "wrapItems", "zIndex"] }, { kind: "component", type: UniDropdownComponent, selector: "uni-dropdown", inputs: ["trigger", "placement", "offset", "ariaHasPopup", "paddingVertical", "paddingHorizontal", "border", "borderRadius", "shadow", "color"], outputs: ["dropdownShowing", "dropdownHiding"] }, { kind: "component", type: UniStackComponent, selector: "[uni-stack-layout], [stack-layout]", inputs: ["display", "flexDirection", "minHeight"] }, { kind: "component", type: UniDividerComponent, selector: "uni-divider", inputs: ["orientation", "border"] }, { kind: "component", type: UniButtonComponent, selector: "button[uni-text-button], button[text-button]", inputs: ["disable", "loading", "fullWidth", "symbolLeft", "symbolRight"] }, { kind: "component", type: UniTextComponent, selector: "[uni-text]", inputs: ["uni-text", "typeface", "color", "display", "align", "nowrap", "maxWidth", "ellipsis"] }, { kind: "component", type: UniSymbolComponent, selector: "uni-symbol", inputs: ["name", "fill", "weight", "grade", "opticalSize"] }, { kind: "component", type: UniRowComponent, selector: "[uni-row-layout], [row-layout]", inputs: ["display", "flexDirection", "minWidth"] }, { kind: "component", type: UniInputBoxComponent, selector: "uni-input-box", inputs: ["disabled", "error", "minWidth", "height"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4661
4617
  }
4662
4618
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniMultiSelectDropdownComponent, decorators: [{
4663
4619
  type: Component,
@@ -7359,9 +7315,211 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
7359
7315
  args: [{ selector: 'uni-toggle', imports: [UniTextComponent], providers: [{ provide: COMPONENT_NAME, useValue: 'toggle' }], changeDetection: ChangeDetectionStrategy.OnPush, template: "<label [class]=\"toggleLabel()\">\n <input\n type=\"checkbox\"\n role=\"switch\"\n [class]=\"toggleInput()\"\n [checked]=\"checked()\"\n (change)=\"handleChange($event)\"\n [disabled]=\"disabled()\"\n [attr.aria-invalid]=\"showError() ? true : null\"\n [attr.aria-required]=\"required() ? true : null\"\n [attr.aria-describedby]=\"ariaDescribedBy() || null\"\n />\n <div class=\"toggle-switch\">\n <div class=\"toggle-slider\"></div>\n </div>\n @if (label()) {\n <span uni-text=\"label\">{{ label() }}</span>\n }\n</label>\n" }]
7360
7316
  }], propDecorators: { checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], dirty: [{ type: i0.Input, args: [{ isSignal: true, alias: "dirty", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], ariaDescribedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaDescribedBy", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }] } });
7361
7317
 
7318
+ class UniTooltipComponent extends BaseComponent {
7319
+ elRef = inject(ElementRef);
7320
+ renderer = inject(Renderer2);
7321
+ timer = useTimer();
7322
+ isMouseInside = signal(false, ...(ngDevMode ? [{ debugName: "isMouseInside" }] : /* istanbul ignore next */ []));
7323
+ /** Whether the bubble is currently shown (or fading out). */
7324
+ visible = signal(false, ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
7325
+ /**
7326
+ * Set when the wrapped control is activated: clicking a button is not a
7327
+ * request to toggle the bubble, and re-showing it right away makes a
7328
+ * state-flipping label ("Expand" → "Collapse") blink back mid-interaction.
7329
+ * Re-arms when the pointer leaves or focus moves away.
7330
+ */
7331
+ suppressed = signal(false, ...(ngDevMode ? [{ debugName: "suppressed" }] : /* istanbul ignore next */ []));
7332
+ tooltipId = uniqueId('uni-tooltip');
7333
+ anchorName = newAnchorName();
7334
+ hoverDelay = input(500, ...(ngDevMode ? [{ debugName: "hoverDelay" }] : /* istanbul ignore next */ []));
7335
+ label = input.required(...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
7336
+ placement = input('top', ...(ngDevMode ? [{ debugName: "placement" }] : /* istanbul ignore next */ []));
7337
+ inlineText = input(false, ...(ngDevMode ? [{ debugName: "inlineText" }] : /* istanbul ignore next */ []));
7338
+ /** @deprecated The tooltip renders in the native top layer; ignored. */
7339
+ appendToBody = input(false, ...(ngDevMode ? [{ debugName: "appendToBody" }] : /* istanbul ignore next */ []));
7340
+ tipRef = viewChild.required('tip');
7341
+ constructor() {
7342
+ super();
7343
+ effect(() => {
7344
+ const timerActive = this.timer.isActive();
7345
+ const mouseInside = this.isMouseInside();
7346
+ // If the timer finished and the mouse is still inside, show tooltip
7347
+ if (!timerActive && mouseInside && !this.suppressed()) {
7348
+ this.showTooltip();
7349
+ }
7350
+ // If the mouse left and the timer is not running, hide tooltip
7351
+ else if (!mouseInside) {
7352
+ this.hideTooltip();
7353
+ }
7354
+ });
7355
+ // A tooltip must be reachable by keyboard (WCAG 1.4.13): when the
7356
+ // projected content has no focusable element, the host itself joins
7357
+ // the tab sequence. The bubble is always in the DOM, so the describedby
7358
+ // relationship is wired once, on the element that receives focus.
7359
+ afterNextRender(() => {
7360
+ const host = this.elRef.nativeElement;
7361
+ if (!host.querySelector(FOCUSABLE_SELECTOR) && !host.matches(FOCUSABLE_SELECTOR)) {
7362
+ this.renderer.setAttribute(host, 'tabindex', '0');
7363
+ }
7364
+ this.renderer.setAttribute(resolveFocusTarget(host), 'aria-describedby', this.tooltipId);
7365
+ });
7366
+ }
7367
+ onFocusIn(event) {
7368
+ // Only keyboard-driven focus shows the tooltip immediately; mouse
7369
+ // interaction keeps the hover-delay behavior.
7370
+ if (event.target.matches(':focus-visible')) {
7371
+ this.showTooltip();
7372
+ }
7373
+ }
7374
+ onFocusOut() {
7375
+ this.suppressed.set(false);
7376
+ if (!this.isMouseInside()) {
7377
+ this.hideTooltip();
7378
+ }
7379
+ }
7380
+ onEscape(event) {
7381
+ if (this.visible()) {
7382
+ // Dismiss only the tooltip, not an enclosing dialog/popover
7383
+ event.stopPropagation();
7384
+ this.hideTooltip();
7385
+ }
7386
+ }
7387
+ /**
7388
+ * A click on an interactive element inside the host is an activation of
7389
+ * that control — hide the bubble and stay suppressed until re-arm. A click
7390
+ * anywhere else (inline-text tooltips, tap on a non-interactive host)
7391
+ * keeps the tap-to-toggle behavior.
7392
+ */
7393
+ onClick(event) {
7394
+ const host = this.elRef.nativeElement;
7395
+ const control = event.target.closest(FOCUSABLE_SELECTOR);
7396
+ if (control && control !== host && host.contains(control)) {
7397
+ this.suppressed.set(true);
7398
+ this.hideTooltip();
7399
+ }
7400
+ else {
7401
+ this.toggleTooltip();
7402
+ }
7403
+ }
7404
+ toggleTooltip() {
7405
+ if (this.visible()) {
7406
+ this.hideTooltip();
7407
+ }
7408
+ else {
7409
+ this.showTooltip();
7410
+ }
7411
+ }
7412
+ mouseenter() {
7413
+ this.isMouseInside.set(true);
7414
+ this.timer.start(this.hoverDelay());
7415
+ }
7416
+ mouseleave() {
7417
+ this.isMouseInside.set(false);
7418
+ this.suppressed.set(false);
7419
+ this.timer.stop();
7420
+ }
7421
+ showTooltip() {
7422
+ if (this.visible())
7423
+ return;
7424
+ const tip = this.tipRef().nativeElement;
7425
+ tip.showPopover();
7426
+ this.renderer.setAttribute(tip, 'fade', 'in');
7427
+ this.visible.set(true);
7428
+ }
7429
+ hideTooltip() {
7430
+ if (!this.visible())
7431
+ return;
7432
+ this.renderer.setAttribute(this.tipRef().nativeElement, 'fade', 'out');
7433
+ }
7434
+ onAnimationEnd(event) {
7435
+ if (event.animationName.includes(this.tooltipFadeOut)) {
7436
+ this.tipRef().nativeElement.hidePopover();
7437
+ this.visible.set(false);
7438
+ }
7439
+ }
7440
+ className = computed(() => css({
7441
+ display: 'inline-flex',
7442
+ anchorName: this.anchorName,
7443
+ }, this.inlineText() && {
7444
+ cursor: 'help',
7445
+ textDecoration: 'underline',
7446
+ textDecorationStyle: 'dotted',
7447
+ }), ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
7448
+ tooltipFadeIn = keyframes({ ...fadeIn });
7449
+ tooltipFadeOut = keyframes({ ...fadeOut });
7450
+ tooltipClassName = computed(() => css([
7451
+ {
7452
+ ...this.theme.colorPair(this.componentOptions().color),
7453
+ ...this.theme.radius(this.componentOptions().borderRadius),
7454
+ ...this.theme.boxShadow(this.componentOptions().shadow),
7455
+ ...this.theme.typeface(this.componentOptions().typeface),
7456
+ border: 'none',
7457
+ padding: 5,
7458
+ width: 'max-content',
7459
+ ...anchorStyles(this.anchorName, this.placement(), { mainAxis: 6 }),
7460
+ '&[fade="in"]': {
7461
+ animation: `${this.tooltipFadeIn} ease-in 350ms`,
7462
+ },
7463
+ '&[fade="out"]': {
7464
+ animation: `${this.tooltipFadeOut} ease-in 350ms`,
7465
+ },
7466
+ },
7467
+ ]), ...(ngDevMode ? [{ debugName: "tooltipClassName" }] : /* istanbul ignore next */ []));
7468
+ arrowClassName = computed(() => css({
7469
+ ...this.theme.colorPair(this.componentOptions().color),
7470
+ ...anchorArrowStyles(this.placement()),
7471
+ }), ...(ngDevMode ? [{ debugName: "arrowClassName" }] : /* istanbul ignore next */ []));
7472
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniTooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7473
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.12", type: UniTooltipComponent, isStandalone: true, selector: "uni-tooltip", inputs: { hoverDelay: { classPropertyName: "hoverDelay", publicName: "hoverDelay", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, inlineText: { classPropertyName: "inlineText", publicName: "inlineText", isSignal: true, isRequired: false, transformFunction: null }, appendToBody: { classPropertyName: "appendToBody", publicName: "appendToBody", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "onClick($event)", "mouseenter": "mouseenter()", "mouseleave": "mouseleave()", "focusin": "onFocusIn($event)", "focusout": "onFocusOut()", "keydown.escape": "onEscape($event)" }, properties: { "class": "className()" } }, providers: [{ provide: COMPONENT_NAME, useValue: 'tooltip' }], viewQueries: [{ propertyName: "tipRef", first: true, predicate: ["tip"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `<ng-content></ng-content
7474
+ ><span
7475
+ #tip
7476
+ popover="manual"
7477
+ role="tooltip"
7478
+ [id]="tooltipId"
7479
+ [class]="tooltipClassName()"
7480
+ (mouseenter)="isMouseInside.set(true)"
7481
+ (mouseleave)="isMouseInside.set(false)"
7482
+ (animationend)="onAnimationEnd($event)"
7483
+ >{{ label() }}<span [class]="arrowClassName()"></span
7484
+ ></span>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
7485
+ }
7486
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniTooltipComponent, decorators: [{
7487
+ type: Component,
7488
+ args: [{
7489
+ selector: 'uni-tooltip',
7490
+ imports: [],
7491
+ // The bubble lives declaratively in the template as a manual popover: the
7492
+ // top layer escapes any overflow context (which made appendToBody obsolete)
7493
+ // and native CSS anchor positioning keeps it attached to the host.
7494
+ template: `<ng-content></ng-content
7495
+ ><span
7496
+ #tip
7497
+ popover="manual"
7498
+ role="tooltip"
7499
+ [id]="tooltipId"
7500
+ [class]="tooltipClassName()"
7501
+ (mouseenter)="isMouseInside.set(true)"
7502
+ (mouseleave)="isMouseInside.set(false)"
7503
+ (animationend)="onAnimationEnd($event)"
7504
+ >{{ label() }}<span [class]="arrowClassName()"></span
7505
+ ></span>`,
7506
+ providers: [{ provide: COMPONENT_NAME, useValue: 'tooltip' }],
7507
+ changeDetection: ChangeDetectionStrategy.OnPush,
7508
+ host: {
7509
+ '[class]': 'className()',
7510
+ '(click)': 'onClick($event)',
7511
+ '(mouseenter)': 'mouseenter()',
7512
+ '(mouseleave)': 'mouseleave()',
7513
+ '(focusin)': 'onFocusIn($event)',
7514
+ '(focusout)': 'onFocusOut()',
7515
+ '(keydown.escape)': 'onEscape($event)',
7516
+ },
7517
+ }]
7518
+ }], ctorParameters: () => [], propDecorators: { hoverDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "hoverDelay", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], inlineText: [{ type: i0.Input, args: [{ isSignal: true, alias: "inlineText", required: false }] }], appendToBody: [{ type: i0.Input, args: [{ isSignal: true, alias: "appendToBody", required: false }] }], tipRef: [{ type: i0.ViewChild, args: ['tip', { isSignal: true }] }] } });
7519
+
7362
7520
  /**
7363
7521
  * Generated bundle index. Do not edit.
7364
7522
  */
7365
7523
 
7366
- export { BodyRenderDirective, ConfirmationDialogComponent, DragAndDropDirective, FOCUSABLE_SELECTOR, LocalStorageService, NotificationService, NotificationsComponent, RippleDirective, ThemeService, UNI_THEMES, UniAlertComponent, UniAppBarComponent, UniAvatarComponent, UniAvatarGroupComponent, UniBackgroundComponent, UniBadgeComponent, UniBaseDatasource, UniBoxComponent, UniBreadcrumbComponent, UniButtonComponent, UniButtonGroupComponent, UniCardComponent, UniCardContentComponent, UniCardHeaderComponent, UniCenterComponent, UniCheckboxComponent, UniDataSearchComponent, UniDataTableComponent, UniDebounceInputComponent, UniDialogButtonsComponent, UniDialogComponent, UniDialogHeaderComponent, UniDividerComponent, UniDrawerComponent, UniDropdownComponent, UniExpandAreaComponent, UniExpandComponent, UniExpandToggleComponent, UniFileDropZoneComponent, UniGridAreaComponent, UniGridComponent, UniIconButtonComponent, UniIconComponent, UniInputBoxComponent, UniInputComponent, UniJsonViewComponent, UniMenuComponent, UniMultiSelectComponent, UniMultiSelectDropdownComponent, UniNotificationBadgeComponent, UniPaginatorComponent, UniPopoverComponent, UniProgressBarComponent, UniProgressGaugeComponent, UniRadioComponent, UniRecordDatasource, UniRowComponent, UniScrollAreaComponent, UniSearchInputComponent, UniSelectComponent, UniServerSideDatasource, UniSkeletonComponent, UniSliderComponent, UniSnackbarComponent, UniSortHeaderComponent, UniStackComponent, UniStatComponent, UniSymbolComponent, UniTabComponent, UniTabsComponent, UniTagComponent, UniTextComponent, UniTextareaComponent, UniThemeBuilderComponent, UniThemeSwitchComponent, UniToggleComponent, UniTooltipComponent, UniWrapComponent, acceptableFile, anchorArrowStyles, anchorStyles, getFileExtension, motionSafe, newAnchorName, resolveFocusTarget, uniqueId, useTimer, visuallyHidden };
7524
+ export { BodyRenderDirective, ConfirmationDialogComponent, DragAndDropDirective, FOCUSABLE_SELECTOR, LocalStorageService, NotificationService, NotificationsComponent, RippleDirective, ThemeService, UNI_THEMES, UniAlertComponent, UniAppBarComponent, UniAvatarComponent, UniAvatarGroupComponent, UniBackgroundComponent, UniBadgeComponent, UniBaseDatasource, UniBoxComponent, UniBreadcrumbComponent, UniButtonComponent, UniButtonGroupComponent, UniCardComponent, UniCardContentComponent, UniCardHeaderComponent, UniCenterComponent, UniCheckboxComponent, UniDataSearchComponent, UniDataTableComponent, UniDebounceInputComponent, UniDialogButtonsComponent, UniDialogComponent, UniDialogHeaderComponent, UniDividerComponent, UniDrawerComponent, UniDropdownComponent, UniExpandAreaComponent, UniExpandComponent, UniExpandToggleComponent, UniFileDropZoneComponent, UniGridAreaComponent, UniGridComponent, UniIconButtonComponent, UniIconComponent, UniInputBoxComponent, UniInputComponent, UniJsonViewComponent, UniMenuComponent, UniMultiSelectComponent, UniMultiSelectDropdownComponent, UniNotificationBadgeComponent, UniPaginatorComponent, UniPopoverComponent, UniProgressBarComponent, UniProgressGaugeComponent, UniRadioComponent, UniRecordDatasource, UniRowComponent, UniScrollAreaComponent, UniSearchInputComponent, UniSelectComponent, UniServerSideDatasource, UniSkeletonComponent, UniSliderComponent, UniSnackbarComponent, UniSortHeaderComponent, UniStackComponent, UniStatComponent, UniSymbolComponent, UniTabComponent, UniTabsComponent, UniTagComponent, UniTextComponent, UniTextareaComponent, UniThemeBuilderComponent, UniThemeSwitchComponent, UniToggleComponent, UniTooltipComponent, UniWrapComponent, acceptableFile, anchorArrowStyles, anchorStyles, getFileExtension, isDivider, motionSafe, newAnchorName, resolveFocusTarget, uniqueId, useTimer, visuallyHidden };
7367
7525
  //# sourceMappingURL=uni-design-system-uni-angular.mjs.map