tailjng 0.1.6 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/README.md +12 -4
  2. package/cli/execute/init-app.js +5 -2
  3. package/cli/execute/sync-app.js +14 -2
  4. package/cli/settings/colors-config-utils.js +43 -8
  5. package/cli/settings/icons-config-utils.js +62 -0
  6. package/cli/settings/path-utils.js +32 -2
  7. package/cli/settings/project-utils.js +7 -1
  8. package/cli/templates/app.generator.js +2 -2
  9. package/fesm2022/tailjng.mjs +247 -80
  10. package/fesm2022/tailjng.mjs.map +1 -1
  11. package/lib/services/static/theme.service.d.ts +39 -1
  12. package/lib/utils/theme/theme-variables.util.d.ts +31 -0
  13. package/package.json +1 -1
  14. package/public-api.d.ts +2 -1
  15. package/registry/components.json +41 -18
  16. package/src/colors.safelist.css +2 -2
  17. package/src/lib/components/.config/README.md +11 -0
  18. package/src/lib/components/.config/colors/README.md +38 -0
  19. package/src/lib/components/{colors-config → .config/colors}/colors.config.ts +5 -5
  20. package/src/lib/components/{colors-config → .config/colors}/colors.safelist.css +2 -2
  21. package/src/lib/components/.config/icons/README.md +26 -0
  22. package/src/lib/components/.config/icons/icons.lucide.ts +134 -0
  23. package/src/lib/components/.config/input/README.md +24 -0
  24. package/src/lib/components/.config/input/input.classes.ts +119 -0
  25. package/src/lib/components/alert/alert-dialog/dialog-alert.component.css +244 -2
  26. package/src/lib/components/alert/alert-dialog/dialog-alert.component.html +25 -38
  27. package/src/lib/components/alert/alert-dialog/dialog-alert.component.ts +66 -56
  28. package/src/lib/components/alert/alert-dialog/dialog-alert.types.ts +19 -0
  29. package/src/lib/components/alert/alert-toast/toast-alert.component.css +630 -12
  30. package/src/lib/components/alert/alert-toast/toast-alert.component.html +103 -102
  31. package/src/lib/components/alert/alert-toast/toast-alert.component.ts +485 -128
  32. package/src/lib/components/alert/alert-toast/toast-alert.types.ts +25 -0
  33. package/src/lib/components/badge/badge.component.html +34 -21
  34. package/src/lib/components/badge/badge.component.ts +140 -31
  35. package/src/lib/components/button/button.component.html +16 -10
  36. package/src/lib/components/button/button.component.ts +162 -22
  37. package/src/lib/components/card/card-complete/complete-card.component.html +2 -2
  38. package/src/lib/components/card/card-complete/complete-card.component.ts +26 -16
  39. package/src/lib/components/card/card-crud-complete/complete-crud-card.component.html +2 -2
  40. package/src/lib/components/card/card-crud-complete/complete-crud-card.component.ts +26 -16
  41. package/src/lib/components/checkbox/checkbox-input/input-checkbox.component.css +97 -0
  42. package/src/lib/components/checkbox/checkbox-input/input-checkbox.component.html +54 -46
  43. package/src/lib/components/checkbox/checkbox-input/input-checkbox.component.ts +135 -64
  44. package/src/lib/components/checkbox/checkbox-input/input-checkbox.types.ts +3 -0
  45. package/src/lib/components/checkbox/checkbox-switch/switch-checkbox.component.css +112 -0
  46. package/src/lib/components/checkbox/checkbox-switch/switch-checkbox.component.html +28 -25
  47. package/src/lib/components/checkbox/checkbox-switch/switch-checkbox.component.ts +67 -15
  48. package/src/lib/components/checkbox/checkbox-switch/switch-checkbox.types.ts +1 -0
  49. package/src/lib/components/coach-mark/coach-mark.component.html +4 -22
  50. package/src/lib/components/coach-mark/coach-mark.component.scss +1 -1
  51. package/src/lib/components/coach-mark/coach-mark.component.ts +51 -18
  52. package/src/lib/components/coach-mark/coach-mark.directive.ts +133 -78
  53. package/src/lib/components/coach-mark/coach-mark.types.ts +12 -0
  54. package/src/lib/components/dialog/dialog.component.css +103 -1
  55. package/src/lib/components/dialog/dialog.component.html +46 -66
  56. package/src/lib/components/dialog/dialog.component.ts +136 -110
  57. package/src/lib/components/dialog/dialog.types.ts +19 -0
  58. package/src/lib/components/filter/filter-complete/complete-filter.component.html +16 -19
  59. package/src/lib/components/filter/filter-complete/complete-filter.component.scss +35 -0
  60. package/src/lib/components/filter/filter-complete/complete-filter.component.ts +58 -34
  61. package/src/lib/components/filter/filter-complete/complete-filter.types.ts +7 -0
  62. package/src/lib/components/filter/filter-complete/complete-filter.util.ts +16 -0
  63. package/src/lib/components/form/form-container/container-form.component.css +4 -0
  64. package/src/lib/components/form/form-container/container-form.component.html +2 -2
  65. package/src/lib/components/form/form-container/container-form.component.ts +72 -16
  66. package/src/lib/components/form/form-container/container-form.types.ts +42 -0
  67. package/src/lib/components/form/form-container/form-col-span.directive.ts +25 -0
  68. package/src/lib/components/form/form-sidebar/sidebar-form.component.css +276 -0
  69. package/src/lib/components/form/form-sidebar/sidebar-form.component.html +117 -125
  70. package/src/lib/components/form/form-sidebar/sidebar-form.component.ts +109 -34
  71. package/src/lib/components/form/form-sidebar/sidebar-form.types.ts +3 -0
  72. package/src/lib/components/{toggle-radio/toggle-radio.component.css → form/form-validation/validation-form.component.css} +0 -1
  73. package/src/lib/components/form/form-validation/validation-form.component.html +10 -6
  74. package/src/lib/components/form/form-validation/validation-form.component.ts +99 -12
  75. package/src/lib/components/form/form-validation/validation-form.types.ts +33 -0
  76. package/src/lib/components/icon/icon.component.html +8 -5
  77. package/src/lib/components/icon/icon.component.ts +111 -9
  78. package/src/lib/components/input/input/input.component.html +19 -16
  79. package/src/lib/components/input/input/input.component.ts +130 -53
  80. package/src/lib/components/input/input/input.types.ts +8 -0
  81. package/src/lib/components/input/input-file/file-input.component.html +65 -56
  82. package/src/lib/components/input/input-file/file-input.component.ts +276 -173
  83. package/src/lib/components/input/input-file/file-input.types.ts +2 -0
  84. package/src/lib/components/input/input-range/range-input.component.css +67 -0
  85. package/src/lib/components/input/input-range/range-input.component.html +50 -58
  86. package/src/lib/components/input/input-range/range-input.component.ts +148 -60
  87. package/src/lib/components/input/input-range/range-input.types.ts +7 -0
  88. package/src/lib/components/input/input-textarea/textarea-input.component.html +16 -7
  89. package/src/lib/components/input/input-textarea/textarea-input.component.ts +140 -50
  90. package/src/lib/components/input/input-textarea/textarea-input.types.ts +2 -0
  91. package/src/lib/components/label/label.component.html +17 -16
  92. package/src/lib/components/label/label.component.ts +70 -16
  93. package/src/lib/components/label/label.types.ts +2 -0
  94. package/src/lib/components/menu/menu-options-table/menu-options-defaults.ts +34 -0
  95. package/src/lib/components/menu/menu-options-table/options-table-menu.component.html +34 -20
  96. package/src/lib/components/menu/menu-options-table/options-table-menu.component.ts +211 -58
  97. package/src/lib/components/menu/menu-options-table/options-table-menu.types.ts +38 -0
  98. package/src/lib/components/menu/options-coach-menu/options-coach-menu.component.html +49 -52
  99. package/src/lib/components/menu/options-coach-menu/options-coach-menu.component.ts +112 -24
  100. package/src/lib/components/menu/options-coach-menu/options-coach-menu.types.ts +9 -0
  101. package/src/lib/components/mode-toggle/mode-toggle.component.html +11 -16
  102. package/src/lib/components/mode-toggle/mode-toggle.component.ts +69 -33
  103. package/src/lib/components/paginator/paginator-complete/complete-paginator.component.html +4 -4
  104. package/src/lib/components/paginator/paginator-complete/complete-paginator.component.ts +31 -7
  105. package/src/lib/components/paginator/paginator-complete/complete-paginator.types.ts +12 -0
  106. package/src/lib/components/paginator/paginator-complete/complete-paginator.util.ts +36 -0
  107. package/src/lib/components/progress-bar/progress-bar.component.css +11 -0
  108. package/src/lib/components/progress-bar/progress-bar.component.html +41 -40
  109. package/src/lib/components/progress-bar/progress-bar.component.ts +95 -11
  110. package/src/lib/components/progress-bar/progress-bar.types.ts +2 -0
  111. package/src/lib/components/select/select-dropdown/dropdown-select.component.css +6 -0
  112. package/src/lib/components/select/select-dropdown/dropdown-select.component.html +54 -44
  113. package/src/lib/components/select/select-dropdown/dropdown-select.component.ts +450 -509
  114. package/src/lib/components/select/select-dropdown/dropdown-select.types.ts +43 -0
  115. package/src/lib/components/select/select-dropdown/dropdown-select.util.ts +179 -0
  116. package/src/lib/components/select/select-multi-dropdown/multi-dropdown-select.component.css +6 -0
  117. package/src/lib/components/select/select-multi-dropdown/multi-dropdown-select.component.html +131 -42
  118. package/src/lib/components/select/select-multi-dropdown/multi-dropdown-select.component.ts +491 -475
  119. package/src/lib/components/select/select-multi-dropdown/multi-dropdown-select.types.ts +22 -0
  120. package/src/lib/components/select/select-multi-dropdown/multi-dropdown-select.util.ts +20 -0
  121. package/src/lib/components/select/select-multi-table/multi-table-select.component.css +10 -0
  122. package/src/lib/components/select/select-multi-table/multi-table-select.component.html +76 -60
  123. package/src/lib/components/select/select-multi-table/multi-table-select.component.ts +250 -313
  124. package/src/lib/components/select/select-multi-table/multi-table-select.types.ts +10 -0
  125. package/src/lib/components/select/select-multi-table/multi-table-select.util.ts +5 -0
  126. package/src/lib/components/sidebar/sidebar-static/static-sidebar.component.css +212 -0
  127. package/src/lib/components/sidebar/sidebar-static/static-sidebar.component.html +62 -53
  128. package/src/lib/components/sidebar/sidebar-static/static-sidebar.component.ts +84 -27
  129. package/src/lib/components/sidebar/sidebar-static/static-sidebar.types.ts +2 -0
  130. package/src/lib/components/table/table-complete/complete-table.component.html +15 -17
  131. package/src/lib/components/table/table-complete/complete-table.component.ts +190 -338
  132. package/src/lib/components/table/table-complete/complete-table.types.ts +28 -0
  133. package/src/lib/components/table/table-complete/complete-table.util.ts +236 -0
  134. package/src/lib/components/table/table-complete/index.ts +2 -0
  135. package/src/lib/components/table/table-crud-complete/complete-crud-table.animations.ts +34 -0
  136. package/src/lib/components/table/table-crud-complete/complete-crud-table.component.html +73 -128
  137. package/src/lib/components/table/table-crud-complete/complete-crud-table.component.ts +542 -829
  138. package/src/lib/components/table/table-crud-complete/complete-crud-table.types.ts +57 -0
  139. package/src/lib/components/table/table-crud-complete/complete-crud-table.util.ts +723 -0
  140. package/src/lib/components/table/table-crud-complete/index.ts +3 -0
  141. package/src/lib/components/theme-generator/theme-generator.component.css +21 -0
  142. package/src/lib/components/theme-generator/theme-generator.component.html +146 -116
  143. package/src/lib/components/theme-generator/theme-generator.component.ts +44 -24
  144. package/src/lib/components/toggle-radio/shared/toggle-options.types.ts +8 -0
  145. package/src/lib/components/toggle-radio/shared/toggle-options.util.ts +44 -0
  146. package/src/lib/components/toggle-radio/toggle-radio/toggle-radio.component.css +135 -0
  147. package/src/lib/components/toggle-radio/toggle-radio/toggle-radio.component.html +52 -0
  148. package/src/lib/components/toggle-radio/toggle-radio/toggle-radio.component.ts +198 -0
  149. package/src/lib/components/toggle-radio/toggle-radio/toggle-radio.types.ts +1 -0
  150. package/src/lib/components/toggle-radio/toggle-segment/segment-toggle.component.css +108 -0
  151. package/src/lib/components/toggle-radio/toggle-segment/segment-toggle.component.html +37 -0
  152. package/src/lib/components/toggle-radio/toggle-segment/segment-toggle.component.ts +193 -0
  153. package/src/lib/components/toggle-radio/toggle-segment/segment-toggle.types.ts +1 -0
  154. package/src/lib/components/tooltip/tooltip.directive.ts +12 -9
  155. package/src/lib/components/tooltip/tooltip.service.ts +331 -133
  156. package/src/lib/components/tooltip/tooltip.types.ts +9 -0
  157. package/src/lib/components/viewer/viewer-image/image-viewer.component.css +90 -4
  158. package/src/lib/components/viewer/viewer-image/image-viewer.component.html +52 -103
  159. package/src/lib/components/viewer/viewer-image/image-viewer.component.ts +182 -177
  160. package/src/lib/components/viewer/viewer-image/image-viewer.types.ts +3 -0
  161. package/src/lib/components/viewer/viewer-pdf/pdf-viewer.component.css +177 -0
  162. package/src/lib/components/viewer/viewer-pdf/pdf-viewer.component.html +74 -24
  163. package/src/lib/components/viewer/viewer-pdf/pdf-viewer.component.ts +168 -15
  164. package/src/lib/components/viewer/viewer-pdf/pdf-viewer.types.ts +1 -0
  165. package/src/styles.css +2 -2
  166. package/lib/services/static/icons.service.d.ts +0 -65
  167. package/src/lib/components/colors-config/README.md +0 -38
  168. package/src/lib/components/form/form-sidebar/sidebar-form.component.scss +0 -0
  169. package/src/lib/components/form/form-validation/validation-form.component.scss +0 -0
  170. package/src/lib/components/menu/menu-options-table/options-table-menu.component.scss +0 -0
  171. package/src/lib/components/menu/options-coach-menu/options-coach-menu.component.scss +0 -12
  172. package/src/lib/components/sidebar/sidebar-static/static-sidebar.component.scss +0 -0
  173. package/src/lib/components/toggle-radio/toggle-radio.component.html +0 -51
  174. package/src/lib/components/toggle-radio/toggle-radio.component.ts +0 -222
  175. package/src/lib/components/viewer/viewer-pdf/pdf-viewer.component.scss +0 -0
  176. package/tailjng-0.1.6.tgz +0 -0
