@libs-ui/components-preview-file 0.2.357-7 → 0.2.357-9

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 (2) hide show
  1. package/README.md +96 -163
  2. package/package.json +10 -10
package/README.md CHANGED
@@ -45,152 +45,75 @@ export class YourComponent {}
45
45
 
46
46
  ## Ví dụ sử dụng
47
47
 
48
- ### Ví dụ 1 — bản (xem danh sách tệp)
48
+ ### Ví dụ 1 — Sử dụng bản
49
49
 
50
- **TypeScript:**
51
-
52
- ```typescript
53
- import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
54
- import { LibsUiComponentsPreviewFileComponent } from '@libs-ui/components-preview-file';
55
- import { IFile } from '@libs-ui/interfaces-types';
56
-
57
- @Component({
58
- selector: 'app-document-list',
59
- templateUrl: './document-list.component.html',
60
- standalone: true,
61
- imports: [LibsUiComponentsPreviewFileComponent],
62
- changeDetection: ChangeDetectionStrategy.OnPush,
63
- })
64
- export class DocumentListComponent {
65
- protected showPreview = signal(false);
66
- protected currentIndex = signal(0);
67
-
68
- protected fileList: IFile[] = [
69
- {
70
- name: 'Bao cao thang 6.pdf',
71
- url: 'https://example.com/files/report-june.pdf',
72
- mimetype: 'application/pdf',
73
- },
74
- {
75
- name: 'Anh san pham.jpg',
76
- url: 'https://example.com/images/product.jpg',
77
- mimetype: 'image/jpeg',
78
- },
79
- {
80
- name: 'Du lieu Excel.xlsx',
81
- url: 'https://example.com/files/data.xlsx',
82
- mimetype: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
83
- },
84
- ];
85
-
86
- protected handlerOpenPreview(index: number): void {
87
- this.currentIndex.set(index);
88
- this.showPreview.set(true);
89
- }
90
-
91
- protected handlerClosePreview(): void {
92
- this.showPreview.set(false);
93
- }
94
- }
95
- ```
50
+ Mở trình xem trước tệp với các thiết lập mặc định.
96
51
 
97
52
  **HTML:**
98
53
 
99
54
  ```html
100
- <button (click)="handlerOpenPreview(0)">Xem tài liệu</button>
55
+ <button (click)="openPreview(0)" class="libs-ui-button-primary">
56
+ Xem danh sách tệp
57
+ </button>
101
58
 
102
59
  @if (showPreview()) {
103
60
  <libs_ui-components-preview_file
104
61
  [data]="fileList"
105
62
  [(index)]="currentIndex"
106
- (outClose)="handlerClosePreview()" />
63
+ (outClose)="showPreview.set(false)" />
107
64
  }
108
65
  ```
109
66
 
110
- ---
111
-
112
- ### Ví dụ 2 — Với nút hành động tùy chỉnh (Download, Share)
113
-
114
67
  **TypeScript:**
115
68
 
