@elderbyte/ngx-starter 18.1.0-beta → 18.2.0-beta

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.
Files changed (25) hide show
  1. package/esm2022/lib/common/utils/input-utils.mjs +6 -0
  2. package/esm2022/lib/components/data-view/table/activation/elder-table-activation.directive.mjs +14 -7
  3. package/esm2022/lib/components/files/blob-viewer/elder-blob-viewer.component.mjs +17 -23
  4. package/esm2022/lib/components/files/elder-file-select.directive.mjs +85 -86
  5. package/esm2022/lib/components/files/listing/file-entry.mjs +15 -30
  6. package/esm2022/lib/components/files/listing/file-listing-rx.mjs +70 -27
  7. package/esm2022/lib/components/forms/directives/validation/validators/elder-multiple-of.validator.mjs +17 -13
  8. package/fesm2022/elderbyte-ngx-starter.mjs +154 -413
  9. package/fesm2022/elderbyte-ngx-starter.mjs.map +1 -1
  10. package/lib/common/utils/input-utils.d.ts +18 -0
  11. package/lib/components/data-view/table/activation/elder-table-activation.directive.d.ts +4 -1
  12. package/lib/components/files/blob-viewer/elder-blob-viewer.component.d.ts +3 -3
  13. package/lib/components/files/elder-file-select.directive.d.ts +23 -15
  14. package/lib/components/files/listing/file-entry.d.ts +1 -10
  15. package/lib/components/files/listing/file-listing-rx.d.ts +6 -2
  16. package/lib/components/forms/directives/validation/validators/elder-multiple-of.validator.d.ts +2 -4
  17. package/package.json +1 -1
  18. package/esm2022/lib/components/files/elder-file-select-input.mjs +0 -119
  19. package/esm2022/lib/components/files/file-system-api.mjs +0 -88
  20. package/esm2022/lib/components/files/listing/file-listing-system-handle.mjs +0 -35
  21. package/esm2022/lib/components/files/listing/file-listing-webkit.mjs +0 -77
  22. package/lib/components/files/elder-file-select-input.d.ts +0 -59
  23. package/lib/components/files/file-system-api.d.ts +0 -82
  24. package/lib/components/files/listing/file-listing-system-handle.d.ts +0 -21
  25. package/lib/components/files/listing/file-listing-webkit.d.ts +0 -26
@@ -1,11 +1,11 @@
1
1
  import * as i2$1 from '@angular/common';
2
2
  import { formatDate, CommonModule, formatCurrency, getCurrencySymbol, NgIf, AsyncPipe, NgFor, NgClass, NgTemplateOutlet, NgStyle, formatNumber, DecimalPipe, DatePipe, registerLocaleData, CurrencyPipe } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
- import { Pipe, LOCALE_ID, Inject, NgModule, Optional, SkipSelf, Directive, Output, Input, forwardRef, ViewChild, HostBinding, ViewChildren, ContentChild, Injectable, Component, ChangeDetectionStrategy, Host, APP_INITIALIZER, TemplateRef, HostListener, EventEmitter, ViewEncapsulation, InjectionToken, ContentChildren, Self, input } from '@angular/core';
4
+ import { Pipe, LOCALE_ID, Inject, NgModule, Optional, SkipSelf, Directive, Output, Input, forwardRef, ViewChild, HostBinding, ViewChildren, ContentChild, Injectable, Component, ChangeDetectionStrategy, Host, APP_INITIALIZER, TemplateRef, HostListener, EventEmitter, input, ViewEncapsulation, InjectionToken, ContentChildren, Self } from '@angular/core';
5
5
  import * as i1 from '@angular/platform-browser';
6
6
  import { Duration, Period, TemporalQueries, LocalTime, Instant, LocalDate, nativeJs, ZoneId, DateTimeFormatter, convert, ZonedDateTime, Temporal } from '@js-joda/core';
7
7
  import { LoggerFactory } from '@elderbyte/ts-logger';
8
- import { timer, defer, ReplaySubject, concat, finalize, exhaustMap, BehaviorSubject, Subject, switchMap, of, combineLatest, EMPTY, merge, throwError, forkJoin, mergeWith, Observable, from, toArray, zip, mergeMap as mergeMap$1, fromEvent, skipUntil, combineLatestWith as combineLatestWith$1, NEVER } from 'rxjs';
8
+ import { timer, defer, ReplaySubject, concat, finalize, exhaustMap, BehaviorSubject, Subject, switchMap, of, combineLatest, EMPTY, merge, throwError, forkJoin, mergeWith, Observable, zip, mergeMap as mergeMap$1, fromEvent, skipUntil, combineLatestWith as combineLatestWith$1, NEVER } from 'rxjs';
9
9
  import { tap, takeUntil, takeWhile, map, filter, distinctUntilChanged, debounceTime, catchError, first, take, switchMap as switchMap$1, mergeMap, expand, reduce, startWith, skip, delay, share, combineLatestWith, skipWhile, timeout } from 'rxjs/operators';
10
10
  import * as i1$2 from '@angular/common/http';
11
11
  import { HttpParams, HttpEventType, HttpRequest, HttpClient, HttpErrorResponse, HTTP_INTERCEPTORS } from '@angular/common/http';
@@ -36,7 +36,6 @@ import { MatAutocompleteTrigger, MatAutocomplete, MatAutocompleteModule } from '
36
36
  import * as i1$7 from '@angular/material/chips';
37
37
  import { MatChipGrid, MatChipRow, MatChipRemove, MatChipInput, MatChipsModule, MatChip, MatChipAvatar, MatChipSet, MatChipTrailingIcon, MatChipListbox, MatChipOption } from '@angular/material/chips';
38
38
  import { MatInput, MatInputModule } from '@angular/material/input';
39
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
40
39
  import { MatList, MatListSubheaderCssMatStyler, MatListItem, MatListModule } from '@angular/material/list';
41
40
  import { MatProgressBar, MatProgressBarModule } from '@angular/material/progress-bar';
42
41
  import * as i1$5 from '@angular/material/snack-bar';
@@ -51,6 +50,7 @@ import * as i1$6 from '@angular/material/dialog';
51
50
  import { MatDialogClose, MAT_DIALOG_DATA, MatDialogConfig, MatDialogModule } from '@angular/material/dialog';
52
51
  import { MatMenuTrigger, MatMenu, MatMenuItem, MatMenuModule } from '@angular/material/menu';
53
52
  import { MatTooltipModule, MatTooltip } from '@angular/material/tooltip';
