@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,308 @@
|
|
|
1
|
+
import { NgTemplateOutlet } from '@angular/common';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
import { input, contentChild, computed, Directive, inject, ElementRef, booleanAttribute, effect, untracked, Component, signal } from '@angular/core';
|
|
4
|
+
import { templateTypesFn, elementSizeSignal } from '@ngneers/controls/api/ng';
|
|
5
|
+
import { NgnBase, provideSelf, getNearestNgnInstance } from '@ngneers/controls/base';
|
|
6
|
+
import * as i1 from '@ngneers/controls/directives';
|
|
7
|
+
import { NgnScrollAmount } from '@ngneers/controls/directives';
|
|
8
|
+
import { NgnError, getScrollTop, toggleClass } from '@ngneers/controls/utils';
|
|
9
|
+
import { scrollerControlTemplate } from '@ngneers/controls-themes/templates/scroller';
|
|
10
|
+
|
|
11
|
+
class ScrollerTemplates extends NgnBase {
|
|
12
|
+
/**
|
|
13
|
+
* The template to be used for rendering each item in the scroller.
|
|
14
|
+
* Can also be set using the `item` content child.
|
|
15
|
+
*/
|
|
16
|
+
templateItem = input(null, /* @ts-ignore */
|
|
17
|
+
...(ngDevMode ? [{ debugName: "templateItem" }] : /* istanbul ignore next */ []));
|
|
18
|
+
_userItemTemplate = contentChild('item', /* @ts-ignore */
|
|
19
|
+
...(ngDevMode ? [{ debugName: "_userItemTemplate" }] : /* istanbul ignore next */ []));
|
|
20
|
+
itemTemplate = computed(() => this._userItemTemplate() ?? this.templateItem(), /* @ts-ignore */
|
|
21
|
+
...(ngDevMode ? [{ debugName: "itemTemplate" }] : /* istanbul ignore next */ []));
|
|
22
|
+
/**
|
|
23
|
+
* Template types for the scroller.
|
|
24
|
+
* Can be used with the {@link NgnTemplate} directive for type safe ng-templates.
|
|
25
|
+
*/
|
|
26
|
+
templateTypes = templateTypesFn();
|
|
27
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ScrollerTemplates, deps: null, target: i0.ɵɵFactoryTarget.Directive });
|
|
28
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "22.0.5", type: ScrollerTemplates, isStandalone: true, inputs: { templateItem: { classPropertyName: "templateItem", publicName: "templateItem", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "_userItemTemplate", first: true, predicate: ["item"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0 });
|
|
29
|
+
}
|
|
30
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ScrollerTemplates, decorators: [{
|
|
31
|
+
type: Directive
|
|
32
|
+
}], propDecorators: { templateItem: [{ type: i0.Input, args: [{ isSignal: true, alias: "templateItem", required: false }] }], _userItemTemplate: [{ type: i0.ContentChild, args: ['item', { isSignal: true }] }] } });
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @category control
|
|
36
|
+
*/
|
|
37
|
+
class NgnScroller extends ScrollerTemplates {
|
|
38
|
+
theme = this.injectThemeTemplate(scrollerControlTemplate, {
|
|
39
|
+
root: true,
|
|
40
|
+
virtual: () => !!this.virtual(),
|
|
41
|
+
});
|
|
42
|
+
_el = inject(ElementRef);
|
|
43
|
+
_scrollAmount = inject(NgnScrollAmount);
|
|
44
|
+
/**
|
|
45
|
+
* The items to be displayed in the scroller.
|
|
46
|
+
* This is a required input and should be an array of items of type {@link T}.
|
|
47
|
+
*/
|
|
48
|
+
items = input.required(/* @ts-ignore */
|
|
49
|
+
...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
50
|
+
/**
|
|
51
|
+
* The field of the item that uniquely identifies it.
|
|
52
|
+
*/
|
|
53
|
+
fieldId = input(/* @ts-ignore */
|
|
54
|
+
...(ngDevMode ? [undefined, { debugName: "fieldId" }] : /* istanbul ignore next */ []));
|
|
55
|
+
/**
|
|
56
|
+
* Whether the scroller should use virtual scrolling.
|
|
57
|
+
* When set to true, the scroller will only render the items that are currently visible
|
|
58
|
+
* on the screen, improving performance for large lists.
|
|
59
|
+
*
|
|
60
|
+
* When virtual scrolling is enabled, {@link itemHeight} must be set to a non-zero value.
|
|
61
|
+
* @default `false`
|
|
62
|
+
*/
|
|
63
|
+
virtual = input(false, { ...(ngDevMode ? { debugName: "virtual" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
64
|
+
/**
|
|
65
|
+
* When {@link virtual} scrolling is enabled, this input is required to define the height of each item in pixels.
|
|
66
|
+
*/
|
|
67
|
+
itemHeight = input(undefined, /* @ts-ignore */
|
|
68
|
+
...(ngDevMode ? [{ debugName: "itemHeight" }] : /* istanbul ignore next */ []));
|
|
69
|
+
/**
|
|
70
|
+
* When {@link virtual} scrolling is enabled, this input defines the number of items to be rendered above and below the visible area.
|
|
71
|
+
* This can help to reduce flickering when scrolling.
|
|
72
|
+
* @default `2`
|
|
73
|
+
*/
|
|
74
|
+
virtualPadding = input(2, /* @ts-ignore */
|
|
75
|
+
...(ngDevMode ? [{ debugName: "virtualPadding" }] : /* istanbul ignore next */ []));
|
|
76
|
+
/**
|
|
77
|
+
* Determines whether the scroller should have a tab index and be focusable.
|
|
78
|
+
* @default `false`
|
|
79
|
+
*/
|
|
80
|
+
focusable = input(false, { ...(ngDevMode ? { debugName: "focusable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
81
|
+
/**
|
|
82
|
+
* Determines whether an item is sticky or not.
|
|
83
|
+
* If set, the scroller will stick the items with a truthy value for the specified field to the top of the scroller.
|
|
84
|
+
*/
|
|
85
|
+
fieldSticky = input(null, /* @ts-ignore */
|
|
86
|
+
...(ngDevMode ? [{ debugName: "fieldSticky" }] : /* istanbul ignore next */ []));
|
|
87
|
+
/**
|
|
88
|
+
* Viewport size — tracks the scroll ancestor's dimensions so that virtual
|
|
89
|
+
* scrolling works when an outer element handles overflow (e.g. table wrapper).
|
|
90
|
+
*/
|
|
91
|
+
_viewportSize = elementSizeSignal(computed(() => this._scrollAmount.scrollTarget()));
|
|
92
|
+
_itemHeightPx = computed(() => this.itemHeight() ?? 0, /* @ts-ignore */
|
|
93
|
+
...(ngDevMode ? [{ debugName: "_itemHeightPx" }] : /* istanbul ignore next */ []));
|
|
94
|
+
/**
|
|
95
|
+
* Vertical offset between the scroll container's top and the scroller element.
|
|
96
|
+
* Non-zero when a parent (e.g. table wrapper) owns the scroll and the scroller
|
|
97
|
+
* is positioned below other content (e.g. a sticky header row).
|
|
98
|
+
*/
|
|
99
|
+
_scrollOffset = computed(() => {
|
|
100
|
+
const target = this._scrollAmount.scrollTarget();
|
|
101
|
+
if (target === this._el.nativeElement)
|
|
102
|
+
return 0;
|
|
103
|
+
return this._el.nativeElement.offsetTop;
|
|
104
|
+
}, /* @ts-ignore */
|
|
105
|
+
...(ngDevMode ? [{ debugName: "_scrollOffset" }] : /* istanbul ignore next */ []));
|
|
106
|
+
_visibleItemCount = computed(() => {
|
|
107
|
+
if (!this.virtual() || this._itemHeightPx() === 0) {
|
|
108
|
+
return 0;
|
|
109
|
+
}
|
|
110
|
+
return Math.ceil(this._viewportSize().height / this._itemHeightPx() + this.virtualPadding() * 2);
|
|
111
|
+
}, /* @ts-ignore */
|
|
112
|
+
...(ngDevMode ? [{ debugName: "_visibleItemCount" }] : /* istanbul ignore next */ []));
|
|
113
|
+
_scrollTop = computed(() => {
|
|
114
|
+
const raw = this._scrollAmount.scrollTop();
|
|
115
|
+
return Math.max(0, raw - this._scrollOffset());
|
|
116
|
+
}, /* @ts-ignore */
|
|
117
|
+
...(ngDevMode ? [{ debugName: "_scrollTop" }] : /* istanbul ignore next */ []));
|
|
118
|
+
/**
|
|
119
|
+
* The index of the first item that is rendered in the (virtual) scroller.
|
|
120
|
+
*/
|
|
121
|
+
itemStartIndex = computed(() => {
|
|
122
|
+
if (!this.virtual() || this._itemHeightPx() === 0) {
|
|
123
|
+
return 0;
|
|
124
|
+
}
|
|
125
|
+
return Math.max(0, Math.ceil(this._scrollTop() / this._itemHeightPx()) - this.virtualPadding());
|
|
126
|
+
}, /* @ts-ignore */
|
|
127
|
+
...(ngDevMode ? [{ debugName: "itemStartIndex" }] : /* istanbul ignore next */ []));
|
|
128
|
+
_itemEndIndex = computed(() => this.virtual()
|
|
129
|
+
? Math.min(this.items().length, this.itemStartIndex() + this._visibleItemCount())
|
|
130
|
+
: 0, /* @ts-ignore */
|
|
131
|
+
...(ngDevMode ? [{ debugName: "_itemEndIndex" }] : /* istanbul ignore next */ []));
|
|
132
|
+
paddingTop = computed(() => {
|
|
133
|
+
if (!this.virtual()) {
|
|
134
|
+
return 0;
|
|
135
|
+
}
|
|
136
|
+
return (this.itemStartIndex() - (this.latestStickyItem() ? 1 : 0)) * this._itemHeightPx();
|
|
137
|
+
}, /* @ts-ignore */
|
|
138
|
+
...(ngDevMode ? [{ debugName: "paddingTop" }] : /* istanbul ignore next */ []));
|
|
139
|
+
paddingBottom = computed(() => {
|
|
140
|
+
if (!this.virtual()) {
|
|
141
|
+
return 0;
|
|
142
|
+
}
|
|
143
|
+
return (this.items().length - this._itemEndIndex()) * this._itemHeightPx();
|
|
144
|
+
}, /* @ts-ignore */
|
|
145
|
+
...(ngDevMode ? [{ debugName: "paddingBottom" }] : /* istanbul ignore next */ []));
|
|
146
|
+
visibleItems = computed(() => {
|
|
147
|
+
if (!this.virtual()) {
|
|
148
|
+
return this.items().map((item, index) => ({ item, index }));
|
|
149
|
+
}
|
|
150
|
+
return this.items()
|
|
151
|
+
.slice(this.itemStartIndex(), this._itemEndIndex())
|
|
152
|
+
.map((item, index) => {
|
|
153
|
+
return {
|
|
154
|
+
item,
|
|
155
|
+
index: this.itemStartIndex() + index,
|
|
156
|
+
};
|
|
157
|
+
});
|
|
158
|
+
}, /* @ts-ignore */
|
|
159
|
+
...(ngDevMode ? [{ debugName: "visibleItems" }] : /* istanbul ignore next */ []));
|
|
160
|
+
/**
|
|
161
|
+
* Returns the last sticky item that is not rendered regularly in the list.
|
|
162
|
+
* Required because sticky items might need to be rendered longer than they would.
|
|
163
|
+
* Only applicable when virtual scrolling is enabled.
|
|
164
|
+
*/
|
|
165
|
+
latestStickyItem = computed(() => {
|
|
166
|
+
if (!this.virtual()) {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
const stickyField = this.fieldSticky();
|
|
170
|
+
if (!stickyField) {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
const unrenderedItemsAtTop = this.items()
|
|
174
|
+
.slice(0, this.itemStartIndex())
|
|
175
|
+
.map((item, index) => ({
|
|
176
|
+
item,
|
|
177
|
+
index,
|
|
178
|
+
}));
|
|
179
|
+
const stickyItems = unrenderedItemsAtTop.filter(item => item.item[stickyField]);
|
|
180
|
+
return stickyItems[stickyItems.length - 1] ?? null;
|
|
181
|
+
}, /* @ts-ignore */
|
|
182
|
+
...(ngDevMode ? [{ debugName: "latestStickyItem" }] : /* istanbul ignore next */ []));
|
|
183
|
+
constructor() {
|
|
184
|
+
super();
|
|
185
|
+
effect(() => {
|
|
186
|
+
if (this.virtual() && !this.itemHeight()) {
|
|
187
|
+
throw new NgnError('scroller', 'itemHeight must be set when virtual is true');
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Scrolls the item with the given index into view.
|
|
193
|
+
* @param index The index of the item to scroll to.
|
|
194
|
+
*/
|
|
195
|
+
scrollToIndex(index, position = 'nearest') {
|
|
196
|
+
untracked(() => {
|
|
197
|
+
const scrollEl = this._scrollAmount.scrollTarget();
|
|
198
|
+
const offset = this._scrollOffset();
|
|
199
|
+
const getItemSize = () => {
|
|
200
|
+
if (this.virtual()) {
|
|
201
|
+
const itemHeight = this._itemHeightPx();
|
|
202
|
+
const itemTop = index * itemHeight + offset;
|
|
203
|
+
return { itemHeight, itemTop };
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
let itemElement = this._el.nativeElement.children[index];
|
|
207
|
+
while (!itemElement?.clientHeight && itemElement?.children.length) {
|
|
208
|
+
itemElement = itemElement?.children[0];
|
|
209
|
+
}
|
|
210
|
+
if (itemElement) {
|
|
211
|
+
const itemTop = itemElement.offsetTop;
|
|
212
|
+
const itemHeight = itemElement.clientHeight;
|
|
213
|
+
return { itemTop, itemHeight };
|
|
214
|
+
}
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
const size = getItemSize();
|
|
219
|
+
if (!size) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
const { itemTop, itemHeight } = size;
|
|
223
|
+
scrollEl.scrollTo({
|
|
224
|
+
top: getScrollTop(itemTop, itemHeight, scrollEl.clientHeight, scrollEl.scrollTop, position),
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
track(item) {
|
|
229
|
+
const fieldId = this.fieldId();
|
|
230
|
+
if (fieldId) {
|
|
231
|
+
return item.item[fieldId];
|
|
232
|
+
}
|
|
233
|
+
return item.index;
|
|
234
|
+
}
|
|
235
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NgnScroller, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
236
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: NgnScroller, isStandalone: true, selector: "ngn-scroller, [ngn-scroller]", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, fieldId: { classPropertyName: "fieldId", publicName: "fieldId", isSignal: true, isRequired: false, transformFunction: null }, virtual: { classPropertyName: "virtual", publicName: "virtual", isSignal: true, isRequired: false, transformFunction: null }, itemHeight: { classPropertyName: "itemHeight", publicName: "itemHeight", isSignal: true, isRequired: false, transformFunction: null }, virtualPadding: { classPropertyName: "virtualPadding", publicName: "virtualPadding", isSignal: true, isRequired: false, transformFunction: null }, focusable: { classPropertyName: "focusable", publicName: "focusable", isSignal: true, isRequired: false, transformFunction: null }, fieldSticky: { classPropertyName: "fieldSticky", publicName: "fieldSticky", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "tabIndex": "focusable() ? 0 : -1", "style.--ngn-scroller-item-height.px": "itemHeight() ?? \"auto\"", "style.--ngn-scroller-padding-top.px": "paddingTop()", "style.--ngn-scroller-padding-bottom.px": "paddingBottom()" } }, providers: [provideSelf(NgnScroller)], usesInheritance: true, hostDirectives: [{ directive: i1.NgnScrollAmount, inputs: ["ngnScrollAmountContainer", "scrollContainer"] }], ngImport: i0, template: "@if (latestStickyItem(); as latestStickyItem) {\n <ng-container\n *ngTemplateOutlet=\"\n itemTemplate();\n context: { $implicit: latestStickyItem.item, index: latestStickyItem.index }\n \"\n ></ng-container>\n}\n\n@for (item of visibleItems(); track track(item)) {\n <ng-container\n *ngTemplateOutlet=\"itemTemplate(); context: { $implicit: item.item, index: item.index }\"\n ></ng-container>\n}\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
|
|
237
|
+
}
|
|
238
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NgnScroller, decorators: [{
|
|
239
|
+
type: Component,
|
|
240
|
+
args: [{ selector: 'ngn-scroller, [ngn-scroller]', imports: [NgTemplateOutlet], providers: [provideSelf(NgnScroller)], hostDirectives: [
|
|
241
|
+
{ directive: NgnScrollAmount, inputs: ['ngnScrollAmountContainer: scrollContainer'] },
|
|
242
|
+
], host: {
|
|
243
|
+
'[tabIndex]': 'focusable() ? 0 : -1',
|
|
244
|
+
'[style.--ngn-scroller-item-height.px]': 'itemHeight() ?? "auto"',
|
|
245
|
+
'[style.--ngn-scroller-padding-top.px]': 'paddingTop()',
|
|
246
|
+
'[style.--ngn-scroller-padding-bottom.px]': 'paddingBottom()',
|
|
247
|
+
}, template: "@if (latestStickyItem(); as latestStickyItem) {\n <ng-container\n *ngTemplateOutlet=\"\n itemTemplate();\n context: { $implicit: latestStickyItem.item, index: latestStickyItem.index }\n \"\n ></ng-container>\n}\n\n@for (item of visibleItems(); track track(item)) {\n <ng-container\n *ngTemplateOutlet=\"itemTemplate(); context: { $implicit: item.item, index: item.index }\"\n ></ng-container>\n}\n" }]
|
|
248
|
+
}], ctorParameters: () => [], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], fieldId: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldId", required: false }] }], virtual: [{ type: i0.Input, args: [{ isSignal: true, alias: "virtual", required: false }] }], itemHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemHeight", required: false }] }], virtualPadding: [{ type: i0.Input, args: [{ isSignal: true, alias: "virtualPadding", required: false }] }], focusable: [{ type: i0.Input, args: [{ isSignal: true, alias: "focusable", required: false }] }], fieldSticky: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldSticky", required: false }] }] } });
|
|
249
|
+
|
|
250
|
+
class NgnScrollerItem {
|
|
251
|
+
_el = inject((ElementRef));
|
|
252
|
+
/**
|
|
253
|
+
* The item bound to this element. Used to resolve its sticky state and apply
|
|
254
|
+
* the scroller's item classes from the enclosing {@link NgnScroller}.
|
|
255
|
+
*/
|
|
256
|
+
ngnScrollerItem = input.required(/* @ts-ignore */
|
|
257
|
+
...(ngDevMode ? [{ debugName: "ngnScrollerItem" }] : /* istanbul ignore next */ []));
|
|
258
|
+
_scroller = signal(null, /* @ts-ignore */
|
|
259
|
+
...(ngDevMode ? [{ debugName: "_scroller" }] : /* istanbul ignore next */ []));
|
|
260
|
+
ngAfterViewInit() {
|
|
261
|
+
if (!this._el.nativeElement.isConnected) {
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
const parentInstance = getNearestNgnInstance(this._el.nativeElement, NgnScroller);
|
|
265
|
+
if (!parentInstance) {
|
|
266
|
+
throw new NgnError('scroller', 'ngnScrollerItem must be used within an NgnScroller component');
|
|
267
|
+
}
|
|
268
|
+
this._scroller.set(parentInstance);
|
|
269
|
+
}
|
|
270
|
+
constructor() {
|
|
271
|
+
let prevItemClass = '';
|
|
272
|
+
let prevStickyClass = '';
|
|
273
|
+
effect(() => {
|
|
274
|
+
const item = this.ngnScrollerItem();
|
|
275
|
+
const scroller = this._scroller();
|
|
276
|
+
if (!item || !scroller) {
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
const stickyField = scroller.fieldSticky();
|
|
280
|
+
const isSticky = !!stickyField && stickyField in item ? !!item[stickyField] : false;
|
|
281
|
+
const stickyClass = scroller['theme'].class('item-sticky');
|
|
282
|
+
if (prevStickyClass && prevStickyClass !== stickyClass) {
|
|
283
|
+
toggleClass(this._el.nativeElement, prevStickyClass, false);
|
|
284
|
+
}
|
|
285
|
+
toggleClass(this._el.nativeElement, stickyClass, isSticky);
|
|
286
|
+
prevStickyClass = stickyClass;
|
|
287
|
+
const itemClass = scroller['theme'].class('item');
|
|
288
|
+
if (prevItemClass && prevItemClass !== itemClass) {
|
|
289
|
+
toggleClass(this._el.nativeElement, prevItemClass, false);
|
|
290
|
+
}
|
|
291
|
+
toggleClass(this._el.nativeElement, itemClass, true);
|
|
292
|
+
prevItemClass = itemClass;
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NgnScrollerItem, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
296
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.5", type: NgnScrollerItem, isStandalone: true, selector: "[ngnScrollerItem]", inputs: { ngnScrollerItem: { classPropertyName: "ngnScrollerItem", publicName: "ngnScrollerItem", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
|
|
297
|
+
}
|
|
298
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NgnScrollerItem, decorators: [{
|
|
299
|
+
type: Directive,
|
|
300
|
+
args: [{ selector: '[ngnScrollerItem]' }]
|
|
301
|
+
}], ctorParameters: () => [], propDecorators: { ngnScrollerItem: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngnScrollerItem", required: true }] }] } });
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Generated bundle index. Do not edit.
|
|
305
|
+
*/
|
|
306
|
+
|
|
307
|
+
export { NgnScroller, NgnScrollerItem };
|
|
308
|
+
//# sourceMappingURL=ngneers-controls-scroller.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ngneers-controls-scroller.mjs","sources":["../../src/scroller/scroller-templates.ts","../../src/scroller/scroller.ts","../../src/scroller/scroller.html","../../src/scroller/scroller-item.ts","../../src/scroller/ngneers-controls-scroller.ts"],"sourcesContent":["import { computed, contentChild, Directive, input, TemplateRef } from '@angular/core';\nimport { templateTypesFn } from '@ngneers/controls/api/ng';\nimport { NgnBase } from '@ngneers/controls/base';\n\n@Directive()\nexport abstract class ScrollerTemplates<T> extends NgnBase<'scroller'> {\n /**\n * The template to be used for rendering each item in the scroller.\n * Can also be set using the `item` content child.\n */\n public readonly templateItem = input<TemplateRef<typeof this.templateTypes.item> | null>(null);\n private readonly _userItemTemplate =\n contentChild<TemplateRef<typeof this.templateTypes.item>>('item');\n protected readonly itemTemplate = computed(() => this._userItemTemplate() ?? this.templateItem());\n\n /**\n * Template types for the scroller.\n * Can be used with the {@link NgnTemplate} directive for type safe ng-templates.\n */\n public readonly templateTypes = templateTypesFn<{\n item: {\n $implicit: T;\n index: number;\n };\n }>();\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n booleanAttribute,\n Component,\n computed,\n effect,\n ElementRef,\n inject,\n input,\n untracked,\n} from '@angular/core';\nimport { elementSizeSignal } from '@ngneers/controls/api/ng';\nimport { provideSelf } from '@ngneers/controls/base';\nimport { NgnScrollAmount } from '@ngneers/controls/directives';\nimport { type AllKeysOfUnion, getScrollTop, NgnError } from '@ngneers/controls/utils';\nimport { scrollerControlTemplate } from '@ngneers/controls-themes/templates/scroller';\n\nimport { ScrollerTemplates } from './scroller-templates';\n\n/**\n * @category control\n */\n@Component({\n selector: 'ngn-scroller, [ngn-scroller]',\n templateUrl: './scroller.html',\n imports: [NgTemplateOutlet],\n providers: [provideSelf(NgnScroller)],\n hostDirectives: [\n { directive: NgnScrollAmount, inputs: ['ngnScrollAmountContainer: scrollContainer'] },\n ],\n host: {\n '[tabIndex]': 'focusable() ? 0 : -1',\n '[style.--ngn-scroller-item-height.px]': 'itemHeight() ?? \"auto\"',\n '[style.--ngn-scroller-padding-top.px]': 'paddingTop()',\n '[style.--ngn-scroller-padding-bottom.px]': 'paddingBottom()',\n },\n})\nexport class NgnScroller<T> extends ScrollerTemplates<T> {\n protected readonly theme = this.injectThemeTemplate(scrollerControlTemplate, {\n root: true,\n virtual: () => !!this.virtual(),\n });\n private readonly _el = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly _scrollAmount = inject(NgnScrollAmount);\n\n /**\n * The items to be displayed in the scroller.\n * This is a required input and should be an array of items of type {@link T}.\n */\n public readonly items = input.required<readonly T[]>();\n /**\n * The field of the item that uniquely identifies it.\n */\n public readonly fieldId = input<keyof T>();\n /**\n * Whether the scroller should use virtual scrolling.\n * When set to true, the scroller will only render the items that are currently visible\n * on the screen, improving performance for large lists.\n *\n * When virtual scrolling is enabled, {@link itemHeight} must be set to a non-zero value.\n * @default `false`\n */\n public readonly virtual = input(false, { transform: booleanAttribute });\n /**\n * When {@link virtual} scrolling is enabled, this input is required to define the height of each item in pixels.\n */\n public readonly itemHeight = input<number | undefined>(undefined);\n /**\n * When {@link virtual} scrolling is enabled, this input defines the number of items to be rendered above and below the visible area.\n * This can help to reduce flickering when scrolling.\n * @default `2`\n */\n public readonly virtualPadding = input<number>(2);\n /**\n * Determines whether the scroller should have a tab index and be focusable.\n * @default `false`\n */\n public readonly focusable = input(false, { transform: booleanAttribute });\n /**\n * Determines whether an item is sticky or not.\n * If set, the scroller will stick the items with a truthy value for the specified field to the top of the scroller.\n */\n public readonly fieldSticky = input<AllKeysOfUnion<T> | null>(null);\n\n /**\n * Viewport size — tracks the scroll ancestor's dimensions so that virtual\n * scrolling works when an outer element handles overflow (e.g. table wrapper).\n */\n private readonly _viewportSize = elementSizeSignal(\n computed(() => this._scrollAmount.scrollTarget())\n );\n\n private readonly _itemHeightPx = computed(() => this.itemHeight() ?? 0);\n\n /**\n * Vertical offset between the scroll container's top and the scroller element.\n * Non-zero when a parent (e.g. table wrapper) owns the scroll and the scroller\n * is positioned below other content (e.g. a sticky header row).\n */\n private readonly _scrollOffset = computed(() => {\n const target = this._scrollAmount.scrollTarget();\n if (target === this._el.nativeElement) return 0;\n return this._el.nativeElement.offsetTop;\n });\n\n private readonly _visibleItemCount = computed(() => {\n if (!this.virtual() || this._itemHeightPx() === 0) {\n return 0;\n }\n return Math.ceil(\n this._viewportSize().height / this._itemHeightPx() + this.virtualPadding() * 2\n );\n });\n private readonly _scrollTop = computed(() => {\n const raw = this._scrollAmount.scrollTop();\n return Math.max(0, raw - this._scrollOffset());\n });\n /**\n * The index of the first item that is rendered in the (virtual) scroller.\n */\n public readonly itemStartIndex = computed(() => {\n if (!this.virtual() || this._itemHeightPx() === 0) {\n return 0;\n }\n return Math.max(0, Math.ceil(this._scrollTop() / this._itemHeightPx()) - this.virtualPadding());\n });\n private readonly _itemEndIndex = computed(() =>\n this.virtual()\n ? Math.min(this.items().length, this.itemStartIndex() + this._visibleItemCount())\n : 0\n );\n\n protected readonly paddingTop = computed(() => {\n if (!this.virtual()) {\n return 0;\n }\n return (this.itemStartIndex() - (this.latestStickyItem() ? 1 : 0)) * this._itemHeightPx();\n });\n\n protected readonly paddingBottom = computed(() => {\n if (!this.virtual()) {\n return 0;\n }\n return (this.items().length - this._itemEndIndex()) * this._itemHeightPx();\n });\n\n protected readonly visibleItems = computed(() => {\n if (!this.virtual()) {\n return this.items().map((item, index) => ({ item, index }));\n }\n return this.items()\n .slice(this.itemStartIndex(), this._itemEndIndex())\n .map((item, index) => {\n return {\n item,\n index: this.itemStartIndex() + index,\n };\n });\n });\n\n /**\n * Returns the last sticky item that is not rendered regularly in the list.\n * Required because sticky items might need to be rendered longer than they would.\n * Only applicable when virtual scrolling is enabled.\n */\n protected readonly latestStickyItem = computed(() => {\n if (!this.virtual()) {\n return null;\n }\n const stickyField = this.fieldSticky();\n if (!stickyField) {\n return null;\n }\n const unrenderedItemsAtTop = this.items()\n .slice(0, this.itemStartIndex())\n .map((item, index) => ({\n item,\n index,\n }));\n const stickyItems = unrenderedItemsAtTop.filter(item => item.item[stickyField]);\n return stickyItems[stickyItems.length - 1] ?? null;\n });\n\n constructor() {\n super();\n effect(() => {\n if (this.virtual() && !this.itemHeight()) {\n throw new NgnError('scroller', 'itemHeight must be set when virtual is true');\n }\n });\n }\n\n /**\n * Scrolls the item with the given index into view.\n * @param index The index of the item to scroll to.\n */\n public scrollToIndex(index: number, position: ScrollLogicalPosition = 'nearest') {\n untracked(() => {\n const scrollEl = this._scrollAmount.scrollTarget();\n const offset = this._scrollOffset();\n\n const getItemSize = () => {\n if (this.virtual()) {\n const itemHeight = this._itemHeightPx();\n const itemTop = index * itemHeight + offset;\n return { itemHeight, itemTop };\n } else {\n let itemElement = this._el.nativeElement.children[index] as HTMLElement | null;\n while (!itemElement?.clientHeight && itemElement?.children.length) {\n itemElement = itemElement?.children[0] as HTMLElement | null;\n }\n if (itemElement) {\n const itemTop = itemElement.offsetTop;\n const itemHeight = itemElement.clientHeight;\n return { itemTop, itemHeight };\n }\n return null;\n }\n };\n const size = getItemSize();\n if (!size) {\n return;\n }\n const { itemTop, itemHeight } = size;\n scrollEl.scrollTo({\n top: getScrollTop(itemTop, itemHeight, scrollEl.clientHeight, scrollEl.scrollTop, position),\n });\n });\n }\n\n protected track(item: { item: T; index: number }): unknown {\n const fieldId = this.fieldId();\n if (fieldId) {\n return item.item[fieldId];\n }\n return item.index;\n }\n}\n","@if (latestStickyItem(); as latestStickyItem) {\n <ng-container\n *ngTemplateOutlet=\"\n itemTemplate();\n context: { $implicit: latestStickyItem.item, index: latestStickyItem.index }\n \"\n ></ng-container>\n}\n\n@for (item of visibleItems(); track track(item)) {\n <ng-container\n *ngTemplateOutlet=\"itemTemplate(); context: { $implicit: item.item, index: item.index }\"\n ></ng-container>\n}\n","import {\n type AfterViewInit,\n Directive,\n effect,\n ElementRef,\n inject,\n input,\n signal,\n} from '@angular/core';\nimport { getNearestNgnInstance } from '@ngneers/controls/base';\nimport { NgnError, toggleClass } from '@ngneers/controls/utils';\n\nimport { NgnScroller } from './scroller';\n\n@Directive({ selector: '[ngnScrollerItem]' })\nexport class NgnScrollerItem implements AfterViewInit {\n private readonly _el = inject(ElementRef<HTMLElement>);\n /**\n * The item bound to this element. Used to resolve its sticky state and apply\n * the scroller's item classes from the enclosing {@link NgnScroller}.\n */\n public readonly ngnScrollerItem = input.required<object>();\n private readonly _scroller = signal<NgnScroller<unknown> | null>(null);\n\n public ngAfterViewInit() {\n if (!this._el.nativeElement.isConnected) {\n return;\n }\n const parentInstance = getNearestNgnInstance(this._el.nativeElement, NgnScroller);\n if (!parentInstance) {\n throw new NgnError(\n 'scroller',\n 'ngnScrollerItem must be used within an NgnScroller component'\n );\n }\n this._scroller.set(parentInstance);\n }\n\n constructor() {\n let prevItemClass = '';\n let prevStickyClass = '';\n effect(() => {\n const item = this.ngnScrollerItem() as Record<string, unknown> | null;\n const scroller = this._scroller();\n if (!item || !scroller) {\n return;\n }\n const stickyField = scroller.fieldSticky() as unknown as string | null;\n const isSticky = !!stickyField && stickyField in item ? !!item[stickyField] : false;\n\n const stickyClass = scroller['theme'].class('item-sticky');\n if (prevStickyClass && prevStickyClass !== stickyClass) {\n toggleClass(this._el.nativeElement, prevStickyClass, false);\n }\n toggleClass(this._el.nativeElement, stickyClass, isSticky);\n prevStickyClass = stickyClass;\n\n const itemClass = scroller['theme'].class('item');\n if (prevItemClass && prevItemClass !== itemClass) {\n toggleClass(this._el.nativeElement, prevItemClass, false);\n }\n toggleClass(this._el.nativeElement, itemClass, true);\n prevItemClass = itemClass;\n });\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, Component } from '@angular/core';
|
|
3
|
+
import { ValueControlBase, NgnPt, provideSelf } from '@ngneers/controls/base';
|
|
4
|
+
import { NgnButtonGroup } from '@ngneers/controls/button-group';
|
|
5
|
+
import { NgnToggleButton } from '@ngneers/controls/toggle-button';
|
|
6
|
+
import { maybeCallback } from '@ngneers/controls/utils';
|
|
7
|
+
import { selectButtonControlTemplate } from '@ngneers/controls-themes/templates/select-button';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @category control
|
|
11
|
+
*/
|
|
12
|
+
class NgnSelectButton extends ValueControlBase {
|
|
13
|
+
theme = this.injectThemeTemplate(selectButtonControlTemplate, {
|
|
14
|
+
root: true,
|
|
15
|
+
invalid: () => this.invalid(),
|
|
16
|
+
});
|
|
17
|
+
/**
|
|
18
|
+
* Defines the orientation of the select buttons.
|
|
19
|
+
* - 'auto' - The orientation is determined based on the available space.
|
|
20
|
+
* - 'horizontal' - The buttons are arranged horizontally. (Default for `auto` if enough space)
|
|
21
|
+
* - 'vertical' - The buttons are arranged vertically.
|
|
22
|
+
* @default 'auto'
|
|
23
|
+
*/
|
|
24
|
+
orientation = input('auto', /* @ts-ignore */
|
|
25
|
+
...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
|
|
26
|
+
/**
|
|
27
|
+
* Defines the options for the select button.
|
|
28
|
+
*/
|
|
29
|
+
options = input.required(/* @ts-ignore */
|
|
30
|
+
...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
31
|
+
/**
|
|
32
|
+
* When `true`, allows unselecting the currently selected option by clicking on it again.
|
|
33
|
+
* If `false`, clicking on the selected option will not change the selection.
|
|
34
|
+
* @default false
|
|
35
|
+
*/
|
|
36
|
+
allowUnselect = input(false, /* @ts-ignore */
|
|
37
|
+
...(ngDevMode ? [{ debugName: "allowUnselect" }] : /* istanbul ignore next */ []));
|
|
38
|
+
maybeCallback = maybeCallback;
|
|
39
|
+
valueChange(value) {
|
|
40
|
+
if (this.value() === value && !this.allowUnselect()) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
this.value.set(value);
|
|
44
|
+
}
|
|
45
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NgnSelectButton, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
46
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: NgnSelectButton, isStandalone: true, selector: "ngn-select-button", inputs: { orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, allowUnselect: { classPropertyName: "allowUnselect", publicName: "allowUnselect", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideSelf(NgnSelectButton)], usesInheritance: true, ngImport: i0, template: "<ngn-button-group\n [orientation]=\"orientation()\"\n [attr.aria-label]=\"label()\"\n [attr.aria-labelledby]=\"labelledBy()\"\n [ptInt]=\"this\"\n [ptDep]=\"'group'\"\n>\n @for (item of options(); track item.value) {\n <ngn-toggle-button\n [label]=\"maybeCallback(item.label)\"\n [icon]=\"item.icon\"\n [fixedWidth]=\"true\"\n (valueChange)=\"valueChange(item.value)\"\n [value]=\"value() === item.value\"\n [readonly]=\"readonly() || (value() === item.value && !allowUnselect())\"\n [attr.data-testid]=\"item.testId\"\n [disabled]=\"disabled()\"\n [ptInt]=\"this\"\n [ptDep]=\"'button'\"\n />\n }\n</ngn-button-group>\n", dependencies: [{ kind: "directive", type: NgnPt, selector: "[ptInt]", inputs: ["ptInt", "ptClass", "ptDep"] }, { kind: "component", type: NgnButtonGroup, selector: "ngn-button-group", inputs: ["orientation"] }, { kind: "component", type: NgnToggleButton, selector: "ngn-toggle-button", inputs: ["labelOn", "labelOff", "icon", "iconOn", "iconOff", "fixedWidth"] }] });
|
|
47
|
+
}
|
|
48
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NgnSelectButton, decorators: [{
|
|
49
|
+
type: Component,
|
|
50
|
+
args: [{ selector: 'ngn-select-button', imports: [NgnPt, NgnButtonGroup, NgnToggleButton], providers: [provideSelf(NgnSelectButton)], template: "<ngn-button-group\n [orientation]=\"orientation()\"\n [attr.aria-label]=\"label()\"\n [attr.aria-labelledby]=\"labelledBy()\"\n [ptInt]=\"this\"\n [ptDep]=\"'group'\"\n>\n @for (item of options(); track item.value) {\n <ngn-toggle-button\n [label]=\"maybeCallback(item.label)\"\n [icon]=\"item.icon\"\n [fixedWidth]=\"true\"\n (valueChange)=\"valueChange(item.value)\"\n [value]=\"value() === item.value\"\n [readonly]=\"readonly() || (value() === item.value && !allowUnselect())\"\n [attr.data-testid]=\"item.testId\"\n [disabled]=\"disabled()\"\n [ptInt]=\"this\"\n [ptDep]=\"'button'\"\n />\n }\n</ngn-button-group>\n" }]
|
|
51
|
+
}], propDecorators: { orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], allowUnselect: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowUnselect", required: false }] }] } });
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Generated bundle index. Do not edit.
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
export { NgnSelectButton };
|
|
58
|
+
//# sourceMappingURL=ngneers-controls-select-button.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ngneers-controls-select-button.mjs","sources":["../../src/select-button/select-button.ts","../../src/select-button/select-button.html","../../src/select-button/ngneers-controls-select-button.ts"],"sourcesContent":["import { Component, input } from '@angular/core';\nimport { NgnPt, provideSelf, ValueControlBase } from '@ngneers/controls/base';\nimport { NgnButtonGroup } from '@ngneers/controls/button-group';\nimport { NgnToggleButton } from '@ngneers/controls/toggle-button';\nimport { maybeCallback } from '@ngneers/controls/utils';\nimport { selectButtonControlTemplate } from '@ngneers/controls-themes/templates/select-button';\n\nimport type { NgnActionItemFlat, NgnItem } from '@ngneers/controls/api';\n\n/**\n * @category control\n */\n@Component({\n selector: 'ngn-select-button',\n templateUrl: './select-button.html',\n imports: [NgnPt, NgnButtonGroup, NgnToggleButton],\n providers: [provideSelf(NgnSelectButton)],\n})\nexport class NgnSelectButton<V> extends ValueControlBase<'selectButton', V> {\n protected readonly theme = this.injectThemeTemplate(selectButtonControlTemplate, {\n root: true,\n invalid: () => this.invalid(),\n });\n\n /**\n * Defines the orientation of the select buttons.\n * - 'auto' - The orientation is determined based on the available space.\n * - 'horizontal' - The buttons are arranged horizontally. (Default for `auto` if enough space)\n * - 'vertical' - The buttons are arranged vertically.\n * @default 'auto'\n */\n public readonly orientation = input<'auto' | 'horizontal' | 'vertical'>('auto');\n /**\n * Defines the options for the select button.\n */\n public readonly options = input.required<readonly NgnActionItemFlat<NgnItem<unknown, V>>[]>();\n /**\n * When `true`, allows unselecting the currently selected option by clicking on it again.\n * If `false`, clicking on the selected option will not change the selection.\n * @default false\n */\n public readonly allowUnselect = input<boolean>(false);\n\n protected readonly maybeCallback = maybeCallback;\n\n protected valueChange(value: V) {\n if (this.value() === value && !this.allowUnselect()) {\n return;\n }\n this.value.set(value);\n }\n}\n","<ngn-button-group\n [orientation]=\"orientation()\"\n [attr.aria-label]=\"label()\"\n [attr.aria-labelledby]=\"labelledBy()\"\n [ptInt]=\"this\"\n [ptDep]=\"'group'\"\n>\n @for (item of options(); track item.value) {\n <ngn-toggle-button\n [label]=\"maybeCallback(item.label)\"\n [icon]=\"item.icon\"\n [fixedWidth]=\"true\"\n (valueChange)=\"valueChange(item.value)\"\n [value]=\"value() === item.value\"\n [readonly]=\"readonly() || (value() === item.value && !allowUnselect())\"\n [attr.data-testid]=\"item.testId\"\n [disabled]=\"disabled()\"\n [ptInt]=\"this\"\n [ptDep]=\"'button'\"\n />\n }\n</ngn-button-group>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;AASA;;AAEG;AAOG,MAAO,eAAmB,SAAQ,gBAAmC,CAAA;AACtD,IAAA,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,2BAA2B,EAAE;AAC/E,QAAA,IAAI,EAAE,IAAI;AACV,QAAA,OAAO,EAAE,MAAM,IAAI,CAAC,OAAO,EAAE;AAC9B,KAAA,CAAC;AAEF;;;;;;AAMG;IACa,WAAW,GAAG,KAAK,CAAqC,MAAM;oFAAC;AAC/E;;AAEG;IACa,OAAO,GAAG,KAAK,CAAC,QAAQ;gFAAqD;AAC7F;;;;AAIG;IACa,aAAa,GAAG,KAAK,CAAU,KAAK;sFAAC;IAElC,aAAa,GAAG,aAAa;AAEtC,IAAA,WAAW,CAAC,KAAQ,EAAA;AAC5B,QAAA,IAAI,IAAI,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE;YACnD;QACF;AACA,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;IACvB;uGAhCW,eAAe,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAf,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,eAAe,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,SAAA,EAFf,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,EAAA,eAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EChB3C,6qBAsBA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDPY,KAAK,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,SAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,cAAc,sFAAE,eAAe,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,SAAA,EAAA,YAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAGrC,eAAe,EAAA,UAAA,EAAA,CAAA;kBAN3B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,mBAAmB,EAAA,OAAA,EAEpB,CAAC,KAAK,EAAE,cAAc,EAAE,eAAe,CAAC,EAAA,SAAA,EACtC,CAAC,WAAW,CAAA,eAAA,CAAiB,CAAC,EAAA,QAAA,EAAA,6qBAAA,EAAA;;;AEhB3C;;AAEG;;;;"}
|