116
69
  ```typescript
117
70
  import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
118
- import { IButton, LibsUiComponentsButtonsButtonComponent } from '@libs-ui/components-buttons-button';
119
71
  import { LibsUiComponentsPreviewFileComponent } from '@libs-ui/components-preview-file';
120
72
  import { IFile } from '@libs-ui/interfaces-types';
121
73
 
122
74
  @Component({
123
- selector: 'app-file-gallery',
124
- templateUrl: './file-gallery.component.html',
125
75
  standalone: true,
126
- imports: [LibsUiComponentsPreviewFileComponent, LibsUiComponentsButtonsButtonComponent],
76
+ imports: [LibsUiComponentsPreviewFileComponent],
127
77
  changeDetection: ChangeDetectionStrategy.OnPush,
78
+ // ...
128
79
  })
129
- export class FileGalleryComponent {
130
- protected showPreview = signal(false);
131
- protected currentIndex = signal(0);
132
-
133
- protected fileList: IFile[] = [
134
- {
135
- name: 'Hop dong dich vu.docx',
136
- url: 'https://example.com/files/contract.docx',
137
- mimetype: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
138
- },
139
- {
140
- name: 'Thuyet trinh Q2.pptx',
141
- url: 'https://example.com/files/presentation-q2.pptx',
142
- mimetype: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
143
- },
80
+ export class YourComponent {
81
+ // [data]="fileList" — danh sách tệp cần xem trước (Bắt buộc)
82
+ readonly fileList: IFile[] = [
83
+ { name: 'Beautiful Landscape.jpg', url: 'https://images.unsplash.com/photo-xxx.jpg', mimetype: 'image/jpeg' },
84
+ { name: 'Sample PDF Document.pdf', url: 'https://example.com/dummy.pdf', mimetype: 'application/pdf' },
85
+ { name: 'Project Plan Excel.xlsx', url: 'https://example.com/plan.xlsx', mimetype: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' },
86
+ { name: 'Sample Presentation.pptx', url: 'https://example.com/deck.pptx', mimetype: 'application/vnd.openxmlformats-officedocument.presentationml.presentation' },
144
87
  ];
145
88
 
146
- protected customButtons: IButton[] = [
147
- {
148
- key: 'download',
149
- label: 'Tai xuong',
150
- type: 'button-primary',
151
- classIconLeft: 'libs-ui-icon-download-outline',
152
- action: async (index: number) => {
153
- const file = this.fileList[index];
154
- window.open(file.url, '_blank');
155
- },
156
- },
157
- {
158
- key: 'share',
159
- label: '',
160
- type: 'button-outline',
161
- classIconLeft: 'libs-ui-icon-upload-outline',
162
- iconOnlyType: true,
163
- action: async (index: number) => {
164
- const file = this.fileList[index];
165
- await navigator.clipboard.writeText(file.url || '');
166
- },
167
- },
168
- ];
89
+ // [(index)]="currentIndex" — chỉ số tệp đang xem (two-way binding)
90
+ readonly currentIndex = signal(0);
91
+
92
+ // @if (showPreview()) — điều kiện hiển thị component
93
+ readonly showPreview = signal(false);
169
94
 
170
- protected handlerOpenPreview(index: number): void {
95
+ // Handler mở preview tại vị trí index gọi từ nút "Xem danh sách tệp"
96
+ openPreview(index: number): void {
171
97
  this.currentIndex.set(index);
172
98
  this.showPreview.set(true);
173
99
  }
174
-
175
- protected handlerClosePreview(): void {
176
- this.showPreview.set(false);
177
- }
178
-
179
- protected handlerChangeIndex(newIndex: number): void {
180
- // Cập nhật nút theo tệp hiện tại nếu cần
181
- console.log('Chuyển sang tệp index:', newIndex);
182
- }
183
100
  }
184
101
  ```
185
102
 
103
+ ---
104
+
105
+ ### Ví dụ 2 — Tùy biến nút hành động
106
+
107
+ Thêm các nút chức năng như Tải xuống, Chia sẻ ngay trong giao diện xem trước.
108
+
186
109
  **HTML:**
187
110
 
188
111
  ```html
189
- <div class="flex flex-col gap-2">
112
+ <!-- Danh sách thumbnail -->
113
+ <div class="flex gap-4">
190
114
  @for (file of fileList; track file.url) {
191
- <div class="flex items-center justify-between p-3 border rounded-lg">
192
- <span>{{ file.name }}</span>
193
- <button (click)="handlerOpenPreview($index)">Xem truoc</button>
115
+ <div (click)="openPreview($index)" class="cursor-pointer">
116
+ {{ file.name }}
194
117
  </div>
195
118
  }
196
119
  </div>
@@ -200,73 +123,91 @@ export class FileGalleryComponent {
200
123
  [data]="fileList"
201
124
  [(index)]="currentIndex"
202
125
  [buttons]="customButtons"
203
- (outClose)="handlerClosePreview()"
204
- (outChangeIndex)="handlerChangeIndex($event)" />
126
+ (outClose)="showPreview.set(false)" />
205
127
  }
206
128
  ```
207
129
 
