@open-rlb/ng-bootstrap 3.2.0 → 3.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9019,39 +9019,33 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
9019
9019
 
9020
9020
  class DndDirective {
9021
9021
  constructor() {
9022
- this.multi = input(false, { ...(ngDevMode ? { debugName: "multi" } : /* istanbul ignore next */ {}), alias: 'multiple', transform: booleanAttribute });
9022
+ this.multiple = input(false, { ...(ngDevMode ? { debugName: "multiple" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
9023
9023
  this.fileDropped = output();
9024
- this.fileOver = signal(false, ...(ngDevMode ? [{ debugName: "fileOver" }] : /* istanbul ignore next */ []));
9024
+ this.isOver = signal(false, ...(ngDevMode ? [{ debugName: "isOver" }] : /* istanbul ignore next */ []));
9025
9025
  }
9026
9026
  onDragOver(evt) {
9027
9027
  evt.preventDefault();
9028
9028
  evt.stopPropagation();
9029
- this.fileOver.set(true);
9029
+ this.isOver.set(true);
9030
9030
  }
9031
9031
  onDragLeave(evt) {
9032
9032
  evt.preventDefault();
9033
9033
  evt.stopPropagation();
9034
- this.fileOver.set(false);
9034
+ this.isOver.set(false);
9035
9035
  }
9036
9036
  onDrop(evt) {
9037
9037
  evt.preventDefault();
9038
9038
  evt.stopPropagation();
9039
- this.fileOver.set(false);
9040
- let files = evt.dataTransfer?.files;
9039
+ this.isOver.set(false);
9040
+ const files = evt.dataTransfer?.files;
9041
9041
  if (files && files.length > 0) {
9042
- const _f = [];
9043
- if (files.length > 1 && !this.multi()) {
9044
- _f.push(files[0]);
9045
- }
9046
- else {
9047
- for (let i = 0; i < files.length; i++)
9048
- _f.push(files[i]);
9049
- }
9050
- this.fileDropped.emit(_f);
9042
+ const fileArray = Array.from(files);
9043
+ const result = this.multiple() ? fileArray : [fileArray[0]];
9044
+ this.fileDropped.emit(result);
9051
9045
  }
9052
9046
  }
9053
9047
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: DndDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
9054
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.7", type: DndDirective, isStandalone: false, selector: "[rlb-dnd]", inputs: { multi: { classPropertyName: "multi", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fileDropped: "fileDropped" }, host: { listeners: { "dragover": "onDragOver($event)", "dragleave": "onDragLeave($event)", "drop": "onDrop($event)" }, properties: { "class.fileover": "fileOver()" } }, ngImport: i0 }); }
9048
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.7", type: DndDirective, isStandalone: false, selector: "[rlb-dnd]", inputs: { multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fileDropped: "fileDropped" }, host: { listeners: { "dragover": "onDragOver($event)", "dragleave": "onDragLeave($event)", "drop": "onDrop($event)" }, properties: { "class.rlb-dnd-over": "isOver()" } }, ngImport: i0 }); }
9055
9049
  }
9056
9050
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: DndDirective, decorators: [{
9057
9051
  type: Directive,
@@ -9059,126 +9053,208 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
9059
9053
  selector: '[rlb-dnd]',
9060
9054
  standalone: false,
9061
9055
  host: {
9062
- '[class.fileover]': 'fileOver()',
9056
+ '[class.rlb-dnd-over]': 'isOver()',
9063
9057
  '(dragover)': 'onDragOver($event)',
9064
9058
  '(dragleave)': 'onDragLeave($event)',
9065
- '(drop)': 'onDrop($event)'
9066
- }
9059
+ '(drop)': 'onDrop($event)',
9060
+ },
9067
9061
  }]
9068
- }], propDecorators: { multi: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], fileDropped: [{ type: i0.Output, args: ["fileDropped"] }] } });
9062
+ }], propDecorators: { multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], fileDropped: [{ type: i0.Output, args: ["fileDropped"] }] } });
9069
9063
 
