@ngneers/controls 0.0.1-next.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.
- package/fesm2022/ngneers-controls-accordion.mjs +234 -0
- package/fesm2022/ngneers-controls-accordion.mjs.map +1 -0
- package/fesm2022/ngneers-controls-api-ng.mjs +959 -0
- package/fesm2022/ngneers-controls-api-ng.mjs.map +1 -0
- package/fesm2022/ngneers-controls-api-resize.mjs +712 -0
- package/fesm2022/ngneers-controls-api-resize.mjs.map +1 -0
- package/fesm2022/ngneers-controls-api.mjs +347 -0
- package/fesm2022/ngneers-controls-api.mjs.map +1 -0
- package/fesm2022/ngneers-controls-avatar.mjs +77 -0
- package/fesm2022/ngneers-controls-avatar.mjs.map +1 -0
- package/fesm2022/ngneers-controls-base.mjs +620 -0
- package/fesm2022/ngneers-controls-base.mjs.map +1 -0
- package/fesm2022/ngneers-controls-breadcrumb.mjs +100 -0
- package/fesm2022/ngneers-controls-breadcrumb.mjs.map +1 -0
- package/fesm2022/ngneers-controls-button-group.mjs +110 -0
- package/fesm2022/ngneers-controls-button-group.mjs.map +1 -0
- package/fesm2022/ngneers-controls-button.mjs +83 -0
- package/fesm2022/ngneers-controls-button.mjs.map +1 -0
- package/fesm2022/ngneers-controls-calendar-time-CJT5AFlA.mjs +74 -0
- package/fesm2022/ngneers-controls-calendar-time-CJT5AFlA.mjs.map +1 -0
- package/fesm2022/ngneers-controls-calendar.mjs +801 -0
- package/fesm2022/ngneers-controls-calendar.mjs.map +1 -0
- package/fesm2022/ngneers-controls-checkbox.mjs +63 -0
- package/fesm2022/ngneers-controls-checkbox.mjs.map +1 -0
- package/fesm2022/ngneers-controls-chip.mjs +55 -0
- package/fesm2022/ngneers-controls-chip.mjs.map +1 -0
- package/fesm2022/ngneers-controls-default-icons.mjs +82 -0
- package/fesm2022/ngneers-controls-default-icons.mjs.map +1 -0
- package/fesm2022/ngneers-controls-defer.mjs +72 -0
- package/fesm2022/ngneers-controls-defer.mjs.map +1 -0
- package/fesm2022/ngneers-controls-dialog.mjs +407 -0
- package/fesm2022/ngneers-controls-dialog.mjs.map +1 -0
- package/fesm2022/ngneers-controls-directives.mjs +498 -0
- package/fesm2022/ngneers-controls-directives.mjs.map +1 -0
- package/fesm2022/ngneers-controls-drawer.mjs +271 -0
- package/fesm2022/ngneers-controls-drawer.mjs.map +1 -0
- package/fesm2022/ngneers-controls-edit-inplace.mjs +127 -0
- package/fesm2022/ngneers-controls-edit-inplace.mjs.map +1 -0
- package/fesm2022/ngneers-controls-errors.mjs +329 -0
- package/fesm2022/ngneers-controls-errors.mjs.map +1 -0
- package/fesm2022/ngneers-controls-filter.mjs +708 -0
- package/fesm2022/ngneers-controls-filter.mjs.map +1 -0
- package/fesm2022/ngneers-controls-hint.mjs +153 -0
- package/fesm2022/ngneers-controls-hint.mjs.map +1 -0
- package/fesm2022/ngneers-controls-i18n-translations-de.mjs +170 -0
- package/fesm2022/ngneers-controls-i18n-translations-de.mjs.map +1 -0
- package/fesm2022/ngneers-controls-i18n-translations-en.mjs +170 -0
- package/fesm2022/ngneers-controls-i18n-translations-en.mjs.map +1 -0
- package/fesm2022/ngneers-controls-i18n.mjs +57 -0
- package/fesm2022/ngneers-controls-i18n.mjs.map +1 -0
- package/fesm2022/ngneers-controls-icon.mjs +195 -0
- package/fesm2022/ngneers-controls-icon.mjs.map +1 -0
- package/fesm2022/ngneers-controls-inplace.mjs +150 -0
- package/fesm2022/ngneers-controls-inplace.mjs.map +1 -0
- package/fesm2022/ngneers-controls-input-field.mjs +165 -0
- package/fesm2022/ngneers-controls-input-field.mjs.map +1 -0
- package/fesm2022/ngneers-controls-input.mjs +72 -0
- package/fesm2022/ngneers-controls-input.mjs.map +1 -0
- package/fesm2022/ngneers-controls-item-view.mjs +473 -0
- package/fesm2022/ngneers-controls-item-view.mjs.map +1 -0
- package/fesm2022/ngneers-controls-list-box.mjs +281 -0
- package/fesm2022/ngneers-controls-list-box.mjs.map +1 -0
- package/fesm2022/ngneers-controls-mask-input.mjs +888 -0
- package/fesm2022/ngneers-controls-mask-input.mjs.map +1 -0
- package/fesm2022/ngneers-controls-menu.mjs +371 -0
- package/fesm2022/ngneers-controls-menu.mjs.map +1 -0
- package/fesm2022/ngneers-controls-message.mjs +30 -0
- package/fesm2022/ngneers-controls-message.mjs.map +1 -0
- package/fesm2022/ngneers-controls-number-input.mjs +366 -0
- package/fesm2022/ngneers-controls-number-input.mjs.map +1 -0
- package/fesm2022/ngneers-controls-paginator.mjs +129 -0
- package/fesm2022/ngneers-controls-paginator.mjs.map +1 -0
- package/fesm2022/ngneers-controls-popover.mjs +215 -0
- package/fesm2022/ngneers-controls-popover.mjs.map +1 -0
- package/fesm2022/ngneers-controls-progress.mjs +98 -0
- package/fesm2022/ngneers-controls-progress.mjs.map +1 -0
- package/fesm2022/ngneers-controls-radio.mjs +152 -0
- package/fesm2022/ngneers-controls-radio.mjs.map +1 -0
- package/fesm2022/ngneers-controls-roving-focus.mjs +323 -0
- package/fesm2022/ngneers-controls-roving-focus.mjs.map +1 -0
- package/fesm2022/ngneers-controls-scroll-shadow.mjs +65 -0
- package/fesm2022/ngneers-controls-scroll-shadow.mjs.map +1 -0
- package/fesm2022/ngneers-controls-scroller.mjs +308 -0
- package/fesm2022/ngneers-controls-scroller.mjs.map +1 -0
- package/fesm2022/ngneers-controls-select-button.mjs +58 -0
- package/fesm2022/ngneers-controls-select-button.mjs.map +1 -0
- package/fesm2022/ngneers-controls-select.mjs +417 -0
- package/fesm2022/ngneers-controls-select.mjs.map +1 -0
- package/fesm2022/ngneers-controls-slider.mjs +167 -0
- package/fesm2022/ngneers-controls-slider.mjs.map +1 -0
- package/fesm2022/ngneers-controls-snackbar.mjs +414 -0
- package/fesm2022/ngneers-controls-snackbar.mjs.map +1 -0
- package/fesm2022/ngneers-controls-spin-buttons.mjs +126 -0
- package/fesm2022/ngneers-controls-spin-buttons.mjs.map +1 -0
- package/fesm2022/ngneers-controls-spinner.mjs +184 -0
- package/fesm2022/ngneers-controls-spinner.mjs.map +1 -0
- package/fesm2022/ngneers-controls-splitter.mjs +604 -0
- package/fesm2022/ngneers-controls-splitter.mjs.map +1 -0
- package/fesm2022/ngneers-controls-state.mjs +185 -0
- package/fesm2022/ngneers-controls-state.mjs.map +1 -0
- package/fesm2022/ngneers-controls-switch.mjs +39 -0
- package/fesm2022/ngneers-controls-switch.mjs.map +1 -0
- package/fesm2022/ngneers-controls-table.mjs +2634 -0
- package/fesm2022/ngneers-controls-table.mjs.map +1 -0
- package/fesm2022/ngneers-controls-tabs.mjs +336 -0
- package/fesm2022/ngneers-controls-tabs.mjs.map +1 -0
- package/fesm2022/ngneers-controls-tag.mjs +30 -0
- package/fesm2022/ngneers-controls-tag.mjs.map +1 -0
- package/fesm2022/ngneers-controls-toast.mjs +350 -0
- package/fesm2022/ngneers-controls-toast.mjs.map +1 -0
- package/fesm2022/ngneers-controls-toggle-button.mjs +70 -0
- package/fesm2022/ngneers-controls-toggle-button.mjs.map +1 -0
- package/fesm2022/ngneers-controls-tooltip.mjs +506 -0
- package/fesm2022/ngneers-controls-tooltip.mjs.map +1 -0
- package/fesm2022/ngneers-controls-tree.mjs +599 -0
- package/fesm2022/ngneers-controls-tree.mjs.map +1 -0
- package/fesm2022/ngneers-controls-upload.mjs +377 -0
- package/fesm2022/ngneers-controls-upload.mjs.map +1 -0
- package/fesm2022/ngneers-controls-utils-ng.mjs +411 -0
- package/fesm2022/ngneers-controls-utils-ng.mjs.map +1 -0
- package/fesm2022/ngneers-controls-utils.mjs +261 -0
- package/fesm2022/ngneers-controls-utils.mjs.map +1 -0
- package/fesm2022/ngneers-controls.mjs +6 -0
- package/fesm2022/ngneers-controls.mjs.map +1 -0
- package/package.json +302 -0
- package/types/ngneers-controls-accordion.d.ts +139 -0
- package/types/ngneers-controls-api-ng.d.ts +364 -0
- package/types/ngneers-controls-api-resize.d.ts +318 -0
- package/types/ngneers-controls-api.d.ts +145 -0
- package/types/ngneers-controls-avatar.d.ts +54 -0
- package/types/ngneers-controls-base.d.ts +277 -0
- package/types/ngneers-controls-breadcrumb.d.ts +272 -0
- package/types/ngneers-controls-button-group.d.ts +46 -0
- package/types/ngneers-controls-button.d.ts +48 -0
- package/types/ngneers-controls-calendar.d.ts +466 -0
- package/types/ngneers-controls-checkbox.d.ts +40 -0
- package/types/ngneers-controls-chip.d.ts +202 -0
- package/types/ngneers-controls-default-icons.d.ts +5 -0
- package/types/ngneers-controls-defer.d.ts +48 -0
- package/types/ngneers-controls-dialog.d.ts +399 -0
- package/types/ngneers-controls-directives.d.ts +171 -0
- package/types/ngneers-controls-drawer.d.ts +308 -0
- package/types/ngneers-controls-edit-inplace.d.ts +263 -0
- package/types/ngneers-controls-errors.d.ts +155 -0
- package/types/ngneers-controls-filter.d.ts +609 -0
- package/types/ngneers-controls-hint.d.ts +88 -0
- package/types/ngneers-controls-i18n-translations-de.d.ts +164 -0
- package/types/ngneers-controls-i18n-translations-en.d.ts +164 -0
- package/types/ngneers-controls-i18n.d.ts +186 -0
- package/types/ngneers-controls-icon.d.ts +68 -0
- package/types/ngneers-controls-inplace.d.ts +98 -0
- package/types/ngneers-controls-input-field.d.ts +248 -0
- package/types/ngneers-controls-input.d.ts +30 -0
- package/types/ngneers-controls-item-view.d.ts +215 -0
- package/types/ngneers-controls-list-box.d.ts +334 -0
- package/types/ngneers-controls-mask-input.d.ts +434 -0
- package/types/ngneers-controls-menu.d.ts +192 -0
- package/types/ngneers-controls-message.d.ts +21 -0
- package/types/ngneers-controls-number-input.d.ts +146 -0
- package/types/ngneers-controls-paginator.d.ts +255 -0
- package/types/ngneers-controls-popover.d.ts +116 -0
- package/types/ngneers-controls-progress.d.ts +49 -0
- package/types/ngneers-controls-radio.d.ts +91 -0
- package/types/ngneers-controls-roving-focus.d.ts +107 -0
- package/types/ngneers-controls-scroll-shadow.d.ts +25 -0
- package/types/ngneers-controls-scroller.d.ts +151 -0
- package/types/ngneers-controls-select-button.d.ts +51 -0
- package/types/ngneers-controls-select.d.ts +409 -0
- package/types/ngneers-controls-slider.d.ts +57 -0
- package/types/ngneers-controls-snackbar.d.ts +330 -0
- package/types/ngneers-controls-spin-buttons.d.ts +69 -0
- package/types/ngneers-controls-spinner.d.ts +117 -0
- package/types/ngneers-controls-splitter.d.ts +465 -0
- package/types/ngneers-controls-state.d.ts +102 -0
- package/types/ngneers-controls-switch.d.ts +18 -0
- package/types/ngneers-controls-table.d.ts +3127 -0
- package/types/ngneers-controls-tabs.d.ts +118 -0
- package/types/ngneers-controls-tag.d.ts +21 -0
- package/types/ngneers-controls-toast.d.ts +298 -0
- package/types/ngneers-controls-toggle-button.d.ts +48 -0
- package/types/ngneers-controls-tooltip.d.ts +189 -0
- package/types/ngneers-controls-tree.d.ts +409 -0
- package/types/ngneers-controls-upload.d.ts +347 -0
- package/types/ngneers-controls-utils-ng.d.ts +129 -0
- package/types/ngneers-controls-utils.d.ts +130 -0
- package/types/ngneers-controls.d.ts +2 -0
|
@@ -0,0 +1,620 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, DestroyRef, signal, afterNextRender, InjectionToken, forwardRef, ElementRef, Injector, input, booleanAttribute, computed, viewChildren, effect, Directive, isDevMode, model } from '@angular/core';
|
|
3
|
+
import { setInputSignalValue, effectWithPrevious, classSignal, generateElementId } from '@ngneers/controls/utils-ng';
|
|
4
|
+
import { Platform, injectThemeTemplate, injectThemeControlKinds, injectThemeColors, getAppliedClasses } from '@ngneers/controls/api/ng';
|
|
5
|
+
import { toggleClass, getPropertyIfExists, objectKeys } from '@ngneers/controls/utils';
|
|
6
|
+
|
|
7
|
+
const NGN_INSTANCE_KEY = '__ngneers_control_instance__';
|
|
8
|
+
function elementWithInstance(element) {
|
|
9
|
+
return element;
|
|
10
|
+
}
|
|
11
|
+
function setNgnInstance(element, instance) {
|
|
12
|
+
elementWithInstance(element)[NGN_INSTANCE_KEY] = instance;
|
|
13
|
+
inject(DestroyRef).onDestroy(() => {
|
|
14
|
+
delete elementWithInstance(element)[NGN_INSTANCE_KEY];
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
function getNgnInstance(element) {
|
|
18
|
+
return elementWithInstance(element)[NGN_INSTANCE_KEY];
|
|
19
|
+
}
|
|
20
|
+
function getNearestNgnInstance(element, kind) {
|
|
21
|
+
let current = element;
|
|
22
|
+
while (current) {
|
|
23
|
+
const instance = elementWithInstance(current)[NGN_INSTANCE_KEY];
|
|
24
|
+
if (instance && (!kind || instance instanceof kind)) {
|
|
25
|
+
return instance;
|
|
26
|
+
}
|
|
27
|
+
current = current.parentElement;
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
function getNearestNgnInstanceSig(element, kind) {
|
|
32
|
+
const sig = signal(null, /* @ts-ignore */
|
|
33
|
+
...(ngDevMode ? [{ debugName: "sig" }] : /* istanbul ignore next */ []));
|
|
34
|
+
afterNextRender(() => {
|
|
35
|
+
sig.set(getNearestNgnInstance(element, kind));
|
|
36
|
+
});
|
|
37
|
+
return sig;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const NGN_CONTROL = new InjectionToken('NGN_CONTROL');
|
|
41
|
+
/* eslint-enable typescript/no-explicit-any */
|
|
42
|
+
/**
|
|
43
|
+
* @internal
|
|
44
|
+
* Provides the control itself for dependency injection.
|
|
45
|
+
* @param control - The control class to provide.
|
|
46
|
+
* @returns A provider for the control itself.
|
|
47
|
+
*/
|
|
48
|
+
function provideSelf(control) {
|
|
49
|
+
return { provide: NGN_CONTROL, useExisting: forwardRef(() => control) };
|
|
50
|
+
}
|
|
51
|
+
class NgnBase {
|
|
52
|
+
_defaultKind = signal(undefined, /* @ts-ignore */
|
|
53
|
+
...(ngDevMode ? [{ debugName: "_defaultKind" }] : /* istanbul ignore next */ []));
|
|
54
|
+
_defaultColor = signal(undefined, /* @ts-ignore */
|
|
55
|
+
...(ngDevMode ? [{ debugName: "_defaultColor" }] : /* istanbul ignore next */ []));
|
|
56
|
+
_kindOverride = signal(undefined, /* @ts-ignore */
|
|
57
|
+
...(ngDevMode ? [{ debugName: "_kindOverride" }] : /* istanbul ignore next */ []));
|
|
58
|
+
/**
|
|
59
|
+
* The element reference for the host element.
|
|
60
|
+
*/
|
|
61
|
+
element = inject(ElementRef);
|
|
62
|
+
/**
|
|
63
|
+
* The injector for the component.
|
|
64
|
+
*/
|
|
65
|
+
injector = inject(Injector);
|
|
66
|
+
/**
|
|
67
|
+
* If true, the control will not apply any theme styles.
|
|
68
|
+
* The base styles of the control will still be applied.
|
|
69
|
+
* @default false
|
|
70
|
+
*/
|
|
71
|
+
unstyled = input(false, { ...(ngDevMode ? { debugName: "unstyled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
72
|
+
/**
|
|
73
|
+
* Some controls support custom kinds for styling purposes.
|
|
74
|
+
* The available kinds depend on the control and the theme used.
|
|
75
|
+
*
|
|
76
|
+
* TODO: link to custom types documentation
|
|
77
|
+
*/
|
|
78
|
+
kind = input(undefined, /* @ts-ignore */
|
|
79
|
+
...(ngDevMode ? [{ debugName: "kind" }] : /* istanbul ignore next */ []));
|
|
80
|
+
color = input(undefined, /* @ts-ignore */
|
|
81
|
+
...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
|
|
82
|
+
appliedKind = computed(() => this._kindOverride() ?? this.kind() ?? this._defaultKind(), /* @ts-ignore */
|
|
83
|
+
...(ngDevMode ? [{ debugName: "appliedKind" }] : /* istanbul ignore next */ []));
|
|
84
|
+
appliedColor = computed(() => this.color() ?? this._defaultColor(), /* @ts-ignore */
|
|
85
|
+
...(ngDevMode ? [{ debugName: "appliedColor" }] : /* istanbul ignore next */ []));
|
|
86
|
+
/**
|
|
87
|
+
* Custom passthrough attributes to apply to the control's theme classes and its dependencies.
|
|
88
|
+
* This allows for fine-grained customization of attributes, styles and more.
|
|
89
|
+
*/
|
|
90
|
+
pt = input(/* @ts-ignore */
|
|
91
|
+
...(ngDevMode ? [undefined, { debugName: "pt" }] : /* istanbul ignore next */ []));
|
|
92
|
+
/**
|
|
93
|
+
* Marks a control as the primary value control of a surrounding field
|
|
94
|
+
* (e.g. `ngn-input-field`). Fields resolve their projected control by
|
|
95
|
+
* filtering for this flag, so auxiliary controls placed inside the field
|
|
96
|
+
* (buttons, icons, spin buttons, …) never shadow the actual input.
|
|
97
|
+
* Overridden with `true` by input, mask-input, calendar, select, ….
|
|
98
|
+
*/
|
|
99
|
+
isFieldControl = false;
|
|
100
|
+
/**
|
|
101
|
+
* Hook for placing focus/selection from a pointer event that originated in the
|
|
102
|
+
* surrounding field (or the control itself). The default does nothing and
|
|
103
|
+
* returns `false`, signalling the surrounding field should fall back to its
|
|
104
|
+
* primitive focusing. Controls that own internal focus placement (e.g.
|
|
105
|
+
* mask-input) override this, act on the pointer location, and return `true`.
|
|
106
|
+
*/
|
|
107
|
+
focusFromPointer(_event) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Hook for stepping the control's value (e.g. from `ngn-spin-buttons` or
|
|
112
|
+
* other external steppers). The default does nothing and returns `false`.
|
|
113
|
+
* Controls with a steppable value (e.g. number-input) override this, apply
|
|
114
|
+
* the step and return `true`.
|
|
115
|
+
* @param _direction - `1` to increment, `-1` to decrement.
|
|
116
|
+
* @param _big - Whether to apply the control's big step (e.g. Shift+Arrow).
|
|
117
|
+
*/
|
|
118
|
+
stepValue(_direction, _big = false) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Hook telling external steppers (e.g. `ngn-spin-buttons`) whether the value
|
|
123
|
+
* can currently be stepped in the given direction. The default returns
|
|
124
|
+
* `false`; controls overriding {@link stepValue} override this as well
|
|
125
|
+
* (typically `false` at a min/max bound or while disabled/readonly).
|
|
126
|
+
*/
|
|
127
|
+
canStepValue(_direction) {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Hook for clearing the control's own value/state (e.g. from a surrounding
|
|
132
|
+
* field's clear button). The default does nothing and returns `false`, so the
|
|
133
|
+
* caller falls back to clearing the underlying DOM input. Controls that manage
|
|
134
|
+
* their own value (e.g. mask-input) override this to reset and return `true`.
|
|
135
|
+
*/
|
|
136
|
+
clearValue() {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Temporarily overrides the authored kind without mutating the public input.
|
|
141
|
+
* Intended for derived control states such as validation-driven hints.
|
|
142
|
+
*/
|
|
143
|
+
setKindOverride(kind) {
|
|
144
|
+
this._kindOverride.set(kind);
|
|
145
|
+
}
|
|
146
|
+
_childNgnControls = viewChildren(NGN_CONTROL, /* @ts-ignore */
|
|
147
|
+
...(ngDevMode ? [{ debugName: "_childNgnControls" }] : /* istanbul ignore next */ []));
|
|
148
|
+
_afterLeaveCbs = [];
|
|
149
|
+
constructor() {
|
|
150
|
+
// `pt` is typed against this control's own `T`, which makes `this`
|
|
151
|
+
// (NgnBase<T>) structurally incompatible with the type-erased AnyNgnBase
|
|
152
|
+
// alias for an unconstrained/generic T. Safe: AnyNgnBase never reads `pt`
|
|
153
|
+
// in a way that depends on the real T at the call site.
|
|
154
|
+
setNgnInstance(this.element.nativeElement, this);
|
|
155
|
+
this.prepareAfterLeaveHook();
|
|
156
|
+
effect(() => {
|
|
157
|
+
// Propagate unstyled state to direct child controls, does not affect
|
|
158
|
+
// custom user content passed into ng-content or projected templates.
|
|
159
|
+
this._childNgnControls().forEach(child => {
|
|
160
|
+
setInputSignalValue(child.unstyled, this.unstyled());
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
this.initializeKindAndColorClasses();
|
|
164
|
+
if (inject(Platform).isBrowser) {
|
|
165
|
+
// Remove the initializing class after the first render to prevent FOUC.
|
|
166
|
+
afterNextRender(() => {
|
|
167
|
+
this.element.nativeElement.classList.remove('ngn-control-initializing');
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
// Remove the initializing class immediately on the server to serve a complete initial HTML.
|
|
172
|
+
this.element.nativeElement.classList.remove('ngn-control-initializing');
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Prepares the after leave hook to be called when the control is destroyed
|
|
177
|
+
* and its leave animation has finished.
|
|
178
|
+
*/
|
|
179
|
+
prepareAfterLeaveHook() {
|
|
180
|
+
inject(DestroyRef).onDestroy(() => {
|
|
181
|
+
if (typeof this.element.nativeElement.getAnimations !== 'function') {
|
|
182
|
+
this.afterLeaveInternal();
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
NgnBase._enqueueLeaveCheck(this.element.nativeElement, () => this.afterLeaveInternal());
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
// --- Batched leave animation checking ---
|
|
190
|
+
// Collects all destroyed components in the same frame into one queue,
|
|
191
|
+
// then processes them in a single rAF to avoid layout thrashing from
|
|
192
|
+
// interleaved getAnimations() calls and DOM mutations.
|
|
193
|
+
static _leaveQueue = [];
|
|
194
|
+
static _leaveRafScheduled = false;
|
|
195
|
+
static _enqueueLeaveCheck(element, callback) {
|
|
196
|
+
NgnBase._leaveQueue.push({ element, callback });
|
|
197
|
+
if (!NgnBase._leaveRafScheduled) {
|
|
198
|
+
NgnBase._leaveRafScheduled = true;
|
|
199
|
+
requestAnimationFrame(() => NgnBase._processLeaveQueue());
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
static _processLeaveQueue() {
|
|
203
|
+
const queue = NgnBase._leaveQueue;
|
|
204
|
+
NgnBase._leaveQueue = [];
|
|
205
|
+
NgnBase._leaveRafScheduled = false;
|
|
206
|
+
// Phase 1: Read all animations (batched queries — no interleaved mutations)
|
|
207
|
+
const results = [];
|
|
208
|
+
for (const { element, callback } of queue) {
|
|
209
|
+
results.push({
|
|
210
|
+
animation: NgnBase._findLeaveAnimation(element),
|
|
211
|
+
callback,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
// Phase 2: Process results (no more style queries needed)
|
|
215
|
+
for (const { animation, callback } of results) {
|
|
216
|
+
if (!animation) {
|
|
217
|
+
callback();
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
animation.finished
|
|
221
|
+
.catch(() => {
|
|
222
|
+
// ignore errors from animations being cancelled
|
|
223
|
+
})
|
|
224
|
+
.finally(() => {
|
|
225
|
+
callback();
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Recursively searches for a leave animation on the element and its parents.
|
|
232
|
+
*/
|
|
233
|
+
static _findLeaveAnimation(element) {
|
|
234
|
+
const animations = element.getAnimations();
|
|
235
|
+
const leaveAnimation = animations.find(a => a instanceof CSSAnimation && a.animationName.endsWith('-leave'));
|
|
236
|
+
if (leaveAnimation) {
|
|
237
|
+
return leaveAnimation;
|
|
238
|
+
}
|
|
239
|
+
if (element.parentElement) {
|
|
240
|
+
return NgnBase._findLeaveAnimation(element.parentElement);
|
|
241
|
+
}
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
afterLeaveInternal() {
|
|
245
|
+
/**
|
|
246
|
+
* After the control is hidden/removed from the DOM,
|
|
247
|
+
* manually wipe the innerHTML to ensure no detached children remain
|
|
248
|
+
* mapped to this component's LView slots in the browser's memory.
|
|
249
|
+
* This is especially important for controls that use ng-content
|
|
250
|
+
* or dynamically render child components.
|
|
251
|
+
*/
|
|
252
|
+
this.element.nativeElement.innerHTML = '';
|
|
253
|
+
this._afterLeaveCbs.forEach(cb => cb());
|
|
254
|
+
this.afterLeave();
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Lifecycle hook that is called after the control has left (been removed from) the DOM.
|
|
258
|
+
* Can be overridden by subclasses to perform custom actions after the leave animation.
|
|
259
|
+
*/
|
|
260
|
+
afterLeave() {
|
|
261
|
+
// Can be overridden by subclasses
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* @internal
|
|
265
|
+
*/
|
|
266
|
+
injectThemeTemplate(template, hostClass) {
|
|
267
|
+
const opts = { unstyled: this.unstyled };
|
|
268
|
+
const theme = injectThemeTemplate(template, opts);
|
|
269
|
+
const kinds = injectThemeControlKinds(theme.scope)();
|
|
270
|
+
if (kinds.length) {
|
|
271
|
+
this._defaultKind.set(kinds[0]);
|
|
272
|
+
}
|
|
273
|
+
const colors = injectThemeColors(theme.scope)();
|
|
274
|
+
if (colors.length) {
|
|
275
|
+
this._defaultColor.set(colors[0]);
|
|
276
|
+
}
|
|
277
|
+
if (hostClass !== undefined) {
|
|
278
|
+
// See constructor comment: `this` (NgnBase<T>) isn't structurally assignable
|
|
279
|
+
// to NgnBaseSafe<T & string> for a generic T because `pt`'s type still
|
|
280
|
+
// depends on T. Narrow the erasure to this control's own T & string, which
|
|
281
|
+
// matches what NgnPtEngine actually needs here.
|
|
282
|
+
new NgnPtEngine(this, hostClass);
|
|
283
|
+
}
|
|
284
|
+
return theme;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Toggles the kind and color theme classes based on the current values of the kind and color inputs.
|
|
288
|
+
*/
|
|
289
|
+
initializeKindAndColorClasses() {
|
|
290
|
+
this.initializeAutoThemeClasses('kind', this.appliedKind);
|
|
291
|
+
this.initializeAutoThemeClasses('color', this.appliedColor);
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Initializes automatic theme class toggling for a given prefix based on the provided string signal.
|
|
295
|
+
*
|
|
296
|
+
* ⚠️ Caution: This method assumes that the control's theme supports classes with the given prefix.
|
|
297
|
+
*
|
|
298
|
+
* ⚠️ Caution: Make sure the signal provides only string or nullish values.
|
|
299
|
+
*
|
|
300
|
+
* @param prefix The prefix for the theme class (e.g., 'kind' or 'color').
|
|
301
|
+
* @param signal The signal that provides the current string value for the theme class.
|
|
302
|
+
*/
|
|
303
|
+
initializeAutoThemeClasses(prefix, signal) {
|
|
304
|
+
const element = this.element.nativeElement;
|
|
305
|
+
/**
|
|
306
|
+
* We can't know here whether the control has any kind or color classes,
|
|
307
|
+
* so we cast explicitly to ThemeClassToken. In practice, controls without
|
|
308
|
+
* kind or color classes will simply not toggle any classes as the input type does not allow it.
|
|
309
|
+
*/
|
|
310
|
+
const classToken = (value) => value;
|
|
311
|
+
const togglePrefixedThemeClass = (prefix, value, enabled) => {
|
|
312
|
+
if (!value) {
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
const theme = this.theme;
|
|
316
|
+
if (!theme) {
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
toggleClass(element, theme.class(classToken(`${prefix}-${value}`)), enabled);
|
|
320
|
+
};
|
|
321
|
+
effectWithPrevious(signal, (current, previous) => {
|
|
322
|
+
togglePrefixedThemeClass(prefix, previous, false);
|
|
323
|
+
togglePrefixedThemeClass(prefix, current, true);
|
|
324
|
+
});
|
|
325
|
+
this._afterLeaveCbs.push(() => {
|
|
326
|
+
togglePrefixedThemeClass(prefix, signal(), false);
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NgnBase, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
330
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "22.0.5", type: NgnBase, isStandalone: true, inputs: { unstyled: { classPropertyName: "unstyled", publicName: "unstyled", isSignal: true, isRequired: false, transformFunction: null }, kind: { classPropertyName: "kind", publicName: "kind", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, pt: { classPropertyName: "pt", publicName: "pt", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "ngn-control ngn-control-initializing" }, viewQueries: [{ propertyName: "_childNgnControls", predicate: NGN_CONTROL, descendants: true, isSignal: true }], ngImport: i0 });
|
|
331
|
+
}
|
|
332
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NgnBase, decorators: [{
|
|
333
|
+
type: Directive,
|
|
334
|
+
args: [{
|
|
335
|
+
host: { class: 'ngn-control ngn-control-initializing' },
|
|
336
|
+
}]
|
|
337
|
+
}], ctorParameters: () => [], propDecorators: { unstyled: [{ type: i0.Input, args: [{ isSignal: true, alias: "unstyled", required: false }] }], kind: [{ type: i0.Input, args: [{ isSignal: true, alias: "kind", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], pt: [{ type: i0.Input, args: [{ isSignal: true, alias: "pt", required: false }] }], _childNgnControls: [{ type: i0.ViewChildren, args: [i0.forwardRef(() => NGN_CONTROL), { isSignal: true }] }] } });
|
|
338
|
+
|
|
339
|
+
class NgnPtEngine {
|
|
340
|
+
pt;
|
|
341
|
+
ptClass;
|
|
342
|
+
_elementRef = inject(ElementRef);
|
|
343
|
+
_destroyRef = inject(DestroyRef);
|
|
344
|
+
/** The passthrough values currently applied to the element, for teardown on destroy. */
|
|
345
|
+
_currentAppliedPts;
|
|
346
|
+
classes = computed(() => {
|
|
347
|
+
const pt = this.pt();
|
|
348
|
+
if ('theme' in pt) {
|
|
349
|
+
const theme = pt['theme'];
|
|
350
|
+
const res = getAppliedClasses(this.ptClass(), theme);
|
|
351
|
+
return res;
|
|
352
|
+
}
|
|
353
|
+
return [];
|
|
354
|
+
}, /* @ts-ignore */
|
|
355
|
+
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
356
|
+
_appliedPts = computed(() => {
|
|
357
|
+
const pt = this.pt()?.pt();
|
|
358
|
+
if (!pt) {
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
const classes = this.classes();
|
|
362
|
+
return classes.map(({ name: ptClass }) => {
|
|
363
|
+
const classPt = getPropertyIfExists(pt, ptClass);
|
|
364
|
+
return classPt;
|
|
365
|
+
});
|
|
366
|
+
}, /* @ts-ignore */
|
|
367
|
+
...(ngDevMode ? [{ debugName: "_appliedPts" }] : /* istanbul ignore next */ []));
|
|
368
|
+
constructor(pt, ptClass, options) {
|
|
369
|
+
const sigPt = typeof pt === 'function' ? pt : signal(pt);
|
|
370
|
+
const sigPtClass = typeof ptClass === 'function' ? ptClass : signal(ptClass);
|
|
371
|
+
this.pt = sigPt;
|
|
372
|
+
this.ptClass = sigPtClass;
|
|
373
|
+
const classes = computed(() => this.classes().map(c => c.class), /* @ts-ignore */
|
|
374
|
+
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
375
|
+
classSignal(this._elementRef.nativeElement, classes);
|
|
376
|
+
if (options?.applyPassthrough === false) {
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
effectWithPrevious(this._appliedPts, (current, previous) => {
|
|
380
|
+
if (previous) {
|
|
381
|
+
for (const classPt of previous) {
|
|
382
|
+
if (!classPt) {
|
|
383
|
+
continue;
|
|
384
|
+
}
|
|
385
|
+
this.removePreviousPtValues(classPt);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
if (current) {
|
|
389
|
+
for (const classPt of current) {
|
|
390
|
+
if (!classPt) {
|
|
391
|
+
continue;
|
|
392
|
+
}
|
|
393
|
+
this.setNewPtValues(classPt);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
this._currentAppliedPts = current;
|
|
397
|
+
});
|
|
398
|
+
// Detach applied passthrough (notably event listeners) when the element is
|
|
399
|
+
// destroyed, so nothing leaks past the control's lifetime.
|
|
400
|
+
this._destroyRef.onDestroy(() => {
|
|
401
|
+
if (!this._currentAppliedPts) {
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
for (const classPt of this._currentAppliedPts) {
|
|
405
|
+
if (!classPt) {
|
|
406
|
+
continue;
|
|
407
|
+
}
|
|
408
|
+
this.removePreviousPtValues(classPt);
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
setNewPtValues(classPt) {
|
|
413
|
+
if (classPt.$styles) {
|
|
414
|
+
const keys = objectKeys(classPt.$styles);
|
|
415
|
+
keys.forEach(key => {
|
|
416
|
+
this._elementRef.nativeElement.style[key] =
|
|
417
|
+
classPt.$styles?.[key] || '';
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
if (classPt.$attributes) {
|
|
421
|
+
const keys = objectKeys(classPt.$attributes);
|
|
422
|
+
keys.forEach(key => {
|
|
423
|
+
this._elementRef.nativeElement.setAttribute(key, classPt.$attributes?.[key] || '');
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
if (classPt.$classes) {
|
|
427
|
+
const arrayOfClasses = Array.isArray(classPt.$classes)
|
|
428
|
+
? classPt.$classes.flatMap(c => c.split(' '))
|
|
429
|
+
: classPt.$classes.split(' ');
|
|
430
|
+
arrayOfClasses.forEach(cls => {
|
|
431
|
+
try {
|
|
432
|
+
this._elementRef.nativeElement.classList.add(cls);
|
|
433
|
+
}
|
|
434
|
+
catch {
|
|
435
|
+
console.warn(`Could not add class '${cls}' to element`, this._elementRef.nativeElement);
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
if (classPt.$listeners) {
|
|
440
|
+
objectKeys(classPt.$listeners).forEach(eventName => {
|
|
441
|
+
const handler = classPt.$listeners?.[eventName];
|
|
442
|
+
if (!handler) {
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
this._elementRef.nativeElement.addEventListener(eventName, handler);
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
removePreviousPtValues(classPt) {
|
|
450
|
+
if (classPt.$styles) {
|
|
451
|
+
const keys = objectKeys(classPt.$styles);
|
|
452
|
+
keys.forEach(key => {
|
|
453
|
+
this._elementRef.nativeElement.style[key] = '';
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
if (classPt.$attributes) {
|
|
457
|
+
const keys = objectKeys(classPt.$attributes);
|
|
458
|
+
keys.forEach(key => {
|
|
459
|
+
this._elementRef.nativeElement.removeAttribute(key);
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
if (classPt.$classes) {
|
|
463
|
+
const arrayOfClasses = Array.isArray(classPt.$classes)
|
|
464
|
+
? classPt.$classes.flatMap(c => c.split(' '))
|
|
465
|
+
: classPt.$classes.split(' ');
|
|
466
|
+
arrayOfClasses.forEach(cls => {
|
|
467
|
+
try {
|
|
468
|
+
this._elementRef.nativeElement.classList.remove(cls);
|
|
469
|
+
}
|
|
470
|
+
catch {
|
|
471
|
+
console.warn(`Could not remove class '${cls}' from element`, this._elementRef.nativeElement);
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
if (classPt.$listeners) {
|
|
476
|
+
objectKeys(classPt.$listeners).forEach(eventName => {
|
|
477
|
+
const listener = classPt.$listeners?.[eventName];
|
|
478
|
+
if (!listener) {
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
this._elementRef.nativeElement.removeEventListener(eventName, listener);
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// Internal passthrough directive; intentionally uses the non-prefixed `ptInt` selector.
|
|
488
|
+
class NgnPt {
|
|
489
|
+
/** The parent control whose theme/passthrough this element pulls from. */
|
|
490
|
+
ptInt = input.required(/* @ts-ignore */
|
|
491
|
+
...(ngDevMode ? [{ debugName: "ptInt" }] : /* istanbul ignore next */ []));
|
|
492
|
+
/**
|
|
493
|
+
* Parent-scope class token(s) applied to this element, along with the parent's
|
|
494
|
+
* `pt` slice for those classes. Use for flat theme parts of the parent.
|
|
495
|
+
*/
|
|
496
|
+
ptClass = input(/* @ts-ignore */
|
|
497
|
+
...(ngDevMode ? [undefined, { debugName: "ptClass" }] : /* istanbul ignore next */ []));
|
|
498
|
+
/**
|
|
499
|
+
* Dependency-slot class on the parent. Applies the parent's marker class
|
|
500
|
+
* (`{parentScope}-{ptDep}`) to this element and forwards the parent's
|
|
501
|
+
* `pt[ptDep]` slice into the nested control that lives on this element, so the
|
|
502
|
+
* nested control resolves it against its own theme.
|
|
503
|
+
*/
|
|
504
|
+
ptDep = input(/* @ts-ignore */
|
|
505
|
+
...(ngDevMode ? [undefined, { debugName: "ptDep" }] : /* istanbul ignore next */ []));
|
|
506
|
+
/**
|
|
507
|
+
* The nested control hosted on THIS element (present when `ptDep` targets a
|
|
508
|
+
* control). `self: true` is essential: without it the injection climbs to an
|
|
509
|
+
* ancestor control (e.g. the parent that owns `[ptInt]`), and the forwarding
|
|
510
|
+
* effect would then overwrite the ancestor's `pt` instead of the child's.
|
|
511
|
+
*/
|
|
512
|
+
_self = inject(NGN_CONTROL, {
|
|
513
|
+
optional: true,
|
|
514
|
+
self: true,
|
|
515
|
+
});
|
|
516
|
+
/**
|
|
517
|
+
* Flat class engine for `ptClass`: applies the parent's scope class(es) and the
|
|
518
|
+
* matching `pt` slice to this element. A missing `ptClass` resolves to a no-op.
|
|
519
|
+
*/
|
|
520
|
+
_classEngine = new NgnPtEngine(this.ptInt, computed(() => this.ptClass() ?? {}));
|
|
521
|
+
/**
|
|
522
|
+
* Marker engine for `ptDep`: applies ONLY the parent's `{parentScope}-{ptDep}`
|
|
523
|
+
* class to this element (`applyPassthrough: false`). The forwarded slice is
|
|
524
|
+
* applied separately, through the nested control's own engine.
|
|
525
|
+
*/
|
|
526
|
+
_markerEngine = new NgnPtEngine(this.ptInt, computed(() => (this.ptDep() ?? {})), { applyPassthrough: false });
|
|
527
|
+
/** The parent's `pt` slice for the current `ptDep` slot, or `undefined`. */
|
|
528
|
+
_depSlice = computed(() => {
|
|
529
|
+
const dep = this.ptDep();
|
|
530
|
+
if (!dep) {
|
|
531
|
+
return undefined;
|
|
532
|
+
}
|
|
533
|
+
const parentPt = this.ptInt().pt?.();
|
|
534
|
+
return parentPt?.[dep];
|
|
535
|
+
}, /* @ts-ignore */
|
|
536
|
+
...(ngDevMode ? [{ debugName: "_depSlice" }] : /* istanbul ignore next */ []));
|
|
537
|
+
constructor() {
|
|
538
|
+
const self = this._self;
|
|
539
|
+
if (!self) {
|
|
540
|
+
// No nested control on this element (e.g. `ptDep` on a plain element): only
|
|
541
|
+
// the marker class applies; there is no child theme to forward the slice to.
|
|
542
|
+
// Warn (dev only) if a `ptDep` is actually set — read it in an effect, since
|
|
543
|
+
// inputs are not yet resolved in the constructor.
|
|
544
|
+
if (isDevMode()) {
|
|
545
|
+
effect(() => {
|
|
546
|
+
if (this.ptDep()) {
|
|
547
|
+
console.warn('[ptDep] is set but no nested control was found on this element; the parent' +
|
|
548
|
+
" dependency slice can't be forwarded. Did you forget to host a control here?");
|
|
549
|
+
}
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
554
|
+
// Forward the parent's dependency slice into the nested control's own `pt`
|
|
555
|
+
// input, so the child's existing engine(s) resolve it against its theme.
|
|
556
|
+
// Reactive to parent `pt` changes; torn down with the directive/child. Writes
|
|
557
|
+
// on every run (even `undefined`) so a slice that disappears (e.g. `ptDep`
|
|
558
|
+
// cleared) clears the child's `pt` instead of leaving it stale; the child's
|
|
559
|
+
// own engine already treats a falsy `pt` as a no-op.
|
|
560
|
+
effect(() => {
|
|
561
|
+
setInputSignalValue(self.pt, this._depSlice());
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NgnPt, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
565
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.5", type: NgnPt, isStandalone: true, selector: "[ptInt]", inputs: { ptInt: { classPropertyName: "ptInt", publicName: "ptInt", isSignal: true, isRequired: true, transformFunction: null }, ptClass: { classPropertyName: "ptClass", publicName: "ptClass", isSignal: true, isRequired: false, transformFunction: null }, ptDep: { classPropertyName: "ptDep", publicName: "ptDep", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
|
|
566
|
+
}
|
|
567
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NgnPt, decorators: [{
|
|
568
|
+
type: Directive,
|
|
569
|
+
args: [{ selector: '[ptInt]' }]
|
|
570
|
+
}], ctorParameters: () => [], propDecorators: { ptInt: [{ type: i0.Input, args: [{ isSignal: true, alias: "ptInt", required: true }] }], ptClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "ptClass", required: false }] }], ptDep: [{ type: i0.Input, args: [{ isSignal: true, alias: "ptDep", required: false }] }] } });
|
|
571
|
+
|
|
572
|
+
class ValueControlBase extends NgnBase {
|
|
573
|
+
/**
|
|
574
|
+
* The label for the control.
|
|
575
|
+
*/
|
|
576
|
+
label = input(null, /* @ts-ignore */
|
|
577
|
+
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
578
|
+
/**
|
|
579
|
+
* Sets the `aria-labelledby` attribute on the control.
|
|
580
|
+
* @default null
|
|
581
|
+
*/
|
|
582
|
+
labelledBy = input(null, /* @ts-ignore */
|
|
583
|
+
...(ngDevMode ? [{ debugName: "labelledBy" }] : /* istanbul ignore next */ []));
|
|
584
|
+
/**
|
|
585
|
+
* The ID for the control
|
|
586
|
+
* @default generateElementId()
|
|
587
|
+
*/
|
|
588
|
+
inputId = input(generateElementId(), /* @ts-ignore */
|
|
589
|
+
...(ngDevMode ? [{ debugName: "inputId" }] : /* istanbul ignore next */ []));
|
|
590
|
+
/**
|
|
591
|
+
* Explicitly apply invalid state styling
|
|
592
|
+
* @default false
|
|
593
|
+
*/
|
|
594
|
+
invalid = input(false, { ...(ngDevMode ? { debugName: "invalid" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
595
|
+
/**
|
|
596
|
+
* The value of the control.
|
|
597
|
+
*/
|
|
598
|
+
value = model(undefined, /* @ts-ignore */
|
|
599
|
+
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
600
|
+
/**
|
|
601
|
+
* Set the disabled state of the control.
|
|
602
|
+
*/
|
|
603
|
+
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
604
|
+
readonly = input(false, { ...(ngDevMode ? { debugName: "readonly" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
605
|
+
touched = model(false, /* @ts-ignore */
|
|
606
|
+
...(ngDevMode ? [{ debugName: "touched" }] : /* istanbul ignore next */ []));
|
|
607
|
+
dirty = input(false, { ...(ngDevMode ? { debugName: "dirty" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
608
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ValueControlBase, deps: null, target: i0.ɵɵFactoryTarget.Directive });
|
|
609
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.5", type: ValueControlBase, isStandalone: true, inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, labelledBy: { classPropertyName: "labelledBy", publicName: "labelledBy", isSignal: true, isRequired: false, transformFunction: null }, inputId: { classPropertyName: "inputId", publicName: "inputId", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, dirty: { classPropertyName: "dirty", publicName: "dirty", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touched: "touchedChange" }, usesInheritance: true, ngImport: i0 });
|
|
610
|
+
}
|
|
611
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ValueControlBase, decorators: [{
|
|
612
|
+
type: Directive
|
|
613
|
+
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], labelledBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelledBy", required: false }] }], inputId: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputId", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], dirty: [{ type: i0.Input, args: [{ isSignal: true, alias: "dirty", required: false }] }] } });
|
|
614
|
+
|
|
615
|
+
/**
|
|
616
|
+
* Generated bundle index. Do not edit.
|
|
617
|
+
*/
|
|
618
|
+
|
|
619
|
+
export { NGN_CONTROL, NgnBase, NgnPt, NgnPtEngine, ValueControlBase, getNearestNgnInstance, getNearestNgnInstanceSig, getNgnInstance, provideSelf, setNgnInstance };
|
|
620
|
+
//# sourceMappingURL=ngneers-controls-base.mjs.map
|