@cute-widgets/base 20.0.1
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.
- package/CHANGELOG.md +1 -0
- package/LICENSE.md +191 -0
- package/README.md +190 -0
- package/abstract/index.d.ts +327 -0
- package/alert/index.d.ts +68 -0
- package/autocomplete/index.d.ts +442 -0
- package/badge/index.d.ts +26 -0
- package/bottom-sheet/index.d.ts +231 -0
- package/button/index.d.ts +182 -0
- package/button-toggle/index.d.ts +225 -0
- package/card/index.d.ts +163 -0
- package/checkbox/index.d.ts +174 -0
- package/chips/index.d.ts +963 -0
- package/collapse/index.d.ts +97 -0
- package/core/animation/index.d.ts +43 -0
- package/core/datetime/index.d.ts +404 -0
- package/core/directives/index.d.ts +168 -0
- package/core/error/index.d.ts +74 -0
- package/core/index.d.ts +1039 -0
- package/core/interfaces/index.d.ts +114 -0
- package/core/layout/index.d.ts +53 -0
- package/core/line/index.d.ts +37 -0
- package/core/nav/index.d.ts +321 -0
- package/core/observers/index.d.ts +124 -0
- package/core/option/index.d.ts +185 -0
- package/core/pipes/index.d.ts +53 -0
- package/core/ripple/index.d.ts +66 -0
- package/core/testing/index.d.ts +154 -0
- package/core/theming/index.d.ts +118 -0
- package/core/types/index.d.ts +53 -0
- package/core/utils/index.d.ts +129 -0
- package/cute-widgets-base-20.0.1.tgz +0 -0
- package/datepicker/index.d.ts +1817 -0
- package/dialog/index.d.ts +484 -0
- package/divider/index.d.ts +24 -0
- package/expansion/README.md +8 -0
- package/expansion/index.d.ts +308 -0
- package/fesm2022/cute-widgets-base-abstract.mjs +547 -0
- package/fesm2022/cute-widgets-base-abstract.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-alert.mjs +198 -0
- package/fesm2022/cute-widgets-base-alert.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-autocomplete.mjs +1217 -0
- package/fesm2022/cute-widgets-base-autocomplete.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-badge.mjs +75 -0
- package/fesm2022/cute-widgets-base-badge.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-bottom-sheet.mjs +416 -0
- package/fesm2022/cute-widgets-base-bottom-sheet.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-button-toggle.mjs +640 -0
- package/fesm2022/cute-widgets-base-button-toggle.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-button.mjs +546 -0
- package/fesm2022/cute-widgets-base-button.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-card.mjs +471 -0
- package/fesm2022/cute-widgets-base-card.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-checkbox.mjs +390 -0
- package/fesm2022/cute-widgets-base-checkbox.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-chips.mjs +2360 -0
- package/fesm2022/cute-widgets-base-chips.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-collapse.mjs +259 -0
- package/fesm2022/cute-widgets-base-collapse.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-animation.mjs +53 -0
- package/fesm2022/cute-widgets-base-core-animation.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-datetime.mjs +568 -0
- package/fesm2022/cute-widgets-base-core-datetime.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-directives.mjs +404 -0
- package/fesm2022/cute-widgets-base-core-directives.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-error.mjs +105 -0
- package/fesm2022/cute-widgets-base-core-error.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-interfaces.mjs +22 -0
- package/fesm2022/cute-widgets-base-core-interfaces.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-layout.mjs +74 -0
- package/fesm2022/cute-widgets-base-core-layout.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-line.mjs +87 -0
- package/fesm2022/cute-widgets-base-core-line.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-nav.mjs +863 -0
- package/fesm2022/cute-widgets-base-core-nav.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-observers.mjs +304 -0
- package/fesm2022/cute-widgets-base-core-observers.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-option.mjs +373 -0
- package/fesm2022/cute-widgets-base-core-option.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-pipes.mjs +97 -0
- package/fesm2022/cute-widgets-base-core-pipes.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-ripple.mjs +172 -0
- package/fesm2022/cute-widgets-base-core-ripple.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-testing.mjs +210 -0
- package/fesm2022/cute-widgets-base-core-testing.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-theming.mjs +314 -0
- package/fesm2022/cute-widgets-base-core-theming.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-types.mjs +22 -0
- package/fesm2022/cute-widgets-base-core-types.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-utils.mjs +257 -0
- package/fesm2022/cute-widgets-base-core-utils.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core.mjs +1600 -0
- package/fesm2022/cute-widgets-base-core.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-datepicker.mjs +4827 -0
- package/fesm2022/cute-widgets-base-datepicker.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-dialog.mjs +1046 -0
- package/fesm2022/cute-widgets-base-dialog.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-divider.mjs +86 -0
- package/fesm2022/cute-widgets-base-divider.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-expansion.mjs +623 -0
- package/fesm2022/cute-widgets-base-expansion.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-form-field.mjs +969 -0
- package/fesm2022/cute-widgets-base-form-field.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-grid-list.mjs +715 -0
- package/fesm2022/cute-widgets-base-grid-list.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-icon.mjs +1105 -0
- package/fesm2022/cute-widgets-base-icon.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-input.mjs +726 -0
- package/fesm2022/cute-widgets-base-input.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-layout-container.mjs +95 -0
- package/fesm2022/cute-widgets-base-layout-container.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-layout-stack.mjs +166 -0
- package/fesm2022/cute-widgets-base-layout-stack.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-layout.mjs +250 -0
- package/fesm2022/cute-widgets-base-layout.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-list.mjs +1557 -0
- package/fesm2022/cute-widgets-base-list.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-menu.mjs +1283 -0
- package/fesm2022/cute-widgets-base-menu.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-navbar.mjs +359 -0
- package/fesm2022/cute-widgets-base-navbar.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-paginator.mjs +485 -0
- package/fesm2022/cute-widgets-base-paginator.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-progress.mjs +321 -0
- package/fesm2022/cute-widgets-base-progress.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-radio.mjs +637 -0
- package/fesm2022/cute-widgets-base-radio.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-select.mjs +1208 -0
- package/fesm2022/cute-widgets-base-select.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-sidenav.mjs +1095 -0
- package/fesm2022/cute-widgets-base-sidenav.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-slider.mjs +99 -0
- package/fesm2022/cute-widgets-base-slider.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-snack-bar.mjs +897 -0
- package/fesm2022/cute-widgets-base-snack-bar.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-sort.mjs +639 -0
- package/fesm2022/cute-widgets-base-sort.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-spinner.mjs +154 -0
- package/fesm2022/cute-widgets-base-spinner.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-stepper.mjs +673 -0
- package/fesm2022/cute-widgets-base-stepper.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-table.mjs +1023 -0
- package/fesm2022/cute-widgets-base-table.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-tabs.mjs +729 -0
- package/fesm2022/cute-widgets-base-tabs.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-timepicker.mjs +965 -0
- package/fesm2022/cute-widgets-base-timepicker.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-toolbar.mjs +120 -0
- package/fesm2022/cute-widgets-base-toolbar.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-tooltip.mjs +947 -0
- package/fesm2022/cute-widgets-base-tooltip.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-tree.mjs +598 -0
- package/fesm2022/cute-widgets-base-tree.mjs.map +1 -0
- package/fesm2022/cute-widgets-base.mjs +68 -0
- package/fesm2022/cute-widgets-base.mjs.map +1 -0
- package/form-field/index.d.ts +401 -0
- package/grid-list/index.d.ts +361 -0
- package/icon/index.d.ts +477 -0
- package/index.d.ts +3 -0
- package/input/index.d.ts +256 -0
- package/layout/container/index.d.ts +31 -0
- package/layout/index.d.ts +78 -0
- package/layout/stack/index.d.ts +52 -0
- package/list/index.d.ts +659 -0
- package/menu/index.d.ts +497 -0
- package/navbar/index.d.ts +91 -0
- package/package.json +279 -0
- package/paginator/index.d.ts +216 -0
- package/progress/index.d.ts +130 -0
- package/radio/index.d.ts +259 -0
- package/select/index.d.ts +426 -0
- package/sidenav/index.d.ts +369 -0
- package/slider/index.d.ts +48 -0
- package/snack-bar/index.d.ts +374 -0
- package/sort/index.d.ts +334 -0
- package/spinner/index.d.ts +70 -0
- package/stepper/index.d.ts +295 -0
- package/table/index.d.ts +395 -0
- package/tabs/index.d.ts +307 -0
- package/timepicker/index.d.ts +350 -0
- package/toolbar/index.d.ts +36 -0
- package/tooltip/index.d.ts +299 -0
- package/tree/index.d.ts +314 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { signal, computed, HostListener, Input, Directive } from '@angular/core';
|
|
3
|
+
import { firstValueFrom, fromEvent } from 'rxjs';
|
|
4
|
+
import { take } from 'rxjs/operators';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @license Apache-2.0
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2025 CuteWidgets Team. All Rights Reserved.
|
|
10
|
+
*
|
|
11
|
+
* You may not use this file except in compliance with the License
|
|
12
|
+
* that can be found at http://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
*/
|
|
14
|
+
const RIPPLE_CLASS_NAME = "cute-ripple-element";
|
|
15
|
+
class Ripple {
|
|
16
|
+
constructor(target) {
|
|
17
|
+
this._active = signal(false, ...(ngDevMode ? [{ debugName: "_active" }] : []));
|
|
18
|
+
this._disabled = false;
|
|
19
|
+
this.isActive = computed(() => this._active(), ...(ngDevMode ? [{ debugName: "isActive" }] : []));
|
|
20
|
+
this._target = target;
|
|
21
|
+
}
|
|
22
|
+
get disabled() { return this._disabled; }
|
|
23
|
+
set disabled(v) { this._disabled = v; }
|
|
24
|
+
stop() {
|
|
25
|
+
if (this._target) {
|
|
26
|
+
const existingRipple = this._target.getElementsByClassName(RIPPLE_CLASS_NAME)[0];
|
|
27
|
+
if (existingRipple) {
|
|
28
|
+
existingRipple.parentElement?.remove();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
this._active.set(false);
|
|
32
|
+
}
|
|
33
|
+
launch(event, options) {
|
|
34
|
+
if (this.disabled) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (this.isActive()) {
|
|
38
|
+
this.stop();
|
|
39
|
+
}
|
|
40
|
+
if (this._target && event) {
|
|
41
|
+
const rect = this._target.getBoundingClientRect();
|
|
42
|
+
const parent = document.createElement("div");
|
|
43
|
+
parent.style.position = "absolute";
|
|
44
|
+
parent.style.top = "0";
|
|
45
|
+
parent.style.right = "0";
|
|
46
|
+
parent.style.bottom = "0";
|
|
47
|
+
parent.style.left = "0";
|
|
48
|
+
parent.style.overflow = "hidden";
|
|
49
|
+
parent.style.borderRadius = "inherit";
|
|
50
|
+
parent.style.transform = "perspective(0)";
|
|
51
|
+
parent.ariaHidden = "true";
|
|
52
|
+
parent.classList.add("cute-ripple");
|
|
53
|
+
const circle = document.createElement("span");
|
|
54
|
+
const diameter = Math.max(rect.width, rect.height);
|
|
55
|
+
const radius = diameter / 2;
|
|
56
|
+
circle.style.width = circle.style.height = `${diameter}px`;
|
|
57
|
+
if (options?.centered) {
|
|
58
|
+
circle.style.left = `${rect.width / 2 - radius}px`;
|
|
59
|
+
circle.style.top = `${rect.height / 2 - radius}px`;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
circle.style.left = `${event.clientX - rect.left - radius}px`;
|
|
63
|
+
circle.style.top = `${event.clientY - rect.top - radius}px`;
|
|
64
|
+
}
|
|
65
|
+
if (options?.color) {
|
|
66
|
+
circle.style.setProperty("--cute-ripple-bg-color", options.color);
|
|
67
|
+
}
|
|
68
|
+
if (options?.duration) {
|
|
69
|
+
circle.style.setProperty("--cute-ripple-duration", String(options.duration));
|
|
70
|
+
}
|
|
71
|
+
circle.classList.add(RIPPLE_CLASS_NAME);
|
|
72
|
+
parent.appendChild(circle);
|
|
73
|
+
this._target.appendChild(parent);
|
|
74
|
+
this._active.set(true);
|
|
75
|
+
Promise.any([
|
|
76
|
+
firstValueFrom(fromEvent(circle, "animationend").pipe(take(1))),
|
|
77
|
+
firstValueFrom(fromEvent(circle, "animationcancel").pipe(take(1))),
|
|
78
|
+
//firstValueFrom(fromEvent(document, "mouseup").pipe(take(1))),
|
|
79
|
+
]).then(() => {
|
|
80
|
+
circle.parentElement?.remove();
|
|
81
|
+
this._active.set(false);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @license Apache-2.0
|
|
89
|
+
*
|
|
90
|
+
* Copyright (c) 2025 CuteWidgets Team. All Rights Reserved.
|
|
91
|
+
*
|
|
92
|
+
* You may not use this file except in compliance with the License
|
|
93
|
+
* that can be found at http://www.apache.org/licenses/LICENSE-2.0
|
|
94
|
+
*/
|
|
95
|
+
class RippleManager {
|
|
96
|
+
static { this._ripples = new WeakMap(); }
|
|
97
|
+
static getInstance(target) {
|
|
98
|
+
return RippleManager.createRipple(target);
|
|
99
|
+
}
|
|
100
|
+
static createRipple(target) {
|
|
101
|
+
if (!target) {
|
|
102
|
+
throw new Error("'target' is required when instantiating a Ripple object");
|
|
103
|
+
}
|
|
104
|
+
let ripple = this._ripples.get(target);
|
|
105
|
+
if (!ripple) {
|
|
106
|
+
ripple = new RippleImpl(target);
|
|
107
|
+
this._ripples.set(target, ripple);
|
|
108
|
+
}
|
|
109
|
+
return ripple;
|
|
110
|
+
}
|
|
111
|
+
static removeRipple(target) {
|
|
112
|
+
if (target) {
|
|
113
|
+
let ripple = this._ripples.get(target);
|
|
114
|
+
if (ripple) {
|
|
115
|
+
ripple.stop();
|
|
116
|
+
}
|
|
117
|
+
this._ripples.delete(target);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
class RippleImpl extends Ripple {
|
|
122
|
+
constructor(target) {
|
|
123
|
+
super(target);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* @license Apache-2.0
|
|
129
|
+
*
|
|
130
|
+
* Copyright (c) 2025 CuteWidgets Team. All Rights Reserved.
|
|
131
|
+
*
|
|
132
|
+
* You may not use this file except in compliance with the License
|
|
133
|
+
* that can be found at http://www.apache.org/licenses/LICENSE-2.0
|
|
134
|
+
*/
|
|
135
|
+
class CuteRipple /* extends ... */ {
|
|
136
|
+
onMouseDown(event) {
|
|
137
|
+
if (this._ripple) {
|
|
138
|
+
this._ripple.launch(event, this.rippleOptions);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
constructor(_elemRef) {
|
|
142
|
+
this._elemRef = _elemRef;
|
|
143
|
+
this._ripple = RippleManager.createRipple(_elemRef.nativeElement);
|
|
144
|
+
}
|
|
145
|
+
ngOnDestroy() {
|
|
146
|
+
RippleManager.removeRipple(this._elemRef.nativeElement);
|
|
147
|
+
}
|
|
148
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CuteRipple /* extends ... */, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
149
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.15", type: CuteRipple /* extends ... */, isStandalone: true, selector: "[cuteRipple]", inputs: { rippleOptions: ["cuteRipple", "rippleOptions"] }, host: { listeners: { "mousedown": "onMouseDown($event)" } }, exportAs: ["cuteRipple"], ngImport: i0 }); }
|
|
150
|
+
}
|
|
151
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CuteRipple /* extends ... */, decorators: [{
|
|
152
|
+
type: Directive,
|
|
153
|
+
args: [{
|
|
154
|
+
selector: '[cuteRipple]',
|
|
155
|
+
exportAs: 'cuteRipple',
|
|
156
|
+
host: {},
|
|
157
|
+
standalone: true,
|
|
158
|
+
}]
|
|
159
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { rippleOptions: [{
|
|
160
|
+
type: Input,
|
|
161
|
+
args: ["cuteRipple"]
|
|
162
|
+
}], onMouseDown: [{
|
|
163
|
+
type: HostListener,
|
|
164
|
+
args: ["mousedown", ['$event']]
|
|
165
|
+
}] } });
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Generated bundle index. Do not edit.
|
|
169
|
+
*/
|
|
170
|
+
|
|
171
|
+
export { CuteRipple, Ripple, RippleManager };
|
|
172
|
+
//# sourceMappingURL=cute-widgets-base-core-ripple.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cute-widgets-base-core-ripple.mjs","sources":["../../../../projects/cute-widgets/base/core/ripple/src/Ripple.ts","../../../../projects/cute-widgets/base/core/ripple/src/RippleManager.ts","../../../../projects/cute-widgets/base/core/ripple/src/ripple.directive.ts","../../../../projects/cute-widgets/base/core/ripple/cute-widgets-base-core-ripple.ts"],"sourcesContent":["/**\r\n * @license Apache-2.0\r\n *\r\n * Copyright (c) 2025 CuteWidgets Team. All Rights Reserved.\r\n *\r\n * You may not use this file except in compliance with the License\r\n * that can be found at http://www.apache.org/licenses/LICENSE-2.0\r\n */\r\n\r\nimport {computed, signal} from \"@angular/core\";\r\nimport {firstValueFrom, fromEvent} from \"rxjs\";\r\nimport {take} from \"rxjs/operators\";\r\n\r\nconst RIPPLE_CLASS_NAME = \"cute-ripple-element\";\r\n\r\nexport type RippleOptions = {centered?: boolean, color?: string|null, duration?: string|number};\r\n\r\nexport abstract class Ripple {\r\n private _active = signal<boolean>(false);\r\n private _disabled: boolean = false;\r\n private readonly _target: HTMLElement | undefined;\r\n\r\n protected constructor(target: HTMLElement) {\r\n this._target = target;\r\n }\r\n\r\n get disabled(): boolean {return this._disabled}\r\n set disabled(v: boolean) {this._disabled = v;}\r\n\r\n isActive = computed(() => this._active());\r\n\r\n stop(): void {\r\n if (this._target) {\r\n const existingRipple = this._target.getElementsByClassName(RIPPLE_CLASS_NAME)[0];\r\n if (existingRipple) {\r\n existingRipple.parentElement?.remove();\r\n }\r\n }\r\n this._active.set(false);\r\n }\r\n\r\n launch(event: MouseEvent, options?: RippleOptions): void {\r\n\r\n if (this.disabled) {\r\n return;\r\n }\r\n\r\n if (this.isActive()) {\r\n this.stop();\r\n }\r\n\r\n if (this._target && event) {\r\n const rect = this._target.getBoundingClientRect();\r\n\r\n const parent = document.createElement(\"div\");\r\n parent.style.position = \"absolute\";\r\n parent.style.top = \"0\";\r\n parent.style.right = \"0\";\r\n parent.style.bottom = \"0\";\r\n parent.style.left = \"0\";\r\n parent.style.overflow = \"hidden\";\r\n parent.style.borderRadius = \"inherit\";\r\n parent.style.transform = \"perspective(0)\";\r\n parent.ariaHidden = \"true\";\r\n parent.classList.add(\"cute-ripple\")\r\n\r\n const circle = document.createElement(\"span\");\r\n const diameter = Math.max(rect.width, rect.height);\r\n const radius = diameter/2;\r\n\r\n circle.style.width = circle.style.height = `${diameter}px`;\r\n if (options?.centered) {\r\n circle.style.left = `${rect.width / 2 - radius}px`;\r\n circle.style.top = `${rect.height / 2 - radius}px`;\r\n } else {\r\n circle.style.left = `${event.clientX - rect.left - radius}px`;\r\n circle.style.top = `${event.clientY - rect.top - radius}px`;\r\n }\r\n if (options?.color) {\r\n circle.style.setProperty(\"--cute-ripple-bg-color\", options.color);\r\n }\r\n if (options?.duration) {\r\n circle.style.setProperty(\"--cute-ripple-duration\", String(options.duration));\r\n }\r\n circle.classList.add(RIPPLE_CLASS_NAME);\r\n\r\n parent.appendChild(circle);\r\n this._target.appendChild(parent);\r\n\r\n this._active.set(true);\r\n\r\n Promise.any([\r\n firstValueFrom(fromEvent(circle, \"animationend\").pipe(take(1))),\r\n firstValueFrom(fromEvent(circle, \"animationcancel\").pipe(take(1))),\r\n //firstValueFrom(fromEvent(document, \"mouseup\").pipe(take(1))),\r\n ]).then(() => {\r\n circle.parentElement?.remove();\r\n this._active.set(false);\r\n })\r\n\r\n }\r\n }\r\n\r\n}\r\n","/**\r\n * @license Apache-2.0\r\n *\r\n * Copyright (c) 2025 CuteWidgets Team. All Rights Reserved.\r\n *\r\n * You may not use this file except in compliance with the License\r\n * that can be found at http://www.apache.org/licenses/LICENSE-2.0\r\n */\r\nimport {Ripple} from \"./Ripple\";\r\n\r\nexport class RippleManager {\r\n private static readonly _ripples = new WeakMap<HTMLElement, Ripple>();\r\n\r\n\r\n static getInstance(target: HTMLElement): Ripple {\r\n return RippleManager.createRipple(target);\r\n }\r\n\r\n static createRipple(target: HTMLElement): Ripple {\r\n\r\n if (!target) {\r\n throw new Error(\"'target' is required when instantiating a Ripple object\")\r\n }\r\n let ripple = this._ripples.get(target);\r\n if (!ripple) {\r\n ripple = new RippleImpl(target);\r\n this._ripples.set(target, ripple);\r\n }\r\n return ripple;\r\n }\r\n\r\n static removeRipple(target: HTMLElement) {\r\n if (target) {\r\n let ripple = this._ripples.get(target);\r\n if (ripple) {\r\n ripple.stop();\r\n }\r\n this._ripples.delete(target);\r\n }\r\n }\r\n}\r\n\r\nclass RippleImpl extends Ripple {\r\n constructor(target: HTMLElement) {\r\n super(target);\r\n }\r\n}\r\n","/**\r\n * @license Apache-2.0\r\n *\r\n * Copyright (c) 2025 CuteWidgets Team. All Rights Reserved.\r\n *\r\n * You may not use this file except in compliance with the License\r\n * that can be found at http://www.apache.org/licenses/LICENSE-2.0\r\n */\r\nimport {Directive, ElementRef, HostListener, Input, OnDestroy} from \"@angular/core\";\r\nimport {Ripple, RippleOptions} from \"./Ripple\";\r\nimport {RippleManager} from \"./RippleManager\";\r\n\r\n@Directive({\r\n selector: '[cuteRipple]',\r\n exportAs: 'cuteRipple',\r\n host: {},\r\n standalone: true,\r\n})\r\nexport class CuteRipple /* extends ... */ implements OnDestroy {\r\n private readonly _ripple: Ripple | undefined;\r\n\r\n @Input(\"cuteRipple\")\r\n rippleOptions: RippleOptions | undefined;\r\n\r\n @HostListener(\"mousedown\", ['$event'])\r\n protected onMouseDown(event: MouseEvent) {\r\n if (this._ripple) {\r\n this._ripple.launch(event, this.rippleOptions);\r\n }\r\n }\r\n\r\n constructor(private _elemRef: ElementRef<HTMLElement>) {\r\n this._ripple = RippleManager.createRipple(_elemRef.nativeElement);\r\n }\r\n\r\n ngOnDestroy() {\r\n RippleManager.removeRipple(this._elemRef.nativeElement);\r\n }\r\n\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { By } from '@angular/platform-browser';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Spec helpers for working with the DOM
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Returns a selector for the `data-testid` attribute with the given attribute value.
|
|
8
|
+
*
|
|
9
|
+
* @param testId Test id set by `data-testid`
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
function testIdSelector(testId) {
|
|
13
|
+
return `[data-testid="${testId}"]`;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Finds a single element inside the Component by the given CSS selector.
|
|
17
|
+
* Throws an error if no element was found.
|
|
18
|
+
*
|
|
19
|
+
* @param fixture Component fixture
|
|
20
|
+
* @param selector CSS selector
|
|
21
|
+
*
|
|
22
|
+
*/
|
|
23
|
+
function queryByCss(fixture, selector) {
|
|
24
|
+
// The return type of DebugElement#query() is declared as DebugElement,
|
|
25
|
+
// but the actual return type is DebugElement | null.
|
|
26
|
+
// See https://github.com/angular/angular/issues/22449.
|
|
27
|
+
const debugElement = fixture.debugElement.query(By.css(selector));
|
|
28
|
+
// Fail on null so the return type is always DebugElement.
|
|
29
|
+
if (!debugElement) {
|
|
30
|
+
throw new Error(`queryByCss: Element with ${selector} not found`);
|
|
31
|
+
}
|
|
32
|
+
return debugElement;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Finds an element inside the Component by the given `data-testid` attribute.
|
|
36
|
+
* Throws an error if no element was found.
|
|
37
|
+
*
|
|
38
|
+
* @param fixture Component fixture
|
|
39
|
+
* @param testId Test id set by `data-testid`
|
|
40
|
+
*
|
|
41
|
+
*/
|
|
42
|
+
function findEl(fixture, testId) {
|
|
43
|
+
return queryByCss(fixture, testIdSelector(testId));
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Finds all elements with the given `data-testid` attribute.
|
|
47
|
+
*
|
|
48
|
+
* @param fixture Component fixture
|
|
49
|
+
* @param testId Test id set by `data-testid`
|
|
50
|
+
*/
|
|
51
|
+
function findEls(fixture, testId) {
|
|
52
|
+
return fixture.debugElement.queryAll(By.css(testIdSelector(testId)));
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Gets the text content of an element with the given `data-testid` attribute.
|
|
56
|
+
*
|
|
57
|
+
* @param fixture Component fixture
|
|
58
|
+
* @param testId Test id set by `data-testid`
|
|
59
|
+
*/
|
|
60
|
+
function getText(fixture, testId) {
|
|
61
|
+
return findEl(fixture, testId).nativeElement.textContent;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Expects that the element with the given `data-testid` attribute
|
|
65
|
+
* has the given text content.
|
|
66
|
+
*
|
|
67
|
+
* @param fixture Component fixture
|
|
68
|
+
* @param testId Test id set by `data-testid`
|
|
69
|
+
* @param text Expected text
|
|
70
|
+
*/
|
|
71
|
+
function expectText(fixture, testId, text) {
|
|
72
|
+
expect(getText(fixture, testId)).toBe(text);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Expects that the element with the given `data-testid` attribute
|
|
76
|
+
* has the given text content.
|
|
77
|
+
*
|
|
78
|
+
* @param fixture Component fixture
|
|
79
|
+
* @param text Expected text
|
|
80
|
+
*/
|
|
81
|
+
function expectContainedText(fixture, text) {
|
|
82
|
+
expect(fixture.nativeElement.textContent).toContain(text);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Expects that a component has the given text content.
|
|
86
|
+
* Both the component text content and the expected text are trimmed for reliability.
|
|
87
|
+
*
|
|
88
|
+
* @param fixture Component fixture
|
|
89
|
+
* @param text Expected text
|
|
90
|
+
*/
|
|
91
|
+
function expectContent(fixture, text) {
|
|
92
|
+
expect(fixture.nativeElement.textContent).toBe(text);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Dispatches a fake event (synthetic event) at the given element.
|
|
96
|
+
*
|
|
97
|
+
* @param element Element that is the target of the event
|
|
98
|
+
* @param type Event name, e.g. `input`
|
|
99
|
+
* @param bubbles Whether the event bubbles up in the DOM tree
|
|
100
|
+
*/
|
|
101
|
+
function dispatchFakeEvent(element, type, bubbles = false) {
|
|
102
|
+
//const event = document.createEvent('Event');
|
|
103
|
+
//event.initEvent(type, bubbles, false);
|
|
104
|
+
const event = new Event(type, { bubbles, cancelable: false });
|
|
105
|
+
element.dispatchEvent(event);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Enters text into a form field (`input`, `textarea` or `select` element).
|
|
109
|
+
* Triggers appropriate events so Angular takes notice of the change.
|
|
110
|
+
* If you listen for the `change` event on `input` or `textarea`,
|
|
111
|
+
* you need to trigger it separately.
|
|
112
|
+
*
|
|
113
|
+
* @param element Form field
|
|
114
|
+
* @param value Form field value
|
|
115
|
+
*/
|
|
116
|
+
function setFieldElementValue(element, value) {
|
|
117
|
+
element.value = value;
|
|
118
|
+
// Dispatch an `input` or `change` fake event
|
|
119
|
+
// so Angular form bindings take notice of the change.
|
|
120
|
+
const isSelect = element instanceof HTMLSelectElement;
|
|
121
|
+
dispatchFakeEvent(element, isSelect ? 'change' : 'input', isSelect ? false : true);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Sets the value of a form field with the given `data-testid` attribute.
|
|
125
|
+
*
|
|
126
|
+
* @param fixture Component fixture
|
|
127
|
+
* @param testId Test id set by `data-testid`
|
|
128
|
+
* @param value Form field value
|
|
129
|
+
*/
|
|
130
|
+
function setFieldValue(fixture, testId, value) {
|
|
131
|
+
setFieldElementValue(findEl(fixture, testId).nativeElement, value);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Checks or unchecks a checkbox or radio button.
|
|
135
|
+
* Triggers appropriate events so Angular takes notice of the change.
|
|
136
|
+
*
|
|
137
|
+
* @param fixture Component fixture
|
|
138
|
+
* @param testId Test id set by `data-testid`
|
|
139
|
+
* @param checked Whether the checkbox or radio should be checked
|
|
140
|
+
*/
|
|
141
|
+
function checkField(fixture, testId, checked) {
|
|
142
|
+
const { nativeElement } = findEl(fixture, testId);
|
|
143
|
+
nativeElement.checked = checked;
|
|
144
|
+
// Dispatch a `change` fake event so Angular form bindings take notice of the change.
|
|
145
|
+
dispatchFakeEvent(nativeElement, 'change');
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Makes a fake click event that provides the most important properties.
|
|
149
|
+
* The event can be passed to DebugElement#triggerEventHandler.
|
|
150
|
+
*
|
|
151
|
+
* @param target Element that is the target of the click event
|
|
152
|
+
* @param button (Optional) Button number. Default is Left-Button.
|
|
153
|
+
*/
|
|
154
|
+
function makeClickEvent(target, button = 0) {
|
|
155
|
+
return {
|
|
156
|
+
preventDefault() { },
|
|
157
|
+
stopPropagation() { },
|
|
158
|
+
stopImmediatePropagation() { },
|
|
159
|
+
type: 'click',
|
|
160
|
+
target,
|
|
161
|
+
currentTarget: target,
|
|
162
|
+
bubbles: true,
|
|
163
|
+
cancelable: true,
|
|
164
|
+
button,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
/** Button events to pass to `DebugElement.triggerEventHandler` */
|
|
168
|
+
const ButtonClickEvents = {
|
|
169
|
+
left: { button: 0 },
|
|
170
|
+
right: { button: 2 },
|
|
171
|
+
};
|
|
172
|
+
/**
|
|
173
|
+
* Emulates a mouse click event on the target element.
|
|
174
|
+
*
|
|
175
|
+
* @param elem Element target
|
|
176
|
+
* @param eventObj (Optional) MouseEvent object. Default is Left-Button click.
|
|
177
|
+
*/
|
|
178
|
+
function click(elem, eventObj = ButtonClickEvents.left) {
|
|
179
|
+
if (elem instanceof HTMLElement) {
|
|
180
|
+
elem.click();
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
elem.triggerEventHandler('click', eventObj);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Finds a nested Component by its selector, e.g. `app-example`.
|
|
188
|
+
* Throws an error if no element was found.
|
|
189
|
+
* Use this only for shallow component testing.
|
|
190
|
+
* When finding other elements, use `findEl` / `findEls` and `data-testid` attributes.
|
|
191
|
+
*
|
|
192
|
+
* @param fixture Fixture of the parent Component
|
|
193
|
+
* @param selector Element selector, e.g. `app-example`
|
|
194
|
+
*/
|
|
195
|
+
function findComponent(fixture, selector) {
|
|
196
|
+
return queryByCss(fixture, selector);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Finds all nested Components by its selector, e.g. `app-example`.
|
|
200
|
+
*/
|
|
201
|
+
function findComponents(fixture, selector) {
|
|
202
|
+
return fixture.debugElement.queryAll(By.css(selector));
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Generated bundle index. Do not edit.
|
|
207
|
+
*/
|
|
208
|
+
|
|
209
|
+
export { ButtonClickEvents, checkField, click, dispatchFakeEvent, expectContainedText, expectContent, expectText, findComponent, findComponents, findEl, findEls, getText, makeClickEvent, queryByCss, setFieldElementValue, setFieldValue, testIdSelector };
|
|
210
|
+
//# sourceMappingURL=cute-widgets-base-core-testing.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cute-widgets-base-core-testing.mjs","sources":["../../../../projects/cute-widgets/base/core/testing/src/dom-helpers.ts","../../../../projects/cute-widgets/base/core/testing/cute-widgets-base-core-testing.ts"],"sourcesContent":["/**\r\n * @license Apache-2.0\r\n *\r\n * Copyright (c) 2025 CuteWidgets Team. All Rights Reserved.\r\n *\r\n * You may not use this file except in compliance with the License\r\n * that can be found at http://www.apache.org/licenses/LICENSE-2.0\r\n */\r\nimport { DebugElement } from '@angular/core';\r\nimport { ComponentFixture } from '@angular/core/testing';\r\nimport { By } from '@angular/platform-browser';\r\n\r\ndeclare function expect<T=any>(spy: T): any;\r\n\r\n/**\r\n * Spec helpers for working with the DOM\r\n */\r\n\r\n/**\r\n * Returns a selector for the `data-testid` attribute with the given attribute value.\r\n *\r\n * @param testId Test id set by `data-testid`\r\n *\r\n */\r\nexport function testIdSelector(testId: string): string {\r\n return `[data-testid=\"${testId}\"]`;\r\n}\r\n\r\n/**\r\n * Finds a single element inside the Component by the given CSS selector.\r\n * Throws an error if no element was found.\r\n *\r\n * @param fixture Component fixture\r\n * @param selector CSS selector\r\n *\r\n */\r\nexport function queryByCss<T>(\r\n fixture: ComponentFixture<T>,\r\n selector: string,\r\n): DebugElement {\r\n // The return type of DebugElement#query() is declared as DebugElement,\r\n // but the actual return type is DebugElement | null.\r\n // See https://github.com/angular/angular/issues/22449.\r\n const debugElement = fixture.debugElement.query(By.css(selector));\r\n // Fail on null so the return type is always DebugElement.\r\n if (!debugElement) {\r\n throw new Error(`queryByCss: Element with ${selector} not found`);\r\n }\r\n return debugElement;\r\n}\r\n\r\n/**\r\n * Finds an element inside the Component by the given `data-testid` attribute.\r\n * Throws an error if no element was found.\r\n *\r\n * @param fixture Component fixture\r\n * @param testId Test id set by `data-testid`\r\n *\r\n */\r\nexport function findEl<T>(fixture: ComponentFixture<T>, testId: string): DebugElement {\r\n return queryByCss<T>(fixture, testIdSelector(testId));\r\n}\r\n\r\n/**\r\n * Finds all elements with the given `data-testid` attribute.\r\n *\r\n * @param fixture Component fixture\r\n * @param testId Test id set by `data-testid`\r\n */\r\nexport function findEls<T>(fixture: ComponentFixture<T>, testId: string): DebugElement[] {\r\n return fixture.debugElement.queryAll(By.css(testIdSelector(testId)));\r\n}\r\n\r\n/**\r\n * Gets the text content of an element with the given `data-testid` attribute.\r\n *\r\n * @param fixture Component fixture\r\n * @param testId Test id set by `data-testid`\r\n */\r\nexport function getText<T>(fixture: ComponentFixture<T>, testId: string): string {\r\n return findEl(fixture, testId).nativeElement.textContent;\r\n}\r\n\r\n/**\r\n * Expects that the element with the given `data-testid` attribute\r\n * has the given text content.\r\n *\r\n * @param fixture Component fixture\r\n * @param testId Test id set by `data-testid`\r\n * @param text Expected text\r\n */\r\nexport function expectText<T>(\r\n fixture: ComponentFixture<T>,\r\n testId: string,\r\n text: string,\r\n): void {\r\n expect(getText(fixture, testId)).toBe(text);\r\n}\r\n\r\n/**\r\n * Expects that the element with the given `data-testid` attribute\r\n * has the given text content.\r\n *\r\n * @param fixture Component fixture\r\n * @param text Expected text\r\n */\r\nexport function expectContainedText<T>(fixture: ComponentFixture<T>, text: string): void {\r\n expect(fixture.nativeElement.textContent).toContain(text);\r\n}\r\n\r\n/**\r\n * Expects that a component has the given text content.\r\n * Both the component text content and the expected text are trimmed for reliability.\r\n *\r\n * @param fixture Component fixture\r\n * @param text Expected text\r\n */\r\nexport function expectContent<T>(fixture: ComponentFixture<T>, text: string): void {\r\n expect(fixture.nativeElement.textContent).toBe(text);\r\n}\r\n\r\n/**\r\n * Dispatches a fake event (synthetic event) at the given element.\r\n *\r\n * @param element Element that is the target of the event\r\n * @param type Event name, e.g. `input`\r\n * @param bubbles Whether the event bubbles up in the DOM tree\r\n */\r\nexport function dispatchFakeEvent(\r\n element: EventTarget,\r\n type: string,\r\n bubbles: boolean = false,\r\n): void {\r\n //const event = document.createEvent('Event');\r\n //event.initEvent(type, bubbles, false);\r\n const event = new Event(type, {bubbles, cancelable: false});\r\n element.dispatchEvent(event);\r\n}\r\n\r\n/**\r\n * Enters text into a form field (`input`, `textarea` or `select` element).\r\n * Triggers appropriate events so Angular takes notice of the change.\r\n * If you listen for the `change` event on `input` or `textarea`,\r\n * you need to trigger it separately.\r\n *\r\n * @param element Form field\r\n * @param value Form field value\r\n */\r\nexport function setFieldElementValue(\r\n element: HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement,\r\n value: string,\r\n): void {\r\n element.value = value;\r\n // Dispatch an `input` or `change` fake event\r\n // so Angular form bindings take notice of the change.\r\n const isSelect = element instanceof HTMLSelectElement;\r\n dispatchFakeEvent(element, isSelect ? 'change' : 'input', isSelect ? false : true);\r\n}\r\n\r\n/**\r\n * Sets the value of a form field with the given `data-testid` attribute.\r\n *\r\n * @param fixture Component fixture\r\n * @param testId Test id set by `data-testid`\r\n * @param value Form field value\r\n */\r\nexport function setFieldValue<T>(\r\n fixture: ComponentFixture<T>,\r\n testId: string,\r\n value: string,\r\n): void {\r\n setFieldElementValue(findEl(fixture, testId).nativeElement, value);\r\n}\r\n\r\n/**\r\n * Checks or unchecks a checkbox or radio button.\r\n * Triggers appropriate events so Angular takes notice of the change.\r\n *\r\n * @param fixture Component fixture\r\n * @param testId Test id set by `data-testid`\r\n * @param checked Whether the checkbox or radio should be checked\r\n */\r\nexport function checkField<T>(\r\n fixture: ComponentFixture<T>,\r\n testId: string,\r\n checked: boolean,\r\n): void {\r\n const { nativeElement } = findEl(fixture, testId);\r\n nativeElement.checked = checked;\r\n // Dispatch a `change` fake event so Angular form bindings take notice of the change.\r\n dispatchFakeEvent(nativeElement, 'change');\r\n}\r\n\r\n/**\r\n * Makes a fake click event that provides the most important properties.\r\n * The event can be passed to DebugElement#triggerEventHandler.\r\n *\r\n * @param target Element that is the target of the click event\r\n * @param button (Optional) Button number. Default is Left-Button.\r\n */\r\nexport function makeClickEvent(target: EventTarget, button: number = 0): Partial<MouseEvent> {\r\n return {\r\n preventDefault(): void {},\r\n stopPropagation(): void {},\r\n stopImmediatePropagation(): void {},\r\n type: 'click',\r\n target,\r\n currentTarget: target,\r\n bubbles: true,\r\n cancelable: true,\r\n button,\r\n };\r\n}\r\n\r\n/** Button events to pass to `DebugElement.triggerEventHandler` */\r\nexport const ButtonClickEvents = {\r\n left: {button: 0},\r\n right: {button: 2},\r\n}\r\n\r\n/**\r\n * Emulates a mouse click event on the target element.\r\n *\r\n * @param elem Element target\r\n * @param eventObj (Optional) MouseEvent object. Default is Left-Button click.\r\n */\r\nexport function click(elem: DebugElement | HTMLElement, eventObj: Partial<MouseEvent> = ButtonClickEvents.left): void {\r\n if (elem instanceof HTMLElement) {\r\n elem.click();\r\n } else {\r\n elem.triggerEventHandler('click', eventObj);\r\n }\r\n}\r\n\r\n/**\r\n * Finds a nested Component by its selector, e.g. `app-example`.\r\n * Throws an error if no element was found.\r\n * Use this only for shallow component testing.\r\n * When finding other elements, use `findEl` / `findEls` and `data-testid` attributes.\r\n *\r\n * @param fixture Fixture of the parent Component\r\n * @param selector Element selector, e.g. `app-example`\r\n */\r\nexport function findComponent<T>(\r\n fixture: ComponentFixture<T>,\r\n selector: string,\r\n): DebugElement {\r\n return queryByCss(fixture, selector);\r\n}\r\n\r\n/**\r\n * Finds all nested Components by its selector, e.g. `app-example`.\r\n */\r\nexport function findComponents<T>(\r\n fixture: ComponentFixture<T>,\r\n selector: string,\r\n): DebugElement[] {\r\n return fixture.debugElement.queryAll(By.css(selector));\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|