9070
9064
  class FileDndComponent {
9071
9065
  constructor() {
9072
- this.files = [];
9066
+ this.files = signal([], ...(ngDevMode ? [{ debugName: "files" }] : /* istanbul ignore next */ []));
9073
9067
  this.multiple = input(false, { ...(ngDevMode ? { debugName: "multiple" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
9074
9068
  this.data = input({}, ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
9075
- this.userDefinedId = input('', { ...(ngDevMode ? { debugName: "userDefinedId" } : /* istanbul ignore next */ {}), alias: 'id', transform: (v) => v || '' });
9069
+ this.idService = inject(UniqueIdService);
9070
+ this.userDefinedId = input(`dnd${this.idService.id}`, { ...(ngDevMode ? { debugName: "userDefinedId" } : /* istanbul ignore next */ {}), alias: 'id' });
9076
9071
  this.filesChange = output({ alias: 'files' });
9077
- this.fileDropEl = viewChild('fileDropRef', ...(ngDevMode ? [{ debugName: "fileDropEl" }] : /* istanbul ignore next */ []));
9078
9072
  }
9079
- onFileDropped(files) {
9080
- if (this.multiple()) {
9081
- this.files = files;
9082
- }
9083
- else {
9084
- this.files = [files[files.length - 1]];
9085
- }
9086
- this.filesChange.emit(this.files);
9087
- const el = this.fileDropEl();
9088
- if (el) {
9089
- el.nativeElement.value = "";
9090
- }
9073
+ onFileDropped(newFiles) {
9074
+ this.updateFiles(newFiles);
9091
9075
  }
9092
9076
  fileBrowseHandler(event) {
9093
- const _target = event.target;
9094
- if (_target.files && _target.files?.length) {
9095
- let _f = [];
9096
- if (this.multiple()) {
9097
- for (let i = 0; i < _target.files.length; i++)
9098
- _f.push(_target.files[i]);
9099
- }
9100
- else {
9101
- for (let i = 0; i < _target.files.length; i++)
9102
- _f = [_target.files[i]];
9103
- }
9104
- this.files = _f;
9105
- this.filesChange.emit(this.files);
9106
- const el = this.fileDropEl();
9107
- if (el) {
9108
- el.nativeElement.value = "";
9109
- }
9077
+ const target = event.target;
9078
+ if (target.files) {
9079
+ this.updateFiles(Array.from(target.files));
9080
+ target.value = '';
9110
9081
  }
9111
9082
  }
9112
- deleteFile(index) {
9113
- this.files.splice(this.files.indexOf(index), 1);
9114
- this.filesChange.emit(this.files);
9083
+ updateFiles(incoming) {
9084
+ this.files.update(current => {
9085
+ const updated = this.multiple() ? [...current, ...incoming] : [incoming[incoming.length - 1]];
9086
+ this.filesChange.emit(updated);
9087
+ return updated;
9088
+ });
9115
9089
  }
9116
- formatBytes(bytes, decimals = 2) {
9117
- if (bytes === 0) {
9118
- return "0 Bytes";
9119
- }
9090
+ deleteFile(fileToRemove) {
9091
+ this.files.update(current => {
9092
+ const updated = current.filter(f => f !== fileToRemove);
9093
+ this.filesChange.emit(updated);
9094
+ return updated;
9095
+ });
9096
+ }
9097
+ formatBytes(bytes) {
9098
+ if (bytes === 0)
9099
+ return '0 Bytes';
9120
9100
  const k = 1024;
9121
- const dm = decimals <= 0 ? 0 : decimals;
9122
- const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
9101
+ const sizes = ['Bytes', 'KB', 'MB', 'GB'];
9123
9102
  const i = Math.floor(Math.log(bytes) / Math.log(k));
9124
- return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
9103
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
9125
9104
  }
9126
9105
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: FileDndComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9127
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.7", type: FileDndComponent, isStandalone: false, selector: "rlb-file-dnd", inputs: { multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, userDefinedId: { classPropertyName: "userDefinedId", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filesChange: "files" }, viewQueries: [{ propertyName: "fileDropEl", first: true, predicate: ["fileDropRef"], descendants: true, isSignal: true }], ngImport: i0, template: `
9128
- <div class="rlb-file-dnd" rlb-dnd [multiple]="multiple()" (fileDropped)="onFileDropped($event)">
9129
- <input type="file" #fileDropRef id="fileDropRef" [attr.multiple]="multiple() ? '' : undefined" (change)="fileBrowseHandler($event)" />
9130
- <i class="bi bi-upload"></i>
9131
- <h3>{{ data()?.content?.drag }}</h3>
9132
- <h3>-</h3>
9133
- <label class="btn btn-primary" for="fileDropRef">{{ data()?.content?.button }}</label>
9134
- </div>
9135
- <div class="rlb-file-dnd-list">
9136
- @for (file of files; track file; let i = $index) {
9137
- <div class="single-file">
9138
- <i class="bi bi-file-earmark-image" style="font-size: 36px;"></i>
9139
- <div class="info">
9140
- <span class="d-block name"> {{ file.name }} </span>
9141
- <span class="d-block size">{{ formatBytes(file.size) }}</span>
9142
- <rlb-progress [height]="3" [value]="10" animated ></rlb-progress>
9143
- </div>
9144
- <button rlb-button outline class="p-0 mb-auto border-0">
9145
- <i class="bi bi-trash" (click)="deleteFile(file)"></i>
9146
- </button>
9106
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.7", type: FileDndComponent, isStandalone: false, selector: "rlb-file-dnd", inputs: { multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, userDefinedId: { classPropertyName: "userDefinedId", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filesChange: "files" }, ngImport: i0, template: `
9107
+ <div
9108
+ class="rlb-dnd-container"
9109
+ rlb-dnd
9110
+ [multiple]="multiple()"
9111
+ (fileDropped)="onFileDropped($event)"
9112
+ >
9113
+ <input
9114
+ type="file"
9115
+ #fileDropRef
9116
+ class="d-none"
9117
+ [id]="userDefinedId()"
9118
+ [attr.multiple]="multiple() ? '' : null"
9119
+ (change)="fileBrowseHandler($event)"
9120
+ />
9121
+
9122
+ <!-- Empty State -->
9123
+ <div class="d-flex flex-column align-items-center justify-content-center">
9124
+ <div
9125
+ class="mb-1"
9126
+ style="font-size: 5rem"
9127
+ >
9128
+ <i class="bi bi-cloud-arrow-up"></i>
9147
9129
  </div>
9148
- }
9149
- </div>`, isInline: true, dependencies: [{ kind: "directive", type: DndDirective, selector: "[rlb-dnd]", inputs: ["multiple"], outputs: ["fileDropped"] }, { kind: "component", type: ButtonComponent, selector: "button[rlb-button], a[rlb-button]", inputs: ["color", "size", "disabled", "outline", "isLink"] }, { kind: "component", type: ProgressComponent, selector: "rlb-progress", inputs: ["max", "min", "value", "height", "animated", "striped", "infinite", "aria-label", "showValue", "color", "text-color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9130
+ <h3 class="fs-2 fw-bold m-0">{{ data()?.content?.drag || 'Drag & Drop files here' }}</h3>
9131
+ <p class="fs-4 fw-normal mb-4">
9132
+ {{ multiple() ? 'Supports multiple files' : 'Select a single file' }}
9133
+ </p>
9134
+
9135
+ <label
9136
+ [for]="userDefinedId()"
9137
+ class="btn btn-primary px-4 py-2"
9138
+ >
9139
+ {{ data()?.content?.button || 'Browse Files' }}
9140
+ </label>
9141
+ </div>
9142
+ </div>
9143
+
9144
+ <!-- File List Implementation -->
9145
+ @if (files().length > 0) {
9146
+ <div class="mt-3">
9147
+ @for (file of files(); track file.name + file.size) {
9148
+ <rlb-card>
9149
+ <rlb-card-body class="d-flex align-items-center">
9150
+ <div class="fs-3">
9151
+ <i class="bi bi-file-earmark-text"></i>
9152
+ </div>
9153
+
9154
+ <div class="mx-3 flex-grow-1">
9155
+ <div class="d-flex justify-content-between align-items-center mb-1">
9156
+ <span class="fw-bold text-truncate">{{ file.name }}</span>
9157
+ <span class="text-secondary">{{ formatBytes(file.size) }}</span>
9158
+ </div>
9159
+ <rlb-progress
9160
+ [height]="4"
9161
+ [value]="100"
9162
+ ></rlb-progress>
9163
+ </div>
9164
+
9165
+ <button
9166
+ rlb-button
9167
+ outline
9168
+ color="danger"
9169
+ (click)="deleteFile(file)"
9170
+ aria-label="Remove file"
9171
+ >
9172
+ <i class="bi bi-x-lg"></i>
9173
+ </button>
9174
+ </rlb-card-body>
9175
+ </rlb-card>
9176
+ }
9177
+ </div>
9178
+ }
9179
+ `, isInline: true, styles: [":host{display:block}.rlb-dnd-container{border:2px dashed rgba(255,255,255,.15);border-radius:1rem;padding:3rem 2rem;cursor:pointer}.rlb-dnd-over{border-color:var(--bs-border-color);background:#6366f11a;transform:scale(1.01)}\n"], dependencies: [{ kind: "directive", type: DndDirective, selector: "[rlb-dnd]", inputs: ["multiple"], outputs: ["fileDropped"] }, { kind: "component", type: ButtonComponent, selector: "button[rlb-button], a[rlb-button]", inputs: ["color", "size", "disabled", "outline", "isLink"] }, { kind: "component", type: CardBodyComponent, selector: "rlb-card-body" }, { kind: "component", type: CardComponent, selector: "rlb-card", inputs: ["align", "overlay", "background", "border"] }, { kind: "component", type: ProgressComponent, selector: "rlb-progress", inputs: ["max", "min", "value", "height", "animated", "striped", "infinite", "aria-label", "showValue", "color", "text-color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9150
9180
  }
9151
9181
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: FileDndComponent, decorators: [{
9152
9182
  type: Component,
9153
- args: [{
9154
- selector: 'rlb-file-dnd',
9155
- template: `
9156
- <div class="rlb-file-dnd" rlb-dnd [multiple]="multiple()" (fileDropped)="onFileDropped($event)">
9157
- <input type="file" #fileDropRef id="fileDropRef" [attr.multiple]="multiple() ? '' : undefined" (change)="fileBrowseHandler($event)" />
9158
- <i class="bi bi-upload"></i>
9159
- <h3>{{ data()?.content?.drag }}</h3>
9160
- <h3>-</h3>
9161
- <label class="btn btn-primary" for="fileDropRef">{{ data()?.content?.button }}</label>
9162
- </div>
9163
- <div class="rlb-file-dnd-list">
9164
- @for (file of files; track file; let i = $index) {
9165
- <div class="single-file">
9166
- <i class="bi bi-file-earmark-image" style="font-size: 36px;"></i>
9167
- <div class="info">
9168
- <span class="d-block name"> {{ file.name }} </span>
9169
- <span class="d-block size">{{ formatBytes(file.size) }}</span>
9170
- <rlb-progress [height]="3" [value]="10" animated ></rlb-progress>
9171
- </div>
9172
- <button rlb-button outline class="p-0 mb-auto border-0">
9173
- <i class="bi bi-trash" (click)="deleteFile(file)"></i>
9174
- </button>
9183
+ args: [{ selector: 'rlb-file-dnd', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: `
9184
+ <div
9185
+ class="rlb-dnd-container"
9186
+ rlb-dnd
9187
+ [multiple]="multiple()"
9188
+ (fileDropped)="onFileDropped($event)"
9189
+ >
9190
+ <input
9191
+ type="file"
9192
+ #fileDropRef
9193
+ class="d-none"
9194
+ [id]="userDefinedId()"
9195
+ [attr.multiple]="multiple() ? '' : null"
9196
+ (change)="fileBrowseHandler($event)"
9197
+ />
9198
+
9199
+ <!-- Empty State -->
9200
+ <div class="d-flex flex-column align-items-center justify-content-center">
9201
+ <div
9202
+ class="mb-1"
9203
+ style="font-size: 5rem"
9204
+ >
9205
+ <i class="bi bi-cloud-arrow-up"></i>
9175
9206
  </div>
9176
- }
9177
- </div>`,
9178
- standalone: false,
9179
- changeDetection: ChangeDetectionStrategy.OnPush,
9180
- }]
9181
- }], propDecorators: { multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], userDefinedId: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], filesChange: [{ type: i0.Output, args: ["files"] }], fileDropEl: [{ type: i0.ViewChild, args: ['fileDropRef', { isSignal: true }] }] } });
9207
+ <h3 class="fs-2 fw-bold m-0">{{ data()?.content?.drag || 'Drag & Drop files here' }}</h3>
9208
+ <p class="fs-4 fw-normal mb-4">
9209
+ {{ multiple() ? 'Supports multiple files' : 'Select a single file' }}
9210
+ </p>
9211
+
9212
+ <label
9213
+ [for]="userDefinedId()"
9214
+ class="btn btn-primary px-4 py-2"
9215
+ >
9216
+ {{ data()?.content?.button || 'Browse Files' }}
9217
+ </label>
9218
+ </div>
9219
+ </div>
9220
+
9221
+ <!-- File List Implementation -->
9222
+ @if (files().length > 0) {
9223
+ <div class="mt-3">
9224
+ @for (file of files(); track file.name + file.size) {
9225
+ <rlb-card>
9226
+ <rlb-card-body class="d-flex align-items-center">
9227
+ <div class="fs-3">
9228
+ <i class="bi bi-file-earmark-text"></i>
9229
+ </div>
9230
+
9231
+ <div class="mx-3 flex-grow-1">
9232
+ <div class="d-flex justify-content-between align-items-center mb-1">
9233
+ <span class="fw-bold text-truncate">{{ file.name }}</span>
9234
+ <span class="text-secondary">{{ formatBytes(file.size) }}</span>
9235
+ </div>
9236
+ <rlb-progress
9237
+ [height]="4"
9238
+ [value]="100"
9239
+ ></rlb-progress>
9240
+ </div>
9241
+
9242
+ <button
9243
+ rlb-button
9244
+ outline
9245
+ color="danger"
9246
+ (click)="deleteFile(file)"
9247
+ aria-label="Remove file"
9248
+ >
9249
+ <i class="bi bi-x-lg"></i>
9250
+ </button>
9251
+ </rlb-card-body>
9252
+ </rlb-card>
9253
+ }
9254
+ </div>
9255
+ }
9256
+ `, styles: [":host{display:block}.rlb-dnd-container{border:2px dashed rgba(255,255,255,.15);border-radius:1rem;padding:3rem 2rem;cursor:pointer}.rlb-dnd-over{border-color:var(--bs-border-color);background:#6366f11a;transform:scale(1.01)}\n"] }]
9257
+ }], propDecorators: { multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], userDefinedId: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], filesChange: [{ type: i0.Output, args: ["files"] }] } });
9182
9258
 
9183
9259
  class FileComponent extends AbstractComponent {
9184
9260
  constructor() {