53
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
54
54
  import { MatPaginator, MatPaginatorIntl, MatPaginatorModule } from '@angular/material/paginator';
55
55
  import { MatColumnDef, MatRowDef, MatTable, MatHeaderCellDef, MatHeaderCell, MatCellDef, MatCell, MatFooterCellDef, MatFooterCell, MatHeaderRowDef, MatHeaderRow, MatRow, MatFooterRowDef, MatFooterRow, MatTableModule } from '@angular/material/table';
56
56
  import * as i1$8 from '@angular/cdk/table';
@@ -9715,92 +9715,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImpor
9715
9715
  }]
9716
9716
  }] });
9717
9717
 
9718
- /***************************************************************************
9719
- * *
9720
- * FileSystem API *
9721
- * *
9722
- **************************************************************************/
9723
- /**
9724
- * Holds experimental features of the browser `File System API`. No typescript lint checks
9725
- * are performed here!
9726
- */
9727
- class FileSystemApi {
9728
- /***************************************************************************
9729
- * *
9730
- * DataTransferItem *
9731
- * *
9732
- **************************************************************************/
9733
- static isGetAsFileSystemHandleSupported(transferItem) {
9734
- // @ts-ignore
9735
- return transferItem.getAsFileSystemHandle !== undefined;
9736
- }
9737
- static getAsFileSystemHandle(transferItem) {
9738
- // @ts-ignore
9739
- return from(transferItem.getAsFileSystemHandle());
9740
- }
9741
- /***************************************************************************
9742
- * *
9743
- * File Picker *
9744
- * *
9745
- **************************************************************************/
9746
- static isFileSystemSupported() {
9747
- return 'showOpenFilePicker' in window;
9748
- }
9749
- static openFilePicker(pickerOpts) {
9750
- try {
9751
- // @ts-ignore
9752
- return from(window.showOpenFilePicker(pickerOpts));
9753
- }
9754
- catch (e) {
9755
- return throwError(() => new Error(e));
9756
- }
9757
- }
9758
- /***************************************************************************
9759
- * *
9760
- * Directory Picker *
9761
- * *
9762
- **************************************************************************/
9763
- static isDirectoryPickerSupported() {
9764
- return 'showDirectoryPicker' in window;
9765
- }
9766
- static openDirectoryPicker(pickerOpts) {
9767
- try {
9768
- // @ts-ignore
9769
- return from(window.showDirectoryPicker(pickerOpts));
9770
- }
9771
- catch (e) {
9772
- return throwError(() => new Error(e));
9773
- }
9774
- }
9775
- /***************************************************************************
9776
- * *
9777
- * FileSystemDirectoryHandle *
9778
- * *
9779
- **************************************************************************/
9780
- static getHandlesFromDirectory(dirHandle) {
9781
- return from(FileSystemApi.getHandlesFromDirectoryAsync(dirHandle));
9782
- }
9783
- static buildRelativeParent(fileOrDirHandle, rootDirectory) {
9784
- if (rootDirectory == null) {
9785
- return of(undefined);
9786
- }
9787
- const relativeParents$ = from(rootDirectory.resolve(fileOrDirHandle));
9788
- return relativeParents$.pipe(map(parents => {
9789
- const path = parents;
9790
- path.pop();
9791
- return path.join('/');
9792
- }));
9793
- }
9794
- static async getHandlesFromDirectoryAsync(dirHandle) {
9795
- const handles = [];
9796
- // @ts-ignore
9797
- for await (const handle of dirHandle.values()) {
9798
- handles.push(handle);
9799
- }
9800
- return handles;
9801
- }
9802
- }
9803
-
9804
9718
  /**
9805
9719
  * Represents a file and the relative path where the user has selected it.
9806
9720
  * This is useful if the user has selected a folder and files
@@ -9815,24 +9729,26 @@ class FileEntry {
9815
9729
  * which is also supported by this method.
9816
9730
  */
9817
9731
  static ofFile(file) {
9818
- return FileEntry.relativeFile(file, this.buildRelativeParent(file));
9819
- }
9820
- /**
9821
- * Creates an Observable of a File Entry by resolving its FileSystemFileHandle.
9822
- * @param fileHandle
9823
- * @param rootDirectory is needed to build a relative parent
9824
- */
9825
- static ofFileHandle(fileHandle, rootDirectory) {
9826
- return from(fileHandle.getFile()).pipe(combineLatestWith(FileSystemApi.buildRelativeParent(fileHandle, rootDirectory)), map(([file, relativeParent]) => FileEntry.relativeFile(file, relativeParent, fileHandle)));
9732
+ let relativeParent = null;
9733
+ if (file.webkitRelativePath) {
9734
+ if (file.webkitRelativePath.endsWith(file.name)) {
9735
+ const nameStart = file.webkitRelativePath.length - file.name.length;
9736
+ relativeParent = file.webkitRelativePath.substring(0, nameStart);
9737
+ }
9738
+ else {
9739
+ relativeParent = file.webkitRelativePath;
9740
+ }
9741
+ }
9742
+ return FileEntry.relativeFile(file, relativeParent);
9827
9743
  }
9828
9744
  /**
9829
9745
  * Creates a file Entry with a relative parent path
9830
9746
  */
