@libs-ui/components-line-clamp 0.2.356-42 → 0.2.356-43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -1,102 +1,300 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @libs-ui/components-line-clamp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> Component giới hạn số dòng văn bản, hỗ trợ nút Xem thêm / Thu gọn và Tooltip tích hợp sẵn.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Giới thiệu
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
- 🔗 **View More / Collapse**: Tự động hiển thị nút điều khiển khi nội dung vượt quá giới hạn.
|
|
9
|
-
- 💬 **Tooltip Support**: Tích hợp sẵn Tooltip để người dùng xem nhanh nội dung đầy đủ khi hover mà không cần mở rộng.
|
|
10
|
-
- 🎨 **Custom Styling**: Dễ dàng tùy chỉnh class cho nội dung và các nút điều khiển thông qua `ngClassObject`.
|
|
11
|
-
- 🔒 **Security**: Hỗ trợ lọc XSS thông qua `useXssFilter` và hỗ trợ cả `innerHTML` lẫn `innerText`.
|
|
12
|
-
- 🌈 **Gradient Effect**: Tùy chọn hiển thị hiệu ứng mờ dần (gradient) ở cuối đoạn văn bản bị cắt.
|
|
7
|
+
`@libs-ui/components-line-clamp` là component Angular dùng để cắt ngắn đoạn văn bản dài theo chiều cao tối đa (px) và tự động hiển thị nút điều khiển "Xem thêm" / "Thu gọn" khi nội dung vượt giới hạn. Component hỗ trợ render cả HTML (có lọc XSS) lẫn plain text, tích hợp Tooltip khi hover, hiệu ứng gradient mờ dần, và cung cấp `FunctionsControl` để component cha điều khiển trực tiếp qua `ViewChild`.
|
|
13
8
|
|
|
14
|
-
##
|
|
9
|
+
## Tính năng
|
|
10
|
+
|
|
11
|
+
- Giới hạn chiều cao hiển thị dựa trên `maxHeight` (px) — tính toán thực tế từ DOM
|
|
12
|
+
- Tự động hiển thị / ẩn nút "Xem thêm" và "Thu gọn" khi nội dung thay đổi
|
|
13
|
+
- Hỗ trợ render HTML an toàn qua `useXssFilter` hoặc plain text qua `isInnerText`
|
|
14
|
+
- Tích hợp Tooltip (Popover) hiển thị nội dung đầy đủ khi hover
|
|
15
|
+
- Hiệu ứng gradient mờ dần ở cuối đoạn văn bị cắt (`hasBackgroundGradient`)
|
|
16
|
+
- Tự động refresh khi cửa sổ trình duyệt resize (`window:resize`)
|
|
17
|
+
- Cho phép tùy chỉnh nhãn nút, CSS class nội dung và nút điều khiển
|
|
18
|
+
- Cung cấp `FunctionsControl` (refresh, viewMore, hiddenMore, checkIsDisplayLineClamp) để điều khiển từ bên ngoài
|
|
19
|
+
- Hỗ trợ i18n thông qua `@ngx-translate/core`
|
|
20
|
+
|
|
21
|
+
## Khi nào sử dụng
|
|
15
22
|
|
|
16
|
-
|
|
23
|
+
- Hiển thị phần giới thiệu ngắn trong danh sách thẻ (Card list) khi không đủ không gian
|
|
24
|
+
- Cắt bớt bình luận, mô tả sản phẩm hoặc ghi chú dài trong giao diện Dashboard
|
|
25
|
+
- Cần render HTML từ backend nhưng vẫn đảm bảo an toàn XSS và hỗ trợ rút gọn
|
|
26
|
+
- Muốn người dùng xem nhanh nội dung đầy đủ qua Tooltip mà không cần mở rộng trang
|
|
27
|
+
|
|
28
|
+
## Cài đặt
|
|
17
29
|
|
|
18
30
|
```bash
|
|
19
31
|
npm install @libs-ui/components-line-clamp
|
|
20
32
|
```
|
|
21
33
|
|
|
22
|
-
##
|
|
23
|
-
|
|
24
|
-
### Import Module
|
|
34
|
+
## Import
|
|
25
35
|
|
|
26
36
|
```typescript
|
|
27
37
|
import { LibsUiComponentsLineClampComponent } from '@libs-ui/components-line-clamp';
|
|
38
|
+
import { ILineClampFunctionControlEvent, ILineClampConfig } from '@libs-ui/components-line-clamp';
|
|
28
39
|
|
|
29
40
|
@Component({
|
|
30
41
|
standalone: true,
|
|
31
42
|
imports: [LibsUiComponentsLineClampComponent],
|
|
32
|
-
// ...
|
|
33
43
|
})
|
|
34
44
|
export class YourComponent {}
|
|
35
45
|
```
|
|
36
46
|
|
|
37
|
-
|
|
47
|
+
## Ví dụ sử dụng
|
|
38
48
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
49
|
+
### Cắt dòng cơ bản (2 dòng, line-height 20px)
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// your.component.ts
|
|
53
|
+
import { Component } from '@angular/core';
|
|
54
|
+
import { LibsUiComponentsLineClampComponent } from '@libs-ui/components-line-clamp';
|
|
55
|
+
|
|
56
|
+
@Component({
|
|
57
|
+
standalone: true,
|
|
58
|
+
imports: [LibsUiComponentsLineClampComponent],
|
|
59
|
+
template: `
|
|
60
|
+
<libs_ui-components-line_clamp
|
|
61
|
+
[content]="longText"
|
|
62
|
+
[maxHeight]="40"
|
|
63
|
+
[labelButtonViewMore]="'Xem thêm nội dung'"
|
|
64
|
+
[labelButtonCollapse]="'Thu gọn lại'">
|
|
65
|
+
</libs_ui-components-line_clamp>
|
|
66
|
+
`,
|
|
67
|
+
})
|
|
68
|
+
export class BasicExampleComponent {
|
|
69
|
+
readonly longText = `Angular là một nền tảng và framework để xây dựng các ứng dụng khách đơn trang
|
|
70
|
+
sử dụng HTML và TypeScript. Nó triển khai chức năng cốt lõi và tùy chọn dưới dạng
|
|
71
|
+
một tập hợp các thư viện TypeScript mà bạn import vào ứng dụng của mình.`;
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Tooltip và hiệu ứng gradient
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
// your.component.ts
|
|
79
|
+
import { Component } from '@angular/core';
|
|
80
|
+
import { LibsUiComponentsLineClampComponent } from '@libs-ui/components-line-clamp';
|
|
81
|
+
|
|
82
|
+
@Component({
|
|
83
|
+
standalone: true,
|
|
84
|
+
imports: [LibsUiComponentsLineClampComponent],
|
|
85
|
+
template: `
|
|
86
|
+
<libs_ui-components-line_clamp
|
|
87
|
+
[content]="htmlContent"
|
|
88
|
+
[maxHeight]="60"
|
|
89
|
+
[showTooltip]="true"
|
|
90
|
+
[hasBackgroundGradient]="true"
|
|
91
|
+
[maxWidthTooltip]="350"
|
|
92
|
+
[directionTooltip]="'bottom'">
|
|
93
|
+
</libs_ui-components-line_clamp>
|
|
94
|
+
`,
|
|
95
|
+
})
|
|
96
|
+
export class TooltipExampleComponent {
|
|
97
|
+
readonly htmlContent = `
|
|
98
|
+
<p style="color: #ef4444; font-weight: bold;">Nội dung HTML quan trọng:</p>
|
|
99
|
+
<ul>
|
|
100
|
+
<li>Signal là một cách mới để quản lý state.</li>
|
|
101
|
+
<li>Control Flow Syntax giúp template sạch hơn.</li>
|
|
102
|
+
<li>Deferrable Views giúp tối ưu lazy loading.</li>
|
|
103
|
+
</ul>
|
|
104
|
+
`;
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Plain text mode (không render HTML)
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
// your.component.ts
|
|
112
|
+
import { Component } from '@angular/core';
|
|
113
|
+
import { LibsUiComponentsLineClampComponent } from '@libs-ui/components-line-clamp';
|
|
114
|
+
|
|
115
|
+
@Component({
|
|
116
|
+
standalone: true,
|
|
117
|
+
imports: [LibsUiComponentsLineClampComponent],
|
|
118
|
+
template: `
|
|
119
|
+
<libs_ui-components-line_clamp
|
|
120
|
+
[content]="plainText"
|
|
121
|
+
[maxHeight]="40"
|
|
122
|
+
[isInnerText]="true"
|
|
123
|
+
[ngClassObject]="{ 'text-gray-500 italic': true }">
|
|
124
|
+
</libs_ui-components-line_clamp>
|
|
125
|
+
`,
|
|
126
|
+
})
|
|
127
|
+
export class PlainTextExampleComponent {
|
|
128
|
+
readonly plainText = `Đây là văn bản thuần túy, sẽ được render bằng innerText.
|
|
129
|
+
Mọi thẻ HTML trong chuỗi này sẽ hiển thị dưới dạng ký tự thay vì được phân tích cú pháp.`;
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Điều khiển từ component cha qua FunctionsControl
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
// parent.component.ts
|
|
137
|
+
import { Component, signal, viewChild } from '@angular/core';
|
|
138
|
+
import {
|
|
139
|
+
LibsUiComponentsLineClampComponent,
|
|
140
|
+
ILineClampFunctionControlEvent,
|
|
141
|
+
} from '@libs-ui/components-line-clamp';
|
|
142
|
+
|
|
143
|
+
@Component({
|
|
144
|
+
standalone: true,
|
|
145
|
+
imports: [LibsUiComponentsLineClampComponent],
|
|
146
|
+
template: `
|
|
147
|
+
<libs_ui-components-line_clamp
|
|
148
|
+
[content]="description"
|
|
149
|
+
[maxHeight]="60"
|
|
150
|
+
(outFunctionControl)="handlerFunctionControl($event)"
|
|
151
|
+
(outAction)="handlerAction($event)"
|
|
152
|
+
(outDisplayLineClamp)="handlerDisplayLineClamp($event)">
|
|
153
|
+
</libs_ui-components-line_clamp>
|
|
154
|
+
|
|
155
|
+
<button (click)="handlerRefresh()">Refresh</button>
|
|
156
|
+
<button (click)="handlerExpandAll()">Mở rộng tất cả</button>
|
|
157
|
+
`,
|
|
158
|
+
})
|
|
159
|
+
export class ParentExampleComponent {
|
|
160
|
+
protected description = `Mô tả dài của sản phẩm sẽ được cắt sau 3 dòng (60px với line-height 20px).
|
|
161
|
+
Nhấn nút bên dưới để điều khiển trạng thái từ component cha.`;
|
|
162
|
+
|
|
163
|
+
private lineClampControl: ILineClampFunctionControlEvent | undefined;
|
|
164
|
+
|
|
165
|
+
protected handlerFunctionControl(control: ILineClampFunctionControlEvent): void {
|
|
166
|
+
this.lineClampControl = control;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
protected handlerAction(action: string): void {
|
|
170
|
+
// action: 'view-more' | 'hidden-more'
|
|
171
|
+
console.log('Line clamp action:', action);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
protected handlerDisplayLineClamp(isCollapsed: boolean): void {
|
|
175
|
+
console.log('Is collapsed:', isCollapsed);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
protected handlerRefresh(): void {
|
|
179
|
+
this.lineClampControl?.refresh();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
protected handlerExpandAll(): void {
|
|
183
|
+
this.lineClampControl?.viewMore();
|
|
184
|
+
}
|
|
185
|
+
}
|
|
45
186
|
```
|
|
46
187
|
|
|
47
|
-
###
|
|
188
|
+
### Ẩn nút thu gọn (chỉ hiển thị "Xem thêm")
|
|
48
189
|
|
|
49
190
|
```html
|
|
50
191
|
<libs_ui-components-line_clamp
|
|
51
|
-
[content]="
|
|
52
|
-
[maxHeight]="
|
|
53
|
-
[
|
|
54
|
-
[
|
|
55
|
-
|
|
192
|
+
[content]="shortDescription"
|
|
193
|
+
[maxHeight]="40"
|
|
194
|
+
[ignoreShowButtonCollapse]="true"
|
|
195
|
+
[labelButtonViewMore]="'Đọc thêm'">
|
|
196
|
+
</libs_ui-components-line_clamp>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## @Input()
|
|
200
|
+
|
|
201
|
+
| Input | Type | Default | Mô tả | Ví dụ |
|
|
202
|
+
|---|---|---|---|---|
|
|
203
|
+
| `classClassIncludeButtonCollapseExpand` | `string` | `'!p-0'` | Class CSS cho container wrapper của nút collapse/expand | `[classClassIncludeButtonCollapseExpand]="'mt-2 !p-0'"` |
|
|
204
|
+
| `classClassLabelButtonCollapseExpand` | `string` | `'libs-ui-font-h5r'` | Class CSS typography cho nhãn nút collapse/expand | `[classClassLabelButtonCollapseExpand]="'libs-ui-font-h6r'"` |
|
|
205
|
+
| `content` | `string` | **bắt buộc** | Nội dung văn bản hoặc HTML cần hiển thị và cắt ngắn | `[content]="description"` |
|
|
206
|
+
| `defaultIsCollapse` | `boolean` | `true` | Trạng thái thu gọn mặc định khi nội dung vượt `maxHeight` | `[defaultIsCollapse]="false"` |
|
|
207
|
+
| `directionTooltip` | `TYPE_POPOVER_DIRECTION` | `'top'` | Hướng xuất hiện của Tooltip (top, bottom, left, right) | `[directionTooltip]="'bottom'"` |
|
|
208
|
+
| `hasBackgroundGradient` | `boolean` | `false` | Hiển thị hiệu ứng mờ dần gradient ở cuối đoạn văn bị cắt | `[hasBackgroundGradient]="true"` |
|
|
209
|
+
| `ignoreShowButtonCollapse` | `boolean` | `undefined` | Ẩn nút "Thu gọn", chỉ giữ lại nút "Xem thêm" | `[ignoreShowButtonCollapse]="true"` |
|
|
210
|
+
| `ignoreShowButtonCollapseExpand` | `boolean` | `false` | Ẩn hoàn toàn cả hai nút Xem thêm và Thu gọn | `[ignoreShowButtonCollapseExpand]="true"` |
|
|
211
|
+
| `ignoreStopPropagationTooltipEvent` | `boolean` | `false` | Cho phép sự kiện Tooltip nổi bọt lên component cha | `[ignoreStopPropagationTooltipEvent]="true"` |
|
|
212
|
+
| `isInnerText` | `boolean` | `undefined` | Render nội dung bằng `innerText` thay vì `innerHTML`, mọi thẻ HTML sẽ hiển thị dạng ký tự | `[isInnerText]="true"` |
|
|
213
|
+
| `labelButtonCollapse` | `string` | `undefined` (dùng i18n `i18n_collapse`) | Nhãn tùy chỉnh cho nút Thu gọn | `[labelButtonCollapse]="'Thu gọn lại'"` |
|
|
214
|
+
| `labelButtonViewMore` | `string` | `undefined` (dùng i18n `i18n_view_more`) | Nhãn tùy chỉnh cho nút Xem thêm | `[labelButtonViewMore]="'Xem thêm nội dung'"` |
|
|
215
|
+
| `lengthLimitDisplay` | `number` | `200` | Giới hạn số ký tự dùng để tính toán cắt chuỗi ban đầu trước khi đo DOM | `[lengthLimitDisplay]="300"` |
|
|
216
|
+
| `maxHeight` | `number` | **bắt buộc** | Chiều cao tối đa (px) trước khi cắt. Công thức: `line-height × số dòng`. Ví dụ: `20px × 3 dòng = 60` | `[maxHeight]="60"` |
|
|
217
|
+
| `maxHeightTooltip` | `number` | `150` | Chiều cao tối đa (px) của Tooltip | `[maxHeightTooltip]="200"` |
|
|
218
|
+
| `maxWidthTooltip` | `number` | `250` | Chiều rộng tối đa (px) của Tooltip | `[maxWidthTooltip]="350"` |
|
|
219
|
+
| `ngClassObject` | `TYPE_OBJECT` | `{ 'libs-ui-line-clamp-content libs-ui-font-h5r': true }` | Object `ngClass` để apply class CSS vào div chứa nội dung | `[ngClassObject]="{ 'libs-ui-font-h6r text-gray-700': true }"` |
|
|
220
|
+
| `showTooltip` | `boolean` | `undefined` | Bật Tooltip hiển thị toàn bộ nội dung khi hover vào vùng văn bản đã cắt | `[showTooltip]="true"` |
|
|
221
|
+
| `timeHidePopoverOnMouseout` | `number` | `50` | Thời gian delay (ms) trước khi ẩn Tooltip sau sự kiện `mouseout` | `[timeHidePopoverOnMouseout]="100"` |
|
|
222
|
+
| `useXssFilter` | `boolean` | `true` | Bật bộ lọc XSS cho nội dung HTML (chỉ có hiệu lực khi `isInnerText` là `false`) | `[useXssFilter]="false"` |
|
|
223
|
+
| `zIndexPopover` | `number` | `1001` | Giá trị `z-index` của Tooltip/Popover | `[zIndexPopover]="1050"` |
|
|
224
|
+
|
|
225
|
+
## @Output()
|
|
226
|
+
|
|
227
|
+
| Output | Type | Mô tả | Handler TS | Binding HTML |
|
|
228
|
+
|---|---|---|---|---|
|
|
229
|
+
| `(outAction)` | `string` | Phát ra chuỗi `'view-more'` khi nhấn nút Xem thêm, hoặc `'hidden-more'` khi nhấn nút Thu gọn | `handlerAction(action: string): void { action.stopPropagation?.(); console.log(action); }` | `(outAction)="handlerAction($event)"` |
|
|
230
|
+
| `(outClick)` | `Event \| TYPE_POPOVER_EVENT` | Phát ra khi người dùng click vào vùng nội dung hoặc Tooltip được click | `handlerClick(event: Event): void { event.stopPropagation(); }` | `(outClick)="handlerClick($event)"` |
|
|
231
|
+
| `(outDisplayLineClamp)` | `boolean` | Phát ra trạng thái thu gọn hiện tại (`true` = đang thu gọn, `false` = đã mở rộng). Kích hoạt khi nội dung vượt `maxHeight` | `handlerDisplayLineClamp(isCollapsed: boolean): void { this.isCollapsed.set(isCollapsed); }` | `(outDisplayLineClamp)="handlerDisplayLineClamp($event)"` |
|
|
232
|
+
| `(outFunctionControl)` | `ILineClampFunctionControlEvent` | Phát ra ngay khi component khởi tạo (`ngOnInit`), cung cấp các method điều khiển để component cha gọi từ bên ngoài | `handlerFunctionControl(control: ILineClampFunctionControlEvent): void { this.lineClampControl = control; }` | `(outFunctionControl)="handlerFunctionControl($event)"` |
|
|
233
|
+
|
|
234
|
+
## Types & Interfaces
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
import {
|
|
238
|
+
ILineClampFunctionControlEvent,
|
|
239
|
+
ILineClampConfig,
|
|
240
|
+
} from '@libs-ui/components-line-clamp';
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### ILineClampFunctionControlEvent
|
|
244
|
+
|
|
245
|
+
Interface nhận được qua event `(outFunctionControl)`, dùng để điều khiển component từ bên ngoài:
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
export interface ILineClampFunctionControlEvent {
|
|
249
|
+
/** Làm mới trạng thái, tính toán lại từ đầu */
|
|
250
|
+
refresh: () => Promise<void>;
|
|
251
|
+
|
|
252
|
+
/** Kiểm tra component có đang ở trạng thái clamp (nội dung bị cắt) không */
|
|
253
|
+
checkIsDisplayLineClamp: () => Promise<boolean>;
|
|
254
|
+
|
|
255
|
+
/** Mở rộng nội dung (tương đương nhấn nút "Xem thêm") */
|
|
256
|
+
viewMore: () => Promise<void>;
|
|
257
|
+
|
|
258
|
+
/** Thu gọn nội dung (tương đương nhấn nút "Thu gọn") */
|
|
259
|
+
hiddenMore: () => Promise<void>;
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### ILineClampConfig
|
|
264
|
+
|
|
265
|
+
Interface cấu hình tùy chọn (dùng cho các trường hợp cần type hóa config object):
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
268
|
+
import { TYPE_OBJECT } from '@libs-ui/interfaces-types';
|
|
269
|
+
|
|
270
|
+
export interface ILineClampConfig {
|
|
271
|
+
maxHeight?: number;
|
|
272
|
+
class?: string;
|
|
273
|
+
ignoreShowButtonCollapseExpand?: boolean;
|
|
274
|
+
showTooltip?: boolean;
|
|
275
|
+
maxWidthTooltip?: number;
|
|
276
|
+
maxHeightTooltip?: number;
|
|
277
|
+
ngClassObject?: TYPE_OBJECT;
|
|
278
|
+
isInnerText?: boolean;
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## Lưu ý quan trọng
|
|
283
|
+
|
|
284
|
+
⚠️ **Tính toán maxHeight**: `maxHeight` phải bằng `line-height (px) × số dòng mong muốn`. Ví dụ: text có `line-height: 20px`, muốn hiển thị 3 dòng thì set `[maxHeight]="60"`. Sai giá trị này sẽ khiến việc phát hiện clamp không chính xác.
|
|
285
|
+
|
|
286
|
+
⚠️ **isInnerText và useXssFilter**: Khi bật `[isInnerText]="true"`, nội dung được render bằng `innerText` — mọi thẻ HTML đều hiển thị dưới dạng ký tự. Trong trường hợp này `useXssFilter` không có tác dụng. Chỉ dùng `useXssFilter` khi render HTML (mặc định).
|
|
287
|
+
|
|
288
|
+
⚠️ **ngClassObject — CSS typography**: Object `ngClassObject` được apply vào thẻ div bao quanh nội dung. Mặc định là `{ 'libs-ui-line-clamp-content libs-ui-font-h5r': true }`. Khi ghi đè, cần bao gồm cả class layout cần thiết, không chỉ class typography.
|
|
289
|
+
|
|
290
|
+
⚠️ **outFunctionControl phát ra khi ngOnInit**: Event `(outFunctionControl)` chỉ phát ra một lần duy nhất khi component khởi tạo. Cần lưu lại reference để dùng sau: `private lineClampControl: ILineClampFunctionControlEvent | undefined`.
|
|
291
|
+
|
|
292
|
+
⚠️ **Resize tự động**: Component lắng nghe sự kiện `window:resize` và tự động gọi `refresh()`. Việc này đảm bảo trạng thái clamp luôn chính xác khi kích thước viewport thay đổi.
|
|
293
|
+
|
|
294
|
+
## Demo
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
npx nx serve core-ui
|
|
56
298
|
```
|
|
57
299
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
### Inputs
|
|
61
|
-
|
|
62
|
-
| Thuộc tính | Kiểu dữ liệu | Mặc định | Mô tả |
|
|
63
|
-
| :-------------------------------------- | :----------------------- | :----------------- | :------------------------------------------------------------ |
|
|
64
|
-
| `classClassIncludeButtonCollapseExpand` | `string` | `'!p-0'` | Class CSS cho container nút collapse/expand. |
|
|
65
|
-
| `classClassLabelButtonCollapseExpand` | `string` | `libs-...` | Class CSS cho nhãn nút collapse/expand. |
|
|
66
|
-
| `content` | `string` | `required` | Nội dung văn bản hoặc HTML cần hiển thị. |
|
|
67
|
-
| `defaultIsCollapse` | `boolean` | `true` | Mặc định thu gọn khi khởi tạo. |
|
|
68
|
-
| `directionTooltip` | `TYPE_POPOVER_DIRECTION` | `'top'` | Hướng hiển thị tooltip. |
|
|
69
|
-
| `hasBackgroundGradient` | `boolean` | `false` | Hiển thị hiệu ứng mờ dần ở phía dưới khi bị cắt. |
|
|
70
|
-
| `ignoreShowButtonCollapse` | `boolean` | `undefined` | Ẩn nút Thu gọn (chỉ hiện nút Xem thêm). |
|
|
71
|
-
| `ignoreShowButtonCollapseExpand` | `boolean` | `false` | Ẩn hoàn toàn nút Xem thêm / Thu gọn. |
|
|
72
|
-
| `ignoreStopPropagationTooltipEvent` | `boolean` | `false` | Ngăn chặn nổi bọt sự kiện tooltip. |
|
|
73
|
-
| `isInnerText` | `boolean` | `false` | Nếu true, sẽ render dưới dạng `innerText` (không xử lý HTML). |
|
|
74
|
-
| `labelButtonCollapse` | `string` | `'i18n_collapse'` | Nhãn cho nút Thu gọn. |
|
|
75
|
-
| `labelButtonViewMore` | `string` | `'i18n_view_more'` | Nhãn cho nút Xem thêm. |
|
|
76
|
-
| `lengthLimitDisplay` | `number` | `200` | Giới hạn số ký tự để tính toán cắt chuỗi ban đầu. |
|
|
77
|
-
| `maxHeight` | `number` | `required` | Độ cao tối đa (px). Công thức: (line-height) \* (số dòng). |
|
|
78
|
-
| `maxHeightTooltip` | `number` | `150` | Chiều cao tối đa của tooltip. |
|
|
79
|
-
| `maxWidthTooltip` | `number` | `250` | Chiều rộng tối đa của tooltip. |
|
|
80
|
-
| `ngClassObject` | `TYPE_OBJECT` | `...` | Đối tượng class CSS để apply vào div chứa nội dung. |
|
|
81
|
-
| `showTooltip` | `boolean` | `false` | Bật/tắt hiển thị tooltip khi nội dung bị cắt. |
|
|
82
|
-
| `timeHidePopoverOnMouseout` | `number` | `50` | Thời gian ẩn tooltip sau khi mouseout (ms). |
|
|
83
|
-
| `useXssFilter` | `boolean` | `true` | Bật bộ lọc XSS cho nội dung HTML. |
|
|
84
|
-
| `zIndexPopover` | `number` | `1001` | Z-index của tooltip. |
|
|
85
|
-
|
|
86
|
-
### Outputs
|
|
87
|
-
|
|
88
|
-
| Sự kiện | Kiểu dữ liệu | Mô tả |
|
|
89
|
-
| :-------------------- | :------------------------------- | :----------------------------------------------------------- |
|
|
90
|
-
| `outAction` | `string` | Phát ra khi người dùng nhấn 'view-more' hoặc 'hidden-more'. |
|
|
91
|
-
| `outClick` | `Event \| TYPE_POPOVER_EVENT` | Phát ra khi người dùng click vào vùng nội dung hoặc tooltip. |
|
|
92
|
-
| `outDisplayLineClamp` | `boolean` | Phát ra trạng thái đang thu gọn hay mở rộng. |
|
|
93
|
-
| `outFunctionControl` | `ILineClampFunctionControlEvent` | Cung cấp các phương thức điều khiển component (refresh). |
|
|
94
|
-
|
|
95
|
-
## Tech Stack
|
|
96
|
-
|
|
97
|
-
- **Core**: Angular 18+, Signals
|
|
98
|
-
- **Dependencies**: `@libs-ui/components-popover`, `@libs-ui/components-buttons-button`, `@libs-ui/pipes-security-trust`.
|
|
99
|
-
|
|
100
|
-
## License
|
|
101
|
-
|
|
102
|
-
MIT
|
|
300
|
+
Truy cập: http://localhost:4500/components/line-clamp
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NgClass, AsyncPipe } from '@angular/common';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { signal, input, output, inject, ElementRef, effect, untracked, Directive,
|
|
3
|
+
import { signal, input, output, inject, ElementRef, effect, untracked, Directive, Component, ChangeDetectionStrategy, HostListener } from '@angular/core';
|
|
4
4
|
import { LibsUiComponentsButtonsButtonComponent } from '@libs-ui/components-buttons-button';
|
|
5
5
|
import { LibsUiComponentsPopoverComponent } from '@libs-ui/components-popover';
|
|
6
6
|
import { LibsUiPipesEscapeHtmlPipe } from '@libs-ui/pipes-escape-html';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"libs-ui-components-line-clamp.mjs","sources":["../../../../../libs-ui/components/line-clamp/src/line-clamp.directive.ts","../../../../../libs-ui/components/line-clamp/src/line-clamp.component.ts","../../../../../libs-ui/components/line-clamp/src/line-clamp.component.html","../../../../../libs-ui/components/line-clamp/src/libs-ui-components-line-clamp.ts"],"sourcesContent":["import { Directive, effect, ElementRef, inject, input, OnDestroy, output, signal, untracked } from '@angular/core';\n\n@Directive({\n // eslint-disable-next-line @angular-eslint/directive-selector\n selector: '[LibsUiComponentsLineClampDirective]',\n standalone: true,\n})\nexport class LibsUiComponentsLineClampDirective implements OnDestroy {\n /** PROPERTY */\n private readonly timeInterval = signal<number | undefined>(undefined);\n private readonly textView = signal<string>('');\n\n /** INPUT */\n readonly lengthLimitDisplay = input.required<number>();\n readonly methodDisplay = input.required<string>();\n readonly content = input.required<string>();\n readonly ignoreThreeDots = input<boolean>();\n\n /** OUTPUT */\n readonly outContentSub = output<string>();\n\n /** INJECT */\n private readonly elementRef = inject(ElementRef);\n\n constructor() {\n effect(() => {\n if (!this.content() || !this.methodDisplay() || !this.lengthLimitDisplay()) {\n return;\n }\n untracked(() => {\n this.textView.set(this.content());\n if (this.textView().length > this.lengthLimitDisplay()) {\n this.textView.update((val) => val.substring(0, this.lengthLimitDisplay()));\n }\n\n if (!this.textView()) {\n return;\n }\n this.process();\n this.timeInterval.set(\n setInterval(() => {\n this.process();\n }, 250)\n );\n });\n });\n }\n\n /** FUNCTIONS */\n\n private process() {\n if (this.elementRef?.nativeElement[this.methodDisplay()]) {\n clearInterval(this.timeInterval());\n this.truncate();\n }\n }\n\n private truncate() {\n let content = this.textView();\n while (this.elementRef.nativeElement.scrollHeight - 2 > this.elementRef.nativeElement.offsetHeight) {\n if (!content) {\n return;\n }\n content = content.substring(0, content.length - 3);\n this.elementRef.nativeElement[this.methodDisplay()] = this.ignoreThreeDots() ? content : `${content}...`;\n }\n if (content !== this.textView()) {\n this.outContentSub.emit(this.ignoreThreeDots() ? content : `${content}...`);\n }\n }\n ngOnDestroy() {\n clearInterval(this.timeInterval());\n }\n}\n","import { AsyncPipe, NgClass } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, HostListener, OnDestroy, OnInit, effect, input, output, signal, untracked } from '@angular/core';\nimport { LibsUiComponentsButtonsButtonComponent } from '@libs-ui/components-buttons-button';\nimport { LibsUiComponentsPopoverComponent, TYPE_POPOVER_DIRECTION, TYPE_POPOVER_EVENT } from '@libs-ui/components-popover';\nimport { TYPE_OBJECT } from '@libs-ui/interfaces-types';\nimport { LibsUiPipesEscapeHtmlPipe } from '@libs-ui/pipes-escape-html';\nimport { LibsUiPipesSecurityTrustPipe } from '@libs-ui/pipes-security-trust';\nimport { isNil } from '@libs-ui/utils';\nimport { TranslateModule } from '@ngx-translate/core';\nimport { ILineClampFunctionControlEvent } from './interfaces';\nimport { LibsUiComponentsLineClampDirective } from './line-clamp.directive';\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'libs_ui-components-line_clamp',\n templateUrl: './line-clamp.component.html',\n styleUrls: ['./line-clamp.component.scss'],\n standalone: true,\n imports: [NgClass, TranslateModule, AsyncPipe, LibsUiComponentsLineClampDirective, LibsUiPipesSecurityTrustPipe, LibsUiPipesEscapeHtmlPipe, LibsUiComponentsPopoverComponent, LibsUiComponentsButtonsButtonComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class LibsUiComponentsLineClampComponent implements OnInit, OnDestroy {\n /** PROPERTY */\n protected displayLineClamp = signal<boolean>(false);\n protected isCollapse = signal<boolean>(false);\n protected contentClamp = signal<string>('');\n protected contentDisplay = signal<string>('');\n\n /** INPUT */\n readonly content = input.required<string>();\n readonly lengthLimitDisplay = input<number, number | undefined>(200, { transform: (val) => val || 200 });\n readonly maxHeight = input.required<number>(); // maxHeight = (line-height của text)*(số dòng mong muốn)\n readonly ignoreShowButtonCollapseExpand = input<boolean>();\n readonly ignoreShowButtonCollapse = input<boolean>();\n readonly showTooltip = input<boolean>();\n readonly timeHidePopoverOnMouseout = input<number, number | undefined>(50, { transform: (val) => val ?? 50 });\n readonly maxWidthTooltip = input<number, number | undefined>(250, { transform: (val) => val ?? 250 });\n readonly maxHeightTooltip = input<number, number | undefined>(150, { transform: (val) => val ?? 150 });\n readonly zIndexPopover = input<number, number | undefined>(1001, { transform: (val) => val ?? 1001 });\n readonly isInnerText = input<boolean>(); // không cần escapeHTML content khi biến bằng true\n readonly classClassLabelButtonCollapseExpand = input<string, string | undefined>('libs-ui-font-h5r', { transform: (val) => val ?? 'libs-ui-font-h5r' });\n readonly classClassIncludeButtonCollapseExpand = input<string, string | undefined>('!p-0', { transform: (val) => val ?? '!p-0' });\n readonly ignoreStopPropagationTooltipEvent = input<boolean, boolean | undefined>(false, { transform: (val) => val ?? false });\n readonly ngClassObject = input<TYPE_OBJECT, TYPE_OBJECT | undefined>({ 'libs-ui-line-clamp-content libs-ui-font-h5r': true }, { transform: (val) => val || { 'libs-ui-line-clamp-content lib-ui-font-h5r': true } }); // object ngClass\n readonly hasBackgroundGradient = input<boolean, boolean | undefined>(false, { transform: (val) => val ?? false });\n readonly labelButtonViewMore = input<string>();\n readonly labelButtonCollapse = input<string>();\n readonly directionTooltip = input<TYPE_POPOVER_DIRECTION, TYPE_POPOVER_DIRECTION | undefined>('top', { transform: (val) => val ?? 'top' });\n readonly useXssFilter = input<boolean, boolean | undefined>(true, { transform: (val) => val ?? true });\n readonly defaultIsCollapse = input<boolean, boolean | undefined>(true, { transform: (val) => val ?? true });\n\n /** OUTPUT */\n protected readonly outDisplayLineClamp = output<boolean>();\n protected readonly outAction = output<string>();\n protected readonly outClick = output<Event | TYPE_POPOVER_EVENT>();\n protected readonly outFunctionControl = output<ILineClampFunctionControlEvent>();\n\n constructor() {\n effect(() => {\n if (!isNil(this.content())) {\n untracked(() => {\n this.contentDisplay.set('');\n this.displayLineClamp.set(false);\n this.isCollapse.set(false);\n });\n }\n });\n }\n\n async ngOnInit() {\n this.outFunctionControl.emit(this.FunctionsControl);\n }\n\n /** FUNCTIONS */\n public get FunctionsControl(): ILineClampFunctionControlEvent {\n return {\n refresh: this.refresh.bind(this),\n checkIsDisplayLineClamp: async () => this.displayLineClamp(),\n viewMore: this.viewMore.bind(this),\n hiddenMore: this.hiddenMore.bind(this),\n };\n }\n\n protected async handlerContentSub(content: string) {\n if (this.content() !== content) {\n this.displayLineClamp.set(true);\n this.isCollapse.set(this.defaultIsCollapse());\n this.contentClamp.set(content);\n this.contentDisplay.set(this.isCollapse() ? content : this.content());\n this.outDisplayLineClamp.emit(this.isCollapse());\n }\n }\n\n protected async viewMore(e?: Event) {\n e?.stopPropagation();\n this.isCollapse.set(false);\n this.contentDisplay.set(this.content());\n e?.preventDefault();\n this.outAction.emit('view-more');\n }\n\n protected async hiddenMore(e?: Event) {\n e?.stopPropagation();\n this.isCollapse.set(true);\n this.contentDisplay.set(this.contentClamp());\n e?.preventDefault();\n this.outAction.emit('hidden-more');\n }\n\n @HostListener('window:resize', ['$event'])\n protected async resize() {\n this.refresh();\n }\n\n protected async refresh() {\n this.contentDisplay.set(this.content());\n this.displayLineClamp.set(false);\n this.isCollapse.set(false);\n }\n\n protected async handlerClick(event: Event | TYPE_POPOVER_EVENT) {\n if (typeof event === 'string' && event !== 'click') {\n return;\n }\n this.outClick.emit(event);\n }\n\n ngOnDestroy() {\n this.displayLineClamp.set(false);\n }\n}\n","@if (!displayLineClamp()) {\n @if (!isInnerText()) {\n <div\n LibsUiComponentsLineClampDirective\n [lengthLimitDisplay]=\"lengthLimitDisplay()\"\n [ignoreThreeDots]=\"hasBackgroundGradient()\"\n methodDisplay=\"innerHTML\"\n class=\"overflow-hidden\"\n [content]=\"content()\"\n [ngClass]=\"ngClassObject()\"\n [style.maxHeight.px]=\"maxHeight()\"\n [innerHtml]=\"content() | translate | LibsUiPipesSecurityTrustPipe: 'html' : useXssFilter() | async\"\n (click)=\"handlerClick($event)\"\n (keydown.enter)=\"handlerClick($event)\"\n (outContentSub)=\"handlerContentSub($event)\"></div>\n } @else {\n <div\n LibsUiComponentsLineClampDirective\n [lengthLimitDisplay]=\"lengthLimitDisplay()\"\n [ignoreThreeDots]=\"hasBackgroundGradient()\"\n methodDisplay=\"innerText\"\n class=\"overflow-hidden\"\n [content]=\"content()\"\n [ngClass]=\"ngClassObject()\"\n [style.maxHeight.px]=\"maxHeight()\"\n [innerText]=\"content() | translate\"\n (click)=\"handlerClick($event)\"\n (keydown.enter)=\"handlerClick($event)\"\n (outContentSub)=\"handlerContentSub($event)\"></div>\n }\n} @else {\n <libs_ui-components-popover\n class=\"relative\"\n type=\"other\"\n [ignoreShowPopover]=\"!showTooltip()\"\n [ignoreStopPropagationEvent]=\"ignoreStopPropagationTooltipEvent()\"\n [config]=\"{\n timerDestroy: timeHidePopoverOnMouseout(),\n maxWidth: maxWidthTooltip(),\n maxHeight: maxHeightTooltip(),\n direction: directionTooltip(),\n content: isInnerText() ? (this.content() | LibsUiPipesEscapeHtmlPipe) : this.content(),\n zIndex: zIndexPopover(),\n }\"\n (outEvent)=\"handlerClick($event)\">\n @if (isCollapse() && hasBackgroundGradient()) {\n <div class=\"h-[40px] libs-ui-line-clamp-bg-gradient\"></div>\n }\n @if (!isInnerText()) {\n <div\n [ngClass]=\"ngClassObject()\"\n [innerHtml]=\"contentDisplay() | translate | LibsUiPipesSecurityTrustPipe: 'html' : useXssFilter() | async\"></div>\n } @else {\n <div\n [ngClass]=\"ngClassObject()\"\n [innerText]=\"contentDisplay() | translate\"></div>\n }\n </libs_ui-components-popover>\n\n @if (!ignoreShowButtonCollapseExpand()) {\n @if (isCollapse()) {\n <libs_ui-components-buttons-button\n type=\"button-link-primary\"\n [label]=\"labelButtonViewMore() || 'i18n_view_more'\"\n [classInclude]=\"classClassIncludeButtonCollapseExpand()\"\n [classLabel]=\"classClassLabelButtonCollapseExpand()\"\n (outClick)=\"viewMore($event)\" />\n } @else {\n @if (!ignoreShowButtonCollapse()) {\n <libs_ui-components-buttons-button\n type=\"button-link-primary\"\n [label]=\"labelButtonCollapse() || 'i18n_collapse'\"\n [classInclude]=\"classClassIncludeButtonCollapseExpand()\"\n [classLabel]=\"classClassLabelButtonCollapseExpand()\"\n (outClick)=\"hiddenMore($event)\" />\n }\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"libs-ui-components-line-clamp.mjs","sources":["../../../../../libs-ui/components/line-clamp/src/line-clamp.directive.ts","../../../../../libs-ui/components/line-clamp/src/line-clamp.component.ts","../../../../../libs-ui/components/line-clamp/src/line-clamp.component.html","../../../../../libs-ui/components/line-clamp/src/libs-ui-components-line-clamp.ts"],"sourcesContent":["import { Directive, effect, ElementRef, inject, input, OnDestroy, output, signal, untracked } from '@angular/core';\n\n@Directive({\n // eslint-disable-next-line @angular-eslint/directive-selector\n selector: '[LibsUiComponentsLineClampDirective]',\n standalone: true,\n})\nexport class LibsUiComponentsLineClampDirective implements OnDestroy {\n /** PROPERTY */\n private readonly timeInterval = signal<number | undefined>(undefined);\n private readonly textView = signal<string>('');\n\n /** INPUT */\n readonly lengthLimitDisplay = input.required<number>();\n readonly methodDisplay = input.required<string>();\n readonly content = input.required<string>();\n readonly ignoreThreeDots = input<boolean>();\n\n /** OUTPUT */\n readonly outContentSub = output<string>();\n\n /** INJECT */\n private readonly elementRef = inject(ElementRef);\n\n constructor() {\n effect(() => {\n if (!this.content() || !this.methodDisplay() || !this.lengthLimitDisplay()) {\n return;\n }\n untracked(() => {\n this.textView.set(this.content());\n if (this.textView().length > this.lengthLimitDisplay()) {\n this.textView.update((val) => val.substring(0, this.lengthLimitDisplay()));\n }\n\n if (!this.textView()) {\n return;\n }\n this.process();\n this.timeInterval.set(\n setInterval(() => {\n this.process();\n }, 250)\n );\n });\n });\n }\n\n /** FUNCTIONS */\n\n private process() {\n if (this.elementRef?.nativeElement[this.methodDisplay()]) {\n clearInterval(this.timeInterval());\n this.truncate();\n }\n }\n\n private truncate() {\n let content = this.textView();\n while (this.elementRef.nativeElement.scrollHeight - 2 > this.elementRef.nativeElement.offsetHeight) {\n if (!content) {\n return;\n }\n content = content.substring(0, content.length - 3);\n this.elementRef.nativeElement[this.methodDisplay()] = this.ignoreThreeDots() ? content : `${content}...`;\n }\n if (content !== this.textView()) {\n this.outContentSub.emit(this.ignoreThreeDots() ? content : `${content}...`);\n }\n }\n ngOnDestroy() {\n clearInterval(this.timeInterval());\n }\n}\n","import { AsyncPipe, NgClass } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, HostListener, OnDestroy, OnInit, effect, input, output, signal, untracked } from '@angular/core';\nimport { LibsUiComponentsButtonsButtonComponent } from '@libs-ui/components-buttons-button';\nimport { LibsUiComponentsPopoverComponent, TYPE_POPOVER_DIRECTION, TYPE_POPOVER_EVENT } from '@libs-ui/components-popover';\nimport { TYPE_OBJECT } from '@libs-ui/interfaces-types';\nimport { LibsUiPipesEscapeHtmlPipe } from '@libs-ui/pipes-escape-html';\nimport { LibsUiPipesSecurityTrustPipe } from '@libs-ui/pipes-security-trust';\nimport { isNil } from '@libs-ui/utils';\nimport { TranslateModule } from '@ngx-translate/core';\nimport { ILineClampFunctionControlEvent } from './interfaces';\nimport { LibsUiComponentsLineClampDirective } from './line-clamp.directive';\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'libs_ui-components-line_clamp',\n templateUrl: './line-clamp.component.html',\n styleUrls: ['./line-clamp.component.scss'],\n standalone: true,\n imports: [NgClass, TranslateModule, AsyncPipe, LibsUiComponentsLineClampDirective, LibsUiPipesSecurityTrustPipe, LibsUiPipesEscapeHtmlPipe, LibsUiComponentsPopoverComponent, LibsUiComponentsButtonsButtonComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class LibsUiComponentsLineClampComponent implements OnInit, OnDestroy {\n /** PROPERTY */\n protected displayLineClamp = signal<boolean>(false);\n protected isCollapse = signal<boolean>(false);\n protected contentClamp = signal<string>('');\n protected contentDisplay = signal<string>('');\n\n /** INPUT */\n readonly content = input.required<string>();\n readonly lengthLimitDisplay = input<number, number | undefined>(200, { transform: (val) => val || 200 });\n readonly maxHeight = input.required<number>(); // maxHeight = (line-height của text)*(số dòng mong muốn)\n readonly ignoreShowButtonCollapseExpand = input<boolean>();\n readonly ignoreShowButtonCollapse = input<boolean>();\n readonly showTooltip = input<boolean>();\n readonly timeHidePopoverOnMouseout = input<number, number | undefined>(50, { transform: (val) => val ?? 50 });\n readonly maxWidthTooltip = input<number, number | undefined>(250, { transform: (val) => val ?? 250 });\n readonly maxHeightTooltip = input<number, number | undefined>(150, { transform: (val) => val ?? 150 });\n readonly zIndexPopover = input<number, number | undefined>(1001, { transform: (val) => val ?? 1001 });\n readonly isInnerText = input<boolean>(); // không cần escapeHTML content khi biến bằng true\n readonly classClassLabelButtonCollapseExpand = input<string, string | undefined>('libs-ui-font-h5r', { transform: (val) => val ?? 'libs-ui-font-h5r' });\n readonly classClassIncludeButtonCollapseExpand = input<string, string | undefined>('!p-0', { transform: (val) => val ?? '!p-0' });\n readonly ignoreStopPropagationTooltipEvent = input<boolean, boolean | undefined>(false, { transform: (val) => val ?? false });\n readonly ngClassObject = input<TYPE_OBJECT, TYPE_OBJECT | undefined>({ 'libs-ui-line-clamp-content libs-ui-font-h5r': true }, { transform: (val) => val || { 'libs-ui-line-clamp-content lib-ui-font-h5r': true } }); // object ngClass\n readonly hasBackgroundGradient = input<boolean, boolean | undefined>(false, { transform: (val) => val ?? false });\n readonly labelButtonViewMore = input<string>();\n readonly labelButtonCollapse = input<string>();\n readonly directionTooltip = input<TYPE_POPOVER_DIRECTION, TYPE_POPOVER_DIRECTION | undefined>('top', { transform: (val) => val ?? 'top' });\n readonly useXssFilter = input<boolean, boolean | undefined>(true, { transform: (val) => val ?? true });\n readonly defaultIsCollapse = input<boolean, boolean | undefined>(true, { transform: (val) => val ?? true });\n\n /** OUTPUT */\n protected readonly outDisplayLineClamp = output<boolean>();\n protected readonly outAction = output<string>();\n protected readonly outClick = output<Event | TYPE_POPOVER_EVENT>();\n protected readonly outFunctionControl = output<ILineClampFunctionControlEvent>();\n\n constructor() {\n effect(() => {\n if (!isNil(this.content())) {\n untracked(() => {\n this.contentDisplay.set('');\n this.displayLineClamp.set(false);\n this.isCollapse.set(false);\n });\n }\n });\n }\n\n async ngOnInit() {\n this.outFunctionControl.emit(this.FunctionsControl);\n }\n\n /** FUNCTIONS */\n public get FunctionsControl(): ILineClampFunctionControlEvent {\n return {\n refresh: this.refresh.bind(this),\n checkIsDisplayLineClamp: async () => this.displayLineClamp(),\n viewMore: this.viewMore.bind(this),\n hiddenMore: this.hiddenMore.bind(this),\n };\n }\n\n protected async handlerContentSub(content: string) {\n if (this.content() !== content) {\n this.displayLineClamp.set(true);\n this.isCollapse.set(this.defaultIsCollapse());\n this.contentClamp.set(content);\n this.contentDisplay.set(this.isCollapse() ? content : this.content());\n this.outDisplayLineClamp.emit(this.isCollapse());\n }\n }\n\n protected async viewMore(e?: Event) {\n e?.stopPropagation();\n this.isCollapse.set(false);\n this.contentDisplay.set(this.content());\n e?.preventDefault();\n this.outAction.emit('view-more');\n }\n\n protected async hiddenMore(e?: Event) {\n e?.stopPropagation();\n this.isCollapse.set(true);\n this.contentDisplay.set(this.contentClamp());\n e?.preventDefault();\n this.outAction.emit('hidden-more');\n }\n\n @HostListener('window:resize', ['$event'])\n protected async resize() {\n this.refresh();\n }\n\n protected async refresh() {\n this.contentDisplay.set(this.content());\n this.displayLineClamp.set(false);\n this.isCollapse.set(false);\n }\n\n protected async handlerClick(event: Event | TYPE_POPOVER_EVENT) {\n if (typeof event === 'string' && event !== 'click') {\n return;\n }\n this.outClick.emit(event);\n }\n\n ngOnDestroy() {\n this.displayLineClamp.set(false);\n }\n}\n","@if (!displayLineClamp()) {\n @if (!isInnerText()) {\n <div\n LibsUiComponentsLineClampDirective\n [lengthLimitDisplay]=\"lengthLimitDisplay()\"\n [ignoreThreeDots]=\"hasBackgroundGradient()\"\n methodDisplay=\"innerHTML\"\n class=\"overflow-hidden\"\n [content]=\"content()\"\n [ngClass]=\"ngClassObject()\"\n [style.maxHeight.px]=\"maxHeight()\"\n [innerHtml]=\"content() | translate | LibsUiPipesSecurityTrustPipe: 'html' : useXssFilter() | async\"\n (click)=\"handlerClick($event)\"\n (keydown.enter)=\"handlerClick($event)\"\n (outContentSub)=\"handlerContentSub($event)\"></div>\n } @else {\n <div\n LibsUiComponentsLineClampDirective\n [lengthLimitDisplay]=\"lengthLimitDisplay()\"\n [ignoreThreeDots]=\"hasBackgroundGradient()\"\n methodDisplay=\"innerText\"\n class=\"overflow-hidden\"\n [content]=\"content()\"\n [ngClass]=\"ngClassObject()\"\n [style.maxHeight.px]=\"maxHeight()\"\n [innerText]=\"content() | translate\"\n (click)=\"handlerClick($event)\"\n (keydown.enter)=\"handlerClick($event)\"\n (outContentSub)=\"handlerContentSub($event)\"></div>\n }\n} @else {\n <libs_ui-components-popover\n class=\"relative\"\n type=\"other\"\n [ignoreShowPopover]=\"!showTooltip()\"\n [ignoreStopPropagationEvent]=\"ignoreStopPropagationTooltipEvent()\"\n [config]=\"{\n timerDestroy: timeHidePopoverOnMouseout(),\n maxWidth: maxWidthTooltip(),\n maxHeight: maxHeightTooltip(),\n direction: directionTooltip(),\n content: isInnerText() ? (this.content() | LibsUiPipesEscapeHtmlPipe) : this.content(),\n zIndex: zIndexPopover(),\n }\"\n (outEvent)=\"handlerClick($event)\">\n @if (isCollapse() && hasBackgroundGradient()) {\n <div class=\"h-[40px] libs-ui-line-clamp-bg-gradient\"></div>\n }\n @if (!isInnerText()) {\n <div\n [ngClass]=\"ngClassObject()\"\n [innerHtml]=\"contentDisplay() | translate | LibsUiPipesSecurityTrustPipe: 'html' : useXssFilter() | async\"></div>\n } @else {\n <div\n [ngClass]=\"ngClassObject()\"\n [innerText]=\"contentDisplay() | translate\"></div>\n }\n </libs_ui-components-popover>\n\n @if (!ignoreShowButtonCollapseExpand()) {\n @if (isCollapse()) {\n <libs_ui-components-buttons-button\n type=\"button-link-primary\"\n [label]=\"labelButtonViewMore() || 'i18n_view_more'\"\n [classInclude]=\"classClassIncludeButtonCollapseExpand()\"\n [classLabel]=\"classClassLabelButtonCollapseExpand()\"\n (outClick)=\"viewMore($event)\" />\n } @else {\n @if (!ignoreShowButtonCollapse()) {\n <libs_ui-components-buttons-button\n type=\"button-link-primary\"\n [label]=\"labelButtonCollapse() || 'i18n_collapse'\"\n [classInclude]=\"classClassIncludeButtonCollapseExpand()\"\n [classLabel]=\"classClassLabelButtonCollapseExpand()\"\n (outClick)=\"hiddenMore($event)\" />\n }\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@libs-ui/components-line-clamp",
|
|
3
|
-
"version": "0.2.356-
|
|
3
|
+
"version": "0.2.356-43",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"@angular/common": ">=18.0.0",
|
|
6
6
|
"@angular/core": ">=18.0.0",
|
|
7
|
-
"@libs-ui/interfaces-types": "0.2.356-
|
|
8
|
-
"@libs-ui/components-buttons-button": "0.2.356-
|
|
9
|
-
"@libs-ui/components-popover": "0.2.356-
|
|
10
|
-
"@libs-ui/pipes-escape-html": "0.2.356-
|
|
11
|
-
"@libs-ui/pipes-security-trust": "0.2.356-
|
|
7
|
+
"@libs-ui/interfaces-types": "0.2.356-43",
|
|
8
|
+
"@libs-ui/components-buttons-button": "0.2.356-43",
|
|
9
|
+
"@libs-ui/components-popover": "0.2.356-43",
|
|
10
|
+
"@libs-ui/pipes-escape-html": "0.2.356-43",
|
|
11
|
+
"@libs-ui/pipes-security-trust": "0.2.356-43",
|
|
12
12
|
"@ngx-translate/core": "^15.0.0",
|
|
13
|
-
"@libs-ui/utils": "0.2.356-
|
|
13
|
+
"@libs-ui/utils": "0.2.356-43"
|
|
14
14
|
},
|
|
15
15
|
"sideEffects": false,
|
|
16
16
|
"module": "fesm2022/libs-ui-components-line-clamp.mjs",
|