208
- ---
209
-
210
- ### Ví dụ 3 — Chế độ Iframe trực tiếp (Google Drive, Dropbox)
211
-
212
- Dùng khi URL đã là embed link sẵn (ví dụ Google Drive `/preview`), không cần qua Google Docs Viewer hay Microsoft Viewer.
213
-
214
130
  **TypeScript:**
215
131
 
216
132
  ```typescript
217
- import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
218
- import { LibsUiComponentsPreviewFileComponent } from '@libs-ui/components-preview-file';
219
- import { IFile } from '@libs-ui/interfaces-types';
220
-
221
- @Component({
222
- selector: 'app-drive-preview',
223
- templateUrl: './drive-preview.component.html',
224
- standalone: true,
225
- imports: [LibsUiComponentsPreviewFileComponent],
226
- changeDetection: ChangeDetectionStrategy.OnPush,
227
- })
228
- export class DrivePreviewComponent {
229
- protected showPreview = signal(false);
230
- protected currentIndex = signal(0);
133
+ import { IButton } from '@libs-ui/components-buttons-button';
231
134
 
232
- protected driveFiles: IFile[] = [
233
- {
234
- name: 'Tai lieu Google Drive',
235
- url: 'https://drive.google.com/file/d/1B9Ke75VYIznY4cjyZTnXRsRYPkmJ1AgK/preview',
236
- mimetype: 'application/pdf',
135
+ // fileList / currentIndex / showPreview / openPreview() — xem Ví dụ 1 phía trên.
136
+
137
+ // [buttons]="customButtons" thêm nút hành động tùy biến trên header preview
138
+ readonly customButtons: IButton[] = [
139
+ {
140
+ key: 'download',
141
+ label: 'Tải xuống',
142
+ type: 'button-primary',
143
+ classIconLeft: 'libs-ui-icon-download-outline',
144
+ action: async (index: number) => {
145
+ alert(`Bắt đầu tải xuống: ${this.fileList[index].name}`);
237
146
  },
238
- {
239
- name: 'Dropbox Shared File',
240
- url: 'https://www.dropbox.com/s/abc123/file.pdf?dl=0&raw=1',
241
- mimetype: 'application/pdf',
147
+ },
148
+ {
149
+ key: 'share',
150
+ label: '',
151
+ type: 'button-outline',
152
+ classIconLeft: 'libs-ui-icon-upload-outline',
153
+ iconOnlyType: true,
154
+ action: async (index: number) => {
155
+ alert(`Chia sẻ tệp: ${this.fileList[index].name}`);
242
156
  },
243
- ];
157
+ },
158
+ ];
159
+ ```
244
160
 
245
- protected handlerOpen(): void {
246
- this.currentIndex.set(0);
247
- this.showPreview.set(true);
248
- }
161
+ ---
249
162
 
250
- protected handlerClose(): void {
251
- this.showPreview.set(false);
252
- }
253
- }
254
- ```
163
+ ### Ví dụ 3 — Nguồn Iframe trực tiếp (Google Drive, Dropbox)
164
+
165
+ Có thể bỏ qua map URL viewer, dùng luôn link cho iframe (VD: Share link public của Google Drive). Không cần qua Google Docs Viewer hay Microsoft Viewer.
255
166
 
256
167
  **HTML:**
257
168
 
258
169
  ```html
259
- <button (click)="handlerOpen()">Mo Google Drive Preview</button>
170
+ <button (click)="openPreviewIframe(0)" class="libs-ui-button-primary">
171
+ Mở Link Dạng Iframe
172
+ </button>
260
173
 