9831
- static relativeFile(file, relativeParent, fileHandle) {
9747
+ static relativeFile(file, relativeParent) {
9832
9748
  if (relativeParent && relativeParent.endsWith('/')) {
9833
9749
  relativeParent = relativeParent.substring(0, relativeParent.length - 1);
9834
9750
  }
9835
- return new FileEntry(file, relativeParent, fileHandle);
9751
+ return new FileEntry(file, relativeParent);
9836
9752
  }
9837
9753
  static toFileMap(entries) {
9838
9754
  const map = new Map();
@@ -9852,10 +9768,9 @@ class FileEntry {
9852
9768
  * Contains the relative path from the selected folder
9853
9769
  * to this file. Only relevant if the user has selected a folder.
9854
9770
  */
9855
- relativeParent, fileHandle) {
9771
+ relativeParent) {
9856
9772
  this.file = file;
9857
9773
  this.relativeParent = relativeParent;
9858
- this.fileHandle = fileHandle;
9859
9774
  this.relativePath = FileEntry.buildRelativePath(relativeParent, file);
9860
9775
  }
9861
9776
  /***************************************************************************
@@ -9874,46 +9789,42 @@ class FileEntry {
9874
9789
  return file.name;
9875
9790
  }
9876
9791
  }
9877
- static buildRelativeParent(file) {
9878
- let relativeParent = null;
9879
- if (file.webkitRelativePath) {
9880
- if (file.webkitRelativePath.endsWith(file.name)) {
9881
- const nameStart = file.webkitRelativePath.length - file.name.length;
9882
- relativeParent = file.webkitRelativePath.substring(0, nameStart);
9883
- }
9884
- else {
9885
- relativeParent = file.webkitRelativePath;
9886
- }
9887
- }
9888
- return relativeParent;
9889
- }
9890
9792
  }
9891
9793
 
9892
- class ElderFileSelectInput {
9794
+ class ElderFileSelectDirective {
9893
9795
  /***************************************************************************
9894
9796
  * *
9895
9797
  * Constructor *
9896
9798
  * *
9897
9799
  **************************************************************************/
9898
- constructor(renderer, el) {
9899
- this.renderer = renderer;
9800
+ constructor(el, renderer) {
9900
9801
  this.el = el;
9802
+ this.renderer = renderer;
9901
9803
  /***************************************************************************
9902
9804
  * *
9903
9805
  * Fields *
9904
9806
  * *
9905
9807
  **************************************************************************/
9906
9808
  this.logger = LoggerFactory.getLogger(this.constructor.name);
9907
- this._filesSelected = new Subject;
9809
+ this.elderFileSelectChange = new EventEmitter();
9810
+ this.elderSingleFileSelectChange = new EventEmitter();
9908
9811
  }
9909
9812
  /***************************************************************************
9910
9813
  * *
9911
- * Properties *
9814
+ * Life Cycle *
9912
9815
  * *
9913
9816
  **************************************************************************/
9914
- get filesSelected() {
9915
- return this._filesSelected;
9817
+ ngOnInit() {
9818
+ this.createFileSelect();
9916
9819
  }
9820
+ ngOnDestroy() {
9821
+ this.removeFileSelect();
9822
+ }
9823
+ /***************************************************************************
9824
+ * *
9825
+ * Properties *
9826
+ * *
9827
+ **************************************************************************/
9917
9828
  set elderFileSelect(value) {
9918
9829
  this._accept = value;
9919
9830
  if (this._fileInput) {
@@ -9926,6 +9837,11 @@ class ElderFileSelectInput {
9926
9837
  this.renderer.setProperty(this._fileInput, 'multiple', value);
9927
9838
  }
9928
9839
  }
9840
+ /**
9841
+ * Allow the user to select a directory. All files that are recursively contained are selected.
9842
+ * However, the user will no longer be able to select individual files if this is enabled.
9843
+ * @param value
9844
+ */
9929
9845
  set elderFileSelectDirectory(value) {
9930
9846
  this._directory = coerceBooleanProperty(value);
9931
9847
  if (this._fileInput) {
@@ -9938,6 +9854,17 @@ class ElderFileSelectInput {
9938
9854
  * Public API *
9939
9855
  * *
9940
9856
  **************************************************************************/
9857
+ onClick(event) {
9858
+ this.openFileSelectDialog();
9859
+ }
9860
+ openFileSelectDialog() {
9861
+ this._fileInput.click();
9862
+ }
9863
+ /***************************************************************************
9864
+ * *
9865
+ * Private methods *
9866
+ * *
9867
+ **************************************************************************/
9941
9868
  /**
9942
9869
  * <input type="file"
9943
9870
  * hidden #fileInput
@@ -9961,9 +9888,7 @@ class ElderFileSelectInput {
9961
9888
  this.renderer.setAttribute(this._fileInput, 'webkitdirectory', 'true');
9962
9889
  this.renderer.setAttribute(this._fileInput, 'directory', 'true');
9963
9890
  }
9964
- this._unlisten = this.renderer.listen(this._fileInput, 'change', event => {
9965
- this.fileInputChanged(this._fileInput.files);
9966
- });
9891
+ this._unlisten = this.renderer.listen(this._fileInput, 'change', event => this.fileInputChanged(event));
9967
9892
  }
9968
9893
  removeFileSelect() {
9969
9894
  if (this._unlisten) {
@@ -9975,24 +9900,26 @@ class ElderFileSelectInput {
9975
9900
  this._fileInput = null;
9976
9901
  }
9977
9902
  }
9978
- openFileSelectDialog() {
9979
- this._fileInput.click();
9980
- }
9981
- /***************************************************************************
9982
- * *
9983
- * Private methods *
9984
- * *
9985
- **************************************************************************/
9986
- fileInputChanged(fileList) {
9903
+ fileInputChanged(event) {
9904
+ const fileList = this._fileInput.files;
9987
9905
  const files = this.toFileEntries(fileList);
9988
9906
  this.logger.debug('fileInputChanged, files:', files);
9907
+ this.emitFileList(files);
9989
9908
  this.clearFileList();
9990
- this._filesSelected.next(files);
9991
9909
  }
9992
9910
  clearFileList() {
9993
9911
  // not nice but works
9994
9912
  this._fileInput.value = null;
9995
9913
  }
9914
+ emitFileList(files) {
9915
+ if (files.length > 0) {
9916
+ this.elderFileSelectChange.next(files);
9917
+ this.elderSingleFileSelectChange.emit(files[0].file);
9918
+ }
9919
+ else {
9920
+ this.logger.warn('User did not select any File or the Folder was empty.');
9921
+ }
9922
+ }
9996
9923
  toFileEntries(fileList) {
9997
9924
  const files = [];
9998
9925
  for (const key in fileList) {
@@ -10002,174 +9929,7 @@ class ElderFileSelectInput {
10002
9929
  }
10003
9930
  return files;
10004
9931
  }
10005
- }
10006
-
10007
- class FileListingSystemHandle {
10008
- /***************************************************************************
10009
- * *
10010
- * Public methods *
10011
- * *
10012
- **************************************************************************/
10013
- /**
10014
- * Creates a File Entry Array Observable by resolving its FileSystemHandle.
10015
- * @returns An `Observable<FileEntry[]>` with the FileSystemFileHandle included
10016
- */
10017
- static listFiles(handle, rootDirectory) {
10018
- switch (handle.kind) {
10019
- case 'file':
10020
- return FileEntry.ofFileHandle(handle, rootDirectory).pipe(toArray());
10021
- case 'directory':
10022
- return FileListingSystemHandle.listFilesRecursive(handle, rootDirectory);
10023
- }
10024
- }
10025
- /***************************************************************************
10026
- * *
10027
- * Private methods *
10028
- * *
10029
- **************************************************************************/
10030
- static listFilesRecursive(dirHandle, rootDirectory) {
10031
- return FileSystemApi.getHandlesFromDirectory(dirHandle).pipe(map(handles => FileListingSystemHandle.listFilesOfEach(handles, rootDirectory ? rootDirectory : dirHandle)), switchMap(fileEntriesArray$ => zip(fileEntriesArray$)), map(fileEntriesArray => fileEntriesArray.flat()));
10032
- }
10033
- static listFilesOfEach(handles, rootDirectory) {
10034
- return handles.map(fileOrDirHandle => FileListingSystemHandle.listFiles(fileOrDirHandle, rootDirectory));
10035
- }
10036
- }
10037
-
10038
- class ElderFileSelectDirective {
10039
- /***************************************************************************
10040
- * *
10041
- * Constructor *
10042
- * *
10043
- **************************************************************************/
10044
- constructor(renderer, el, destroyRef) {
10045
- this.renderer = renderer;
10046
- this.el = el;
10047
- this.destroyRef = destroyRef;
10048
- /***************************************************************************
10049
- * *
10050
- * Fields *
10051
- * *
10052
- **************************************************************************/
10053
- this.logger = LoggerFactory.getLogger(this.constructor.name);
10054
- this.elderFileSelectChange = new EventEmitter();
10055
- this.elderSingleFileSelectChange = new EventEmitter();
10056
- this._useDirectoryPicker = false;
10057
- this._legacyInput = new ElderFileSelectInput(this.renderer, this.el);
10058
- }
10059
- /***************************************************************************
10060
- * *
10061
- * Life Cycle *
10062
- * *
10063
- **************************************************************************/
10064
- ngOnInit() {
10065
- if (!FileSystemApi.isFileSystemSupported() || !FileSystemApi.isDirectoryPickerSupported()) {
10066
- this.logger.warn('showOpenFilePicker or showDirectoryPicker is not supported for this browser, falling back to legacy file picker');
10067
- this._legacyInput.createFileSelect();
10068
- this._legacyInput.filesSelected.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
10069
- next: multiFileChange => {
10070
- this.elderFileSelectChange.next(multiFileChange);
10071
- const file = multiFileChange[0]?.file;
10072
- if (file) {
10073
- this.elderSingleFileSelectChange.next(file);
10074
- }
10075
- }
10076
- });
10077
- }
10078
- }
10079
- ngOnDestroy() {
10080
- this._legacyInput.removeFileSelect();
10081
- }
10082
- /***************************************************************************
10083
- * *
10084
- * Properties *
10085
- * *
10086
- **************************************************************************/
10087
- set elderFileSelect(value) {
10088
- this._filePickerOptions = {
10089
- excludeAcceptAllOptions: true,
10090
- id: this._filePickerOptions?.id,
10091
- multiple: this._filePickerOptions?.multiple,
10092
- startIn: this._filePickerOptions?.startIn,
10093
- types: [this.buildTypeOption(value)]
10094
- };
10095
- this._legacyInput.elderFileSelect = value;
10096
- }
10097
- buildTypeOption(value) {
10098
- if (this.isFileExtension(value)) {
10099
- return {
10100
- accept: {
10101
- '*/*': value.trim()
10102
- .replace(/\s+/g, '')
10103
- .split(',')
10104
- }
10105
- };
10106
- }
10107
- else if (this.isMimeType(value)) {
10108
- return {
10109
- accept: { [value]: [] }
10110
- };
10111
- }
10112
- return null;
10113
- }
10114
- isFileExtension(input) {
10115
- const regex = new RegExp(/^(\.\w+)(, ?\.\w+)*$/);
10116
- return regex.test(input);
10117
- }
10118
- isMimeType(input) {
10119
- const regex = new RegExp(/^.+\/.+$/);
10120
- return regex.test(input);
10121
- }
10122
- set elderFileSelectMultiple(value) {
10123
- this._filePickerOptions = {
10124
- excludeAcceptAllOptions: this._filePickerOptions?.excludeAcceptAllOptions,
10125
- id: this._filePickerOptions?.id,
10126
- multiple: coerceBooleanProperty(value),
10127
- startIn: this._filePickerOptions?.startIn,
10128
- types: this._filePickerOptions?.types
10129
- };
10130
- this._legacyInput.elderFileSelectMultiple = value;
10131
- }
10132
- /**
10133
- * Allow the user to select a directory. All files that are recursively contained are selected.
10134
- * However, the user will no longer be able to select individual files if this is enabled.
10135
- * @param value
10136
- */
10137
- set elderFileSelectDirectory(value) {
10138
- this._useDirectoryPicker = coerceBooleanProperty(value);
10139
- this._legacyInput.elderFileSelectDirectory = value;
10140
- }
10141
- /***************************************************************************
10142
- * *
10143
- * Public API *
10144
- * *
10145
- **************************************************************************/
10146
- onClick(event) {
10147
- if (!this._useDirectoryPicker && FileSystemApi.isFileSystemSupported()) {
10148
- this.openFilePicker(this._filePickerOptions).subscribe({
10149
- next: fileList => this.elderFileSelectChange.next(fileList)
10150
- });
10151
- }
10152
- else if (this._useDirectoryPicker && FileSystemApi.isDirectoryPickerSupported()) {
10153
- this.openDirectoryPicker(this._directoryPickerOptions).subscribe({
10154
- next: fileList => this.elderFileSelectChange.next(fileList)
10155
- });
10156
- }
10157
- else {
10158
- this._legacyInput.openFileSelectDialog();
10159
- }
10160
- }
10161
- /***************************************************************************
10162
- * *
10163
- * Private methods *
10164
- * *
10165
- **************************************************************************/
10166
- openFilePicker(pickerOpts) {
10167
- return FileSystemApi.openFilePicker(pickerOpts).pipe(switchMap(files => combineLatest(files.map(file => FileEntry.ofFileHandle(file)))));
10168
- }
10169
- openDirectoryPicker(pickerOpts) {
10170
- return FileSystemApi.openDirectoryPicker(pickerOpts).pipe(switchMap(dir => FileListingSystemHandle.listFiles(dir)));
10171
- }
10172
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: ElderFileSelectDirective, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i0.DestroyRef }], target: i0.ɵɵFactoryTarget.Directive }); }
9932
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: ElderFileSelectDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive }); }
10173
9933
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.0.4", type: ElderFileSelectDirective, isStandalone: true, selector: "[elderFileSelect]", inputs: { elderFileSelect: "elderFileSelect", elderFileSelectMultiple: "elderFileSelectMultiple", elderFileSelectDirectory: "elderFileSelectDirectory" }, outputs: { elderFileSelectChange: "elderFileSelectChange", elderSingleFileSelectChange: "elderSingleFileSelectChange" }, host: { listeners: { "click": "onClick($event)" } }, ngImport: i0 }); }
10174
9934
  }