@@ -1,15 +1,257 @@
1
+ :host {
2
+ display: contents;
3
+ }
4
+
5
+ .j-alert-dialog {
6
+ position: fixed;
7
+ inset: 0;
8
+ z-index: 999999;
9
+ display: flex;
10
+ align-items: center;
11
+ justify-content: center;
12
+ padding: 1rem;
13
+ background-color: rgb(0 0 0 / 0.45);
14
+ backdrop-filter: blur(2px);
15
+ }
16
+
1
17
  .j-alert-dialog-card {
18
+ position: relative;
19
+ width: 100%;
20
+ max-width: 28rem;
2
21
  min-height: 5.5rem;
22
+ overflow: hidden;
23
+ border: 1px solid color-mix(in srgb, var(--color-border) 65%, transparent);
24
+ border-radius: 0.75rem;
25
+ background-color: color-mix(in srgb, var(--color-background) 92%, transparent);
26
+ box-shadow: 0 20px 48px rgb(0 0 0 / 0.14);
27
+ backdrop-filter: blur(16px);
3
28
  }
4
29
 
5
- .j-alert-dialog-watermark--lg {
30
+ :host-context(.dark) .j-alert-dialog-card,
31
+ :host-context(html.dark) .j-alert-dialog-card {
32
+ border-color: color-mix(in srgb, var(--color-dark-border) 70%, transparent);
33
+ background-color: color-mix(in srgb, var(--color-dark-background) 92%, transparent);
34
+ box-shadow: 0 24px 56px rgb(0 0 0 / 0.45);
35
+ }
36
+
37
+ .j-alert-dialog-card--mono {
38
+ background-color: color-mix(in srgb, var(--color-background) 95%, transparent);
39
+ }
40
+
41
+ :host-context(.dark) .j-alert-dialog-card--mono,
42
+ :host-context(html.dark) .j-alert-dialog-card--mono {
43
+ background-color: color-mix(in srgb, var(--color-dark-background) 95%, transparent);
44
+ }
45
+
46
+ .j-alert-dialog-card--success {
47
+ background-color: color-mix(in srgb, #22c55e 9%, var(--color-background));
48
+ }
49
+
50
+ .j-alert-dialog-card--error {
51
+ background-color: color-mix(in srgb, #ef4444 9%, var(--color-background));
52
+ }
53
+
54
+ .j-alert-dialog-card--warning {
55
+ background-color: color-mix(in srgb, #eab308 10%, var(--color-background));
56
+ }
57
+
58
+ .j-alert-dialog-card--info {
59
+ background-color: color-mix(in srgb, #3b82f6 9%, var(--color-background));
60
+ }
61
+
62
+ .j-alert-dialog-card--question {
63
+ background-color: color-mix(in srgb, #a855f7 9%, var(--color-background));
64
+ }
65
+
66
+ .j-alert-dialog-card--loading {
67
+ background-color: color-mix(in srgb, var(--color-muted) 22%, var(--color-background));
68
+ }
69
+
70
+ :host-context(.dark) .j-alert-dialog-card--success,
71
+ :host-context(html.dark) .j-alert-dialog-card--success {
72
+ background-color: color-mix(in srgb, #22c55e 14%, var(--color-dark-background));
73
+ }
74
+
75
+ :host-context(.dark) .j-alert-dialog-card--error,
76
+ :host-context(html.dark) .j-alert-dialog-card--error {
77
+ background-color: color-mix(in srgb, #ef4444 14%, var(--color-dark-background));
78
+ }
79
+
80
+ :host-context(.dark) .j-alert-dialog-card--warning,
81
+ :host-context(html.dark) .j-alert-dialog-card--warning {
82
+ background-color: color-mix(in srgb, #eab308 14%, var(--color-dark-background));
83
+ }
84
+
85
+ :host-context(.dark) .j-alert-dialog-card--info,
86
+ :host-context(html.dark) .j-alert-dialog-card--info {
87
+ background-color: color-mix(in srgb, #3b82f6 14%, var(--color-dark-background));
88
+ }
89
+
90
+ :host-context(.dark) .j-alert-dialog-card--question,
91
+ :host-context(html.dark) .j-alert-dialog-card--question {
92
+ background-color: color-mix(in srgb, #a855f7 14%, var(--color-dark-background));
93
+ }
94
+
95
+ :host-context(.dark) .j-alert-dialog-card--loading,
96
+ :host-context(html.dark) .j-alert-dialog-card--loading {
97
+ background-color: color-mix(in srgb, var(--color-dark-muted) 28%, var(--color-dark-background));
98
+ }
99
+
100
+ .j-alert-dialog-accent {
101
+ position: absolute;
102
+ top: 0;
103
+ bottom: 0;
104
+ left: 0;
105
+ z-index: 1;
106
+ width: 0.25rem;
107
+ }
108
+
109
+ .j-alert-dialog-accent--mono {
110
+ background-color: var(--color-primary);
111
+ }
112
+
113
+ .j-alert-dialog-accent--success {
114
+ background-color: #22c55e;
115
+ }
116
+
117
+ .j-alert-dialog-accent--error {
118
+ background-color: #ef4444;
119
+ }
120
+
121
+ .j-alert-dialog-accent--warning {
122
+ background-color: #eab308;
123
+ }
124
+
125
+ .j-alert-dialog-accent--info {
126
+ background-color: #3b82f6;
127
+ }
128
+
129
+ .j-alert-dialog-accent--question {
130
+ background-color: #a855f7;
131
+ }
132
+
133
+ .j-alert-dialog-accent--loading {
134
+ background-color: var(--color-muted-foreground);
135
+ }
136
+
137
+ .j-alert-dialog-watermark {
138
+ position: absolute;
139
+ z-index: 0;
140
+ pointer-events: none;
141
+ user-select: none;
142
+ opacity: 0.22;
6
143
  filter: blur(0.15px);
7
144
  }
8
145
 
9
- .j-alert-dialog-watermark--sm {
146
+ .j-alert-dialog-watermark--subtle {
147
+ opacity: 0.12;
10
148
  filter: blur(0.1px);
11
149
  }
12
150
 
151
+ .j-alert-dialog-watermark--lg {
152
+ bottom: -2rem;
153
+ left: -1.25rem;
154
+ }
155
+
156
+ .j-alert-dialog-watermark--sm {
157
+ top: 0.5rem;
158
+ right: 0.75rem;
159
+ }
160
+
161
+ .j-alert-dialog-watermark--mono {
162
+ color: var(--color-primary);
163
+ }
164
+
165
+ .j-alert-dialog-watermark--success {
166
+ color: #22c55e;
167
+ }
168
+
169
+ .j-alert-dialog-watermark--error {
170
+ color: #ef4444;
171
+ }
172
+
173
+ .j-alert-dialog-watermark--warning {
174
+ color: #eab308;
175
+ }
176
+
177
+ .j-alert-dialog-watermark--info {
178
+ color: #3b82f6;
179
+ }
180
+
181
+ .j-alert-dialog-watermark--question {
182
+ color: #a855f7;
183
+ }
184
+
185
+ .j-alert-dialog-watermark--loading {
186
+ color: var(--color-muted-foreground);
187
+ }
188
+
189
+ .j-alert-dialog-watermark--spin {
190
+ animation: j-alert-dialog-spin 1s linear infinite;
191
+ }
192
+
193
+ @keyframes j-alert-dialog-spin {
194
+ to {
195
+ transform: rotate(360deg);
196
+ }
197
+ }
198
+
199
+ .j-alert-dialog-body {
200
+ position: relative;
201
+ z-index: 10;
202
+ padding: 1rem 1rem 1rem 1.25rem;
203
+ }
204
+
205
+ .j-alert-dialog-body--with-actions {
206
+ padding-bottom: 0.5rem;
207
+ }
208
+
209
+ .j-alert-dialog-title {
210
+ margin: 0;
211
+ font-size: 0.875rem;
212
+ font-weight: 600;
213
+ line-height: 1.3;
214
+ letter-spacing: -0.01em;
215
+ color: var(--color-foreground);
216
+ }
217
+
218
+ :host-context(.dark) .j-alert-dialog-title,
219
+ :host-context(html.dark) .j-alert-dialog-title {
220
+ color: var(--color-dark-foreground);
221
+ }
222
+
223
+ .j-alert-dialog-description {
224
+ margin: 0.375rem 0 0;
225
+ font-size: 0.75rem;
226
+ line-height: 1.55;
227
+ color: var(--color-muted-foreground);
228
+ }
229
+
230
+ .j-alert-dialog-description :is(b, strong) {
231
+ font-weight: 600;
232
+ color: var(--color-foreground);
233
+ }
234
+
235
+ :host-context(.dark) .j-alert-dialog-description,
236
+ :host-context(html.dark) .j-alert-dialog-description {
237
+ color: var(--color-dark-muted-foreground);
238
+ }
239
+
240
+ :host-context(.dark) .j-alert-dialog-description :is(b, strong),
241
+ :host-context(html.dark) .j-alert-dialog-description :is(b, strong) {
242
+ color: var(--color-dark-foreground);
243
+ }
244
+
245
+ .j-alert-dialog-actions {
246
+ position: relative;
247
+ z-index: 10;
248
+ display: flex;
249
+ flex-wrap: wrap;
250
+ justify-content: flex-end;
251
+ gap: 0.375rem;
252
+ padding: 0 1rem 1rem 1.25rem;
253
+ }
254
+
13
255
  @media (max-width: 450px) {
14
256
  .j-alert-dialog-card {
15
257
  max-width: 100%;
@@ -1,69 +1,56 @@
1
1
  @for (dialog of dialogs(); track dialog.config.title) {
2
2
  <div
3
- class="j-alert-dialog fixed inset-0 z-999999 flex items-center justify-center bg-black/45 backdrop-blur-[2px] p-4"
3
+ class="j-alert-dialog"
4
4
  role="dialog"
5
5
  aria-modal="true"
6
+ [attr.aria-label]="dialog.config.title"
6
7
  >
7
8
  <div
8
9
  @modalTransition
9
- class="j-alert-dialog-card relative w-full max-w-md overflow-hidden rounded-xl border border-border/40 dark:border-dark-border/40 backdrop-blur-xl shadow-xl shadow-black/10 dark:shadow-black/40"
10
- [ngClass]="getDialogSurfaceClass(dialog.config.type)"
10
+ class="j-alert-dialog-card"
11
+ [ngClass]="cardClasses(dialog.config.type)"
11
12
  >
12
- <div
13
- class="absolute left-0 top-0 bottom-0 w-1 z-[1]"
14
- [ngClass]="getAccentBarClass(dialog.config.type)"
15
- ></div>
13
+ <div [ngClass]="accentClasses(dialog.config.type)"></div>
16
14
 
17
- <!-- Icono decorativo grande -->
18
- <div
19
- class="j-alert-dialog-watermark j-alert-dialog-watermark--lg absolute -bottom-8 -left-5 z-0 pointer-events-none select-none"
20
- [ngClass]="{ 'animate-spin': dialog.config.type === 'loading' }"
21
- >
22
- <lucide-icon
23
- [name]="getIcon(dialog.config.type)"
15
+ <div [ngClass]="watermarkClasses(dialog.config.type)">
16
+ <JIcon
17
+ [icon]="typeIcon(dialog.config.type)"
24
18
  [size]="104"
25
- [ngClass]="getWatermarkIconClass(dialog.config.type)"
26
- ></lucide-icon>
19
+ [inheritParentColor]="true"
20
+ [ariaHidden]="true"
21
+ />
27
22
  </div>
28
23
 
29
- <!-- Icono decorativo pequeño -->
30
- <div
31
- class="j-alert-dialog-watermark j-alert-dialog-watermark--sm absolute top-2 right-3 z-0 pointer-events-none select-none"
32
- [ngClass]="{ 'animate-spin': dialog.config.type === 'loading' }"
33
- >
34
- <lucide-icon
35
- [name]="getIcon(dialog.config.type)"
24
+ <div [ngClass]="watermarkClasses(dialog.config.type, true)">
25
+ <JIcon
26
+ [icon]="typeIcon(dialog.config.type)"
36
27
  [size]="32"
37
- [ngClass]="getWatermarkIconClass(dialog.config.type, true)"
38
- ></lucide-icon>
28
+ [inheritParentColor]="true"
29
+ [ariaHidden]="true"
30
+ />
39
31
  </div>
40
32
 
41
- <!-- Texto -->
42
33
  <div
43
- class="relative z-10 pl-5 pr-4 pt-4"
44
- [class.pb-2]="hasActions(dialog)"
45
- [class.pb-4]="!hasActions(dialog)"
34
+ class="j-alert-dialog-body"
35
+ [class.j-alert-dialog-body--with-actions]="hasActions(dialog)"
46
36
  >
47
- <h3 class="m-0 text-sm font-semibold leading-tight text-foreground dark:text-white">
48
- {{ dialog.config.title }}
49
- </h3>
37
+ <h3 class="j-alert-dialog-title">{{ dialog.config.title }}</h3>
50
38
 
51
39
  @if (dialog.config.description) {
52
40
  <p
53
- class="m-0 mt-1.5 text-xs leading-relaxed text-muted-foreground dark:text-dark-muted-foreground [&_b]:font-semibold [&_b]:text-foreground dark:[&_b]:text-white"
41
+ class="j-alert-dialog-description"
54
42
  [innerHTML]="dialog.config.description"
55
43
  ></p>
56
44
  }
57
45
  </div>
58
46
 
59
- <!-- Acciones alineadas a la card -->
60
47
  @if (hasActions(dialog)) {
61
- <div class="relative z-10 flex flex-wrap justify-end gap-1.5 pl-5 pr-4 pb-4">
48
+ <div class="j-alert-dialog-actions">
62
49
  @if (showRetryButton(dialog.config)) {
63
50
  <JButton
64
51
  size="sm"
65
52
  (clicked)="handleAction('retry')"
66
- [disabled]="dialog.isRetryLoading || dialog.isCancelLoading || dialog.isConfirmLoading"
53
+ [disabled]="isActionDisabled(dialog)"
67
54
  [isLoading]="dialog.isRetryLoading"
68
55
  [ngClasses]="getButtonSecondaryClass(dialog.config.type)"
69
56
  >
@@ -75,7 +62,7 @@
75
62
  <JButton
76
63
  size="sm"
77
64
  (clicked)="handleAction('cancel')"
78
- [disabled]="dialog.isRetryLoading || dialog.isCancelLoading || dialog.isConfirmLoading"
65
+ [disabled]="isActionDisabled(dialog)"
79
66
  [isLoading]="dialog.isCancelLoading"
80
67
  [ngClasses]="getButtonSecondaryClass(dialog.config.type)"
81
68
  >
@@ -87,7 +74,7 @@
87
74
  <JButton
88
75
  size="sm"
89
76
  (clicked)="handleAction('confirm')"
90
- [disabled]="dialog.isRetryLoading || dialog.isCancelLoading || dialog.isConfirmLoading"
77
+ [disabled]="isActionDisabled(dialog)"
91
78
  [isLoading]="dialog.isConfirmLoading"
92
79
  [ngClasses]="getButtonClass(dialog.config.type)"
93
80
  >
@@ -1,90 +1,100 @@
1
- import { Component, inject, computed, Input } from '@angular/core';
1
+ import { Component, computed, inject, Input } from '@angular/core';
2
2
  import { NgClass } from '@angular/common';
3
3
  import { trigger, transition, style, animate } from '@angular/animations';
4
- import { JIconsService, JAlertDialogService, AlertDialogProps, JColorsService } from 'tailjng';
5
- import { LucideAngularModule } from 'lucide-angular';
4
+ import { JAlertDialogService, AlertDialogProps, JColorsService, Dialog } from 'tailjng';
6
5
  import { JButtonComponent } from '../../button/button.component';
6
+ import { JIconComponent } from '../../icon/icon.component';
7
+ import { AlertDialogType, ALERT_DIALOG_TYPE_ICONS } from './dialog-alert.types';
7
8
 
9
+ export type { AlertDialogType } from './dialog-alert.types';
10
+
11
+ /**
12
+ * Global alert/confirm dialog host — mount once (e.g. app root) and call `JAlertDialogService.AlertDialog()`.
13
+ *
14
+ * Install: `npx tailjng add alert-dialog`
15
+ */
8
16
  @Component({
9
17
  selector: 'JAlertDialog',
10
- imports: [LucideAngularModule, NgClass, JButtonComponent],
18
+ imports: [NgClass, JButtonComponent, JIconComponent],
11
19
  templateUrl: './dialog-alert.component.html',
12
20
  styleUrl: './dialog-alert.component.css',
13
21
  animations: [
14
22
  trigger('modalTransition', [
15
23
  transition(':enter', [
16
24
  style({ opacity: 0, transform: 'scale(0.96) translateY(0.5rem)' }),
17
- animate('320ms cubic-bezier(0.16, 1, 0.3, 1)', style({ opacity: 1, transform: 'scale(1) translateY(0)' })),
25
+ animate(
26
+ '320ms cubic-bezier(0.16, 1, 0.3, 1)',
27
+ style({ opacity: 1, transform: 'scale(1) translateY(0)' }),
28
+ ),
18
29
  ]),
19
30
  transition(':leave', [
20
- animate('180ms cubic-bezier(0.4, 0, 1, 1)', style({ opacity: 0, transform: 'scale(0.98) translateY(0.25rem)' })),
31
+ animate(
32
+ '180ms cubic-bezier(0.4, 0, 1, 1)',
33
+ style({ opacity: 0, transform: 'scale(0.98) translateY(0.25rem)' }),
34
+ ),
21
35
  ]),
22
36
  ]),
23
37
  ],
24
38
  })
25
39
  export class JAlertDialogComponent {
26
-
27
- @Input() monocromatic: boolean = false;
28
40
  private readonly alertDialogService = inject(JAlertDialogService);
41
+ private readonly colorsService = inject(JColorsService);
29
42
 
30
- dialogs = computed(() => this.alertDialogService.dialogs());
43
+ @Input() monocromatic = false;
31
44
 
32
- constructor(
33
- private readonly colorsService: JColorsService,
34
- private readonly iconsService: JIconsService,
35
- ) { }
45
+ readonly dialogs = computed(() => this.alertDialogService.dialogs());
36
46
 
37
- getIcon(type: string) {
38
- return this.iconsService.icons[type as keyof typeof this.iconsService.icons] || this.iconsService.icons.info;
47
+ handleAction(action: 'confirm' | 'cancel' | 'retry'): void {
48
+ this.alertDialogService.executeAction(action);
39
49
  }
40
50
 
41
- handleAction(action: 'confirm' | 'cancel' | 'retry') {
42
- this.alertDialogService.executeAction(action);
51
+ /**
52
+ * Lucide icon for the dialog semantic type.
53
+ */
54
+ typeIcon(type: string) {
55
+ return ALERT_DIALOG_TYPE_ICONS[type as AlertDialogType] ?? ALERT_DIALOG_TYPE_ICONS.info;
43
56
  }
44
57
 
45
58
  /**
46
- * Fondo suave del dialog (mismo criterio que JAlertToast).
59
+ * Class map for the dialog card shell.
47
60
  */
48
- getDialogSurfaceClass(type: string): string {
49
- if (this.monocromatic) {
50
- return 'bg-white/95 dark:bg-foreground/95';
51
- }
52
-
53
- const surfaces: Record<string, string> = {
54
- success: 'bg-green-50/95 dark:bg-[#15241f]/95',
55
- error: 'bg-red-50/95 dark:bg-[#21181c]/95',
56
- warning: 'bg-yellow-50/95 dark:bg-[#1f1c1a]/95',
57
- info: 'bg-blue-50/95 dark:bg-[#1a1a24]/95',
58
- question: 'bg-purple-50/95 dark:bg-[#241732]/95',
59
- loading: 'bg-gray-50/95 dark:bg-[#15181e]/95',
61
+ cardClasses(type: string): Record<string, boolean> {
62
+ const alertType = type as AlertDialogType;
63
+ return {
64
+ [`j-alert-dialog-card--${alertType}`]: !this.monocromatic,
65
+ 'j-alert-dialog-card--mono': this.monocromatic,
60
66
  };
61
-
62
- return surfaces[type] ?? 'bg-white/95 dark:bg-foreground/95';
63
67
  }
64
68
 
65
- getAccentBarClass(type: string): string {
66
- if (this.monocromatic) return 'bg-primary';
67
-
68
- const accents: Record<string, string> = {
69
- success: 'bg-green-500',
70
- error: 'bg-red-500',
71
- warning: 'bg-yellow-500',
72
- info: 'bg-blue-500',
73
- question: 'bg-purple-500',
74
- loading: 'bg-gray-500',
69
+ /**
70
+ * Class map for the left accent bar.
71
+ */
72
+ accentClasses(type: string): Record<string, boolean> {
73
+ const alertType = type as AlertDialogType;
74
+ return {
75
+ 'j-alert-dialog-accent': true,
76
+ [`j-alert-dialog-accent--${alertType}`]: !this.monocromatic,
77
+ 'j-alert-dialog-accent--mono': this.monocromatic,
75
78
  };
76
-
77
- return accents[type] ?? 'bg-primary';
78
79
  }
79
80
 
80
- getWatermarkIconClass(type: string, subtle = false): string {
81
- if (subtle) {
82
- return `${this.getIconClass(type)} opacity-[0.12] dark:opacity-[0.2]`;
83
- }
84
- return `${this.getIconClass(type)} opacity-[0.2] dark:opacity-[0.3]`;
81
+ /**
82
+ * Class map for decorative watermark icons.
83
+ */
84
+ watermarkClasses(type: string, subtle = false): Record<string, boolean> {
85
+ const alertType = type as AlertDialogType;
86
+ return {
87
+ 'j-alert-dialog-watermark': true,
88
+ 'j-alert-dialog-watermark--lg': !subtle,
89
+ 'j-alert-dialog-watermark--sm': subtle,
90
+ 'j-alert-dialog-watermark--subtle': subtle,
91
+ [`j-alert-dialog-watermark--${alertType}`]: !this.monocromatic,
92
+ 'j-alert-dialog-watermark--mono': this.monocromatic,
93
+ 'j-alert-dialog-watermark--spin': type === 'loading',
94
+ };
85
95
  }
86
96
 
87
- hasActions(dialog: { config: AlertDialogProps }): boolean {
97
+ hasActions(dialog: Dialog): boolean {
88
98
  const { config } = dialog;
89
99
  return (
90
100
  this.showConfirmButton(config) ||
@@ -121,15 +131,15 @@ export class JAlertDialogComponent {
121
131
  : 'Reintentar';
122
132
  }
123
133
 
124
- getIconClass(type: string) {
125
- return this.colorsService.getIconClass(type, this.monocromatic);
126
- }
127
-
128
- getButtonClass(type: string): { [key: string]: boolean } {
134
+ getButtonClass(type: string): Record<string, boolean> {
129
135
  return this.colorsService.getButtonClass(type, this.monocromatic);
130
136
  }
131
137
 
132
- getButtonSecondaryClass(type: string): { [key: string]: boolean } {
138
+ getButtonSecondaryClass(type: string): Record<string, boolean> {
133
139
  return this.colorsService.getButtonSecondaryClass(type, this.monocromatic);
134
140
  }
141
+
142
+ isActionDisabled(dialog: Dialog): boolean {
143
+ return dialog.isRetryLoading || dialog.isCancelLoading || dialog.isConfirmLoading;
144
+ }
135
145
  }
@@ -0,0 +1,19 @@
1
+ import { LucideIconData } from 'lucide-angular';
2
+ import { Icons } from '../../.config/icons/icons.lucide';
3
+
4
+ export type AlertDialogType =
5
+ | 'success'
6
+ | 'error'
7
+ | 'warning'
8
+ | 'info'
9
+ | 'question'
10
+ | 'loading';
11
+
12
+ export const ALERT_DIALOG_TYPE_ICONS: Record<AlertDialogType, LucideIconData> = {
13
+ success: Icons.CircleCheck,
14
+ error: Icons.CircleX,
15
+ warning: Icons.TriangleAlert,
16
+ info: Icons.Info,
17
+ question: Icons.CircleHelp,
18
+ loading: Icons.Loader2,
19
+ };