261
- @if (showPreview()) {
174
+ @if (showPreviewIframe()) {
262
175
  <libs_ui-components-preview_file
263
- [data]="driveFiles"
264
- [(index)]="currentIndex"
176
+ [data]="fileListIframe"
177
+ [(index)]="currentIframeIndex"
265
178
  [isSourceIframe]="true"
266
- (outClose)="handlerClose()" />
179
+ (outClose)="showPreviewIframe.set(false)" />
267
180
  }
268
181
  ```
269
182
 
183
+ **TypeScript:**
184
+
185
+ ```typescript
186
+ import { signal } from '@angular/core';
187
+ import { IFile } from '@libs-ui/interfaces-types';
188
+
189
+ // [data]="fileListIframe" — dùng link share public (VD: Google Drive) render trực tiếp qua iframe
190
+ readonly fileListIframe: IFile[] = [
191
+ {
192
+ name: 'Google Drive Source',
193
+ url: 'https://drive.google.com/file/d/1B9Ke75VYIznY4cjyZTnXRsRYPkmJ1AgK/preview',
194
+ mimetype: 'application/pdf',
195
+ },
196
+ ];
197
+
198
+ // [(index)]="currentIframeIndex" / @if (showPreviewIframe())
199
+ readonly currentIframeIndex = signal(0);
200
+ readonly showPreviewIframe = signal(false);
201
+
202
+ // Handler mở preview iframe — gọi từ nút "Mở Link Dạng Iframe"
203
+ openPreviewIframe(index: number): void {
204
+ this.currentIframeIndex.set(index);
205
+ this.showPreviewIframe.set(true);
206
+ }
207
+ ```
208
+
209
+ > ⚠️ **`isSourceIframe` cho Google Drive**: Dùng link dạng `https://drive.google.com/file/d/{fileId}/preview` kết hợp `[isSourceIframe]="true"`. Không dùng link `/view` thông thường vì Google Drive chặn nhúng iframe.
210
+
270
211
  ---
271
212
 
272
213
  ### Ví dụ 4 — Với `LINK_IMAGE_ERROR_TOKEN_INJECT` (ảnh placeholder khi lỗi)
@@ -393,11 +334,3 @@ Nút Prev chỉ hiển thị khi `index() > 0`. Nút Next chỉ hiển thị khi
393
334
  ⚠️ **`isSourceIframe` cho Google Drive**: Khi chia sẻ file từ Google Drive, dùng link dạng `https://drive.google.com/file/d/{fileId}/preview` kết hợp với `[isSourceIframe]="true"`. Không dùng link `/view` thông thường vì Google Drive chặn nhúng iframe.
394
335
 
395
336
  ⚠️ **Two-way binding bắt buộc cho `index`**: Input `index` là `model.required()`, phải truyền bằng `[(index)]` hoặc cả `[index]` lẫn `(indexChange)`. Không có giá trị mặc định.
396
-
397
- ## Demo
398
-
399
- ```bash
400
- npx nx serve core-ui
401
- ```
402
-
403
- Truy cập: `http://localhost:4500/components/preview-file`
package/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@libs-ui/components-preview-file",
3
- "version": "0.2.357-7",
3
+ "version": "0.2.357-9",
4
4
  "peerDependencies": {
5
5
  "@angular/common": ">=18.0.0",
6
6
  "@angular/core": ">=18.0.0",
7
- "@libs-ui/components-modal": "0.2.357-7",
8
- "@libs-ui/components-skeleton": "0.2.357-7",
9
- "@libs-ui/interfaces-types": "0.2.357-7",
10
- "@libs-ui/pipes-security-trust": "0.2.357-7",
11
- "@libs-ui/components-buttons-button": "0.2.357-7",
12
- "@libs-ui/components-popover": "0.2.357-7",
13
- "@libs-ui/components-spinner": "0.2.357-7",
14
- "@libs-ui/pipes-check-file-extension": "0.2.357-7",
15
- "@libs-ui/utils": "0.2.357-7"
7
+ "@libs-ui/components-modal": "0.2.357-9",
8
+ "@libs-ui/components-skeleton": "0.2.357-9",
9
+ "@libs-ui/interfaces-types": "0.2.357-9",
10
+ "@libs-ui/pipes-security-trust": "0.2.357-9",
11
+ "@libs-ui/components-buttons-button": "0.2.357-9",
12
+ "@libs-ui/components-popover": "0.2.357-9",
13
+ "@libs-ui/components-spinner": "0.2.357-9",
14
+ "@libs-ui/pipes-check-file-extension": "0.2.357-9",
15
+ "@libs-ui/utils": "0.2.357-9"
16
16
  },
17
17
  "sideEffects": false,
18
18
  "module": "fesm2022/libs-ui-components-preview-file.mjs",