10175
9935
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: ElderFileSelectDirective, decorators: [{
@@ -10178,7 +9938,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImpor
10178
9938
  selector: '[elderFileSelect]',
10179
9939
  standalone: true
10180
9940
  }]
10181
- }], ctorParameters: () => [{ type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i0.DestroyRef }], propDecorators: { elderFileSelectChange: [{
9941
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { elderFileSelectChange: [{
10182
9942
  type: Output
10183
9943
  }], elderSingleFileSelectChange: [{
10184
9944
  type: Output
@@ -10298,44 +10058,70 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImpor
10298
10058
  type: Input
10299
10059
  }] } });
10300
10060
 
10301
- class FileListingWebkit {
10302
- /***************************************************************************
10303
- * *
10304
- * Constructor *
10305
- * *
10306
- **************************************************************************/
10061
+ class FileListingRx {
10307
10062
  constructor() {
10063
+ this.log = LoggerFactory.getLogger(this.constructor.name);
10308
10064
  }
10065
+ static { this.INSTANCE = new FileListingRx(); }
10309
10066
  /***************************************************************************
10310
10067
  * *
10311
- * Public methods *
10068
+ * Public API *
10312
10069
  * *
10313
10070
  **************************************************************************/
10314
- static listFilesRecursive(entry) {
10315
- return FileListingWebkit.listFilesRecursiveAsync(entry, null);
10071
+ toFileList(transferItemList) {
10072
+ const obs = [];
10073
+ for (let i = 0; i < transferItemList.length; i++) {
10074
+ const transferItem = transferItemList[i];
10075
+ const entry = transferItem.webkitGetAsEntry();
10076
+ if (entry) {
10077
+ obs.push(this.listFilesRecursive(entry));
10078
+ }
10079
+ else {
10080
+ const itemAsFile = transferItem.getAsFile();
10081
+ if (itemAsFile) {
10082
+ obs.push(of([FileEntry.ofFile(itemAsFile)]));
10083
+ }
10084
+ else {
10085
+ if (transferItem.kind == 'file') {
10086
+ obs.push(of([
10087
+ FileEntry.ofFile(new File([], '', {
10088
+ type: transferItem.type
10089
+ }))
10090
+ ]));
10091
+ }
10092
+ else {
10093
+ this.log.warn('Could not handle DataTransferItem!', transferItem);
10094
+ }
10095
+ }
10096
+ }
10097
+ }
10098
+ return zip(obs).pipe(map(files => files.flat()));
10099
+ }
10100
+ listFilesRecursive(entry) {
10101
+ return this.listFilesRecursiveAsync(entry, null);
10316
10102
  }
10317
10103
  /***************************************************************************
10318
10104
  * *
10319
10105
  * Private methods *
10320
10106
  * *
10321
10107
  **************************************************************************/
10322
- static listFilesRecursiveAsync(entry, parent) {
10108
+ listFilesRecursiveAsync(entry, parent) {
10323
10109
  if (entry.isDirectory) {
10324
10110
  const directoryEntry = entry;
10325
- return FileListingWebkit.readEntries(directoryEntry).pipe(mergeMap$1(entries => zip(entries.map(entry => this.listFilesRecursiveAsync(entry, directoryEntry)))), map(files => files.flat()));
10111
+ return this.readEntries(directoryEntry).pipe(mergeMap$1(entries => zip(entries.map(entry => this.listFilesRecursiveAsync(entry, directoryEntry)))), map(files => files.flat()));
10326
10112
  }
10327
10113
  else if (entry.isFile) {
10328
10114
  const fileEntry = entry;
10329
- return FileListingWebkit.observableFile(fileEntry, parent).pipe(map(file => [file]));
10115
+ return this.observableFile(fileEntry, parent).pipe(map(file => [file]));
10330
10116
  }
10331
10117
  else {
10332
10118
  return EMPTY;
10333
10119
  }
10334
10120
  }
10335
- static observableFile(fileEntry, parent) {
10121
+ observableFile(fileEntry, parent) {
10336
10122
  return new Observable(observer => {
10337
10123
  fileEntry.file(file => {
10338
- observer.next(FileEntry.relativeFile(file, FileListingWebkit.trimStaringSlash(parent?.fullPath)));
10124
+ observer.next(FileEntry.relativeFile(file, this.trimStaringSlash(parent?.fullPath)));
10339
10125
  observer.complete();
10340
10126
  }, err => {
10341
10127
  observer.error(err);
@@ -10343,7 +10129,7 @@ class FileListingWebkit {
10343
10129
  });
10344
10130
  });
10345
10131
  }
10346
- static trimStaringSlash(path) {
10132
+ trimStaringSlash(path) {
10347
10133
  if (path) {
10348
10134
  if (path.startsWith('/')) {
10349
10135
  path = path.substring(1);
@@ -10351,12 +10137,12 @@ class FileListingWebkit {
10351
10137
  }
10352
10138
  return path;
10353
10139
  }
10354
- static readEntries(directoryEntry) {
10140
+ readEntries(directoryEntry) {
10355
10141
  return new Observable(observer => {
10356
- FileListingWebkit.consumeReaderToCompletion(observer, directoryEntry.createReader());
10142
+ this.consumeReaderToCompletion(observer, directoryEntry.createReader());
10357
10143
  });
10358
10144
  }
10359
- static consumeReaderToCompletion(observer, directoryReader) {
10145
+ consumeReaderToCompletion(observer, directoryReader) {
10360
10146
  directoryReader.readEntries(entries => {
10361
10147
  if (entries && entries.length > 0) {
10362
10148
  observer.next(entries);
@@ -10372,60 +10158,6 @@ class FileListingWebkit {
10372
10158
  }
10373
10159
  }
10374
10160
 
10375
- class FileListingRx {
10376
- constructor() {
10377
- this.log = LoggerFactory.getLogger(this.constructor.name);
10378
- }
10379
- static { this.INSTANCE = new FileListingRx(); }
10380
- /***************************************************************************
10381
- * *
10382
- * Public API *
10383
- * *
10384
- **************************************************************************/
10385
- toFileList(transferItemList) {
10386
- const obs = [];
10387
- for (let i = 0; i < transferItemList.length; i++) {
10388
- const transferItem = transferItemList[i];
10389
- obs.push(this.resolveTransferItem(transferItem));
10390
- }
10391
- return zip(obs).pipe(map(files => files.flat()));
10392
- }
10393
- /***************************************************************************
10394
- * *
10395
- * Private methods *
10396
- * *
10397
- **************************************************************************/
10398
- resolveTransferItem(transferItem) {
10399
- if (FileSystemApi.isGetAsFileSystemHandleSupported(transferItem)) {
10400
- return FileSystemApi.getAsFileSystemHandle(transferItem).pipe(switchMap(handle => FileListingSystemHandle.listFiles(handle)));
10401
- }
10402
- const entry = transferItem.webkitGetAsEntry();
10403
- if (entry) {
10404
- return FileListingWebkit.listFilesRecursive(entry);
10405
- }
10406
- return this.legacyFileListing(transferItem);
10407
- }
10408
- legacyFileListing(transferItem) {
10409
- const itemAsFile = transferItem.getAsFile();
10410
- if (itemAsFile) {
10411
- return of([FileEntry.ofFile(itemAsFile)]);
10412
- }
10413
- else {
10414
- if (transferItem.kind == 'file') {
10415
- return of([
10416
- FileEntry.ofFile(new File([], '', {
10417
- type: transferItem.type
10418
- }))
10419
- ]);
10420
- }
10421
- else {
10422
- this.log.warn('Could not handle DataTransferItem!', transferItem);
10423
- return of([]);
10424
- }
10425
- }
10426
- }
10427
- }
10428
-
10429
10161
  class ElderFileDropZoneDirective {
10430
10162
  /***************************************************************************
10431
10163
  * *
@@ -10979,7 +10711,18 @@ class ElderBlobViewerComponent {
10979
10711
  this._url$ = new BehaviorSubject(null);
10980
10712
  this._mimeType$ = new BehaviorSubject(null);
10981
10713
  this.destroy$ = new Subject();
10982
- this._displayUnknownAsText = false;
10714
+ /***************************************************************************
10715
+ * *
10716
+ * Properties *
10717
+ * *
10718
+ **************************************************************************/
10719
+ /**
10720
+ * Attempt to display unknown blobs as text. (i.e. mime-type is octet-stream)
10721
+ * @param unknownAsText
10722
+ */
10723
+ this.displayUnknownAsText = input(false, {
10724
+ transform: (input) => coerceBooleanProperty(input)
10725
+ });
10983
10726
  }
10984
10727
  /***************************************************************************
10985
10728
  * *
@@ -10993,21 +10736,6 @@ class ElderBlobViewerComponent {
10993
10736
  this.destroy$.next();
10994
10737
  this.destroy$.complete();
10995
10738
  }
10996
- /***************************************************************************
10997
- * *
10998
- * Properties *
10999
- * *
11000
- **************************************************************************/
11001
- /**
11002
- * Attempt to display unknown blobs as text. (i.e. mime-type is octet-stream)
11003
- * @param unknownAsText
11004
- */
11005
- set displayUnknownAsText(unknownAsText) {
11006
- // TODO FIX RACE CONDITION:
11007
- // Since this property is not reactive, it must be set first.
11008
- // Otherwise, it will still be false, even if set to true!
11009
- this._displayUnknownAsText = coerceBooleanProperty(unknownAsText);
11010
- }
11011
10739
  /**
11012
10740
  * Set a in memory blob to display.
11013
10741
  * @param blob
@@ -11086,7 +10814,7 @@ class ElderBlobViewerComponent {
11086
10814
  });
11087
10815
  }
11088
10816
  canDisplayAsText(mimeType) {
11089
- const can = mimeType.isText || (this._displayUnknownAsText && mimeType.isOctetStream);
10817
+ const can = mimeType.isText || (this.displayUnknownAsText() && mimeType.isOctetStream);
11090
10818
  // TODO _displayUnknownAsText might be null due race condition see todo above.
11091
10819
  // this.logger.debug('canDisplayAsText(' + mimeType.value + ') --> '
11092
10820
  // + can + ' ---> this._displayUnknownAsText:' + this._displayUnknownAsText, mimeType);
@@ -11098,14 +10826,12 @@ class ElderBlobViewerComponent {
11098
10826
  });
11099
10827
  }
11100
10828
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: ElderBlobViewerComponent, deps: [{ token: HttpClientPristine }, { token: i1.DomSanitizer }, { token: ElderToastService }], target: i0.ɵɵFactoryTarget.Component }); }
11101
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.0.4", type: ElderBlobViewerComponent, isStandalone: true, selector: "elder-blob-viewer", inputs: { displayUnknownAsText: "displayUnknownAsText", blob: "blob", blobUrl: "blobUrl", url: "url", mimeType: "mimeType" }, ngImport: i0, template: "<div class=\"layout-col full place-center-center document-viewer\">\n\n <ng-container *ngIf=\"blobContext$ | async as blobContext\">\n\n <!-- Video -->\n <div class=\"layout-col place-center-center full\" *ngIf=\"blobContext.mimeType.isVideo\">\n <video class=\"video\"\n controls autoplay loop\n\n >\n <source [src]=\"blobContext.safeUrl\" [type]=\"blobContext.mimeType.value\">\n Your browser does not support HTML5 video.\n </video>\n </div>\n\n <!-- Audio -->\n <div class=\"layout-col place-center-center full\" *ngIf=\"blobContext.mimeType.isAudio\">\n <audio class=\"audio\"\n controls autoplay loop\n >\n <source [src]=\"blobContext.safeUrl\" [type]=\"blobContext.mimeType.value\">\n Your browser does not support HTML5 audio.\n </audio>\n </div>\n\n <!-- Image -->\n <div class=\"layout-col full\" *ngIf=\"blobContext.mimeType.isImage\" style=\"overflow: hidden\">\n <img class=\"cover flex\"\n [src]=\"blobContext.safeUrl\" alt=\"blob image\"/>\n </div>\n\n <!-- Embedded (PDFs etc) -->\n <div class=\"layout-col full\" *ngIf=\"blobContext.displayEmbedded\">\n <div class=\"full\">\n <embed class=\"embedded\" [src]=\"blobContext.safeUrl\" [type]=\"blobContext.mimeType.value\" width=\"100%\" height=\"100%\">\n </div>\n </div>\n\n <!-- Plain Text -->\n <div class=\"layout-col full\" *ngIf=\"blobContext.displayAsText\">\n <textarea\n class=\"document-content\"\n placeholder=\"Content\"\n [value]=\"blobContext.text\" wrap=\"off\"\n readonly\n ></textarea>\n </div>\n\n <div class=\"layout-col place-center-center full\" *ngIf=\"blobContext.cantDisplay\">\n <p>Cant display {{blobContext.mimeType.value}}!</p>\n </div>\n\n </ng-container>\n\n <ng-container *ngIf=\"!(blobContext$ | async)\">\n <div class=\"layout-col place-center-center full\">\n <p>No Document.</p>\n </div>\n </ng-container>\n\n\n</div>\n", styles: [":host{overflow:hidden}.document-viewer{background-color:#dedede;color:#1f1e1e}.video,.audio{width:100%;height:auto}.embedded{width:100%;height:100%}.cover{object-fit:scale-down;width:100%;height:auto;overflow:hidden}.document-content{font-family:Courier,monospace;font-size:14px;background-color:#575757;color:#ccc;outline:none;resize:none;width:100%;height:100%;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-webkit-border-radius:12px;border-radius:0;-webkit-box-shadow:0px 2px 14px #000;box-shadow:0 2px 14px #000;border-top:1px solid #FFF;border-bottom:1px solid #FFF}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
10829
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.0.4", type: ElderBlobViewerComponent, isStandalone: true, selector: "elder-blob-viewer", inputs: { displayUnknownAsText: { classPropertyName: "displayUnknownAsText", publicName: "displayUnknownAsText", isSignal: true, isRequired: false, transformFunction: null }, blob: { classPropertyName: "blob", publicName: "blob", isSignal: false, isRequired: false, transformFunction: null }, blobUrl: { classPropertyName: "blobUrl", publicName: "blobUrl", isSignal: false, isRequired: false, transformFunction: null }, url: { classPropertyName: "url", publicName: "url", isSignal: false, isRequired: false, transformFunction: null }, mimeType: { classPropertyName: "mimeType", publicName: "mimeType", isSignal: false, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"layout-col full place-center-center document-viewer\">\n\n <ng-container *ngIf=\"blobContext$ | async as blobContext\">\n\n <!-- Video -->\n <div class=\"layout-col place-center-center full\" *ngIf=\"blobContext.mimeType.isVideo\">\n <video class=\"video\"\n controls autoplay loop\n\n >\n <source [src]=\"blobContext.safeUrl\" [type]=\"blobContext.mimeType.value\">\n Your browser does not support HTML5 video.\n </video>\n </div>\n\n <!-- Audio -->\n <div class=\"layout-col place-center-center full\" *ngIf=\"blobContext.mimeType.isAudio\">\n <audio class=\"audio\"\n controls autoplay loop\n >\n <source [src]=\"blobContext.safeUrl\" [type]=\"blobContext.mimeType.value\">\n Your browser does not support HTML5 audio.\n </audio>\n </div>\n\n <!-- Image -->\n <div class=\"layout-col full\" *ngIf=\"blobContext.mimeType.isImage\" style=\"overflow: hidden\">\n <img class=\"cover flex\"\n [src]=\"blobContext.safeUrl\" alt=\"blob image\"/>\n </div>\n\n <!-- Embedded (PDFs etc) -->\n <div class=\"layout-col full\" *ngIf=\"blobContext.displayEmbedded\">\n <div class=\"full\">\n <embed class=\"embedded\" [src]=\"blobContext.safeUrl\" [type]=\"blobContext.mimeType.value\" width=\"100%\" height=\"100%\">\n </div>\n </div>\n\n <!-- Plain Text -->\n <div class=\"layout-col full\" *ngIf=\"blobContext.displayAsText\">\n <textarea\n class=\"document-content\"\n placeholder=\"Content\"\n [value]=\"blobContext.text\" wrap=\"off\"\n readonly\n ></textarea>\n </div>\n\n <div class=\"layout-col place-center-center full\" *ngIf=\"blobContext.cantDisplay\">\n <p>Cant display {{blobContext.mimeType.value}}!</p>\n </div>\n\n </ng-container>\n\n <ng-container *ngIf=\"!(blobContext$ | async)\">\n <div class=\"layout-col place-center-center full\">\n <p>No Document.</p>\n </div>\n </ng-container>\n\n\n</div>\n", styles: [":host{overflow:hidden}.document-viewer{background-color:#dedede;color:#1f1e1e}.video,.audio{width:100%;height:auto}.embedded{width:100%;height:100%}.cover{object-fit:scale-down;width:100%;height:auto;overflow:hidden}.document-content{font-family:Courier,monospace;font-size:14px;background-color:#575757;color:#ccc;outline:none;resize:none;width:100%;height:100%;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-webkit-border-radius:12px;border-radius:0;-webkit-box-shadow:0px 2px 14px #000;box-shadow:0 2px 14px #000;border-top:1px solid #FFF;border-bottom:1px solid #FFF}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
11102
10830
  }
11103
10831
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: ElderBlobViewerComponent, decorators: [{
11104
10832
  type: Component,
11105
10833
  args: [{ selector: 'elder-blob-viewer', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [NgIf, AsyncPipe], template: "<div class=\"layout-col full place-center-center document-viewer\">\n\n <ng-container *ngIf=\"blobContext$ | async as blobContext\">\n\n <!-- Video -->\n <div class=\"layout-col place-center-center full\" *ngIf=\"blobContext.mimeType.isVideo\">\n <video class=\"video\"\n controls autoplay loop\n\n >\n <source [src]=\"blobContext.safeUrl\" [type]=\"blobContext.mimeType.value\">\n Your browser does not support HTML5 video.\n </video>\n </div>\n\n <!-- Audio -->\n <div class=\"layout-col place-center-center full\" *ngIf=\"blobContext.mimeType.isAudio\">\n <audio class=\"audio\"\n controls autoplay loop\n >\n <source [src]=\"blobContext.safeUrl\" [type]=\"blobContext.mimeType.value\">\n Your browser does not support HTML5 audio.\n </audio>\n </div>\n\n <!-- Image -->\n <div class=\"layout-col full\" *ngIf=\"blobContext.mimeType.isImage\" style=\"overflow: hidden\">\n <img class=\"cover flex\"\n [src]=\"blobContext.safeUrl\" alt=\"blob image\"/>\n </div>\n\n <!-- Embedded (PDFs etc) -->\n <div class=\"layout-col full\" *ngIf=\"blobContext.displayEmbedded\">\n <div class=\"full\">\n <embed class=\"embedded\" [src]=\"blobContext.safeUrl\" [type]=\"blobContext.mimeType.value\" width=\"100%\" height=\"100%\">\n </div>\n </div>\n\n <!-- Plain Text -->\n <div class=\"layout-col full\" *ngIf=\"blobContext.displayAsText\">\n <textarea\n class=\"document-content\"\n placeholder=\"Content\"\n [value]=\"blobContext.text\" wrap=\"off\"\n readonly\n ></textarea>\n </div>\n\n <div class=\"layout-col place-center-center full\" *ngIf=\"blobContext.cantDisplay\">\n <p>Cant display {{blobContext.mimeType.value}}!</p>\n </div>\n\n </ng-container>\n\n <ng-container *ngIf=\"!(blobContext$ | async)\">\n <div class=\"layout-col place-center-center full\">\n <p>No Document.</p>\n </div>\n </ng-container>\n\n\n</div>\n", styles: [":host{overflow:hidden}.document-viewer{background-color:#dedede;color:#1f1e1e}.video,.audio{width:100%;height:auto}.embedded{width:100%;height:100%}.cover{object-fit:scale-down;width:100%;height:auto;overflow:hidden}.document-content{font-family:Courier,monospace;font-size:14px;background-color:#575757;color:#ccc;outline:none;resize:none;width:100%;height:100%;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-webkit-border-radius:12px;border-radius:0;-webkit-box-shadow:0px 2px 14px #000;box-shadow:0 2px 14px #000;border-top:1px solid #FFF;border-bottom:1px solid #FFF}\n"] }]
11106
- }], ctorParameters: () => [{ type: HttpClientPristine }, { type: i1.DomSanitizer }, { type: ElderToastService }], propDecorators: { displayUnknownAsText: [{
11107
- type: Input
11108
- }], blob: [{
10834
+ }], ctorParameters: () => [{ type: HttpClientPristine }, { type: i1.DomSanitizer }, { type: ElderToastService }], propDecorators: { blob: [{
11109
10835
  type: Input
11110
10836
  }], blobUrl: [{
11111
10837
  type: Input
@@ -15947,6 +15673,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImpor
15947
15673
  type: Input
15948
15674
  }] } });
15949
15675
 
15676
+ class InputUtils {
15677
+ static isNoInputArgs(input) {
15678
+ return input === '';
15679
+ }
15680
+ }
15681
+
15950
15682
  class ElderMultipleOfUtil {
15951
15683
  /***************************************************************************
15952
15684
  * *
@@ -15996,11 +15728,16 @@ class ElderMultipleOfUtil {
15996
15728
  }
15997
15729
  }
15998
15730
  class ElderMultipleOfValidator {
15999
- set elderMultipleOf(value) {
16000
- this._factor = value;
16001
- }
16002
- get factor() {
16003
- return this._factor;
15731
+ constructor() {
15732
+ /***************************************************************************
15733
+ * *
15734
+ * Fields *
15735
+ * *
15736
+ **************************************************************************/
15737
+ this.factor = input(null, {
15738
+ alias: 'elderMultipleOf',
15739
+ transform: (input) => InputUtils.isNoInputArgs(input) ? null : input
15740
+ });
16004
15741
  }
16005
15742
  /***************************************************************************
16006
15743
  * *
@@ -16008,15 +15745,15 @@ class ElderMultipleOfValidator {
16008
15745
  * *
16009
15746
  **************************************************************************/
16010
15747
  validate(control) {
16011
- if (this.factor) {
16012
- return ElderMultipleOfUtil.multipleOfValidator(this.factor)(control);
15748
+ if (this.factor()) {
15749
+ return ElderMultipleOfUtil.multipleOfValidator(this.factor())(control);
16013
15750
  }
16014
15751
  else {
16015
15752
  return null;
16016
15753
  }
16017
15754
  }
16018
15755
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: ElderMultipleOfValidator, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
16019
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.0.4", type: ElderMultipleOfValidator, isStandalone: true, selector: "[elderMultipleOf][formControlName],[elderMultipleOf][formControl],[elderMultipleOf][ngModel]", inputs: { elderMultipleOf: "elderMultipleOf" }, providers: [
15756
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.0.4", type: ElderMultipleOfValidator, isStandalone: true, selector: "[elderMultipleOf][formControlName],[elderMultipleOf][formControl],[elderMultipleOf][ngModel]", inputs: { factor: { classPropertyName: "factor", publicName: "elderMultipleOf", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
16020
15757
  {
16021
15758
  provide: NG_VALIDATORS,
16022
15759
  useExisting: forwardRef(() => ElderMultipleOfValidator),
@@ -16037,9 +15774,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImpor
16037
15774
  ],
16038
15775
  standalone: true
16039
15776
  }]
16040
- }], propDecorators: { elderMultipleOf: [{
16041
- type: Input
16042
- }] } });
15777
+ }] });
16043
15778
 
16044
15779
  /**
16045
15780
  * This directive redirects the next focus element
@@ -16903,7 +16638,7 @@ class ElderTableActivationDirective {
16903
16638
  this._data = [];
16904
16639
  this.activeItem$ = new BehaviorSubject(null);
16905
16640
  this.rows$ = new BehaviorSubject([]);
16906
- this.activationOptions = {};
16641
+ this._activationOptions = {};
16907
16642
  }
16908
16643
  /***************************************************************************
16909
16644
  * *
@@ -16964,6 +16699,12 @@ class ElderTableActivationDirective {
16964
16699
  * Properties *
16965
16700
  * *
16966
16701
  **************************************************************************/
16702
+ set activationOptions(options) {
16703
+ this.activationOptions = InputUtils.isNoInputArgs(options) ? options : {};
16704
+ }
16705
+ get activationOptions() {
16706
+ return this._activationOptions;
16707
+ }
16967
16708
  get activeItemEventChange() {
16968
16709
  return this.itemActivationEventSubject;
16969
16710
  }
@@ -17161,12 +16902,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImpor
17161
16902
  exportAs: 'elderTableActivation',
17162
16903
  standalone: true
17163
16904
  }]
17164
- }], ctorParameters: () => [{ type: ElderTableComponent }], propDecorators: { activationOptions: [{
17165
- type: Input,
17166
- args: ['elderTableActivation']
17167
- }], onKeydown: [{
16905
+ }], ctorParameters: () => [{ type: ElderTableComponent }], propDecorators: { onKeydown: [{
17168
16906
  type: HostListener,
17169
16907
  args: ['keydown', ['$event']]
16908
+ }], activationOptions: [{
16909
+ type: Input,
16910
+ args: ['elderTableActivation']
17170
16911
  }], activeItemEventChange: [{
17171
16912
  type: Output
17172
16913
  }], activeItemChange: [{