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

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 +83 -85
  5. package/esm2022/lib/components/files/listing/file-entry.mjs +15 -30
  6. package/esm2022/lib/components/files/listing/file-listing-rx.mjs +70 -30
  7. package/esm2022/lib/components/forms/directives/validation/validators/elder-multiple-of.validator.mjs +24 -9
  8. package/fesm2022/elderbyte-ngx-starter.mjs +162 -422
  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 -16
  14. package/lib/components/files/listing/file-entry.d.ts +1 -10
  15. package/lib/components/files/listing/file-listing-rx.d.ts +6 -3
  16. package/lib/components/forms/directives/validation/validators/elder-multiple-of.validator.d.ts +9 -3
  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 -96
  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 -86
  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,100 +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
- /**
9738
- * Returns an FileSystemHandle Observable of the given DataTransferItem. The FileSystemHandle can only be accessed in the `dragstart`
9739
- * or `drop` event. Otherwise, it will return null!
9740
- */
9741
- static getAsFileSystemHandle(transferItem) {
9742
- // @ts-ignore
9743
- return from(transferItem.getAsFileSystemHandle());
9744
- }
9745
- /***************************************************************************
9746
- * *
9747
- * File Picker *
9748
- * *
9749
- **************************************************************************/
9750
- static isFileSystemSupported() {
9751
- return 'showOpenFilePicker' in window;
9752
- }
9753
- static openFilePicker(pickerOpts) {
9754
- try {
9755
- // @ts-ignore
9756
- return from(window.showOpenFilePicker(pickerOpts));
9757
- }
9758
- catch (e) {
9759
- return throwError(() => new Error(e));
9760
- }
9761
- }
9762
- /***************************************************************************
9763
- * *
9764
- * Directory Picker *
9765
- * *
9766
- **************************************************************************/
9767
- static isDirectoryPickerSupported() {
9768
- return 'showDirectoryPicker' in window;
9769
- }
9770
- static openDirectoryPicker(pickerOpts) {
9771
- try {
9772
- // @ts-ignore
9773
- return from(window.showDirectoryPicker(pickerOpts));
9774
- }
9775
- catch (e) {
9776
- return throwError(() => new Error(e));
9777
- }
9778
- }
9779
- /***************************************************************************
9780
- * *
9781
- * FileSystemDirectoryHandle *
9782
- * *
9783
- **************************************************************************/
9784
- static getHandlesFromDirectory(dirHandle) {
9785
- return from(FileSystemApi.getHandlesFromDirectoryAsync(dirHandle));
9786
- }
9787
- static buildRelativeParent(fileOrDirHandle, rootDirectory) {
9788
- if (rootDirectory == null) {
9789
- return of(undefined);
9790
- }
9791
- const relativeParents$ = from(rootDirectory.resolve(fileOrDirHandle));
9792
- return relativeParents$.pipe(map(parents => {
9793
- // path/to/folder/file.jpg
9794
- const path = parents;
9795
- // root/path/to/folder/file.jpg
9796
- path.unshift(rootDirectory.name);
9797
- // root/path/to/folder
9798
- path.pop();
9799
- return path.join('/');
9800
- }));
9801
- }
9802
- static async getHandlesFromDirectoryAsync(dirHandle) {
9803
- const handles = [];
9804
- // @ts-ignore
9805
- for await (const handle of dirHandle.values()) {
9806
- handles.push(handle);
9807
- }
9808
- return handles;
9809
- }
9810
- }
9811
-
9812
9718
  /**
9813
9719
  * Represents a file and the relative path where the user has selected it.
9814
9720
  * This is useful if the user has selected a folder and files
@@ -9823,24 +9729,26 @@ class FileEntry {
9823
9729
  * which is also supported by this method.
9824
9730
  */
