minahil 0.0.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.
package/README.md ADDED
@@ -0,0 +1,24 @@
1
+ # Minahil
2
+
3
+ This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 14.2.0.
4
+
5
+ ## Code scaffolding
6
+
7
+ Run `ng generate component component-name --project minahil` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project minahil`.
8
+ > Note: Don't forget to add `--project minahil` or else it will be added to the default project in your `angular.json` file.
9
+
10
+ ## Build
11
+
12
+ Run `ng build minahil` to build the project. The build artifacts will be stored in the `dist/` directory.
13
+
14
+ ## Publishing
15
+
16
+ After building your library with `ng build minahil`, go to the dist folder `cd dist/minahil` and run `npm publish`.
17
+
18
+ ## Running unit tests
19
+
20
+ Run `ng test minahil` to execute the unit tests via [Karma](https://karma-runner.github.io).
21
+
22
+ ## Further help
23
+
24
+ To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
@@ -0,0 +1,481 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Injectable, Component, NgModule, HostListener, Input, Directive, EventEmitter, ViewChild, Output } from '@angular/core';
3
+ import * as i2 from '@angular/cdk/drag-drop';
4
+ import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
5
+ import * as i1 from '@angular/common';
6
+ import { CommonModule } from '@angular/common';
7
+ import { ScrollingModule } from '@angular/cdk/scrolling';
8
+
9
+ class MinahilService {
10
+ constructor() { }
11
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MinahilService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
12
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MinahilService, providedIn: 'root' });
13
+ }
14
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MinahilService, decorators: [{
15
+ type: Injectable,
16
+ args: [{
17
+ providedIn: 'root'
18
+ }]
19
+ }], ctorParameters: () => [] });
20
+
21
+ class MinahilComponent {
22
+ constructor() { }
23
+ ngOnInit() {
24
+ }
25
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MinahilComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
26
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: MinahilComponent, isStandalone: true, selector: "lib-minahil", ngImport: i0, template: `
27
+ <p>
28
+ minahil works!
29
+ </p>
30
+ `, isInline: true });
31
+ }
32
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MinahilComponent, decorators: [{
33
+ type: Component,
34
+ args: [{ selector: 'lib-minahil', template: `
35
+ <p>
36
+ minahil works!
37
+ </p>
38
+ ` }]
39
+ }], ctorParameters: () => [] });
40
+
41
+ class MinahilModule {
42
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MinahilModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
43
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.16", ngImport: i0, type: MinahilModule });
44
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MinahilModule });
45
+ }
46
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MinahilModule, decorators: [{
47
+ type: NgModule,
48
+ args: [{
49
+ declarations: [],
50
+ imports: [],
51
+ exports: [],
52
+ }]
53
+ }] });
54
+
55
+ class TooltipDirective {
56
+ el;
57
+ renderer;
58
+ tooltipContent = '';
59
+ tooltipPosition = 'right';
60
+ tooltipElement = null;
61
+ constructor(el, renderer) {
62
+ this.el = el;
63
+ this.renderer = renderer;
64
+ }
65
+ ngOnInit() {
66
+ this.createTooltip();
67
+ }
68
+ ngOnChanges(changes) {
69
+ if (changes['tooltipContent'] && !changes['tooltipContent'].firstChange) {
70
+ this.updateTooltipContent();
71
+ }
72
+ }
73
+ ngOnDestroy() {
74
+ this.removeTooltip();
75
+ }
76
+ updateTooltipContent() {
77
+ // If tooltip doesn't exist yet and content is now available, create it
78
+ if (!this.tooltipElement && !this.isTooltipContentEmpty()) {
79
+ this.createTooltip();
80
+ return;
81
+ }
82
+ if (!this.tooltipElement)
83
+ return;
84
+ if (this.isTooltipContentEmpty())
85
+ return;
86
+ // remove old .text nodes
87
+ Array.from(this.tooltipElement.querySelectorAll('.text')).forEach((el) => this.renderer.removeChild(this.tooltipElement, el));
88
+ this.appendContent();
89
+ }
90
+ appendContent() {
91
+ if (!this.tooltipElement)
92
+ return;
93
+ const contentLines = Array.isArray(this.tooltipContent)
94
+ ? this.tooltipContent
95
+ : [this.tooltipContent];
96
+ contentLines.forEach((line) => {
97
+ const div = this.renderer.createElement('div');
98
+ this.renderer.addClass(div, 'text');
99
+ if (line?.trim().startsWith('<')) {
100
+ div.innerHTML = line;
101
+ }
102
+ else {
103
+ const text = this.renderer.createText(line ?? '');
104
+ this.renderer.appendChild(div, text);
105
+ }
106
+ this.renderer.appendChild(this.tooltipElement, div);
107
+ });
108
+ }
109
+ onMouseEnter() {
110
+ if (this.tooltipElement) {
111
+ this.setTooltipPosition();
112
+ this.setStyle(this.tooltipElement, {
113
+ visibility: 'visible',
114
+ opacity: '1',
115
+ });
116
+ this.renderer.setStyle(document.body, 'overflow-x', 'hidden'); // ✅ temporarily lock horizontal scroll
117
+ }
118
+ }
119
+ onMouseLeave() {
120
+ if (this.tooltipElement) {
121
+ this.setStyle(this.tooltipElement, {
122
+ visibility: 'hidden',
123
+ opacity: '0',
124
+ });
125
+ this.renderer.removeStyle(document.body, 'overflow-x'); // ✅ restore scroll when tooltip hides
126
+ }
127
+ }
128
+ onWindowChange() {
129
+ if (this.tooltipElement?.style.visibility === 'visible') {
130
+ this.setTooltipPosition();
131
+ }
132
+ }
133
+ isTooltipContentEmpty() {
134
+ if (typeof this.tooltipContent === 'string') {
135
+ return !this.tooltipContent.trim();
136
+ }
137
+ else if (Array.isArray(this.tooltipContent)) {
138
+ return (this.tooltipContent.length === 0 ||
139
+ this.tooltipContent.every((line) => !line.trim()));
140
+ }
141
+ return true;
142
+ }
143
+ createTooltip() {
144
+ if (this.isTooltipContentEmpty())
145
+ return;
146
+ this.tooltipElement = this.renderer.createElement('div');
147
+ this.renderer.addClass(this.tooltipElement, 'tooltip-content');
148
+ // Add content
149
+ const contentLines = Array.isArray(this.tooltipContent)
150
+ ? this.tooltipContent
151
+ : [this.tooltipContent];
152
+ contentLines.forEach((line) => {
153
+ const div = this.renderer.createElement('div');
154
+ this.renderer.addClass(div, 'text');
155
+ // this.renderer.appendChild(div, this.renderer.createText(line));
156
+ // Check if the line contains HTML
157
+ if (line.trim().startsWith('<')) {
158
+ div.innerHTML = line;
159
+ }
160
+ else {
161
+ const text = this.renderer.createText(line);
162
+ this.renderer.appendChild(div, text);
163
+ }
164
+ this.renderer.appendChild(this.tooltipElement, div);
165
+ });
166
+ // Add triangle
167
+ const triangle = this.renderer.createElement('div');
168
+ this.renderer.addClass(triangle, 'tooltip-triangle');
169
+ this.renderer.appendChild(this.tooltipElement, triangle);
170
+ // Set base styles
171
+ this.setStyle(this.tooltipElement, {
172
+ position: 'fixed',
173
+ visibility: 'hidden',
174
+ opacity: '0',
175
+ zIndex: '9999',
176
+ transition: 'opacity 0.3s ease, visibility 0.3s ease',
177
+ });
178
+ this.renderer.appendChild(document.body, this.tooltipElement);
179
+ }
180
+ setTooltipPosition() {
181
+ if (!this.tooltipElement)
182
+ return;
183
+ const hostRect = this.el.nativeElement.getBoundingClientRect();
184
+ const tooltipRect = this.tooltipElement.getBoundingClientRect();
185
+ const scrollTop = window.scrollY || document.documentElement.scrollTop;
186
+ const scrollLeft = window.scrollX || document.documentElement.scrollLeft;
187
+ const triangle = this.tooltipElement.querySelector('.tooltip-triangle');
188
+ const padding = 10;
189
+ let top = 0, left = 0;
190
+ // Position logic
191
+ switch (this.tooltipPosition) {
192
+ case 'right':
193
+ case 'left':
194
+ top = hostRect.top + scrollTop + hostRect.height / 2;
195
+ left =
196
+ this.tooltipPosition === 'right'
197
+ ? hostRect.right + scrollLeft + padding
198
+ : hostRect.left + scrollLeft - tooltipRect.width - padding;
199
+ // Auto flip if out of viewport
200
+ if (this.tooltipPosition === 'right' &&
201
+ left + tooltipRect.width > window.innerWidth) {
202
+ left = hostRect.left + scrollLeft - tooltipRect.width - padding;
203
+ }
204
+ else if (this.tooltipPosition === 'left' && left < 0) {
205
+ left = hostRect.right + scrollLeft + padding;
206
+ }
207
+ this.setStyle(this.tooltipElement, {
208
+ transform: 'translateY(-50%)',
209
+ });
210
+ this.setTriangleStyles(triangle, this.tooltipPosition, left < hostRect.left + scrollLeft);
211
+ break;
212
+ case 'top':
213
+ case 'bottom':
214
+ left =
215
+ hostRect.left +
216
+ scrollLeft +
217
+ hostRect.width / 2 -
218
+ tooltipRect.width / 2;
219
+ top =
220
+ this.tooltipPosition === 'top'
221
+ ? hostRect.top + scrollTop - tooltipRect.height - padding
222
+ : hostRect.bottom + scrollTop + padding;
223
+ // Prevent overflow
224
+ left = Math.max(10, Math.min(left, window.innerWidth - tooltipRect.width - 10));
225
+ this.setStyle(this.tooltipElement, {
226
+ transform: 'translateX(0)',
227
+ });
228
+ this.setTriangleStyles(triangle, this.tooltipPosition);
229
+ break;
230
+ }
231
+ this.setStyle(this.tooltipElement, {
232
+ top: `${top}px`,
233
+ left: `${left}px`,
234
+ });
235
+ }
236
+ setTriangleStyles(triangle, position, flipped = false) {
237
+ if (!triangle)
238
+ return;
239
+ const base = {
240
+ top: '',
241
+ left: '',
242
+ right: '',
243
+ bottom: '',
244
+ transform: '',
245
+ borderColor: '',
246
+ };
247
+ let styles = { ...base };
248
+ switch (position) {
249
+ case 'right':
250
+ styles = flipped
251
+ ? {
252
+ left: '100%',
253
+ top: '50%',
254
+ transform: 'translateY(-50%) translateX(0)',
255
+ borderColor: 'transparent transparent transparent #1a1a1a',
256
+ }
257
+ : {
258
+ left: '-15px',
259
+ top: '50%',
260
+ transform: 'translateY(-50%)',
261
+ borderColor: 'transparent #1a1a1a transparent transparent',
262
+ };
263
+ break;
264
+ case 'left':
265
+ styles = flipped
266
+ ? {
267
+ left: '100%',
268
+ top: '50%',
269
+ transform: 'translateY(-50%) translateX(0)',
270
+ borderColor: 'transparent transparent transparent #1a1a1a',
271
+ }
272
+ : {
273
+ left: '-15px',
274
+ top: '50%',
275
+ transform: 'translateY(-50%)',
276
+ borderColor: 'transparent #1a1a1a transparent transparent',
277
+ };
278
+ break;
279
+ case 'top':
280
+ styles = {
281
+ bottom: '-15px',
282
+ left: '50%',
283
+ transform: 'translateX(-50%)',
284
+ borderColor: '#1a1a1a transparent transparent transparent',
285
+ };
286
+ break;
287
+ case 'bottom':
288
+ styles = {
289
+ top: '-15px',
290
+ left: '50%',
291
+ transform: 'translateX(-50%)',
292
+ borderColor: 'transparent transparent #1a1a1a transparent',
293
+ };
294
+ break;
295
+ }
296
+ this.setStyle(triangle, styles);
297
+ }
298
+ removeTooltip() {
299
+ if (this.tooltipElement) {
300
+ this.renderer.removeChild(document.body, this.tooltipElement);
301
+ this.tooltipElement = null;
302
+ }
303
+ }
304
+ // Utility function to apply multiple styles
305
+ setStyle(el, styles) {
306
+ Object.entries(styles).forEach(([prop, value]) => {
307
+ this.renderer.setStyle(el, prop, value);
308
+ });
309
+ }
310
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TooltipDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
311
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.16", type: TooltipDirective, isStandalone: true, selector: "[appTooltip]", inputs: { tooltipContent: ["appTooltip", "tooltipContent"], tooltipPosition: ["appTooltipPosition", "tooltipPosition"] }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()", "window:scroll": "onWindowChange()", "window:resize": "onWindowChange()" } }, usesOnChanges: true, ngImport: i0 });
312
+ }
313
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TooltipDirective, decorators: [{
314
+ type: Directive,
315
+ args: [{
316
+ selector: '[appTooltip]',
317
+ standalone: true,
318
+ }]
319
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { tooltipContent: [{
320
+ type: Input,
321
+ args: ['appTooltip']
322
+ }], tooltipPosition: [{
323
+ type: Input,
324
+ args: ['appTooltipPosition']
325
+ }], onMouseEnter: [{
326
+ type: HostListener,
327
+ args: ['mouseenter']
328
+ }], onMouseLeave: [{
329
+ type: HostListener,
330
+ args: ['mouseleave']
331
+ }], onWindowChange: [{
332
+ type: HostListener,
333
+ args: ['window:scroll']
334
+ }, {
335
+ type: HostListener,
336
+ args: ['window:resize']
337
+ }] } });
338
+
339
+ class GenericTableComponent {
340
+ draggable = false;
341
+ columns = [];
342
+ result;
343
+ actions = [];
344
+ hasPermission = true;
345
+ actionClick = new EventEmitter();
346
+ sortChange = new EventEmitter();
347
+ dragDropChange = new EventEmitter();
348
+ sortColumn;
349
+ sortDirection = 'asc';
350
+ tableScrollContainer;
351
+ /* ---------- Sorting ---------- */
352
+ sort(column, index) {
353
+ if (!column.sortable || !column.field)
354
+ return;
355
+ // Toggle sort direction
356
+ this.sortDirection =
357
+ this.sortColumn === column.field
358
+ ? this.sortDirection === 'asc'
359
+ ? 'desc'
360
+ : 'asc'
361
+ : 'asc';
362
+ this.sortColumn = column.field;
363
+ // Emit sort change separately
364
+ this.sortChange.emit({
365
+ columnIndex: index,
366
+ column,
367
+ direction: this.sortDirection,
368
+ });
369
+ }
370
+ /* ---------- Visibility ---------- */
371
+ isColumnVisible(column) {
372
+ return column.visible !== false;
373
+ }
374
+ /* ---------- Cell Value ---------- */
375
+ getCellValue(row, column) {
376
+ if (column.formatter) {
377
+ return column.formatter(row);
378
+ }
379
+ if (column.field) {
380
+ return String(row[column.field] ?? '');
381
+ }
382
+ return '';
383
+ }
384
+ /* ---------- Actions ---------- */
385
+ emitAction(action, row) {
386
+ this.actionClick.emit({
387
+ action: action.name,
388
+ row,
389
+ });
390
+ }
391
+ dropList(event) {
392
+ if (!this.draggable || !this.result?.data)
393
+ return;
394
+ moveItemInArray(this.result.data, event.previousIndex, event.currentIndex);
395
+ // Update existing sortOrder on T
396
+ this.result.data.forEach((item, index) => {
397
+ item.sortOrder = index + 1;
398
+ });
399
+ // Emit reordered list
400
+ this.dragDropChange.emit(this.result.data);
401
+ }
402
+ onDragMoved(event) {
403
+ if (!this.tableScrollContainer)
404
+ return;
405
+ const container = this.tableScrollContainer.nativeElement;
406
+ const rect = container.getBoundingClientRect();
407
+ const pointerY = event.pointerPosition.y - rect.top;
408
+ const threshold = 80;
409
+ const maxSpeed = 25;
410
+ if (pointerY < threshold) {
411
+ const intensity = 1 - pointerY / threshold;
412
+ container.scrollTop -= Math.min(maxSpeed, intensity * maxSpeed);
413
+ }
414
+ else if (pointerY > rect.height - threshold) {
415
+ const intensity = 1 - (rect.height - pointerY) / threshold;
416
+ container.scrollTop += Math.min(maxSpeed, intensity * maxSpeed);
417
+ }
418
+ }
419
+ onDragStart(event) {
420
+ const row = event.source.element.nativeElement;
421
+ const cells = Array.from(row.querySelectorAll('td'));
422
+ setTimeout(() => {
423
+ const preview = document.querySelector('.cdk-drag-preview');
424
+ if (!preview)
425
+ return;
426
+ const previewCells = preview.querySelectorAll('td');
427
+ cells.forEach((cell, index) => {
428
+ const width = cell.getBoundingClientRect().width + 'px';
429
+ const previewCell = previewCells[index];
430
+ if (previewCell) {
431
+ previewCell.style.width = width;
432
+ previewCell.style.minWidth = width;
433
+ previewCell.style.maxWidth = width;
434
+ }
435
+ });
436
+ });
437
+ }
438
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: GenericTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
439
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: GenericTableComponent, isStandalone: true, selector: "lib-generic-table", inputs: { draggable: "draggable", columns: "columns", result: "result", actions: "actions", hasPermission: "hasPermission" }, outputs: { actionClick: "actionClick", sortChange: "sortChange", dragDropChange: "dragDropChange" }, viewQueries: [{ propertyName: "tableScrollContainer", first: true, predicate: ["tableScrollContainer"], descendants: true }], ngImport: i0, template: "<div\r\n #tableScrollContainer\r\n cdkScrollable\r\n class=\"h-[calc(100vh-260px)] overflow-y-auto\"\r\n>\r\n <table\r\n class=\"min-w-full text-sm text-left text-gray-800 table-auto border-collapse\"\r\n >\r\n <!-- ================= HEADER ================= -->\r\n <thead>\r\n <tr>\r\n @for (col of columns; track col.header;let i=$index;) { @if\r\n (isColumnVisible(col)) {\r\n <th\r\n class=\"table-header sticky top-0 cursor-pointer\"\r\n [class.action-sticky]=\"col.sticky\"\r\n [class.z-10]=\"col.sticky\"\r\n [ngClass]=\"col.headerClass\"\r\n (click)=\"sort(col, i)\"\r\n >\r\n <span\r\n class=\"flex items-center gap-1\"\r\n [ngClass]=\"\r\n sortColumn === col.field\r\n ? sortDirection === 'asc'\r\n ? 'asc'\r\n : 'desc'\r\n : ''\r\n \"\r\n >\r\n {{ col.header }}\r\n @if (col.sortable) {\r\n <span class=\"sort-icon\"></span>\r\n }\r\n </span>\r\n </th>\r\n } } @if (actions.length) {\r\n <th\r\n class=\"table-header sticky top-0 action-sticky z-10 !bg-[#FBFBFC] w-20\"\r\n >\r\n Action\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <!-- ================= BODY ================= -->\r\n <tbody\r\n cdkDropList\r\n [cdkDropListDisabled]=\"!draggable\"\r\n [cdkDropListData]=\"result.data || []\"\r\n (cdkDropListDropped)=\"dropList($event)\"\r\n >\r\n @for (row of result.data; track row; let rowIndex = $index) {\r\n <tr\r\n cdkDrag\r\n cdkDragLockAxis=\"y\"\r\n [cdkDragDisabled]=\"!draggable\"\r\n (cdkDragStarted)=\"onDragStart($event)\"\r\n (cdkDragMoved)=\"onDragMoved($event)\"\r\n class=\"\"\r\n [ngClass]=\"{ 'cursor-move ': draggable }\"\r\n >\r\n @for (col of columns; track col.header; let colIndex = $index) { @if\r\n (isColumnVisible(col)) {\r\n <td class=\"table-cell text-nowrap\" [ngClass]=\"col.cellClass\">\r\n @if (draggable && colIndex === 0) {\r\n <span\r\n cdkDragHandle\r\n class=\"mr-2 text-gray-400\"\r\n [ngClass]=\"{ 'cursor-move': draggable }\"\r\n >\u2630</span\r\n >\r\n }\r\n {{ getCellValue(row, col) }}\r\n </td>\r\n } } @if (actions.length) {\r\n <td class=\"table-cell action-sticky text-center\">\r\n <div class=\"flex items-center justify-center gap-1.5\">\r\n @for (action of actions; track action.name) { @if (hasPermission) {\r\n <button\r\n class=\"size-6 flex items-center justify-center rounded hover:bg-[#F8F8FA]\"\r\n (click)=\"emitAction(action, row)\"\r\n appTooltip=\"{{ action.tooltip }}\"\r\n appTooltipPosition=\"top\"\r\n >\r\n <img\r\n [src]=\"action.icon\"\r\n width=\"14\"\r\n height=\"14\"\r\n alt=\"action-icon\"\r\n />\r\n </button>\r\n } }\r\n </div>\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n</div>\r\n", styles: [".cdk-drag-preview{display:table;width:100%;background:#fff;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:.4;background-color:#f3f4f6}.cdk-drag-animating,.cdk-drop-list-dragging .cdk-drag{transition:transform .25s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "directive", type: TooltipDirective, selector: "[appTooltip]", inputs: ["appTooltip", "appTooltipPosition"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2.ɵɵCdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "directive", type: i2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i2.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: ScrollingModule }] });
440
+ }
441
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: GenericTableComponent, decorators: [{
442
+ type: Component,
443
+ args: [{ selector: 'lib-generic-table', standalone: true, imports: [TooltipDirective, CommonModule, DragDropModule, ScrollingModule], template: "<div\r\n #tableScrollContainer\r\n cdkScrollable\r\n class=\"h-[calc(100vh-260px)] overflow-y-auto\"\r\n>\r\n <table\r\n class=\"min-w-full text-sm text-left text-gray-800 table-auto border-collapse\"\r\n >\r\n <!-- ================= HEADER ================= -->\r\n <thead>\r\n <tr>\r\n @for (col of columns; track col.header;let i=$index;) { @if\r\n (isColumnVisible(col)) {\r\n <th\r\n class=\"table-header sticky top-0 cursor-pointer\"\r\n [class.action-sticky]=\"col.sticky\"\r\n [class.z-10]=\"col.sticky\"\r\n [ngClass]=\"col.headerClass\"\r\n (click)=\"sort(col, i)\"\r\n >\r\n <span\r\n class=\"flex items-center gap-1\"\r\n [ngClass]=\"\r\n sortColumn === col.field\r\n ? sortDirection === 'asc'\r\n ? 'asc'\r\n : 'desc'\r\n : ''\r\n \"\r\n >\r\n {{ col.header }}\r\n @if (col.sortable) {\r\n <span class=\"sort-icon\"></span>\r\n }\r\n </span>\r\n </th>\r\n } } @if (actions.length) {\r\n <th\r\n class=\"table-header sticky top-0 action-sticky z-10 !bg-[#FBFBFC] w-20\"\r\n >\r\n Action\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <!-- ================= BODY ================= -->\r\n <tbody\r\n cdkDropList\r\n [cdkDropListDisabled]=\"!draggable\"\r\n [cdkDropListData]=\"result.data || []\"\r\n (cdkDropListDropped)=\"dropList($event)\"\r\n >\r\n @for (row of result.data; track row; let rowIndex = $index) {\r\n <tr\r\n cdkDrag\r\n cdkDragLockAxis=\"y\"\r\n [cdkDragDisabled]=\"!draggable\"\r\n (cdkDragStarted)=\"onDragStart($event)\"\r\n (cdkDragMoved)=\"onDragMoved($event)\"\r\n class=\"\"\r\n [ngClass]=\"{ 'cursor-move ': draggable }\"\r\n >\r\n @for (col of columns; track col.header; let colIndex = $index) { @if\r\n (isColumnVisible(col)) {\r\n <td class=\"table-cell text-nowrap\" [ngClass]=\"col.cellClass\">\r\n @if (draggable && colIndex === 0) {\r\n <span\r\n cdkDragHandle\r\n class=\"mr-2 text-gray-400\"\r\n [ngClass]=\"{ 'cursor-move': draggable }\"\r\n >\u2630</span\r\n >\r\n }\r\n {{ getCellValue(row, col) }}\r\n </td>\r\n } } @if (actions.length) {\r\n <td class=\"table-cell action-sticky text-center\">\r\n <div class=\"flex items-center justify-center gap-1.5\">\r\n @for (action of actions; track action.name) { @if (hasPermission) {\r\n <button\r\n class=\"size-6 flex items-center justify-center rounded hover:bg-[#F8F8FA]\"\r\n (click)=\"emitAction(action, row)\"\r\n appTooltip=\"{{ action.tooltip }}\"\r\n appTooltipPosition=\"top\"\r\n >\r\n <img\r\n [src]=\"action.icon\"\r\n width=\"14\"\r\n height=\"14\"\r\n alt=\"action-icon\"\r\n />\r\n </button>\r\n } }\r\n </div>\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n</div>\r\n", styles: [".cdk-drag-preview{display:table;width:100%;background:#fff;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:.4;background-color:#f3f4f6}.cdk-drag-animating,.cdk-drop-list-dragging .cdk-drag{transition:transform .25s cubic-bezier(0,0,.2,1)}\n"] }]
444
+ }], propDecorators: { draggable: [{
445
+ type: Input
446
+ }], columns: [{
447
+ type: Input
448
+ }], result: [{
449
+ type: Input
450
+ }], actions: [{
451
+ type: Input
452
+ }], hasPermission: [{
453
+ type: Input
454
+ }], actionClick: [{
455
+ type: Output
456
+ }], sortChange: [{
457
+ type: Output
458
+ }], dragDropChange: [{
459
+ type: Output
460
+ }], tableScrollContainer: [{
461
+ type: ViewChild,
462
+ args: ['tableScrollContainer', { static: false }]
463
+ }] } });
464
+
465
+ class PaginatedResult {
466
+ page;
467
+ pageSize;
468
+ total;
469
+ data = [];
470
+ }
471
+
472
+ /*
473
+ * Public API Surface of minahil
474
+ */
475
+
476
+ /**
477
+ * Generated bundle index. Do not edit.
478
+ */
479
+
480
+ export { GenericTableComponent, MinahilComponent, MinahilModule, MinahilService, PaginatedResult, TooltipDirective };
481
+ //# sourceMappingURL=minahil.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"minahil.mjs","sources":["../../../projects/minahil/src/lib/minahil.service.ts","../../../projects/minahil/src/lib/minahil.component.ts","../../../projects/minahil/src/lib/minahil.module.ts","../../../projects/minahil/src/lib/directives/tooltip.directive.ts","../../../projects/minahil/src/lib/generic-table/generic-table.component.ts","../../../projects/minahil/src/lib/generic-table/generic-table.component.html","../../../projects/minahil/src/lib/models/table.model.ts","../../../projects/minahil/src/public-api.ts","../../../projects/minahil/src/minahil.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class MinahilService {\r\n\r\n constructor() { }\r\n}\r\n","import { Component, OnInit } from '@angular/core';\r\n\r\n@Component({\r\n selector: 'lib-minahil',\r\n template: `\r\n <p>\r\n minahil works!\r\n </p>\r\n `,\r\n styles: [\r\n ]\r\n})\r\nexport class MinahilComponent implements OnInit {\r\n\r\n constructor() { }\r\n\r\n ngOnInit(): void {\r\n }\r\n\r\n}\r\n","import { NgModule } from '@angular/core';\r\n\r\n@NgModule({\r\n declarations: [],\r\n imports: [],\r\n exports: [],\r\n})\r\nexport class MinahilModule {}\r\n","import {\r\n Directive,\r\n ElementRef,\r\n HostListener,\r\n Input,\r\n Renderer2,\r\n OnDestroy,\r\n OnInit,\r\n OnChanges,\r\n SimpleChanges,\r\n} from '@angular/core';\r\n\r\n@Directive({\r\n selector: '[appTooltip]',\r\n standalone: true,\r\n})\r\nexport class TooltipDirective implements OnInit, OnChanges, OnDestroy {\r\n @Input('appTooltip') tooltipContent: string | string[] = '';\r\n @Input('appTooltipPosition') tooltipPosition:\r\n | 'left'\r\n | 'right'\r\n | 'top'\r\n | 'bottom' = 'right';\r\n\r\n private tooltipElement: HTMLElement | null = null;\r\n\r\n constructor(private el: ElementRef, private renderer: Renderer2) {}\r\n\r\n ngOnInit(): void {\r\n this.createTooltip();\r\n }\r\n\r\n ngOnChanges(changes: SimpleChanges): void {\r\n if (changes['tooltipContent'] && !changes['tooltipContent'].firstChange) {\r\n this.updateTooltipContent();\r\n }\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.removeTooltip();\r\n }\r\n\r\n updateTooltipContent() {\r\n // If tooltip doesn't exist yet and content is now available, create it\r\n if (!this.tooltipElement && !this.isTooltipContentEmpty()) {\r\n this.createTooltip();\r\n return;\r\n }\r\n\r\n if (!this.tooltipElement) return;\r\n if (this.isTooltipContentEmpty()) return;\r\n\r\n // remove old .text nodes\r\n Array.from(this.tooltipElement.querySelectorAll('.text')).forEach((el) =>\r\n this.renderer.removeChild(this.tooltipElement, el)\r\n );\r\n\r\n this.appendContent();\r\n }\r\n\r\n appendContent() {\r\n if (!this.tooltipElement) return;\r\n\r\n const contentLines = Array.isArray(this.tooltipContent)\r\n ? this.tooltipContent\r\n : [this.tooltipContent];\r\n\r\n contentLines.forEach((line: string) => {\r\n const div = this.renderer.createElement('div');\r\n this.renderer.addClass(div, 'text');\r\n if (line?.trim().startsWith('<')) {\r\n div.innerHTML = line;\r\n } else {\r\n const text = this.renderer.createText(line ?? '');\r\n this.renderer.appendChild(div, text);\r\n }\r\n this.renderer.appendChild(this.tooltipElement!, div);\r\n });\r\n }\r\n\r\n @HostListener('mouseenter')\r\n onMouseEnter() {\r\n if (this.tooltipElement) {\r\n this.setTooltipPosition();\r\n this.setStyle(this.tooltipElement, {\r\n visibility: 'visible',\r\n opacity: '1',\r\n });\r\n this.renderer.setStyle(document.body, 'overflow-x', 'hidden'); // ✅ temporarily lock horizontal scroll\r\n }\r\n }\r\n\r\n @HostListener('mouseleave')\r\n onMouseLeave() {\r\n if (this.tooltipElement) {\r\n this.setStyle(this.tooltipElement, {\r\n visibility: 'hidden',\r\n opacity: '0',\r\n });\r\n this.renderer.removeStyle(document.body, 'overflow-x'); // ✅ restore scroll when tooltip hides\r\n }\r\n }\r\n\r\n @HostListener('window:scroll')\r\n @HostListener('window:resize')\r\n onWindowChange() {\r\n if (this.tooltipElement?.style.visibility === 'visible') {\r\n this.setTooltipPosition();\r\n }\r\n }\r\n private isTooltipContentEmpty(): boolean {\r\n if (typeof this.tooltipContent === 'string') {\r\n return !this.tooltipContent.trim();\r\n } else if (Array.isArray(this.tooltipContent)) {\r\n return (\r\n this.tooltipContent.length === 0 ||\r\n this.tooltipContent.every((line) => !line.trim())\r\n );\r\n }\r\n return true;\r\n }\r\n private createTooltip() {\r\n if (this.isTooltipContentEmpty()) return;\r\n this.tooltipElement = this.renderer.createElement('div');\r\n this.renderer.addClass(this.tooltipElement, 'tooltip-content');\r\n\r\n // Add content\r\n const contentLines = Array.isArray(this.tooltipContent)\r\n ? this.tooltipContent\r\n : [this.tooltipContent];\r\n contentLines.forEach((line: string) => {\r\n const div = this.renderer.createElement('div');\r\n this.renderer.addClass(div, 'text');\r\n // this.renderer.appendChild(div, this.renderer.createText(line));\r\n // Check if the line contains HTML\r\n if (line.trim().startsWith('<')) {\r\n div.innerHTML = line;\r\n } else {\r\n const text = this.renderer.createText(line);\r\n this.renderer.appendChild(div, text);\r\n }\r\n this.renderer.appendChild(this.tooltipElement!, div);\r\n });\r\n\r\n // Add triangle\r\n const triangle = this.renderer.createElement('div');\r\n this.renderer.addClass(triangle, 'tooltip-triangle');\r\n this.renderer.appendChild(this.tooltipElement, triangle);\r\n\r\n // Set base styles\r\n this.setStyle(this.tooltipElement!, {\r\n position: 'fixed',\r\n visibility: 'hidden',\r\n opacity: '0',\r\n zIndex: '9999',\r\n transition: 'opacity 0.3s ease, visibility 0.3s ease',\r\n });\r\n\r\n this.renderer.appendChild(document.body, this.tooltipElement);\r\n }\r\n\r\n private setTooltipPosition() {\r\n if (!this.tooltipElement) return;\r\n\r\n const hostRect = this.el.nativeElement.getBoundingClientRect();\r\n const tooltipRect = this.tooltipElement.getBoundingClientRect();\r\n\r\n const scrollTop = window.scrollY || document.documentElement.scrollTop;\r\n const scrollLeft = window.scrollX || document.documentElement.scrollLeft;\r\n\r\n const triangle = this.tooltipElement.querySelector(\r\n '.tooltip-triangle'\r\n ) as HTMLElement;\r\n const padding = 10;\r\n\r\n let top = 0,\r\n left = 0;\r\n\r\n // Position logic\r\n switch (this.tooltipPosition) {\r\n case 'right':\r\n case 'left':\r\n top = hostRect.top + scrollTop + hostRect.height / 2;\r\n left =\r\n this.tooltipPosition === 'right'\r\n ? hostRect.right + scrollLeft + padding\r\n : hostRect.left + scrollLeft - tooltipRect.width - padding;\r\n\r\n // Auto flip if out of viewport\r\n if (\r\n this.tooltipPosition === 'right' &&\r\n left + tooltipRect.width > window.innerWidth\r\n ) {\r\n left = hostRect.left + scrollLeft - tooltipRect.width - padding;\r\n } else if (this.tooltipPosition === 'left' && left < 0) {\r\n left = hostRect.right + scrollLeft + padding;\r\n }\r\n\r\n this.setStyle(this.tooltipElement, {\r\n transform: 'translateY(-50%)',\r\n });\r\n\r\n this.setTriangleStyles(\r\n triangle,\r\n this.tooltipPosition,\r\n left < hostRect.left + scrollLeft\r\n );\r\n break;\r\n\r\n case 'top':\r\n case 'bottom':\r\n left =\r\n hostRect.left +\r\n scrollLeft +\r\n hostRect.width / 2 -\r\n tooltipRect.width / 2;\r\n top =\r\n this.tooltipPosition === 'top'\r\n ? hostRect.top + scrollTop - tooltipRect.height - padding\r\n : hostRect.bottom + scrollTop + padding;\r\n\r\n // Prevent overflow\r\n left = Math.max(\r\n 10,\r\n Math.min(left, window.innerWidth - tooltipRect.width - 10)\r\n );\r\n\r\n this.setStyle(this.tooltipElement, {\r\n transform: 'translateX(0)',\r\n });\r\n\r\n this.setTriangleStyles(triangle, this.tooltipPosition);\r\n break;\r\n }\r\n\r\n this.setStyle(this.tooltipElement, {\r\n top: `${top}px`,\r\n left: `${left}px`,\r\n });\r\n }\r\n\r\n private setTriangleStyles(\r\n triangle: HTMLElement,\r\n position: 'left' | 'right' | 'top' | 'bottom',\r\n flipped: boolean = false\r\n ) {\r\n if (!triangle) return;\r\n\r\n const base = {\r\n top: '',\r\n left: '',\r\n right: '',\r\n bottom: '',\r\n transform: '',\r\n borderColor: '',\r\n };\r\n\r\n let styles: any = { ...base };\r\n\r\n switch (position) {\r\n case 'right':\r\n styles = flipped\r\n ? {\r\n left: '100%',\r\n top: '50%',\r\n transform: 'translateY(-50%) translateX(0)',\r\n borderColor: 'transparent transparent transparent #1a1a1a',\r\n }\r\n : {\r\n left: '-15px',\r\n top: '50%',\r\n transform: 'translateY(-50%)',\r\n borderColor: 'transparent #1a1a1a transparent transparent',\r\n };\r\n break;\r\n\r\n case 'left':\r\n styles = flipped\r\n ? {\r\n left: '100%',\r\n top: '50%',\r\n transform: 'translateY(-50%) translateX(0)',\r\n borderColor: 'transparent transparent transparent #1a1a1a',\r\n }\r\n : {\r\n left: '-15px',\r\n top: '50%',\r\n transform: 'translateY(-50%)',\r\n borderColor: 'transparent #1a1a1a transparent transparent',\r\n };\r\n break;\r\n\r\n case 'top':\r\n styles = {\r\n bottom: '-15px',\r\n left: '50%',\r\n transform: 'translateX(-50%)',\r\n borderColor: '#1a1a1a transparent transparent transparent',\r\n };\r\n break;\r\n\r\n case 'bottom':\r\n styles = {\r\n top: '-15px',\r\n left: '50%',\r\n transform: 'translateX(-50%)',\r\n borderColor: 'transparent transparent #1a1a1a transparent',\r\n };\r\n break;\r\n }\r\n\r\n this.setStyle(triangle, styles);\r\n }\r\n\r\n private removeTooltip() {\r\n if (this.tooltipElement) {\r\n this.renderer.removeChild(document.body, this.tooltipElement);\r\n this.tooltipElement = null;\r\n }\r\n }\r\n\r\n // Utility function to apply multiple styles\r\n private setStyle(el: HTMLElement, styles: { [key: string]: string }) {\r\n Object.entries(styles).forEach(([prop, value]) => {\r\n this.renderer.setStyle(el, prop, value);\r\n });\r\n }\r\n}\r\n","import {\r\n Component,\r\n ElementRef,\r\n EventEmitter,\r\n Input,\r\n Output,\r\n ViewChild,\r\n} from '@angular/core';\r\nimport {\r\n CdkDragDrop,\r\n moveItemInArray,\r\n CdkDragMove,\r\n CdkDragStart,\r\n DragDropModule,\r\n} from '@angular/cdk/drag-drop';\r\nimport {\r\n TableColumn,\r\n TableAction,\r\n PaginatedResult,\r\n} from '../models/table.model';\r\nimport { TooltipDirective } from '../directives/tooltip.directive';\r\nimport { CommonModule } from '@angular/common';\r\nimport { ScrollingModule } from '@angular/cdk/scrolling';\r\n\r\n@Component({\r\n selector: 'lib-generic-table',\r\n standalone: true,\r\n imports: [TooltipDirective, CommonModule, DragDropModule, ScrollingModule],\r\n templateUrl: './generic-table.component.html',\r\n styleUrls: ['./generic-table.component.css'],\r\n})\r\nexport class GenericTableComponent<T = any> {\r\n @Input() draggable: boolean = false;\r\n @Input() columns: TableColumn<T>[] = [];\r\n @Input() result!: PaginatedResult<T>;\r\n @Input() actions: TableAction<T>[] = [];\r\n\r\n @Input() hasPermission: boolean = true;\r\n\r\n @Output() actionClick = new EventEmitter<{\r\n action: string;\r\n row: T;\r\n }>();\r\n\r\n @Output() sortChange = new EventEmitter<{\r\n columnIndex: number;\r\n column: TableColumn<T>;\r\n direction: 'asc' | 'desc';\r\n }>();\r\n @Output() dragDropChange = new EventEmitter<T[]>();\r\n sortColumn?: keyof T;\r\n sortDirection: 'asc' | 'desc' = 'asc';\r\n\r\n @ViewChild('tableScrollContainer', { static: false })\r\n tableScrollContainer!: ElementRef<HTMLDivElement>;\r\n\r\n /* ---------- Sorting ---------- */\r\n sort(column: TableColumn<T>, index: number) {\r\n if (!column.sortable || !column.field) return;\r\n\r\n // Toggle sort direction\r\n this.sortDirection =\r\n this.sortColumn === column.field\r\n ? this.sortDirection === 'asc'\r\n ? 'desc'\r\n : 'asc'\r\n : 'asc';\r\n\r\n this.sortColumn = column.field;\r\n\r\n // Emit sort change separately\r\n this.sortChange.emit({\r\n columnIndex: index,\r\n column,\r\n direction: this.sortDirection,\r\n });\r\n }\r\n\r\n /* ---------- Visibility ---------- */\r\n isColumnVisible(column: TableColumn<T>): boolean {\r\n return column.visible !== false;\r\n }\r\n\r\n /* ---------- Cell Value ---------- */\r\n getCellValue(row: T, column: TableColumn<T>): string {\r\n if (column.formatter) {\r\n return column.formatter(row);\r\n }\r\n if (column.field) {\r\n return String(row[column.field] ?? '');\r\n }\r\n return '';\r\n }\r\n\r\n /* ---------- Actions ---------- */\r\n emitAction(action: TableAction<T>, row: T) {\r\n this.actionClick.emit({\r\n action: action.name,\r\n row,\r\n });\r\n }\r\n\r\n dropList(event: CdkDragDrop<T[]>) {\r\n if (!this.draggable || !this.result?.data) return;\r\n\r\n moveItemInArray(this.result.data, event.previousIndex, event.currentIndex);\r\n\r\n // Update existing sortOrder on T\r\n this.result.data.forEach((item: any, index) => {\r\n item.sortOrder = index + 1;\r\n });\r\n\r\n // Emit reordered list\r\n this.dragDropChange.emit(this.result.data);\r\n }\r\n\r\n onDragMoved(event: CdkDragMove<any>) {\r\n if (!this.tableScrollContainer) return;\r\n\r\n const container = this.tableScrollContainer.nativeElement;\r\n const rect = container.getBoundingClientRect();\r\n const pointerY = event.pointerPosition.y - rect.top;\r\n\r\n const threshold = 80;\r\n const maxSpeed = 25;\r\n\r\n if (pointerY < threshold) {\r\n const intensity = 1 - pointerY / threshold;\r\n container.scrollTop -= Math.min(maxSpeed, intensity * maxSpeed);\r\n } else if (pointerY > rect.height - threshold) {\r\n const intensity = 1 - (rect.height - pointerY) / threshold;\r\n container.scrollTop += Math.min(maxSpeed, intensity * maxSpeed);\r\n }\r\n }\r\n\r\n onDragStart(event: CdkDragStart<any>) {\r\n const row = event.source.element.nativeElement as HTMLElement;\r\n const cells = Array.from(row.querySelectorAll('td'));\r\n\r\n setTimeout(() => {\r\n const preview = document.querySelector(\r\n '.cdk-drag-preview'\r\n ) as HTMLElement;\r\n\r\n if (!preview) return;\r\n\r\n const previewCells = preview.querySelectorAll('td');\r\n\r\n cells.forEach((cell, index) => {\r\n const width = cell.getBoundingClientRect().width + 'px';\r\n const previewCell = previewCells[index] as HTMLElement;\r\n\r\n if (previewCell) {\r\n previewCell.style.width = width;\r\n previewCell.style.minWidth = width;\r\n previewCell.style.maxWidth = width;\r\n }\r\n });\r\n });\r\n }\r\n}\r\n","<div\r\n #tableScrollContainer\r\n cdkScrollable\r\n class=\"h-[calc(100vh-260px)] overflow-y-auto\"\r\n>\r\n <table\r\n class=\"min-w-full text-sm text-left text-gray-800 table-auto border-collapse\"\r\n >\r\n <!-- ================= HEADER ================= -->\r\n <thead>\r\n <tr>\r\n @for (col of columns; track col.header;let i=$index;) { @if\r\n (isColumnVisible(col)) {\r\n <th\r\n class=\"table-header sticky top-0 cursor-pointer\"\r\n [class.action-sticky]=\"col.sticky\"\r\n [class.z-10]=\"col.sticky\"\r\n [ngClass]=\"col.headerClass\"\r\n (click)=\"sort(col, i)\"\r\n >\r\n <span\r\n class=\"flex items-center gap-1\"\r\n [ngClass]=\"\r\n sortColumn === col.field\r\n ? sortDirection === 'asc'\r\n ? 'asc'\r\n : 'desc'\r\n : ''\r\n \"\r\n >\r\n {{ col.header }}\r\n @if (col.sortable) {\r\n <span class=\"sort-icon\"></span>\r\n }\r\n </span>\r\n </th>\r\n } } @if (actions.length) {\r\n <th\r\n class=\"table-header sticky top-0 action-sticky z-10 !bg-[#FBFBFC] w-20\"\r\n >\r\n Action\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <!-- ================= BODY ================= -->\r\n <tbody\r\n cdkDropList\r\n [cdkDropListDisabled]=\"!draggable\"\r\n [cdkDropListData]=\"result.data || []\"\r\n (cdkDropListDropped)=\"dropList($event)\"\r\n >\r\n @for (row of result.data; track row; let rowIndex = $index) {\r\n <tr\r\n cdkDrag\r\n cdkDragLockAxis=\"y\"\r\n [cdkDragDisabled]=\"!draggable\"\r\n (cdkDragStarted)=\"onDragStart($event)\"\r\n (cdkDragMoved)=\"onDragMoved($event)\"\r\n class=\"\"\r\n [ngClass]=\"{ 'cursor-move ': draggable }\"\r\n >\r\n @for (col of columns; track col.header; let colIndex = $index) { @if\r\n (isColumnVisible(col)) {\r\n <td class=\"table-cell text-nowrap\" [ngClass]=\"col.cellClass\">\r\n @if (draggable && colIndex === 0) {\r\n <span\r\n cdkDragHandle\r\n class=\"mr-2 text-gray-400\"\r\n [ngClass]=\"{ 'cursor-move': draggable }\"\r\n >☰</span\r\n >\r\n }\r\n {{ getCellValue(row, col) }}\r\n </td>\r\n } } @if (actions.length) {\r\n <td class=\"table-cell action-sticky text-center\">\r\n <div class=\"flex items-center justify-center gap-1.5\">\r\n @for (action of actions; track action.name) { @if (hasPermission) {\r\n <button\r\n class=\"size-6 flex items-center justify-center rounded hover:bg-[#F8F8FA]\"\r\n (click)=\"emitAction(action, row)\"\r\n appTooltip=\"{{ action.tooltip }}\"\r\n appTooltipPosition=\"top\"\r\n >\r\n <img\r\n [src]=\"action.icon\"\r\n width=\"14\"\r\n height=\"14\"\r\n alt=\"action-icon\"\r\n />\r\n </button>\r\n } }\r\n </div>\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n</div>\r\n","export interface TableColumn<T = any> {\r\n header: string;\r\n field?: keyof T;\r\n width?: string;\r\n sticky?: boolean;\r\n sortable?: boolean;\r\n headerClass?: string;\r\n cellClass?: string;\r\n formatter?: (row: T) => string;\r\n\r\n /** show / hide both th + td */\r\n visible?: boolean; // default: true\r\n}\r\n\r\nexport interface TableAction<T = any> {\r\n name: string; // e.g. edit, delete\r\n icon: string;\r\n tooltip: string;\r\n permission?: string;\r\n}\r\n\r\nexport class PaginatedResult<T> {\r\n page?: number;\r\n pageSize?: number;\r\n total?: number;\r\n data?: T[] = [];\r\n}\r\n","/*\r\n * Public API Surface of minahil\r\n */\r\n\r\nexport * from './lib/minahil.service';\r\nexport * from './lib/minahil.component';\r\nexport * from './lib/minahil.module';\r\n\r\nexport * from './lib/generic-table/generic-table.component';\r\nexport * from './lib/directives/tooltip.directive';\r\nexport * from './lib/models/table.model';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
package/index.d.ts ADDED
@@ -0,0 +1,105 @@
1
+ import * as i0 from '@angular/core';
2
+ import { OnInit, EventEmitter, ElementRef, OnChanges, OnDestroy, Renderer2, SimpleChanges } from '@angular/core';
3
+ import { CdkDragDrop, CdkDragMove, CdkDragStart } from '@angular/cdk/drag-drop';
4
+
5
+ declare class MinahilService {
6
+ constructor();
7
+ static ɵfac: i0.ɵɵFactoryDeclaration<MinahilService, never>;
8
+ static ɵprov: i0.ɵɵInjectableDeclaration<MinahilService>;
9
+ }
10
+
11
+ declare class MinahilComponent implements OnInit {
12
+ constructor();
13
+ ngOnInit(): void;
14
+ static ɵfac: i0.ɵɵFactoryDeclaration<MinahilComponent, never>;
15
+ static ɵcmp: i0.ɵɵComponentDeclaration<MinahilComponent, "lib-minahil", never, {}, {}, never, never, true, never>;
16
+ }
17
+
18
+ declare class MinahilModule {
19
+ static ɵfac: i0.ɵɵFactoryDeclaration<MinahilModule, never>;
20
+ static ɵmod: i0.ɵɵNgModuleDeclaration<MinahilModule, never, never, never>;
21
+ static ɵinj: i0.ɵɵInjectorDeclaration<MinahilModule>;
22
+ }
23
+
24
+ interface TableColumn<T = any> {
25
+ header: string;
26
+ field?: keyof T;
27
+ width?: string;
28
+ sticky?: boolean;
29
+ sortable?: boolean;
30
+ headerClass?: string;
31
+ cellClass?: string;
32
+ formatter?: (row: T) => string;
33
+ /** show / hide both th + td */
34
+ visible?: boolean;
35
+ }
36
+ interface TableAction<T = any> {
37
+ name: string;
38
+ icon: string;
39
+ tooltip: string;
40
+ permission?: string;
41
+ }
42
+ declare class PaginatedResult<T> {
43
+ page?: number;
44
+ pageSize?: number;
45
+ total?: number;
46
+ data?: T[];
47
+ }
48
+
49
+ declare class GenericTableComponent<T = any> {
50
+ draggable: boolean;
51
+ columns: TableColumn<T>[];
52
+ result: PaginatedResult<T>;
53
+ actions: TableAction<T>[];
54
+ hasPermission: boolean;
55
+ actionClick: EventEmitter<{
56
+ action: string;
57
+ row: T;
58
+ }>;
59
+ sortChange: EventEmitter<{
60
+ columnIndex: number;
61
+ column: TableColumn<T>;
62
+ direction: "asc" | "desc";
63
+ }>;
64
+ dragDropChange: EventEmitter<T[]>;
65
+ sortColumn?: keyof T;
66
+ sortDirection: 'asc' | 'desc';
67
+ tableScrollContainer: ElementRef<HTMLDivElement>;
68
+ sort(column: TableColumn<T>, index: number): void;
69
+ isColumnVisible(column: TableColumn<T>): boolean;
70
+ getCellValue(row: T, column: TableColumn<T>): string;
71
+ emitAction(action: TableAction<T>, row: T): void;
72
+ dropList(event: CdkDragDrop<T[]>): void;
73
+ onDragMoved(event: CdkDragMove<any>): void;
74
+ onDragStart(event: CdkDragStart<any>): void;
75
+ static ɵfac: i0.ɵɵFactoryDeclaration<GenericTableComponent<any>, never>;
76
+ static ɵcmp: i0.ɵɵComponentDeclaration<GenericTableComponent<any>, "lib-generic-table", never, { "draggable": { "alias": "draggable"; "required": false; }; "columns": { "alias": "columns"; "required": false; }; "result": { "alias": "result"; "required": false; }; "actions": { "alias": "actions"; "required": false; }; "hasPermission": { "alias": "hasPermission"; "required": false; }; }, { "actionClick": "actionClick"; "sortChange": "sortChange"; "dragDropChange": "dragDropChange"; }, never, never, true, never>;
77
+ }
78
+
79
+ declare class TooltipDirective implements OnInit, OnChanges, OnDestroy {
80
+ private el;
81
+ private renderer;
82
+ tooltipContent: string | string[];
83
+ tooltipPosition: 'left' | 'right' | 'top' | 'bottom';
84
+ private tooltipElement;
85
+ constructor(el: ElementRef, renderer: Renderer2);
86
+ ngOnInit(): void;
87
+ ngOnChanges(changes: SimpleChanges): void;
88
+ ngOnDestroy(): void;
89
+ updateTooltipContent(): void;
90
+ appendContent(): void;
91
+ onMouseEnter(): void;
92
+ onMouseLeave(): void;
93
+ onWindowChange(): void;
94
+ private isTooltipContentEmpty;
95
+ private createTooltip;
96
+ private setTooltipPosition;
97
+ private setTriangleStyles;
98
+ private removeTooltip;
99
+ private setStyle;
100
+ static ɵfac: i0.ɵɵFactoryDeclaration<TooltipDirective, never>;
101
+ static ɵdir: i0.ɵɵDirectiveDeclaration<TooltipDirective, "[appTooltip]", never, { "tooltipContent": { "alias": "appTooltip"; "required": false; }; "tooltipPosition": { "alias": "appTooltipPosition"; "required": false; }; }, {}, never, never, true, never>;
102
+ }
103
+
104
+ export { GenericTableComponent, MinahilComponent, MinahilModule, MinahilService, PaginatedResult, TooltipDirective };
105
+ export type { TableAction, TableColumn };
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "minahil",
3
+ "version": "0.0.1",
4
+ "peerDependencies": {
5
+ "@angular/common": "^20.0.0",
6
+ "@angular/core": "^20.0.0",
7
+ "@angular/cdk": "^20.0.0"
8
+ },
9
+ "dependencies": {
10
+ "tslib": "^2.3.0"
11
+ },
12
+ "module": "fesm2022/minahil.mjs",
13
+ "typings": "index.d.ts",
14
+ "exports": {
15
+ "./package.json": {
16
+ "default": "./package.json"
17
+ },
18
+ ".": {
19
+ "types": "./index.d.ts",
20
+ "default": "./fesm2022/minahil.mjs"
21
+ }
22
+ },
23
+ "sideEffects": false
24
+ }