@uni-design-system/uni-angular 7.1.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;
|
|
@@ -1388,7 +1388,13 @@ class UniIconComponent {
|
|
|
1388
1388
|
const size = this.size();
|
|
1389
1389
|
if (size === undefined || size === null || size === '')
|
|
1390
1390
|
return null;
|
|
1391
|
-
|
|
1391
|
+
if (typeof size === 'number')
|
|
1392
|
+
return `${size}px`;
|
|
1393
|
+
// A static attribute (`size="24"`) arrives as a string, so a bare number
|
|
1394
|
+
// has to mean px here too — otherwise it emits the invalid `width: 24`,
|
|
1395
|
+
// which the browser drops, silently falling back to filling the container.
|
|
1396
|
+
const trimmed = size.trim();
|
|
1397
|
+
return /^-?\d*\.?\d+$/.test(trimmed) ? `${trimmed}px` : trimmed;
|
|
1392
1398
|
}, ...(ngDevMode ? [{ debugName: "sizeValue" }] : /* istanbul ignore next */ []));
|
|
1393
1399
|
className = computed(() => css([{ ...this.themeService.color(this.color()) }]), ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
|
|
1394
1400
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
@@ -2285,6 +2291,20 @@ class UniIconButtonComponent {
|
|
|
2285
2291
|
loading = input(...(ngDevMode ? [undefined, { debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
2286
2292
|
opticalSize = input(24, ...(ngDevMode ? [{ debugName: "opticalSize" }] : /* istanbul ignore next */ []));
|
|
2287
2293
|
srOnlyClass = css(visuallyHidden);
|
|
2294
|
+
/**
|
|
2295
|
+
* Sizes `iconName` from the size token's `fontSize`, the same value that sizes
|
|
2296
|
+
* a `symbolName` ligature — so the two paths render the same glyph size and
|
|
2297
|
+
* `symbolName` → `iconName` is a like-for-like swap. Without it a masked icon
|
|
2298
|
+
* fills the whole button box, since the base size tokens carry no padding.
|
|
2299
|
+
* Themes that do use padding (Carbon) set a matching `fontSize`, so they land
|
|
2300
|
+
* on the same glyph either way.
|
|
2301
|
+
*/
|
|
2302
|
+
glyphSize = computed(() => {
|
|
2303
|
+
// Size tokens are Emotion style objects, so `fontSize` is typed wider than
|
|
2304
|
+
// a CSS length; anything exotic falls back to filling the button as before.
|
|
2305
|
+
const fontSize = this.config().sizes?.[this.size()]?.fontSize;
|
|
2306
|
+
return typeof fontSize === 'number' || typeof fontSize === 'string' ? fontSize : undefined;
|
|
2307
|
+
}, ...(ngDevMode ? [{ debugName: "glyphSize" }] : /* istanbul ignore next */ []));
|
|
2288
2308
|
className = computed(() => {
|
|
2289
2309
|
const { sizes, variants } = this.config();
|
|
2290
2310
|
const sizeConfig = sizes && sizes[this.size()];
|
|
@@ -2300,7 +2320,15 @@ class UniIconButtonComponent {
|
|
|
2300
2320
|
// Token-driven radius (`max` = circle) with the legacy 999 fallback
|
|
2301
2321
|
// for hand-authored themes that predate iconButton options.
|
|
2302
2322
|
...(this.theme.radius(this.config().options?.borderRadius) ?? { borderRadius: 999 }),
|
|
2303
|
-
|
|
2323
|
+
// Block-level, but centring: the size tokens make the box bigger than
|
|
2324
|
+
// the glyph (an `sm` button is 22px around an 18px icon), so a plain
|
|
2325
|
+
// `display: block` parks the glyph in the top-left corner. Flex is
|
|
2326
|
+
// still block-level, so nothing about the button's own layout changes.
|
|
2327
|
+
// The accessible-name span is absolutely positioned and so stays out
|
|
2328
|
+
// of the flex flow.
|
|
2329
|
+
display: 'flex',
|
|
2330
|
+
alignItems: 'center',
|
|
2331
|
+
justifyContent: 'center',
|
|
2304
2332
|
'&:disabled': {
|
|
2305
2333
|
cursor: 'not-allowed !important',
|
|
2306
2334
|
},
|
|
@@ -2343,7 +2371,7 @@ class UniIconButtonComponent {
|
|
|
2343
2371
|
} @else if (symbolName()) {
|
|
2344
2372
|
<uni-symbol [name]="symbolName()!" [opticalSize]="opticalSize()" />
|
|
2345
2373
|
} @else if (iconName()) {
|
|
2346
|
-
<uni-icon [name]="iconName()!" />
|
|
2374
|
+
<uni-icon [name]="iconName()!" [size]="glyphSize()" />
|
|
2347
2375
|
}
|
|
2348
2376
|
<!-- Projected text is the button's accessible name (visually hidden) -->
|
|
2349
2377
|
<span [class]="srOnlyClass"><ng-content /></span>
|
|
@@ -2360,7 +2388,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
|
|
|
2360
2388
|
} @else if (symbolName()) {
|
|
2361
2389
|
<uni-symbol [name]="symbolName()!" [opticalSize]="opticalSize()" />
|
|
2362
2390
|
} @else if (iconName()) {
|
|
2363
|
-
<uni-icon [name]="iconName()!" />
|
|
2391
|
+
<uni-icon [name]="iconName()!" [size]="glyphSize()" />
|
|
2364
2392
|
}
|
|
2365
2393
|
<!-- Projected text is the button's accessible name (visually hidden) -->
|
|
2366
2394
|
<span [class]="srOnlyClass"><ng-content /></span>
|
|
@@ -3280,6 +3308,13 @@ class UniDropdownComponent extends BaseComponent {
|
|
|
3280
3308
|
popoverId = uniqueId('uni-dropdown');
|
|
3281
3309
|
paddingVertical = input(...(ngDevMode ? [undefined, { debugName: "paddingVertical" }] : /* istanbul ignore next */ []));
|
|
3282
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 */ []));
|
|
3283
3318
|
dropdownShowing = output();
|
|
3284
3319
|
dropdownHiding = output();
|
|
3285
3320
|
dropdownRef;
|
|
@@ -3404,17 +3439,17 @@ class UniDropdownComponent extends BaseComponent {
|
|
|
3404
3439
|
}
|
|
3405
3440
|
}
|
|
3406
3441
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniDropdownComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
3407
|
-
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: `
|
|
3408
3443
|
<!-- 1. The native 'popover' attribute brings it to the top layer with native light-dismiss -->
|
|
3409
3444
|
<div #dropdown popover="auto" [id]="popoverId" [class]="dropdownClass()">
|
|
3410
3445
|
<div
|
|
3411
3446
|
box-layout
|
|
3412
|
-
[border]="componentOptions().border"
|
|
3413
|
-
[borderRadius]="componentOptions().borderRadius"
|
|
3447
|
+
[border]="border() ?? componentOptions().border"
|
|
3448
|
+
[borderRadius]="borderRadius() ?? componentOptions().borderRadius"
|
|
3414
3449
|
[paddingVertical]="paddingVertical()"
|
|
3415
3450
|
[paddingHorizontal]="paddingHorizontal()"
|
|
3416
|
-
[color]="componentOptions().color"
|
|
3417
|
-
[shadow]="componentOptions().shadow"
|
|
3451
|
+
[color]="color() ?? componentOptions().color"
|
|
3452
|
+
[shadow]="shadow() ?? componentOptions().shadow"
|
|
3418
3453
|
>
|
|
3419
3454
|
<ng-content></ng-content>
|
|
3420
3455
|
</div>
|
|
@@ -3432,12 +3467,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
|
|
|
3432
3467
|
<div #dropdown popover="auto" [id]="popoverId" [class]="dropdownClass()">
|
|
3433
3468
|
<div
|
|
3434
3469
|
box-layout
|
|
3435
|
-
[border]="componentOptions().border"
|
|
3436
|
-
[borderRadius]="componentOptions().borderRadius"
|
|
3470
|
+
[border]="border() ?? componentOptions().border"
|
|
3471
|
+
[borderRadius]="borderRadius() ?? componentOptions().borderRadius"
|
|
3437
3472
|
[paddingVertical]="paddingVertical()"
|
|
3438
3473
|
[paddingHorizontal]="paddingHorizontal()"
|
|
3439
|
-
[color]="componentOptions().color"
|
|
3440
|
-
[shadow]="componentOptions().shadow"
|
|
3474
|
+
[color]="color() ?? componentOptions().color"
|
|
3475
|
+
[shadow]="shadow() ?? componentOptions().shadow"
|
|
3441
3476
|
>
|
|
3442
3477
|
<ng-content></ng-content>
|
|
3443
3478
|
</div>
|
|
@@ -3445,13 +3480,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
|
|
|
3445
3480
|
`,
|
|
3446
3481
|
providers: [{ provide: COMPONENT_NAME, useValue: 'dropdown' }],
|
|
3447
3482
|
}]
|
|
3448
|
-
}], 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: [{
|
|
3449
3484
|
type: ViewChild,
|
|
3450
3485
|
args: ['dropdown', { static: true }]
|
|
3451
3486
|
}] } });
|
|
3452
3487
|
|
|
3453
|
-
class UniExpandComponent {
|
|
3488
|
+
class UniExpandComponent extends BaseComponent {
|
|
3454
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 */ []));
|
|
3455
3497
|
/** Referenced by the controlling toggle's aria-controls. */
|
|
3456
3498
|
regionId = uniqueId('uni-expand');
|
|
3457
3499
|
/**
|
|
@@ -3460,12 +3502,58 @@ class UniExpandComponent {
|
|
|
3460
3502
|
* animations only after the first render, i.e. on real state changes.
|
|
3461
3503
|
*/
|
|
3462
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 */ []));
|
|
3463
3515
|
constructor() {
|
|
3516
|
+
super();
|
|
3464
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
|
+
});
|
|
3465
3526
|
}
|
|
3466
3527
|
toggle() {
|
|
3467
3528
|
this.collapsed.update((collapsed) => !collapsed);
|
|
3468
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 */ []));
|
|
3548
|
+
/**
|
|
3549
|
+
* A custom element is `display: inline` by default, which would lay the
|
|
3550
|
+
* animated grid out as a block-in-inline box and distort the revealed
|
|
3551
|
+
* content's spacing. Every consumer would otherwise have to write
|
|
3552
|
+
* `uni-expand { display: block }` themselves.
|
|
3553
|
+
*/
|
|
3554
|
+
hostClassName = css({
|
|
3555
|
+
display: 'block',
|
|
3556
|
+
});
|
|
3469
3557
|
expandClassName = css({
|
|
3470
3558
|
display: 'grid',
|
|
3471
3559
|
});
|
|
@@ -3474,22 +3562,37 @@ class UniExpandComponent {
|
|
|
3474
3562
|
});
|
|
3475
3563
|
expand = keyframes({ ...expandFadeIn });
|
|
3476
3564
|
collapse = keyframes({ ...collapseFadeOut });
|
|
3477
|
-
|
|
3565
|
+
/**
|
|
3566
|
+
* Reveal is motion-safe (WCAG 2.3.3): under `prefers-reduced-motion` these
|
|
3567
|
+
* classes are empty, so the region appears and disappears instantly.
|
|
3568
|
+
* `overflow: hidden` rides inside the guard deliberately — it exists to clip
|
|
3569
|
+
* the growing box mid-animation, and leaving it applied at rest would crop
|
|
3570
|
+
* decorations that legitimately paint outside the region (focus rings,
|
|
3571
|
+
* offset outlines). Angular removes a leaving node on the next frame when it
|
|
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.
|
|
3578
|
+
*/
|
|
3579
|
+
expandAnimation = css(motionSafe({
|
|
3478
3580
|
overflow: 'hidden',
|
|
3479
|
-
animation: `${this.expand} ease-in
|
|
3480
|
-
});
|
|
3481
|
-
collapseAnimation = css({
|
|
3581
|
+
animation: `${this.expand} ease-in-out ${EXPAND_DEFAULT_SPEED}s`,
|
|
3582
|
+
}));
|
|
3583
|
+
collapseAnimation = css(motionSafe({
|
|
3482
3584
|
overflow: 'hidden',
|
|
3483
|
-
animation: `${this.collapse} ease-in
|
|
3484
|
-
});
|
|
3585
|
+
animation: `${this.collapse} ease-in-out ${EXPAND_DEFAULT_SPEED}s`,
|
|
3586
|
+
}));
|
|
3485
3587
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniExpandComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3486
|
-
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" } }, 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()) {
|
|
3487
3589
|
<div
|
|
3488
3590
|
[animate.enter]="ready() ? expandAnimation : ''"
|
|
3489
3591
|
[animate.leave]="collapseAnimation"
|
|
3490
3592
|
[class]="expandClassName"
|
|
3593
|
+
[style.animation-duration]="cssDuration()"
|
|
3491
3594
|
>
|
|
3492
|
-
<div [class]="contentClassName">
|
|
3595
|
+
<div #content [class]="contentClassName">
|
|
3493
3596
|
<ng-content></ng-content>
|
|
3494
3597
|
</div>
|
|
3495
3598
|
</div>
|
|
@@ -3501,22 +3604,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
|
|
|
3501
3604
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
3502
3605
|
selector: 'uni-expand',
|
|
3503
3606
|
imports: [],
|
|
3607
|
+
providers: [{ provide: COMPONENT_NAME, useValue: 'expand' }],
|
|
3504
3608
|
template: `@if (!collapsed()) {
|
|
3505
3609
|
<div
|
|
3506
3610
|
[animate.enter]="ready() ? expandAnimation : ''"
|
|
3507
3611
|
[animate.leave]="collapseAnimation"
|
|
3508
3612
|
[class]="expandClassName"
|
|
3613
|
+
[style.animation-duration]="cssDuration()"
|
|
3509
3614
|
>
|
|
3510
|
-
<div [class]="contentClassName">
|
|
3615
|
+
<div #content [class]="contentClassName">
|
|
3511
3616
|
<ng-content></ng-content>
|
|
3512
3617
|
</div>
|
|
3513
3618
|
</div>
|
|
3514
3619
|
}`,
|
|
3515
3620
|
host: {
|
|
3516
3621
|
'[attr.id]': 'regionId',
|
|
3622
|
+
'[class]': 'hostClassName',
|
|
3517
3623
|
},
|
|
3518
3624
|
}]
|
|
3519
|
-
}], 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 }] }] } });
|
|
3520
3626
|
|
|
3521
3627
|
/**
|
|
3522
3628
|
* UniExpandComponent Barrel File
|
|
@@ -3524,242 +3630,155 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
|
|
|
3524
3630
|
* This file exports all public-facing elements of the expand component.
|
|
3525
3631
|
*/
|
|
3526
3632
|
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
label = input.required(...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
3538
|
-
placement = input('top', ...(ngDevMode ? [{ debugName: "placement" }] : /* istanbul ignore next */ []));
|
|
3539
|
-
inlineText = input(false, ...(ngDevMode ? [{ debugName: "inlineText" }] : /* istanbul ignore next */ []));
|
|
3540
|
-
/** @deprecated The tooltip renders in the native top layer; ignored. */
|
|
3541
|
-
appendToBody = input(false, ...(ngDevMode ? [{ debugName: "appendToBody" }] : /* istanbul ignore next */ []));
|
|
3542
|
-
tipRef = viewChild.required('tip');
|
|
3543
|
-
constructor() {
|
|
3544
|
-
super();
|
|
3545
|
-
effect(() => {
|
|
3546
|
-
const timerActive = this.timer.isActive();
|
|
3547
|
-
const mouseInside = this.isMouseInside();
|
|
3548
|
-
// If the timer finished and the mouse is still inside, show tooltip
|
|
3549
|
-
if (!timerActive && mouseInside) {
|
|
3550
|
-
this.showTooltip();
|
|
3551
|
-
}
|
|
3552
|
-
// If the mouse left and the timer is not running, hide tooltip
|
|
3553
|
-
else if (!mouseInside) {
|
|
3554
|
-
this.hideTooltip();
|
|
3555
|
-
}
|
|
3556
|
-
});
|
|
3557
|
-
// A tooltip must be reachable by keyboard (WCAG 1.4.13): when the
|
|
3558
|
-
// projected content has no focusable element, the host itself joins
|
|
3559
|
-
// the tab sequence. The bubble is always in the DOM, so the describedby
|
|
3560
|
-
// relationship is wired once, on the element that receives focus.
|
|
3561
|
-
afterNextRender(() => {
|
|
3562
|
-
const host = this.elRef.nativeElement;
|
|
3563
|
-
if (!host.querySelector(FOCUSABLE_SELECTOR) && !host.matches(FOCUSABLE_SELECTOR)) {
|
|
3564
|
-
this.renderer.setAttribute(host, 'tabindex', '0');
|
|
3565
|
-
}
|
|
3566
|
-
this.renderer.setAttribute(resolveFocusTarget(host), 'aria-describedby', this.tooltipId);
|
|
3567
|
-
});
|
|
3568
|
-
}
|
|
3569
|
-
onFocusIn(event) {
|
|
3570
|
-
// Only keyboard-driven focus shows the tooltip immediately; mouse
|
|
3571
|
-
// interaction keeps the hover-delay behavior.
|
|
3572
|
-
if (event.target.matches(':focus-visible')) {
|
|
3573
|
-
this.showTooltip();
|
|
3574
|
-
}
|
|
3575
|
-
}
|
|
3576
|
-
onFocusOut() {
|
|
3577
|
-
if (!this.isMouseInside()) {
|
|
3578
|
-
this.hideTooltip();
|
|
3579
|
-
}
|
|
3580
|
-
}
|
|
3581
|
-
onEscape(event) {
|
|
3582
|
-
if (this.visible()) {
|
|
3583
|
-
// Dismiss only the tooltip, not an enclosing dialog/popover
|
|
3584
|
-
event.stopPropagation();
|
|
3585
|
-
this.hideTooltip();
|
|
3586
|
-
}
|
|
3587
|
-
}
|
|
3588
|
-
toggleTooltip() {
|
|
3589
|
-
if (this.visible()) {
|
|
3590
|
-
this.hideTooltip();
|
|
3591
|
-
}
|
|
3592
|
-
else {
|
|
3593
|
-
this.showTooltip();
|
|
3594
|
-
}
|
|
3595
|
-
}
|
|
3596
|
-
mouseenter() {
|
|
3597
|
-
this.isMouseInside.set(true);
|
|
3598
|
-
this.timer.start(this.hoverDelay());
|
|
3599
|
-
}
|
|
3600
|
-
mouseleave() {
|
|
3601
|
-
this.isMouseInside.set(false);
|
|
3602
|
-
this.timer.stop();
|
|
3603
|
-
}
|
|
3604
|
-
showTooltip() {
|
|
3605
|
-
if (this.visible())
|
|
3606
|
-
return;
|
|
3607
|
-
const tip = this.tipRef().nativeElement;
|
|
3608
|
-
tip.showPopover();
|
|
3609
|
-
this.renderer.setAttribute(tip, 'fade', 'in');
|
|
3610
|
-
this.visible.set(true);
|
|
3611
|
-
}
|
|
3612
|
-
hideTooltip() {
|
|
3613
|
-
if (!this.visible())
|
|
3614
|
-
return;
|
|
3615
|
-
this.renderer.setAttribute(this.tipRef().nativeElement, 'fade', 'out');
|
|
3616
|
-
}
|
|
3617
|
-
onAnimationEnd(event) {
|
|
3618
|
-
if (event.animationName.includes(this.tooltipFadeOut)) {
|
|
3619
|
-
this.tipRef().nativeElement.hidePopover();
|
|
3620
|
-
this.visible.set(false);
|
|
3621
|
-
}
|
|
3622
|
-
}
|
|
3623
|
-
className = computed(() => css({
|
|
3624
|
-
display: 'inline-flex',
|
|
3625
|
-
anchorName: this.anchorName,
|
|
3626
|
-
}, this.inlineText() && {
|
|
3627
|
-
cursor: 'help',
|
|
3628
|
-
textDecoration: 'underline',
|
|
3629
|
-
textDecorationStyle: 'dotted',
|
|
3630
|
-
}), ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
|
|
3631
|
-
tooltipFadeIn = keyframes({ ...fadeIn });
|
|
3632
|
-
tooltipFadeOut = keyframes({ ...fadeOut });
|
|
3633
|
-
tooltipClassName = computed(() => css([
|
|
3634
|
-
{
|
|
3635
|
-
...this.theme.colorPair(this.componentOptions().color),
|
|
3636
|
-
...this.theme.radius(this.componentOptions().borderRadius),
|
|
3637
|
-
...this.theme.boxShadow(this.componentOptions().shadow),
|
|
3638
|
-
...this.theme.typeface(this.componentOptions().typeface),
|
|
3639
|
-
border: 'none',
|
|
3640
|
-
padding: 5,
|
|
3641
|
-
width: 'max-content',
|
|
3642
|
-
...anchorStyles(this.anchorName, this.placement(), { mainAxis: 6 }),
|
|
3643
|
-
'&[fade="in"]': {
|
|
3644
|
-
animation: `${this.tooltipFadeIn} ease-in 350ms`,
|
|
3645
|
-
},
|
|
3646
|
-
'&[fade="out"]': {
|
|
3647
|
-
animation: `${this.tooltipFadeOut} ease-in 350ms`,
|
|
3648
|
-
},
|
|
3649
|
-
},
|
|
3650
|
-
]), ...(ngDevMode ? [{ debugName: "tooltipClassName" }] : /* istanbul ignore next */ []));
|
|
3651
|
-
arrowClassName = computed(() => css({
|
|
3652
|
-
...this.theme.colorPair(this.componentOptions().color),
|
|
3653
|
-
...anchorArrowStyles(this.placement()),
|
|
3654
|
-
}), ...(ngDevMode ? [{ debugName: "arrowClassName" }] : /* istanbul ignore next */ []));
|
|
3655
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniTooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3656
|
-
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
|
|
3657
|
-
><span
|
|
3658
|
-
#tip
|
|
3659
|
-
popover="manual"
|
|
3660
|
-
role="tooltip"
|
|
3661
|
-
[id]="tooltipId"
|
|
3662
|
-
[class]="tooltipClassName()"
|
|
3663
|
-
(mouseenter)="isMouseInside.set(true)"
|
|
3664
|
-
(mouseleave)="isMouseInside.set(false)"
|
|
3665
|
-
(animationend)="onAnimationEnd($event)"
|
|
3666
|
-
>{{ label() }}<span [class]="arrowClassName()"></span
|
|
3667
|
-
></span>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3668
|
-
}
|
|
3669
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniTooltipComponent, decorators: [{
|
|
3670
|
-
type: Component,
|
|
3671
|
-
args: [{
|
|
3672
|
-
selector: 'uni-tooltip',
|
|
3673
|
-
imports: [],
|
|
3674
|
-
// The bubble lives declaratively in the template as a manual popover: the
|
|
3675
|
-
// top layer escapes any overflow context (which made appendToBody obsolete)
|
|
3676
|
-
// and native CSS anchor positioning keeps it attached to the host.
|
|
3677
|
-
template: `<ng-content></ng-content
|
|
3678
|
-
><span
|
|
3679
|
-
#tip
|
|
3680
|
-
popover="manual"
|
|
3681
|
-
role="tooltip"
|
|
3682
|
-
[id]="tooltipId"
|
|
3683
|
-
[class]="tooltipClassName()"
|
|
3684
|
-
(mouseenter)="isMouseInside.set(true)"
|
|
3685
|
-
(mouseleave)="isMouseInside.set(false)"
|
|
3686
|
-
(animationend)="onAnimationEnd($event)"
|
|
3687
|
-
>{{ label() }}<span [class]="arrowClassName()"></span
|
|
3688
|
-
></span>`,
|
|
3689
|
-
providers: [{ provide: COMPONENT_NAME, useValue: 'tooltip' }],
|
|
3690
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
3691
|
-
host: {
|
|
3692
|
-
'[class]': 'className()',
|
|
3693
|
-
'(click)': 'toggleTooltip()',
|
|
3694
|
-
'(mouseenter)': 'mouseenter()',
|
|
3695
|
-
'(mouseleave)': 'mouseleave()',
|
|
3696
|
-
'(focusin)': 'onFocusIn($event)',
|
|
3697
|
-
'(focusout)': 'onFocusOut()',
|
|
3698
|
-
'(keydown.escape)': 'onEscape($event)',
|
|
3699
|
-
},
|
|
3700
|
-
}]
|
|
3701
|
-
}], 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 }] }] } });
|
|
3702
|
-
|
|
3633
|
+
/**
|
|
3634
|
+
* Trigger for a {@link UniExpandComponent} region.
|
|
3635
|
+
*
|
|
3636
|
+
* Two shapes, chosen by whether `label` is set:
|
|
3637
|
+
* - **Icon only** (default) — the bare chevron, sized for a Card Header.
|
|
3638
|
+
* - **Labelled** — chevron plus a label and optional muted sublabel, as a
|
|
3639
|
+
* single full-width button. Most real disclosures need a name for the
|
|
3640
|
+
* section, and building that row by hand is the thing this saves; it also
|
|
3641
|
+
* makes the label the button's accessible name rather than adjacent text.
|
|
3642
|
+
*/
|
|
3703
3643
|
class UniExpandToggleComponent {
|
|
3704
3644
|
collapsed = model(true, ...(ngDevMode ? [{ debugName: "collapsed" }] : /* istanbul ignore next */ []));
|
|
3705
3645
|
/** Id of the Expand region this toggle controls (see UniExpandComponent.regionId). */
|
|
3706
3646
|
ariaControls = input(...(ngDevMode ? [undefined, { debugName: "ariaControls" }] : /* istanbul ignore next */ []));
|
|
3647
|
+
/** Names the region. Setting it switches the toggle to its labelled shape. */
|
|
3648
|
+
label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : /* istanbul ignore next */ []));
|
|
3649
|
+
/** Muted qualifier beside the label ("for POs & custom orders"). Needs `label`. */
|
|
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 */ []));
|
|
3660
|
+
/**
|
|
3661
|
+
* The glyph rotates, never the host.
|
|
3662
|
+
*
|
|
3663
|
+
* The host is taller than the glyph (an inline-level box reserves baseline
|
|
3664
|
+
* descender space), so spinning it about its own centre walks the glyph
|
|
3665
|
+
* off-centre. `uni-icon` is a centred square sized to the glyph, which makes
|
|
3666
|
+
* it the only box here that rotates symmetrically. It also keeps a label
|
|
3667
|
+
* from turning upside down with the chevron.
|
|
3668
|
+
*/
|
|
3669
|
+
glyphStyles = computed(() => ({
|
|
3670
|
+
'& uni-icon': {
|
|
3671
|
+
flexShrink: 0,
|
|
3672
|
+
...motionSafe({
|
|
3673
|
+
transition: `transform ${this.speed()}s ease-in-out`,
|
|
3674
|
+
}),
|
|
3675
|
+
transform: this.collapsed() ? 'rotate(-180deg)' : 'rotate(0)',
|
|
3676
|
+
},
|
|
3677
|
+
}), ...(ngDevMode ? [{ debugName: "glyphStyles" }] : /* istanbul ignore next */ []));
|
|
3707
3678
|
className = computed(() => {
|
|
3679
|
+
if (this.label()) {
|
|
3680
|
+
return css({ display: 'block', ...this.glyphStyles() });
|
|
3681
|
+
}
|
|
3708
3682
|
return css({
|
|
3709
3683
|
display: 'inline-flex',
|
|
3710
3684
|
cursor: 'pointer',
|
|
3711
|
-
|
|
3712
|
-
transform: 'rotate(0)',
|
|
3713
|
-
'&[toggled]': {
|
|
3714
|
-
transform: 'rotate(-180deg)',
|
|
3715
|
-
},
|
|
3685
|
+
...this.glyphStyles(),
|
|
3716
3686
|
});
|
|
3717
3687
|
}, ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
|
|
3688
|
+
triggerClassName = css({
|
|
3689
|
+
display: 'flex',
|
|
3690
|
+
alignItems: 'center',
|
|
3691
|
+
gap: 8,
|
|
3692
|
+
width: '100%',
|
|
3693
|
+
padding: 0,
|
|
3694
|
+
border: 0,
|
|
3695
|
+
background: 'none',
|
|
3696
|
+
font: 'inherit',
|
|
3697
|
+
color: 'inherit',
|
|
3698
|
+
textAlign: 'left',
|
|
3699
|
+
cursor: 'pointer',
|
|
3700
|
+
});
|
|
3701
|
+
labelClassName = css({
|
|
3702
|
+
display: 'flex',
|
|
3703
|
+
alignItems: 'baseline',
|
|
3704
|
+
gap: 6,
|
|
3705
|
+
minWidth: 0,
|
|
3706
|
+
});
|
|
3718
3707
|
toggle() {
|
|
3719
3708
|
this.collapsed.update((collapsed) => !collapsed);
|
|
3720
3709
|
}
|
|
3721
3710
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniExpandToggleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3722
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
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: `
|
|
3712
|
+
@if (label()) {
|
|
3713
|
+
<button
|
|
3714
|
+
type="button"
|
|
3715
|
+
[class]="triggerClassName"
|
|
3716
|
+
(click)="toggle()"
|
|
3717
|
+
[attr.aria-expanded]="!collapsed()"
|
|
3718
|
+
[attr.aria-controls]="ariaControls() || null"
|
|
3719
|
+
>
|
|
3720
|
+
<uni-icon name="chevronUp" size="1em" />
|
|
3721
|
+
<span [class]="labelClassName">
|
|
3722
|
+
<span uni-text="label">{{ label() }}</span>
|
|
3723
|
+
@if (sublabel()) {
|
|
3724
|
+
<span uni-text="caption" color="on-background-variant">{{ sublabel() }}</span>
|
|
3725
|
+
}
|
|
3726
|
+
</span>
|
|
3727
|
+
</button>
|
|
3728
|
+
} @else {
|
|
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>
|
|
3738
|
+
}
|
|
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 });
|
|
3736
3740
|
}
|
|
3737
3741
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniExpandToggleComponent, decorators: [{
|
|
3738
3742
|
type: Component,
|
|
3739
3743
|
args: [{
|
|
3740
3744
|
selector: 'uni-expand-toggle',
|
|
3741
|
-
imports: [UniIconButtonComponent,
|
|
3742
|
-
template:
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3745
|
+
imports: [UniIconComponent, UniIconButtonComponent, UniTextComponent],
|
|
3746
|
+
template: `
|
|
3747
|
+
@if (label()) {
|
|
3748
|
+
<button
|
|
3749
|
+
type="button"
|
|
3750
|
+
[class]="triggerClassName"
|
|
3751
|
+
(click)="toggle()"
|
|
3752
|
+
[attr.aria-expanded]="!collapsed()"
|
|
3753
|
+
[attr.aria-controls]="ariaControls() || null"
|
|
3754
|
+
>
|
|
3755
|
+
<uni-icon name="chevronUp" size="1em" />
|
|
3756
|
+
<span [class]="labelClassName">
|
|
3757
|
+
<span uni-text="label">{{ label() }}</span>
|
|
3758
|
+
@if (sublabel()) {
|
|
3759
|
+
<span uni-text="caption" color="on-background-variant">{{ sublabel() }}</span>
|
|
3760
|
+
}
|
|
3761
|
+
</span>
|
|
3762
|
+
</button>
|
|
3763
|
+
} @else {
|
|
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>
|
|
3773
|
+
}
|
|
3774
|
+
`,
|
|
3756
3775
|
host: {
|
|
3757
3776
|
'[class]': 'className()',
|
|
3758
3777
|
'[attr.toggled]': 'collapsed() || null',
|
|
3759
3778
|
},
|
|
3760
3779
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
3761
3780
|
}]
|
|
3762
|
-
}], 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 }] }] } });
|
|
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 }] }] } });
|
|
3763
3782
|
|
|
3764
3783
|
class UniExpandAreaComponent {
|
|
3765
3784
|
title = input.required(...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
@@ -3795,6 +3814,7 @@ class UniExpandAreaComponent {
|
|
|
3795
3814
|
style="display: inline-flex; margin: -2px"
|
|
3796
3815
|
[collapsed]="initCollapsed()"
|
|
3797
3816
|
[ariaControls]="expand.regionId"
|
|
3817
|
+
[transitionSpeed]="expand.duration()"
|
|
3798
3818
|
/>
|
|
3799
3819
|
</div>
|
|
3800
3820
|
|
|
@@ -3804,7 +3824,7 @@ class UniExpandAreaComponent {
|
|
|
3804
3824
|
</div>
|
|
3805
3825
|
</uni-expand>
|
|
3806
3826
|
</div>
|
|
3807
|
-
`, 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"], 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 });
|
|
3808
3828
|
}
|
|
3809
3829
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniExpandAreaComponent, decorators: [{
|
|
3810
3830
|
type: Component,
|
|
@@ -3836,6 +3856,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
|
|
|
3836
3856
|
style="display: inline-flex; margin: -2px"
|
|
3837
3857
|
[collapsed]="initCollapsed()"
|
|
3838
3858
|
[ariaControls]="expand.regionId"
|
|
3859
|
+
[transitionSpeed]="expand.duration()"
|
|
3839
3860
|
/>
|
|
3840
3861
|
</div>
|
|
3841
3862
|
|
|
@@ -4142,32 +4163,61 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
|
|
|
4142
4163
|
* This file exports all public-facing elements of the json-view component.
|
|
4143
4164
|
*/
|
|
4144
4165
|
|
|
4145
|
-
|
|
4166
|
+
const isDivider = (item) => 'divider' in item;
|
|
4167
|
+
|
|
4168
|
+
class UniMenuItemComponent {
|
|
4169
|
+
theme = inject(ThemeService);
|
|
4146
4170
|
_elementRef = inject(ElementRef);
|
|
4147
|
-
display = input('flex', ...(ngDevMode ? [{ debugName: "display" }] : /* istanbul ignore next */ []));
|
|
4148
|
-
flexDirection = input('row', ...(ngDevMode ? [{ debugName: "flexDirection" }] : /* istanbul ignore next */ []));
|
|
4149
|
-
alignItems = input('center', ...(ngDevMode ? [{ debugName: "alignItems" }] : /* istanbul ignore next */ []));
|
|
4150
|
-
paddingHorizontal = input('md', ...(ngDevMode ? [{ debugName: "paddingHorizontal" }] : /* istanbul ignore next */ []));
|
|
4151
|
-
gap = input('md', ...(ngDevMode ? [{ debugName: "gap" }] : /* istanbul ignore next */ []));
|
|
4152
4171
|
label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : /* istanbul ignore next */ []));
|
|
4153
4172
|
template = input(...(ngDevMode ? [undefined, { debugName: "template" }] : /* istanbul ignore next */ []));
|
|
4154
4173
|
context = input(...(ngDevMode ? [undefined, { debugName: "context" }] : /* istanbul ignore next */ []));
|
|
4155
4174
|
symbolName = input(...(ngDevMode ? [undefined, { debugName: "symbolName" }] : /* istanbul ignore next */ []));
|
|
4156
4175
|
active = input(...(ngDevMode ? [undefined, { debugName: "active" }] : /* istanbul ignore next */ []));
|
|
4157
|
-
|
|
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 */ []));
|
|
4158
4180
|
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
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
|
+
},
|
|
4168
4214
|
},
|
|
4169
|
-
|
|
4170
|
-
|
|
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 */ []));
|
|
4171
4221
|
/** Host element, used by Menu for roving-focus bookkeeping. */
|
|
4172
4222
|
get host() {
|
|
4173
4223
|
return this._elementRef.nativeElement;
|
|
@@ -4175,21 +4225,22 @@ class UniMenuItemComponent extends UniBoxComponent {
|
|
|
4175
4225
|
focus() {
|
|
4176
4226
|
this._elementRef.nativeElement.focus();
|
|
4177
4227
|
}
|
|
4178
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniMenuItemComponent, deps:
|
|
4179
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: UniMenuItemComponent, isStandalone: true, selector: "[uni-menu-item], [menu-item]", inputs: {
|
|
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 });
|
|
4180
4230
|
}
|
|
4181
4231
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniMenuItemComponent, decorators: [{
|
|
4182
4232
|
type: Component,
|
|
4183
|
-
args: [{ selector: '[uni-menu-item], [menu-item]', imports: [
|
|
4233
|
+
args: [{ selector: '[uni-menu-item], [menu-item]', imports: [UniSymbolComponent, UniBoxComponent, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
4184
4234
|
role: 'menuitem',
|
|
4185
4235
|
tabindex: '-1',
|
|
4186
4236
|
'[attr.aria-disabled]': "disabled() ? 'true' : null",
|
|
4187
4237
|
'[attr.aria-current]': "active() ? 'true' : null",
|
|
4188
4238
|
'[class]': 'menuItemClassName()',
|
|
4189
|
-
}, 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
|
|
4190
|
-
}], propDecorators: {
|
|
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 }] }] } });
|
|
4191
4241
|
|
|
4192
4242
|
class UniMenuComponent {
|
|
4243
|
+
theme = inject(ThemeService);
|
|
4193
4244
|
// Modern Signal Inputs for perfect Zoneless tracking
|
|
4194
4245
|
menuItems = input.required(...(ngDevMode ? [{ debugName: "menuItems" }] : /* istanbul ignore next */ []));
|
|
4195
4246
|
activeItem = input(...(ngDevMode ? [undefined, { debugName: "activeItem" }] : /* istanbul ignore next */ []));
|
|
@@ -4197,6 +4248,21 @@ class UniMenuComponent {
|
|
|
4197
4248
|
// Modern Signal Output
|
|
4198
4249
|
menuItemClicked = output();
|
|
4199
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 */ []));
|
|
4200
4266
|
itemComponents = viewChildren(UniMenuItemComponent, ...(ngDevMode ? [{ debugName: "itemComponents" }] : /* istanbul ignore next */ []));
|
|
4201
4267
|
dropdownComponent = viewChild(UniDropdownComponent, ...(ngDevMode ? [{ debugName: "dropdownComponent" }] : /* istanbul ignore next */ []));
|
|
4202
4268
|
/** Which item receives focus when the menu opens (ArrowUp opens onto the last item). */
|
|
@@ -4208,7 +4274,7 @@ class UniMenuComponent {
|
|
|
4208
4274
|
});
|
|
4209
4275
|
}, ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
|
|
4210
4276
|
handleMenuItemClick(item, dropdown) {
|
|
4211
|
-
if (item.action) {
|
|
4277
|
+
if (!isDivider(item) && item.action) {
|
|
4212
4278
|
item.action();
|
|
4213
4279
|
}
|
|
4214
4280
|
this.menuItemClicked.emit(item);
|
|
@@ -4305,7 +4371,12 @@ class UniMenuComponent {
|
|
|
4305
4371
|
[trigger]="trigger"
|
|
4306
4372
|
[placement]="placement()"
|
|
4307
4373
|
ariaHasPopup="menu"
|
|
4308
|
-
|
|
4374
|
+
[color]="menuOptions().color"
|
|
4375
|
+
[border]="menuOptions().border"
|
|
4376
|
+
[borderRadius]="menuOptions().borderRadius"
|
|
4377
|
+
[shadow]="menuOptions().shadow"
|
|
4378
|
+
[paddingVertical]="menuOptions().paddingVertical"
|
|
4379
|
+
[paddingHorizontal]="menuOptions().paddingHorizontal"
|
|
4309
4380
|
#dropdown
|
|
4310
4381
|
(dropdownShowing)="onOpened()"
|
|
4311
4382
|
>
|
|
@@ -4313,23 +4384,29 @@ class UniMenuComponent {
|
|
|
4313
4384
|
the focused item (menu-item hosts carry tabindex="-1"), and
|
|
4314
4385
|
Enter/Space activation is dispatched from onMenuKeydown. -->
|
|
4315
4386
|
<!-- eslint-disable-next-line @angular-eslint/template/interactive-supports-focus -->
|
|
4316
|
-
<div role="menu" (keydown)="onMenuKeydown($event, dropdown)">
|
|
4387
|
+
<div role="menu" [class]="menuClassName()" (keydown)="onMenuKeydown($event, dropdown)">
|
|
4317
4388
|
@for (item of menuItems(); track item) {
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
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
|
+
}
|
|
4328
4405
|
}
|
|
4329
4406
|
</div>
|
|
4330
4407
|
</uni-dropdown>
|
|
4331
4408
|
}
|
|
4332
|
-
`, isInline: true, dependencies: [{ kind: "component", type: UniMenuItemComponent, selector: "[uni-menu-item], [menu-item]", inputs: ["
|
|
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 });
|
|
4333
4410
|
}
|
|
4334
4411
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniMenuComponent, decorators: [{
|
|
4335
4412
|
type: Component,
|
|
@@ -4350,7 +4427,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
|
|
|
4350
4427
|
[trigger]="trigger"
|
|
4351
4428
|
[placement]="placement()"
|
|
4352
4429
|
ariaHasPopup="menu"
|
|
4353
|
-
|
|
4430
|
+
[color]="menuOptions().color"
|
|
4431
|
+
[border]="menuOptions().border"
|
|
4432
|
+
[borderRadius]="menuOptions().borderRadius"
|
|
4433
|
+
[shadow]="menuOptions().shadow"
|
|
4434
|
+
[paddingVertical]="menuOptions().paddingVertical"
|
|
4435
|
+
[paddingHorizontal]="menuOptions().paddingHorizontal"
|
|
4354
4436
|
#dropdown
|
|
4355
4437
|
(dropdownShowing)="onOpened()"
|
|
4356
4438
|
>
|
|
@@ -4358,18 +4440,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
|
|
|
4358
4440
|
the focused item (menu-item hosts carry tabindex="-1"), and
|
|
4359
4441
|
Enter/Space activation is dispatched from onMenuKeydown. -->
|
|
4360
4442
|
<!-- eslint-disable-next-line @angular-eslint/template/interactive-supports-focus -->
|
|
4361
|
-
<div role="menu" (keydown)="onMenuKeydown($event, dropdown)">
|
|
4443
|
+
<div role="menu" [class]="menuClassName()" (keydown)="onMenuKeydown($event, dropdown)">
|
|
4362
4444
|
@for (item of menuItems(); track item) {
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
|
|
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
|
+
}
|
|
4373
4461
|
}
|
|
4374
4462
|
</div>
|
|
4375
4463
|
</uni-dropdown>
|
|
@@ -4525,7 +4613,7 @@ class UniMultiSelectDropdownComponent extends BaseComponent {
|
|
|
4525
4613
|
});
|
|
4526
4614
|
}
|
|
4527
4615
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniMultiSelectDropdownComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
4528
|
-
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 });
|
|
4529
4617
|
}
|
|
4530
4618
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniMultiSelectDropdownComponent, decorators: [{
|
|
4531
4619
|
type: Component,
|
|
@@ -7227,9 +7315,211 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
|
|
|
7227
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" }]
|
|
7228
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 }] }] } });
|
|
7229
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
|
+
|
|
7230
7520
|
/**
|
|
7231
7521
|
* Generated bundle index. Do not edit.
|
|
7232
7522
|
*/
|
|
7233
7523
|
|
|
7234
|
-
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 };
|
|
7235
7525
|
//# sourceMappingURL=uni-design-system-uni-angular.mjs.map
|