9825
9731
  static ofFile(file) {
9826
- return FileEntry.relativeFile(file, this.buildRelativeParent(file));
9827
- }
9828
- /**
9829
- * Creates an Observable of a File Entry by resolving its FileSystemFileHandle.
9830
- * @param fileHandle
9831
- * @param rootDirectory is needed to build a relative parent
9832
- */
9833
- static ofFileHandle(fileHandle, rootDirectory) {
9834
- 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);
9835
9743
  }
9836
9744
  /**
9837
9745
  * Creates a file Entry with a relative parent path
9838
9746
  */
9839
- static relativeFile(file, relativeParent, fileHandle) {
9747
+ static relativeFile(file, relativeParent) {
9840
9748
  if (relativeParent && relativeParent.endsWith('/')) {
9841
9749
  relativeParent = relativeParent.substring(0, relativeParent.length - 1);
9842
9750
  }
9843
- return new FileEntry(file, relativeParent, fileHandle);
9751
+ return new FileEntry(file, relativeParent);
9844
9752
  }
9845
9753
  static toFileMap(entries) {
9846
9754
  const map = new Map();
@@ -9860,10 +9768,9 @@ class FileEntry {
9860
9768
  * Contains the relative path from the selected folder
9861
9769
  * to this file. Only relevant if the user has selected a folder.
9862
9770
  */
9863
- relativeParent, fileHandle) {
9771
+ relativeParent) {
9864
9772
  this.file = file;
9865
9773
  this.relativeParent = relativeParent;
9866
- this.fileHandle = fileHandle;
9867
9774
  this.relativePath = FileEntry.buildRelativePath(relativeParent, file);
9868
9775
  }
9869
9776
  /***************************************************************************
@@ -9882,46 +9789,42 @@ class FileEntry {
9882
9789
  return file.name;
9883
9790
  }
9884
9791
  }
9885
- static buildRelativeParent(file) {
9886
- let relativeParent = null;
9887
- if (file.webkitRelativePath) {
9888
- if (file.webkitRelativePath.endsWith(file.name)) {
9889
- const nameStart = file.webkitRelativePath.length - file.name.length;
9890
- relativeParent = file.webkitRelativePath.substring(0, nameStart);
9891
- }
9892
- else {
9893
- relativeParent = file.webkitRelativePath;
9894
- }
9895
- }
9896
- return relativeParent;
9897
- }
9898
9792
  }
9899
9793
 
9900
- class ElderFileSelectInput {
9794
+ class ElderFileSelectDirective {
9901
9795
  /***************************************************************************
9902
9796
  * *
9903
9797
  * Constructor *
9904
9798
  * *
9905
9799
  **************************************************************************/
9906
- constructor(renderer, el) {
9907
- this.renderer = renderer;
9800
+ constructor(el, renderer) {
9908
9801
  this.el = el;
9802
+ this.renderer = renderer;
9909
9803
  /***************************************************************************
9910
9804
  * *
9911
9805
  * Fields *
9912
9806
  * *
9913
9807
  **************************************************************************/
9914
9808
  this.logger = LoggerFactory.getLogger(this.constructor.name);
9915
- this._filesSelected = new Subject;
9809
+ this.elderFileSelectChange = new EventEmitter();
9810
+ this.elderSingleFileSelectChange = new EventEmitter();
9916
9811
  }
9917
9812
  /***************************************************************************
9918
9813
  * *
9919
- * Properties *
9814
+ * Life Cycle *
9920
9815
  * *
9921
9816
  **************************************************************************/
9922
- get filesSelected() {
9923
- return this._filesSelected;
9817
+ ngOnInit() {
9818
+ this.createFileSelect();
9819
+ }
9820
+ ngOnDestroy() {
9821
+ this.removeFileSelect();
9924
9822
  }
9823
+ /***************************************************************************
9824
+ * *
9825
+ * Properties *
9826
+ * *
9827
+ **************************************************************************/
9925
9828
  set elderFileSelect(value) {
9926
9829
  this._accept = value;
9927
9830
  if (this._fileInput) {
@@ -9934,6 +9837,11 @@ class ElderFileSelectInput {
9934
9837
  this.renderer.setProperty(this._fileInput, 'multiple', value);
9935
9838
  }
9936
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
+ */
9937
9845
  set elderFileSelectDirectory(value) {
9938
9846
  this._directory = coerceBooleanProperty(value);
9939
9847
  if (this._fileInput) {
@@ -9946,6 +9854,17 @@ class ElderFileSelectInput {
9946
9854
  * Public API *
9947
9855
  * *
9948
9856
  **************************************************************************/
9857
+ onClick(event) {
9858
+ this.openFileSelectDialog();
9859
+ }
9860
+ openFileSelectDialog() {
9861
+ this._fileInput.click();
9862
+ }
9863
+ /***************************************************************************
9864
+ * *
9865
+ * Private methods *
9866
+ * *
9867
+ **************************************************************************/
9949
9868
  /**
9950
9869
  * <input type="file"
9951
9870
  * hidden #fileInput
@@ -9969,9 +9888,7 @@ class ElderFileSelectInput {
9969
9888
  this.renderer.setAttribute(this._fileInput, 'webkitdirectory', 'true');
9970
9889
  this.renderer.setAttribute(this._fileInput, 'directory', 'true');
9971
9890
  }
9972
- this._unlisten = this.renderer.listen(this._fileInput, 'change', event => {
9973
- this.fileInputChanged(this._fileInput.files);
9974
- });
9891
+ this._unlisten = this.renderer.listen(this._fileInput, 'change', event => this.fileInputChanged(event));
9975
9892
  }
9976
9893
  removeFileSelect() {
9977
9894
  if (this._unlisten) {
@@ -9983,24 +9900,26 @@ class ElderFileSelectInput {
9983
9900
  this._fileInput = null;
9984
9901
  }
9985
9902
  }
9986
- openFileSelectDialog() {
9987
- this._fileInput.click();
9988
- }
9989
- /***************************************************************************
9990
- * *
9991
- * Private methods *
9992
- * *
9993
- **************************************************************************/
9994
- fileInputChanged(fileList) {
9903
+ fileInputChanged(event) {
9904
+ const fileList = this._fileInput.files;
9995
9905
  const files = this.toFileEntries(fileList);
9996
9906
  this.logger.debug('fileInputChanged, files:', files);
9907
+ this.emitFileList(files);
9997
9908
  this.clearFileList();
9998
- this._filesSelected.next(files);
9999
9909
  }
10000
9910
  clearFileList() {
10001
9911
  // not nice but works
10002
9912
  this._fileInput.value = null;
10003
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
+ }
10004
9923
  toFileEntries(fileList) {
10005
9924
  const files = [];
10006
9925
  for (const key in fileList) {
@@ -10010,175 +9929,7 @@ class ElderFileSelectInput {
10010
9929
  }
10011
9930
  return files;
10012
9931
  }
10013
- }
10014
-
10015
- class FileListingSystemHandle {
10016
- /***************************************************************************
10017
- * *
10018
- * Public methods *
10019
- * *
10020
- **************************************************************************/
10021
- /**
10022
- * Creates a File Entry Array Observable by resolving its FileSystemHandle.
10023
- * @returns An `Observable<FileEntry[]>` with the FileSystemFileHandle included
10024
- */
10025
- static listFiles(handle, rootDirectory) {
10026
- switch (handle.kind) {
10027
- case 'file':
10028
- return FileEntry.ofFileHandle(handle, rootDirectory).pipe(toArray());
10029
- case 'directory':
10030
- return FileListingSystemHandle.listFilesRecursive(handle, rootDirectory);
10031
- }
10032
- }
10033
- /***************************************************************************
10034
- * *
10035
- * Private methods *
10036
- * *
10037
- **************************************************************************/
10038
- static listFilesRecursive(dirHandle, rootDirectory) {
10039
- return FileSystemApi.getHandlesFromDirectory(dirHandle).pipe(map(handles => FileListingSystemHandle.listFilesOfEach(handles, rootDirectory ? rootDirectory : dirHandle)), switchMap(fileEntriesArray$ => zip(fileEntriesArray$)), map(fileEntriesArray => fileEntriesArray.flat()));
10040
- }
10041
- static listFilesOfEach(handles, rootDirectory) {
10042
- return handles.map(fileOrDirHandle => FileListingSystemHandle.listFiles(fileOrDirHandle, rootDirectory));
10043
- }
10044
- }
10045
-
10046
- class ElderFileSelectDirective {
10047
- /***************************************************************************
10048
- * *
10049
- * Constructor *
10050
- * *
10051
- **************************************************************************/
10052
- constructor(renderer, el, destroyRef) {
10053
- this.renderer = renderer;
10054
- this.el = el;
10055
- this.destroyRef = destroyRef;
10056
- /***************************************************************************
10057
- * *
10058
- * Fields *
10059
- * *
10060
- **************************************************************************/
10061
- this.logger = LoggerFactory.getLogger(this.constructor.name);
10062
- this.elderFileSelectChange = new EventEmitter();
10063
- this.elderSingleFileSelectChange = new EventEmitter();
10064
- this._useDirectoryPicker = false;
10065
- this._legacyInput = new ElderFileSelectInput(this.renderer, this.el);
10066
- }
10067
- /***************************************************************************
10068
- * *
10069
- * Life Cycle *
10070
- * *
10071
- **************************************************************************/
10072
- ngOnInit() {
10073
- if (!FileSystemApi.isFileSystemSupported() || !FileSystemApi.isDirectoryPickerSupported()) {
10074
- this.logger.warn('showOpenFilePicker or showDirectoryPicker is not supported for this browser, falling back to legacy file picker');
10075
- this._legacyInput.createFileSelect();
10076
- this._legacyInput.filesSelected.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
10077
- next: multiFileChange => this.pushFileChanges(multiFileChange)
10078
- });
10079
- }
10080
- }
10081
- ngOnDestroy() {
10082
- this._legacyInput.removeFileSelect();
10083
- }
10084
- /***************************************************************************
10085
- * *
10086
- * Properties *
10087
- * *
10088
- **************************************************************************/
10089
- set elderFileSelect(value) {
10090
- this._filePickerOptions = {
10091
- excludeAcceptAllOptions: true,
10092
- id: this._filePickerOptions?.id,
10093
- multiple: this._filePickerOptions?.multiple,
10094
- startIn: this._filePickerOptions?.startIn,
10095
- types: [this.buildTypeOption(value)]
10096
- };
10097
- this._legacyInput.elderFileSelect = value;
10098
- }
10099
- buildTypeOption(value) {
10100
- if (this.isFileExtension(value)) {
10101
- return {
10102
- accept: {
10103
- '*/*': value.trim()
10104
- .replace(/\s+/g, '')
10105
- .split(',')
10106
- }
10107
- };
10108
- }
10109
- else if (this.isMimeType(value)) {
10110
- return {
10111
- accept: { [value]: [] }
10112
- };
10113
- }
10114
- return null;
10115
- }
10116
- isFileExtension(input) {
10117
- const regex = new RegExp(/^(\.\w+)(, ?\.\w+)*$/);
10118
- return regex.test(input);
10119
- }
10120
- isMimeType(input) {
10121
- const regex = new RegExp(/^.+\/.+$/);
10122
- return regex.test(input);
10123
- }
10124
- set elderFileSelectMultiple(value) {
10125
- this._filePickerOptions = {
10126
- excludeAcceptAllOptions: this._filePickerOptions?.excludeAcceptAllOptions,
10127
- id: this._filePickerOptions?.id,
10128
- multiple: coerceBooleanProperty(value),
10129
- startIn: this._filePickerOptions?.startIn,
10130
- types: this._filePickerOptions?.types
10131
- };
10132
- this._legacyInput.elderFileSelectMultiple = value;
10133
- }
10134
- /**
10135
- * Allow the user to select a directory. All files that are recursively contained are selected.
10136
- * However, the user will no longer be able to select individual files if this is enabled.
10137
- * @param value
10138
- */
10139
- set elderFileSelectDirectory(value) {
10140
- this._useDirectoryPicker = coerceBooleanProperty(value);
10141
- this._legacyInput.elderFileSelectDirectory = value;
10142
- }
10143
- /***************************************************************************
10144
- * *
10145
- * Public API *
10146
- * *
10147
- **************************************************************************/
10148
- onClick(event) {
10149
- if (!this._useDirectoryPicker && FileSystemApi.isFileSystemSupported()) {
10150
- this.openFilePicker(this._filePickerOptions).subscribe({
10151
- next: multiFileChange => this.pushFileChanges(multiFileChange)
10152
- });
10153
- }
10154
- else if (this._useDirectoryPicker && FileSystemApi.isDirectoryPickerSupported()) {
10155
- this.openDirectoryPicker(this._directoryPickerOptions).subscribe({
10156
- next: multiFileChange => this.pushFileChanges(multiFileChange)
10157
- });
10158
- }
10159
- else {
10160
- this._legacyInput.openFileSelectDialog();
10161
- }
10162
- }
10163
- /***************************************************************************
10164
- * *
10165
- * Private methods *
10166
- * *
10167
- **************************************************************************/
10168
- pushFileChanges(multiFileChange) {
10169
- this.elderFileSelectChange.next(multiFileChange);
10170
- const file = multiFileChange[0]?.file;
10171
- if (file) {
10172
- this.elderSingleFileSelectChange.next(file);
10173
- }
10174
- }
10175
- openFilePicker(pickerOpts) {
10176
- return FileSystemApi.openFilePicker(pickerOpts).pipe(switchMap(files => combineLatest(files.map(file => FileEntry.ofFileHandle(file)))));
10177
- }
10178
- openDirectoryPicker(pickerOpts) {
10179
- return FileSystemApi.openDirectoryPicker(pickerOpts).pipe(switchMap(dir => FileListingSystemHandle.listFiles(dir)));
10180
- }
10181
- 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 }); }
10182
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 }); }
10183
9934
  }
10184
9935
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: ElderFileSelectDirective, decorators: [{
@@ -10187,7 +9938,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImpor
10187
9938
  selector: '[elderFileSelect]',
10188
9939
  standalone: true
10189
9940
  }]
10190
- }], ctorParameters: () => [{ type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i0.DestroyRef }], propDecorators: { elderFileSelectChange: [{
9941
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { elderFileSelectChange: [{
10191
9942
  type: Output
10192
9943
  }], elderSingleFileSelectChange: [{
10193
9944
  type: Output
@@ -10307,44 +10058,70 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImpor
10307
10058
  type: Input
10308
10059
  }] } });
10309
10060
 
10310
- class FileListingWebkit {
10311
- /***************************************************************************
10312
- * *
10313
- * Constructor *
10314
- * *
10315
- **************************************************************************/
10061
+ class FileListingRx {
10316
10062
  constructor() {
10063
+ this.log = LoggerFactory.getLogger(this.constructor.name);
10317
10064
  }
10065
+ static { this.INSTANCE = new FileListingRx(); }
10318
10066
  /***************************************************************************
10319
10067
  * *
10320
- * Public methods *
10068
+ * Public API *
10321
10069
  * *
10322
10070
  **************************************************************************/
10323
- static listFilesRecursive(entry) {
10324
- 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);
10325
10102
  }
10326
10103
  /***************************************************************************
10327
10104
  * *
10328
10105
  * Private methods *
10329
10106
  * *
10330
10107
  **************************************************************************/
10331
- static listFilesRecursiveAsync(entry, parent) {
10108
+ listFilesRecursiveAsync(entry, parent) {
10332
10109
  if (entry.isDirectory) {
10333
10110
  const directoryEntry = entry;
10334
- 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()));
10335
10112
  }
10336
10113
  else if (entry.isFile) {
10337
10114
  const fileEntry = entry;
10338
- return FileListingWebkit.observableFile(fileEntry, parent).pipe(map(file => [file]));
10115
+ return this.observableFile(fileEntry, parent).pipe(map(file => [file]));
10339
10116
  }
10340
10117
  else {
10341
10118
  return EMPTY;
10342
10119
  }
10343
10120
  }
10344
- static observableFile(fileEntry, parent) {
10121
+ observableFile(fileEntry, parent) {
10345
10122
  return new Observable(observer => {
10346
10123
  fileEntry.file(file => {
10347
- observer.next(FileEntry.relativeFile(file, FileListingWebkit.trimStaringSlash(parent?.fullPath)));
10124
+ observer.next(FileEntry.relativeFile(file, this.trimStaringSlash(parent?.fullPath)));
10348
10125
  observer.complete();
10349
10126
  }, err => {
10350
10127
  observer.error(err);
@@ -10352,7 +10129,7 @@ class FileListingWebkit {
10352
10129
  });
10353
10130
  });
10354
10131
  }
10355
- static trimStaringSlash(path) {
10132
+ trimStaringSlash(path) {
10356
10133
  if (path) {
10357
10134
  if (path.startsWith('/')) {
10358
10135
  path = path.substring(1);
@@ -10360,12 +10137,12 @@ class FileListingWebkit {
10360
10137
  }
10361
10138
  return path;
10362
10139
  }
10363
- static readEntries(directoryEntry) {
10140
+ readEntries(directoryEntry) {
10364
10141
  return new Observable(observer => {
10365
- FileListingWebkit.consumeReaderToCompletion(observer, directoryEntry.createReader());
10142
+ this.consumeReaderToCompletion(observer, directoryEntry.createReader());
10366
10143
  });
10367
10144
  }
10368
- static consumeReaderToCompletion(observer, directoryReader) {
10145
+ consumeReaderToCompletion(observer, directoryReader) {
10369
10146
  directoryReader.readEntries(entries => {
10370
10147
  if (entries && entries.length > 0) {
10371
10148
  observer.next(entries);
@@ -10381,63 +10158,6 @@ class FileListingWebkit {
10381
10158
  }
10382
10159
  }
10383
10160
 
10384
- class FileListingRx {
10385
- constructor() {
10386
- this.log = LoggerFactory.getLogger(this.constructor.name);
10387
- }
10388
- static { this.INSTANCE = new FileListingRx(); }
10389
- /***************************************************************************
10390
- * *
10391
- * Public API *
10392
- * *
10393
- **************************************************************************/
10394
- toFileList(transferItemList) {
10395
- const obs = [];
10396
- for (let i = 0; i < transferItemList.length; i++) {
10397
- const transferItem = transferItemList[i];
10398
- obs.push(this.resolveTransferItem(transferItem));
10399
- }
10400
- return zip(obs).pipe(map(files => files.flat()));
10401
- }
10402
- /***************************************************************************
10403
- * *
10404
- * Private methods *
10405
- * *
10406
- **************************************************************************/
10407
- resolveTransferItem(transferItem) {
10408
- if (FileSystemApi.isGetAsFileSystemHandleSupported(transferItem)) {
10409
- return FileSystemApi.getAsFileSystemHandle(transferItem).pipe(switchMap(handle => handle ? FileListingSystemHandle.listFiles(handle) : this.legacyFileListing(transferItem)));
10410
- }
10411
- return this.legacyFileListing(transferItem);
10412
- }
10413
- legacyFileListing(transferItem) {
10414
- const entry = transferItem.webkitGetAsEntry();
10415
- if (entry) {
10416
- return FileListingWebkit.listFilesRecursive(entry);
10417
- }
10418
- return this.fallbackFileListing(transferItem);
10419
- }
10420
- fallbackFileListing(transferItem) {
10421
- const itemAsFile = transferItem.getAsFile();
10422
- if (itemAsFile) {
10423
- return of([FileEntry.ofFile(itemAsFile)]);
10424
- }
10425
- else {
10426
- if (transferItem.kind == 'file') {
10427
- return of([
10428
- FileEntry.ofFile(new File([], '', {
10429
- type: transferItem.type
10430
- }))
10431
- ]);
10432
- }
10433
- else {
10434
- this.log.warn('Could not handle DataTransferItem!', transferItem);
10435
- return of([]);
10436
- }
10437
- }
10438
- }
10439
- }
10440
-
10441
10161
  class ElderFileDropZoneDirective {
10442
10162
  /***************************************************************************
10443
10163
  * *
@@ -10991,7 +10711,18 @@ class ElderBlobViewerComponent {
10991
10711
  this._url$ = new BehaviorSubject(null);
10992
10712
  this._mimeType$ = new BehaviorSubject(null);
10993
10713
  this.destroy$ = new Subject();
10994
- 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
+ });
10995
10726
  }
10996
10727
  /***************************************************************************
10997
10728
  * *
@@ -11005,21 +10736,6 @@ class ElderBlobViewerComponent {
11005
10736
  this.destroy$.next();
11006
10737
  this.destroy$.complete();
11007
10738
  }
11008
- /***************************************************************************
11009
- * *
11010
- * Properties *
11011
- * *
11012
- **************************************************************************/
11013
- /**
11014
- * Attempt to display unknown blobs as text. (i.e. mime-type is octet-stream)
11015
- * @param unknownAsText
11016
- */
11017
- set displayUnknownAsText(unknownAsText) {
11018
- // TODO FIX RACE CONDITION:
11019
- // Since this property is not reactive, it must be set first.
11020
- // Otherwise, it will still be false, even if set to true!
11021
- this._displayUnknownAsText = coerceBooleanProperty(unknownAsText);
11022
- }
11023
10739
  /**
11024
10740
  * Set a in memory blob to display.
11025
10741
  * @param blob
@@ -11098,7 +10814,7 @@ class ElderBlobViewerComponent {
11098
10814
  });
11099
10815
  }
11100
10816
  canDisplayAsText(mimeType) {
11101
- const can = mimeType.isText || (this._displayUnknownAsText && mimeType.isOctetStream);
10817
+ const can = mimeType.isText || (this.displayUnknownAsText() && mimeType.isOctetStream);
11102
10818
  // TODO _displayUnknownAsText might be null due race condition see todo above.
11103
10819
  // this.logger.debug('canDisplayAsText(' + mimeType.value + ') --> '
11104
10820
  // + can + ' ---> this._displayUnknownAsText:' + this._displayUnknownAsText, mimeType);
@@ -11110,14 +10826,12 @@ class ElderBlobViewerComponent {
11110
10826
  });
11111
10827
  }
11112
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 }); }
11113
- 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 }); }
11114
10830
  }
11115
10831
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: ElderBlobViewerComponent, decorators: [{
11116
10832
  type: Component,
11117
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"] }]
11118
- }], ctorParameters: () => [{ type: HttpClientPristine }, { type: i1.DomSanitizer }, { type: ElderToastService }], propDecorators: { displayUnknownAsText: [{
11119
- type: Input
11120
- }], blob: [{
10834
+ }], ctorParameters: () => [{ type: HttpClientPristine }, { type: i1.DomSanitizer }, { type: ElderToastService }], propDecorators: { blob: [{
11121
10835
  type: Input
11122
10836
  }], blobUrl: [{
11123
10837
  type: Input
@@ -15959,6 +15673,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImpor
15959
15673
  type: Input
15960
15674
  }] } });
15961
15675
 
15676
+ class InputUtils {
15677
+ static isNoInputArgs(input) {
15678
+ return input === '';
15679
+ }
15680
+ }
15681
+
15962
15682
  class ElderMultipleOfUtil {
15963
15683
  /***************************************************************************
15964
15684
  * *
@@ -16008,11 +15728,13 @@ class ElderMultipleOfUtil {
16008
15728
  }
16009
15729
  }
16010
15730
  class ElderMultipleOfValidator {
16011
- set elderMultipleOf(value) {
16012
- this._factor = value;
16013
- }
16014
- get factor() {
16015
- return this._factor;
15731
+ constructor() {
15732
+ /***************************************************************************
15733
+ * *
15734
+ * Fields *
15735
+ * *
15736
+ **************************************************************************/
15737
+ this._factor = null;
16016
15738
  }
16017
15739
  /***************************************************************************
16018
15740
  * *
@@ -16027,8 +15749,19 @@ class ElderMultipleOfValidator {
16027
15749
  return null;
16028
15750
  }
16029
15751
  }
15752
+ /***************************************************************************
15753
+ * *
15754
+ * Properties *
15755
+ * *
15756
+ **************************************************************************/
15757
+ set factor(input) {
15758
+ this._factor = InputUtils.isNoInputArgs(input) ? null : input;
15759
+ }
15760
+ get factor() {
15761
+ return this._factor;
15762
+ }
16030
15763
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: ElderMultipleOfValidator, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
16031
- 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: [
15764
+ 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: { factor: ["elderMultipleOf", "factor"] }, providers: [
16032
15765
  {
16033
15766
  provide: NG_VALIDATORS,
16034
15767
  useExisting: forwardRef(() => ElderMultipleOfValidator),
@@ -16049,8 +15782,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImpor
16049
15782
  ],
16050
15783
  standalone: true
16051
15784
  }]
16052
- }], propDecorators: { elderMultipleOf: [{
16053
- type: Input
15785
+ }], propDecorators: { factor: [{
15786
+ type: Input,
15787
+ args: ['elderMultipleOf']
16054
15788
  }] } });
16055
15789
 
16056
15790
  /**
@@ -16915,7 +16649,7 @@ class ElderTableActivationDirective {
16915
16649
  this._data = [];
16916
16650
  this.activeItem$ = new BehaviorSubject(null);
16917
16651
  this.rows$ = new BehaviorSubject([]);
16918
- this.activationOptions = {};
16652
+ this._activationOptions = {};
16919
16653
  }
16920
16654
  /***************************************************************************
16921
16655
  * *
@@ -16976,6 +16710,12 @@ class ElderTableActivationDirective {
16976
16710
  * Properties *
16977
16711
  * *
16978
16712
  **************************************************************************/
16713
+ set activationOptions(options) {
16714
+ this.activationOptions = InputUtils.isNoInputArgs(options) ? options : {};
16715
+ }
16716
+ get activationOptions() {
16717
+ return this._activationOptions;
16718
+ }
16979
16719
  get activeItemEventChange() {
16980
16720
  return this.itemActivationEventSubject;
16981
16721
  }
@@ -17173,12 +16913,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImpor
17173
16913
  exportAs: 'elderTableActivation',
17174
16914
  standalone: true
17175
16915
  }]
17176
- }], ctorParameters: () => [{ type: ElderTableComponent }], propDecorators: { activationOptions: [{
17177
- type: Input,
17178
- args: ['elderTableActivation']
17179
- }], onKeydown: [{
16916
+ }], ctorParameters: () => [{ type: ElderTableComponent }], propDecorators: { onKeydown: [{
17180
16917
  type: HostListener,
17181
16918
  args: ['keydown', ['$event']]
16919
+ }], activationOptions: [{
16920
+ type: Input,
16921
+ args: ['elderTableActivation']
17182
16922
  }], activeItemEventChange: [{
17183
16923
  type: Output
17184
16924
  }], activeItemChange: [{