|
1 | | -import { booleanAttribute, Directive, ElementRef, HostBinding, inject, Input, OnInit, Renderer2 } from '@angular/core'; |
| 1 | +import { booleanAttribute, computed, Directive, effect, ElementRef, inject, input, Renderer2 } from '@angular/core'; |
2 | 2 | import { Breakpoints, Colors } from '../coreui.types'; |
3 | | -import { ITable } from './table.type'; |
4 | 3 |
|
5 | 4 | @Directive({ |
6 | 5 | selector: 'table[cTable]', |
7 | | - host: { class: 'table' } |
| 6 | + exportAs: 'cTable', |
| 7 | + host: { |
| 8 | + class: 'table', |
| 9 | + '[class]': 'hostClasses()' |
| 10 | + } |
8 | 11 | }) |
9 | | -export class TableDirective implements ITable, OnInit { |
| 12 | +export class TableDirective { |
10 | 13 | readonly #renderer = inject(Renderer2); |
11 | 14 | readonly #hostElement = inject(ElementRef); |
12 | 15 |
|
13 | 16 | /** |
14 | 17 | * Set the vertical alignment. |
15 | | - * @type string |
| 18 | + * @return string |
16 | 19 | * @values 'bottom' | 'middle' | 'top' |
17 | 20 | */ |
18 | | - @Input() align?: 'bottom' | 'middle' | 'top'; |
| 21 | + readonly align = input<'bottom' | 'middle' | 'top'>(); |
19 | 22 |
|
20 | 23 | /** |
21 | 24 | * Sets the border color of the component to one of CoreUI’s themed colors. |
22 | | - * @type Colors |
| 25 | + * @return Colors |
23 | 26 | */ |
24 | | - @Input() borderColor?: Colors; |
| 27 | + readonly borderColor = input<Colors>(); |
25 | 28 |
|
26 | 29 | /** |
27 | 30 | * Add borders on all sides of the table and cells. |
28 | | - * @type boolean |
| 31 | + * @return boolean |
29 | 32 | */ |
30 | | - @Input({ transform: booleanAttribute }) bordered: string | boolean = false; |
| 33 | + readonly bordered = input(false, { transform: booleanAttribute }); |
31 | 34 |
|
32 | 35 | /** |
33 | 36 | * Remove borders on all sides of the table and cells. |
34 | | - * @type boolean |
| 37 | + * @return boolean |
35 | 38 | */ |
36 | | - @Input({ transform: booleanAttribute }) borderless: string | boolean = false; |
| 39 | + readonly borderless = input(false, { transform: booleanAttribute }); |
37 | 40 |
|
38 | 41 | /** |
39 | 42 | * Put the `<caption>` on the top of the table. |
| 43 | + * @return 'top' |
40 | 44 | * @values 'top' |
41 | 45 | */ |
42 | | - @Input() caption?: 'top'; |
| 46 | + readonly caption = input<'top'>(); |
43 | 47 |
|
44 | 48 | /** |
45 | 49 | * Sets the color context of the component to one of CoreUI’s themed colors. |
46 | | - * @type Colors |
| 50 | + * @return Colors |
47 | 51 | */ |
48 | | - @Input() color?: Colors; |
| 52 | + readonly color = input<Colors>(); |
49 | 53 |
|
50 | 54 | /** |
51 | 55 | * Enable a hover state on table rows within table body. |
52 | | - * @type boolean |
| 56 | + * @return boolean |
53 | 57 | */ |
54 | | - @Input({ transform: booleanAttribute }) hover: string | boolean = false; |
| 58 | + readonly hover = input(false, { transform: booleanAttribute }); |
55 | 59 |
|
56 | 60 | /** |
57 | 61 | * Make table responsive across all viewports or pick a maximum breakpoint with which to have a responsive table up to. |
58 | | - * @type: {boolean | 'sm' | 'md' | 'lg' | 'xl' | 'xxl'} |
| 62 | + * @values: {boolean | 'sm' | 'md' | 'lg' | 'xl' | 'xxl'} |
59 | 63 | */ |
60 | | - @Input() responsive?: boolean | Omit<Breakpoints, 'xs'>; |
| 64 | + readonly responsive = input<boolean | Omit<Breakpoints, 'xs'>>(); |
61 | 65 |
|
62 | 66 | /** |
63 | 67 | * Make table more compact by cutting all cell `padding` in half. |
64 | | - * @type boolean |
| 68 | + * @return boolean |
65 | 69 | */ |
66 | | - @Input({ transform: booleanAttribute }) small: string | boolean = false; |
| 70 | + readonly small = input(false, { transform: booleanAttribute }); |
67 | 71 |
|
68 | 72 | /** |
69 | 73 | * Add zebra-striping to any table row within the table body. |
70 | | - * @type boolean |
| 74 | + * @return boolean |
71 | 75 | */ |
72 | | - @Input({ transform: booleanAttribute }) striped: string | boolean = false; |
| 76 | + readonly striped = input(false, { transform: booleanAttribute }); |
73 | 77 |
|
74 | 78 | /** |
75 | 79 | * Add zebra-striping to any table column. |
76 | | - * @type boolean |
| 80 | + * @return boolean |
77 | 81 | * @since 4.2.4 |
78 | 82 | */ |
79 | | - @Input({ transform: booleanAttribute }) stripedColumns: string | boolean = false; |
| 83 | + readonly stripedColumns = input(false, { transform: booleanAttribute }); |
| 84 | + |
| 85 | + readonly hostClasses = computed(() => { |
| 86 | + const align = this.align(); |
| 87 | + const caption = this.caption(); |
| 88 | + const borderColor = this.borderColor(); |
| 89 | + const bordered = this.bordered(); |
| 90 | + const borderless = this.borderless(); |
| 91 | + const color = this.color(); |
| 92 | + const hover = this.hover(); |
| 93 | + const small = this.small(); |
| 94 | + const striped = this.striped(); |
| 95 | + const stripedColumns = this.stripedColumns(); |
80 | 96 |
|
81 | | - @HostBinding('class') |
82 | | - get hostClasses(): any { |
83 | 97 | return { |
84 | 98 | table: true, |
85 | | - [`align-${this.align}`]: !!this.align, |
86 | | - [`caption-${this.caption}`]: !!this.caption, |
87 | | - [`border-${this.borderColor}`]: !!this.borderColor, |
88 | | - 'table-bordered': this.bordered, |
89 | | - 'table-borderless': this.borderless, |
90 | | - [`table-${this.color}`]: !!this.color, |
91 | | - 'table-hover': this.hover, |
92 | | - 'table-sm': this.small, |
93 | | - 'table-striped': this.striped, |
94 | | - 'table-striped-columns': this.stripedColumns |
| 99 | + [`align-${align}`]: !!align, |
| 100 | + [`caption-${caption}`]: !!caption, |
| 101 | + [`border-${borderColor}`]: !!borderColor, |
| 102 | + 'table-bordered': bordered, |
| 103 | + 'table-borderless': borderless, |
| 104 | + [`table-${color}`]: !!color, |
| 105 | + 'table-hover': hover, |
| 106 | + 'table-sm': small, |
| 107 | + 'table-striped': striped, |
| 108 | + 'table-striped-columns': stripedColumns |
95 | 109 | }; |
96 | | - } |
| 110 | + }); |
97 | 111 |
|
98 | | - ngOnInit(): void { |
99 | | - this.setResponsiveWrapper(); |
100 | | - } |
101 | | - |
102 | | - // todo |
103 | | - setResponsiveWrapper(): void { |
104 | | - if (!!this.responsive) { |
| 112 | + readonly #responsiveWrapperEffect = effect(() => { |
| 113 | + const responsive = this.responsive(); |
| 114 | + if (!!responsive) { |
105 | 115 | const nativeElement: HTMLElement = this.#hostElement.nativeElement; |
106 | 116 | const wrapper = this.#renderer.createElement('div'); |
107 | | - const className = this.responsive === true ? 'table-responsive' : `table-responsive-${this.responsive}`; |
| 117 | + const className = responsive === true ? 'table-responsive' : `table-responsive-${responsive}`; |
108 | 118 | this.#renderer.addClass(wrapper, className); |
109 | 119 | const parentNode = this.#renderer.parentNode(nativeElement); |
110 | 120 | this.#renderer.appendChild(parentNode, wrapper); |
111 | 121 | this.#renderer.insertBefore(parentNode, wrapper, nativeElement); |
112 | 122 | this.#renderer.appendChild(wrapper, nativeElement); |
113 | 123 | } |
114 | | - } |
| 124 | + }); |
115 | 125 | } |
0 commit comments