@area8975/ui 0.2.2-dev.48 → 0.2.2-dev.50

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 (182) hide show
  1. package/README.md +3 -2
  2. package/fesm2022/area8975-ui-alert.mjs +113 -0
  3. package/fesm2022/area8975-ui-alert.mjs.map +1 -0
  4. package/fesm2022/area8975-ui-avatar.mjs +157 -0
  5. package/fesm2022/area8975-ui-avatar.mjs.map +1 -0
  6. package/fesm2022/area8975-ui-badge.mjs +116 -0
  7. package/fesm2022/area8975-ui-badge.mjs.map +1 -0
  8. package/fesm2022/area8975-ui-button.mjs +314 -0
  9. package/fesm2022/area8975-ui-button.mjs.map +1 -0
  10. package/fesm2022/area8975-ui-calendar.mjs +549 -0
  11. package/fesm2022/area8975-ui-calendar.mjs.map +1 -0
  12. package/fesm2022/area8975-ui-card-header.mjs +96 -0
  13. package/fesm2022/area8975-ui-card-header.mjs.map +1 -0
  14. package/fesm2022/area8975-ui-card.mjs +73 -0
  15. package/fesm2022/area8975-ui-card.mjs.map +1 -0
  16. package/fesm2022/area8975-ui-chart-palette.mjs +225 -0
  17. package/fesm2022/area8975-ui-chart-palette.mjs.map +1 -0
  18. package/fesm2022/area8975-ui-charts.mjs +2813 -0
  19. package/fesm2022/area8975-ui-charts.mjs.map +1 -0
  20. package/fesm2022/area8975-ui-checkbox.mjs +202 -0
  21. package/fesm2022/area8975-ui-checkbox.mjs.map +1 -0
  22. package/fesm2022/area8975-ui-colour.mjs +200 -0
  23. package/fesm2022/area8975-ui-colour.mjs.map +1 -0
  24. package/fesm2022/area8975-ui-container.mjs +40 -0
  25. package/fesm2022/area8975-ui-container.mjs.map +1 -0
  26. package/fesm2022/area8975-ui-counter.mjs +246 -0
  27. package/fesm2022/area8975-ui-counter.mjs.map +1 -0
  28. package/fesm2022/area8975-ui-date-range-picker.mjs +554 -0
  29. package/fesm2022/area8975-ui-date-range-picker.mjs.map +1 -0
  30. package/fesm2022/area8975-ui-datepicker.mjs +547 -0
  31. package/fesm2022/area8975-ui-datepicker.mjs.map +1 -0
  32. package/fesm2022/area8975-ui-disclosure.mjs +279 -0
  33. package/fesm2022/area8975-ui-disclosure.mjs.map +1 -0
  34. package/fesm2022/area8975-ui-drawer.mjs +106 -0
  35. package/fesm2022/area8975-ui-drawer.mjs.map +1 -0
  36. package/fesm2022/area8975-ui-dropdown-button.mjs +141 -0
  37. package/fesm2022/area8975-ui-dropdown-button.mjs.map +1 -0
  38. package/fesm2022/area8975-ui-dropdown-menu.mjs +96 -0
  39. package/fesm2022/area8975-ui-dropdown-menu.mjs.map +1 -0
  40. package/fesm2022/area8975-ui-dropdown.mjs +208 -0
  41. package/fesm2022/area8975-ui-dropdown.mjs.map +1 -0
  42. package/fesm2022/area8975-ui-dropzone.mjs +332 -0
  43. package/fesm2022/area8975-ui-dropzone.mjs.map +1 -0
  44. package/fesm2022/area8975-ui-field.mjs +191 -0
  45. package/fesm2022/area8975-ui-field.mjs.map +1 -0
  46. package/fesm2022/area8975-ui-file-input.mjs +340 -0
  47. package/fesm2022/area8975-ui-file-input.mjs.map +1 -0
  48. package/fesm2022/area8975-ui-file.mjs +47 -0
  49. package/fesm2022/area8975-ui-file.mjs.map +1 -0
  50. package/fesm2022/area8975-ui-format.mjs +70 -0
  51. package/fesm2022/area8975-ui-format.mjs.map +1 -0
  52. package/fesm2022/area8975-ui-input-addon.mjs +42 -0
  53. package/fesm2022/area8975-ui-input-addon.mjs.map +1 -0
  54. package/fesm2022/area8975-ui-input-group.mjs +86 -0
  55. package/fesm2022/area8975-ui-input-group.mjs.map +1 -0
  56. package/fesm2022/area8975-ui-input.mjs +682 -0
  57. package/fesm2022/area8975-ui-input.mjs.map +1 -0
  58. package/fesm2022/area8975-ui-kpi.mjs +167 -0
  59. package/fesm2022/area8975-ui-kpi.mjs.map +1 -0
  60. package/fesm2022/area8975-ui-layout.mjs +63 -0
  61. package/fesm2022/area8975-ui-layout.mjs.map +1 -0
  62. package/fesm2022/area8975-ui-loading.mjs +76 -0
  63. package/fesm2022/area8975-ui-loading.mjs.map +1 -0
  64. package/fesm2022/area8975-ui-modal-close-btn.mjs +89 -0
  65. package/fesm2022/area8975-ui-modal-close-btn.mjs.map +1 -0
  66. package/fesm2022/area8975-ui-modal.mjs +235 -0
  67. package/fesm2022/area8975-ui-modal.mjs.map +1 -0
  68. package/fesm2022/area8975-ui-money.mjs +230 -0
  69. package/fesm2022/area8975-ui-money.mjs.map +1 -0
  70. package/fesm2022/area8975-ui-overlay.mjs +317 -0
  71. package/fesm2022/area8975-ui-overlay.mjs.map +1 -0
  72. package/fesm2022/area8975-ui-pagination.mjs +152 -0
  73. package/fesm2022/area8975-ui-pagination.mjs.map +1 -0
  74. package/fesm2022/area8975-ui-private.mjs +63 -0
  75. package/fesm2022/area8975-ui-private.mjs.map +1 -0
  76. package/fesm2022/area8975-ui-progress.mjs +307 -0
  77. package/fesm2022/area8975-ui-progress.mjs.map +1 -0
  78. package/fesm2022/area8975-ui-radio.mjs +199 -0
  79. package/fesm2022/area8975-ui-radio.mjs.map +1 -0
  80. package/fesm2022/area8975-ui-rich-text-editor.mjs +778 -0
  81. package/fesm2022/area8975-ui-rich-text-editor.mjs.map +1 -0
  82. package/fesm2022/area8975-ui-search.mjs +266 -0
  83. package/fesm2022/area8975-ui-search.mjs.map +1 -0
  84. package/fesm2022/area8975-ui-segmented.mjs +118 -0
  85. package/fesm2022/area8975-ui-segmented.mjs.map +1 -0
  86. package/fesm2022/area8975-ui-select.mjs +926 -0
  87. package/fesm2022/area8975-ui-select.mjs.map +1 -0
  88. package/fesm2022/area8975-ui-sidebar-group.mjs +60 -0
  89. package/fesm2022/area8975-ui-sidebar-group.mjs.map +1 -0
  90. package/fesm2022/area8975-ui-sidebar-item.mjs +107 -0
  91. package/fesm2022/area8975-ui-sidebar-item.mjs.map +1 -0
  92. package/fesm2022/area8975-ui-sidebar.mjs +109 -0
  93. package/fesm2022/area8975-ui-sidebar.mjs.map +1 -0
  94. package/fesm2022/area8975-ui-skeleton.mjs +116 -0
  95. package/fesm2022/area8975-ui-skeleton.mjs.map +1 -0
  96. package/fesm2022/area8975-ui-stat.mjs +55 -0
  97. package/fesm2022/area8975-ui-stat.mjs.map +1 -0
  98. package/fesm2022/area8975-ui-switch.mjs +132 -0
  99. package/fesm2022/area8975-ui-switch.mjs.map +1 -0
  100. package/fesm2022/area8975-ui-tab.mjs +217 -0
  101. package/fesm2022/area8975-ui-tab.mjs.map +1 -0
  102. package/fesm2022/area8975-ui-table-filters.mjs +499 -0
  103. package/fesm2022/area8975-ui-table-filters.mjs.map +1 -0
  104. package/fesm2022/area8975-ui-table.mjs +1237 -0
  105. package/fesm2022/area8975-ui-table.mjs.map +1 -0
  106. package/fesm2022/area8975-ui-textarea.mjs +375 -0
  107. package/fesm2022/area8975-ui-textarea.mjs.map +1 -0
  108. package/fesm2022/area8975-ui-theme.mjs +246 -0
  109. package/fesm2022/area8975-ui-theme.mjs.map +1 -0
  110. package/fesm2022/area8975-ui-time-select.mjs +170 -0
  111. package/fesm2022/area8975-ui-time-select.mjs.map +1 -0
  112. package/fesm2022/area8975-ui-toast.mjs +269 -0
  113. package/fesm2022/area8975-ui-toast.mjs.map +1 -0
  114. package/fesm2022/area8975-ui-toaster.mjs +117 -0
  115. package/fesm2022/area8975-ui-toaster.mjs.map +1 -0
  116. package/fesm2022/area8975-ui-tooltip.mjs +196 -0
  117. package/fesm2022/area8975-ui-tooltip.mjs.map +1 -0
  118. package/fesm2022/area8975-ui-user-menu.mjs +186 -0
  119. package/fesm2022/area8975-ui-user-menu.mjs.map +1 -0
  120. package/fesm2022/area8975-ui.mjs +0 -16269
  121. package/package.json +237 -1
  122. package/types/area8975-ui-alert.d.ts +25 -0
  123. package/types/area8975-ui-avatar.d.ts +40 -0
  124. package/types/area8975-ui-badge.d.ts +31 -0
  125. package/types/area8975-ui-button.d.ts +129 -0
  126. package/types/area8975-ui-calendar.d.ts +177 -0
  127. package/types/area8975-ui-card-header.d.ts +28 -0
  128. package/types/area8975-ui-card.d.ts +18 -0
  129. package/types/area8975-ui-chart-palette.d.ts +176 -0
  130. package/types/area8975-ui-charts.d.ts +747 -0
  131. package/types/area8975-ui-checkbox.d.ts +61 -0
  132. package/types/area8975-ui-colour.d.ts +31 -0
  133. package/types/area8975-ui-container.d.ts +5 -0
  134. package/types/area8975-ui-counter.d.ts +43 -0
  135. package/types/area8975-ui-date-range-picker.d.ts +132 -0
  136. package/types/area8975-ui-datepicker.d.ts +124 -0
  137. package/types/area8975-ui-disclosure.d.ts +79 -0
  138. package/types/area8975-ui-drawer.d.ts +25 -0
  139. package/types/area8975-ui-dropdown-button.d.ts +32 -0
  140. package/types/area8975-ui-dropdown-menu.d.ts +25 -0
  141. package/types/area8975-ui-dropdown.d.ts +56 -0
  142. package/types/area8975-ui-dropzone.d.ts +96 -0
  143. package/types/area8975-ui-field.d.ts +72 -0
  144. package/types/area8975-ui-file-input.d.ts +72 -0
  145. package/types/area8975-ui-file.d.ts +21 -0
  146. package/types/area8975-ui-format.d.ts +37 -0
  147. package/types/area8975-ui-input-addon.d.ts +10 -0
  148. package/types/area8975-ui-input-group.d.ts +18 -0
  149. package/types/area8975-ui-input.d.ts +224 -0
  150. package/types/area8975-ui-kpi.d.ts +36 -0
  151. package/types/area8975-ui-layout.d.ts +7 -0
  152. package/types/area8975-ui-loading.d.ts +16 -0
  153. package/types/area8975-ui-modal-close-btn.d.ts +14 -0
  154. package/types/area8975-ui-modal.d.ts +45 -0
  155. package/types/area8975-ui-money.d.ts +77 -0
  156. package/types/area8975-ui-overlay.d.ts +75 -0
  157. package/types/area8975-ui-pagination.d.ts +27 -0
  158. package/types/area8975-ui-private.d.ts +20 -0
  159. package/types/area8975-ui-progress.d.ts +127 -0
  160. package/types/area8975-ui-radio.d.ts +61 -0
  161. package/types/area8975-ui-rich-text-editor.d.ts +165 -0
  162. package/types/area8975-ui-search.d.ts +56 -0
  163. package/types/area8975-ui-segmented.d.ts +41 -0
  164. package/types/area8975-ui-select.d.ts +293 -0
  165. package/types/area8975-ui-sidebar-group.d.ts +15 -0
  166. package/types/area8975-ui-sidebar-item.d.ts +20 -0
  167. package/types/area8975-ui-sidebar.d.ts +16 -0
  168. package/types/area8975-ui-skeleton.d.ts +35 -0
  169. package/types/area8975-ui-stat.d.ts +13 -0
  170. package/types/area8975-ui-switch.d.ts +32 -0
  171. package/types/area8975-ui-tab.d.ts +45 -0
  172. package/types/area8975-ui-table-filters.d.ts +138 -0
  173. package/types/area8975-ui-table.d.ts +371 -0
  174. package/types/area8975-ui-textarea.d.ts +126 -0
  175. package/types/area8975-ui-theme.d.ts +61 -0
  176. package/types/area8975-ui-time-select.d.ts +35 -0
  177. package/types/area8975-ui-toast.d.ts +78 -0
  178. package/types/area8975-ui-toaster.d.ts +23 -0
  179. package/types/area8975-ui-tooltip.d.ts +47 -0
  180. package/types/area8975-ui-user-menu.d.ts +39 -0
  181. package/types/area8975-ui.d.ts +1 -4464
  182. package/fesm2022/area8975-ui.mjs.map +0 -1
@@ -0,0 +1,269 @@
1
+ import * as i0 from "@angular/core";
2
+ import { Component, Injectable, booleanAttribute, computed, effect, input, output, signal } from "@angular/core";
3
+ import { UiCardComponent } from "@area8975/ui/card";
4
+ import { NgIcon, provideIcons } from "@ng-icons/core";
5
+ import { heroXMark } from "@ng-icons/heroicons/outline";
6
+ import { heroCheckCircleSolid, heroExclamationTriangleSolid, heroInformationCircleSolid, heroXCircleSolid } from "@ng-icons/heroicons/solid";
7
+ const INTENT_ICONS = {
8
+ info: "heroInformationCircleSolid",
9
+ success: "heroCheckCircleSolid",
10
+ warning: "heroExclamationTriangleSolid",
11
+ danger: "heroXCircleSolid"
12
+ };
13
+ const INTENT_COLOURS = {
14
+ info: "text-primary-600",
15
+ success: "text-success-600",
16
+ warning: "text-warning-600",
17
+ danger: "text-danger-600"
18
+ };
19
+ var UiToastComponent = class UiToastComponent {
20
+ intent = input("info", ...ngDevMode ? [{ debugName: "intent" }] : /* istanbul ignore next */ []);
21
+ classes = input("", ...ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []);
22
+ dismissable = input(false, {
23
+ ...ngDevMode ? { debugName: "dismissable" } : /* istanbul ignore next */ {},
24
+ transform: booleanAttribute
25
+ });
26
+ timeoutMs = input(null, ...ngDevMode ? [{ debugName: "timeoutMs" }] : /* istanbul ignore next */ []);
27
+ dismissed = output();
28
+ icon = computed(() => INTENT_ICONS[this.intent()], ...ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []);
29
+ iconColour = computed(() => INTENT_COLOURS[this.intent()], ...ngDevMode ? [{ debugName: "iconColour" }] : /* istanbul ignore next */ []);
30
+ role = computed(() => this.intent() === "danger" ? "alert" : "status", ...ngDevMode ? [{ debugName: "role" }] : /* istanbul ignore next */ []);
31
+ hovered = false;
32
+ focused = false;
33
+ timer;
34
+ startedAt = 0;
35
+ remaining = 0;
36
+ constructor() {
37
+ effect((onCleanup) => {
38
+ const timeoutMs = this.timeoutMs();
39
+ if (timeoutMs === null) return;
40
+ this.remaining = timeoutMs;
41
+ this.updateTimer();
42
+ onCleanup(() => this.stopTimer());
43
+ });
44
+ }
45
+ setHovered(hovered) {
46
+ this.hovered = hovered;
47
+ this.updateTimer();
48
+ }
49
+ setFocused(focused) {
50
+ this.focused = focused;
51
+ this.updateTimer();
52
+ }
53
+ updateTimer() {
54
+ if (this.hovered || this.focused) this.stopTimer();
55
+ else if (this.timeoutMs() !== null && this.timer === void 0) this.startTimer();
56
+ }
57
+ startTimer() {
58
+ this.startedAt = Date.now();
59
+ this.timer = setTimeout(() => this.dismissed.emit(), this.remaining);
60
+ }
61
+ stopTimer() {
62
+ if (this.timer === void 0) return;
63
+ clearTimeout(this.timer);
64
+ this.timer = void 0;
65
+ this.remaining -= Date.now() - this.startedAt;
66
+ }
67
+ static ɵfac = i0.ɵɵngDeclareFactory({
68
+ minVersion: "12.0.0",
69
+ version: "22.2.1",
70
+ ngImport: i0,
71
+ type: UiToastComponent,
72
+ deps: [],
73
+ target: i0.ɵɵFactoryTarget.Component
74
+ });
75
+ static ɵcmp = i0.ɵɵngDeclareComponent({
76
+ minVersion: "17.0.0",
77
+ version: "22.2.1",
78
+ type: UiToastComponent,
79
+ isStandalone: true,
80
+ selector: "ui-toast",
81
+ inputs: {
82
+ intent: {
83
+ classPropertyName: "intent",
84
+ publicName: "intent",
85
+ isSignal: true,
86
+ isRequired: false,
87
+ transformFunction: null
88
+ },
89
+ classes: {
90
+ classPropertyName: "classes",
91
+ publicName: "classes",
92
+ isSignal: true,
93
+ isRequired: false,
94
+ transformFunction: null
95
+ },
96
+ dismissable: {
97
+ classPropertyName: "dismissable",
98
+ publicName: "dismissable",
99
+ isSignal: true,
100
+ isRequired: false,
101
+ transformFunction: null
102
+ },
103
+ timeoutMs: {
104
+ classPropertyName: "timeoutMs",
105
+ publicName: "timeoutMs",
106
+ isSignal: true,
107
+ isRequired: false,
108
+ transformFunction: null
109
+ }
110
+ },
111
+ outputs: { dismissed: "dismissed" },
112
+ host: { listeners: {
113
+ "mouseenter": "setHovered(true)",
114
+ "mouseleave": "setHovered(false)",
115
+ "focusin": "setFocused(true)",
116
+ "focusout": "setFocused(false)"
117
+ } },
118
+ providers: [provideIcons({
119
+ heroInformationCircleSolid,
120
+ heroCheckCircleSolid,
121
+ heroExclamationTriangleSolid,
122
+ heroXCircleSolid,
123
+ heroXMark
124
+ })],
125
+ ngImport: i0,
126
+ template: "<ui-card\n radius=\"xl\"\n class=\"p-4 w-full max-w-xs\"\n [class]=\"classes()\"\n [attr.role]=\"role()\"\n tabindex=\"-1\"\n>\n <div class=\"flex gap-x-3\">\n <div class=\"inline-flex\" [class]=\"iconColour()\">\n <ng-icon\n [name]=\"icon()\"\n class=\"shrink-0\"\n size=\"24\"\n />\n </div>\n <div class=\"grow\">\n <p class=\"text-layer-foreground ui-text-body\">\n <ng-content />\n </p>\n </div>\n @if (dismissable()) {\n <button\n type=\"button\"\n aria-label=\"Dismiss\"\n (click)=\"dismissed.emit()\"\n >\n <ng-icon name=\"heroXMark\" />\n </button>\n }\n </div>\n</ui-card>\n",
127
+ dependencies: [{
128
+ kind: "component",
129
+ type: NgIcon,
130
+ selector: "ng-icon",
131
+ inputs: [
132
+ "name",
133
+ "svg",
134
+ "size",
135
+ "strokeWidth",
136
+ "color"
137
+ ]
138
+ }, {
139
+ kind: "component",
140
+ type: UiCardComponent,
141
+ selector: "ui-card",
142
+ inputs: ["radius"]
143
+ }]
144
+ });
145
+ };
146
+ i0.ɵɵngDeclareClassMetadata({
147
+ minVersion: "12.0.0",
148
+ version: "22.2.1",
149
+ ngImport: i0,
150
+ type: UiToastComponent,
151
+ decorators: [{
152
+ type: Component,
153
+ args: [{
154
+ selector: "ui-toast",
155
+ imports: [NgIcon, UiCardComponent],
156
+ host: {
157
+ "(mouseenter)": "setHovered(true)",
158
+ "(mouseleave)": "setHovered(false)",
159
+ "(focusin)": "setFocused(true)",
160
+ "(focusout)": "setFocused(false)"
161
+ },
162
+ providers: [provideIcons({
163
+ heroInformationCircleSolid,
164
+ heroCheckCircleSolid,
165
+ heroExclamationTriangleSolid,
166
+ heroXCircleSolid,
167
+ heroXMark
168
+ })],
169
+ template: "<ui-card\n radius=\"xl\"\n class=\"p-4 w-full max-w-xs\"\n [class]=\"classes()\"\n [attr.role]=\"role()\"\n tabindex=\"-1\"\n>\n <div class=\"flex gap-x-3\">\n <div class=\"inline-flex\" [class]=\"iconColour()\">\n <ng-icon\n [name]=\"icon()\"\n class=\"shrink-0\"\n size=\"24\"\n />\n </div>\n <div class=\"grow\">\n <p class=\"text-layer-foreground ui-text-body\">\n <ng-content />\n </p>\n </div>\n @if (dismissable()) {\n <button\n type=\"button\"\n aria-label=\"Dismiss\"\n (click)=\"dismissed.emit()\"\n >\n <ng-icon name=\"heroXMark\" />\n </button>\n }\n </div>\n</ui-card>\n"
170
+ }]
171
+ }],
172
+ ctorParameters: () => [],
173
+ propDecorators: {
174
+ intent: [{
175
+ type: i0.Input,
176
+ args: [{
177
+ isSignal: true,
178
+ alias: "intent",
179
+ required: false
180
+ }]
181
+ }],
182
+ classes: [{
183
+ type: i0.Input,
184
+ args: [{
185
+ isSignal: true,
186
+ alias: "classes",
187
+ required: false
188
+ }]
189
+ }],
190
+ dismissable: [{
191
+ type: i0.Input,
192
+ args: [{
193
+ isSignal: true,
194
+ alias: "dismissable",
195
+ required: false
196
+ }]
197
+ }],
198
+ timeoutMs: [{
199
+ type: i0.Input,
200
+ args: [{
201
+ isSignal: true,
202
+ alias: "timeoutMs",
203
+ required: false
204
+ }]
205
+ }],
206
+ dismissed: [{
207
+ type: i0.Output,
208
+ args: ["dismissed"]
209
+ }]
210
+ }
211
+ });
212
+ var UiToastService = class UiToastService {
213
+ _toasts = signal([], ...ngDevMode ? [{ debugName: "_toasts" }] : /* istanbul ignore next */ []);
214
+ nextId = 0;
215
+ toasts = this._toasts.asReadonly();
216
+ show(message, options = {}) {
217
+ const id = this.nextId++;
218
+ const toast = {
219
+ id,
220
+ message,
221
+ templateContext: {
222
+ $implicit: options.context,
223
+ dismiss: () => this.dismiss(id)
224
+ },
225
+ intent: options.intent ?? "info",
226
+ dismissable: options.dismissable ?? true,
227
+ timeoutMs: options.timeoutMs
228
+ };
229
+ this._toasts.update((toasts) => [...toasts, toast]);
230
+ return id;
231
+ }
232
+ dismiss(id) {
233
+ this._toasts.update((toasts) => toasts.filter((toast) => toast.id !== id));
234
+ }
235
+ static ɵfac = i0.ɵɵngDeclareFactory({
236
+ minVersion: "12.0.0",
237
+ version: "22.2.1",
238
+ ngImport: i0,
239
+ type: UiToastService,
240
+ deps: [],
241
+ target: i0.ɵɵFactoryTarget.Injectable
242
+ });
243
+ static ɵprov = i0.ɵɵngDeclareInjectable({
244
+ minVersion: "12.0.0",
245
+ version: "22.2.1",
246
+ ngImport: i0,
247
+ type: UiToastService,
248
+ providedIn: "root"
249
+ });
250
+ };
251
+ i0.ɵɵngDeclareClassMetadata({
252
+ minVersion: "12.0.0",
253
+ version: "22.2.1",
254
+ ngImport: i0,
255
+ type: UiToastService,
256
+ decorators: [{
257
+ type: Injectable,
258
+ args: [{ providedIn: "root" }]
259
+ }]
260
+ });
261
+ const ToastIntents = [
262
+ "info",
263
+ "success",
264
+ "warning",
265
+ "danger"
266
+ ];
267
+ export { ToastIntents, UiToastComponent, UiToastService };
268
+
269
+ //# sourceMappingURL=area8975-ui-toast.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"area8975-ui-toast.mjs","names":[],"sources":["../../../projects/ui/toast/toast.component.ts","../../../projects/ui/toast/toast.component.html","../../../projects/ui/toast/toast.service.ts","../../../projects/ui/toast/toast.types.ts"],"sourcesContent":["import {\n booleanAttribute,\n Component,\n computed,\n effect,\n input,\n output\n} from '@angular/core';\n\nimport { UiCardComponent } from '@area8975/ui/card';\nimport { IconType, NgIcon, provideIcons } from '@ng-icons/core';\nimport { heroXMark } from '@ng-icons/heroicons/outline';\nimport {\n heroCheckCircleSolid,\n heroExclamationTriangleSolid,\n heroInformationCircleSolid,\n heroXCircleSolid\n} from '@ng-icons/heroicons/solid';\n\nimport { ToastIntent } from './toast.types';\n\n\nconst INTENT_ICONS: Record<ToastIntent, IconType> = {\n info: 'heroInformationCircleSolid',\n success: 'heroCheckCircleSolid',\n warning: 'heroExclamationTriangleSolid',\n danger: 'heroXCircleSolid'\n};\n\nconst INTENT_COLOURS: Record<ToastIntent, string> = {\n info: 'text-primary-600',\n success: 'text-success-600',\n warning: 'text-warning-600',\n danger: 'text-danger-600'\n};\n\n@Component({\n selector: 'ui-toast',\n templateUrl: './toast.component.html',\n imports: [NgIcon, UiCardComponent],\n host: {\n '(mouseenter)': 'setHovered(true)',\n '(mouseleave)': 'setHovered(false)',\n '(focusin)': 'setFocused(true)',\n '(focusout)': 'setFocused(false)'\n },\n providers: [provideIcons({\n heroInformationCircleSolid,\n heroCheckCircleSolid,\n heroExclamationTriangleSolid,\n heroXCircleSolid,\n heroXMark\n })]\n})\nexport class UiToastComponent {\n readonly intent = input<ToastIntent>('info');\n readonly classes = input<string>('');\n readonly dismissable = input(false, { transform: booleanAttribute });\n\n /** ms before the toast dismisses itself, paused while hovered or focused. null never times out. */\n readonly timeoutMs = input<number | null>(null);\n\n readonly dismissed = output<void>();\n\n protected readonly icon = computed(() => INTENT_ICONS[this.intent()]);\n protected readonly iconColour = computed(() =>\n INTENT_COLOURS[this.intent()]\n );\n\n // errors interrupt the screen reader, everything else waits its turn\n protected readonly role = computed(() =>\n this.intent() === 'danger' ? 'alert' : 'status'\n );\n\n private hovered = false;\n private focused = false;\n\n private timer?: ReturnType<typeof setTimeout>;\n private startedAt = 0;\n private remaining = 0;\n\n constructor() {\n effect(onCleanup => {\n const timeoutMs = this.timeoutMs();\n\n if (timeoutMs === null) {\n return;\n }\n\n this.remaining = timeoutMs;\n this.updateTimer();\n\n onCleanup(() => this.stopTimer());\n });\n }\n\n protected setHovered(hovered: boolean): void {\n this.hovered = hovered;\n this.updateTimer();\n }\n\n protected setFocused(focused: boolean): void {\n this.focused = focused;\n this.updateTimer();\n }\n\n private updateTimer(): void {\n if (this.hovered || this.focused) {\n this.stopTimer();\n } else if (this.timeoutMs() !== null && this.timer === undefined) {\n this.startTimer();\n }\n }\n\n private startTimer(): void {\n this.startedAt = Date.now();\n this.timer = setTimeout(() => this.dismissed.emit(), this.remaining);\n }\n\n // keeps whatever time was left so the countdown carries on after a pause\n private stopTimer(): void {\n if (this.timer === undefined) {\n return;\n }\n\n clearTimeout(this.timer);\n this.timer = undefined;\n this.remaining -= Date.now() - this.startedAt;\n }\n}\n","<ui-card\n radius=\"xl\"\n class=\"p-4 w-full max-w-xs\"\n [class]=\"classes()\"\n [attr.role]=\"role()\"\n tabindex=\"-1\"\n>\n <div class=\"flex gap-x-3\">\n <div class=\"inline-flex\" [class]=\"iconColour()\">\n <ng-icon\n [name]=\"icon()\"\n class=\"shrink-0\"\n size=\"24\"\n />\n </div>\n <div class=\"grow\">\n <p class=\"text-layer-foreground ui-text-body\">\n <ng-content />\n </p>\n </div>\n @if (dismissable()) {\n <button\n type=\"button\"\n aria-label=\"Dismiss\"\n (click)=\"dismissed.emit()\"\n >\n <ng-icon name=\"heroXMark\" />\n </button>\n }\n </div>\n</ui-card>\n","import { Injectable, signal } from '@angular/core';\n\nimport { Toast, ToastMessage, ToastOptions } from './toast.types';\n\n\n@Injectable({ providedIn: 'root' })\nexport class UiToastService {\n private readonly _toasts = signal<Toast[]>([]);\n private nextId = 0;\n\n readonly toasts = this._toasts.asReadonly();\n\n show<ContextType>(\n message: ToastMessage<ContextType>,\n options: ToastOptions<ContextType> = {}\n ): number {\n const id = this.nextId++;\n\n const toast: Toast = {\n id,\n message,\n templateContext: {\n $implicit: options.context,\n dismiss: () => this.dismiss(id)\n },\n intent: options.intent ?? 'info',\n dismissable: options.dismissable ?? true,\n timeoutMs: options.timeoutMs\n };\n\n this._toasts.update(toasts => [...toasts, toast]);\n\n return id;\n }\n\n dismiss(id: number): void {\n this._toasts.update(toasts => toasts.filter(toast => toast.id !== id));\n }\n}\n","import { TemplateRef } from '@angular/core';\n\n\nexport const ToastIntents = [\n 'info',\n 'success',\n 'warning',\n 'danger'\n] as const;\n\nexport type ToastIntent = typeof ToastIntents[number];\n\n/** What a toast template receives: `let-data` for the context, `let-dismiss=\"dismiss\"` to close it. */\nexport interface ToastTemplateContext<ContextType = unknown> {\n $implicit: ContextType;\n dismiss: () => void;\n}\n\nexport type ToastMessage<ContextType = unknown> =\n | string\n | TemplateRef<ToastTemplateContext<ContextType>>;\n\nexport interface Toast {\n id: number;\n message: ToastMessage;\n templateContext: ToastTemplateContext;\n intent: ToastIntent;\n dismissable: boolean;\n\n // null never times out, undefined falls back to the toaster's timeout\n timeoutMs?: number | null;\n}\n\nexport type ToastOptions<ContextType = unknown> =\n & Partial<\n Pick<Toast, 'intent' | 'dismissable' | 'timeoutMs'>\n >\n & {\n context?: ContextType;\n };\n"],"mappings":"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"}
@@ -0,0 +1,117 @@
1
+ import { NgTemplateOutlet } from "@angular/common";
2
+ import * as i0 from "@angular/core";
3
+ import { Component, computed, inject, input } from "@angular/core";
4
+ import { UiToastComponent, UiToastService } from "@area8975/ui/toast";
5
+ const POSITION_CLASSES = {
6
+ "top-left": "top-0 left-0 items-start flex-col-reverse",
7
+ "top-center": "top-0 left-1/2 -translate-x-1/2 items-center flex-col-reverse",
8
+ "top-right": "top-0 right-0 items-end flex-col-reverse",
9
+ "bottom-left": "bottom-0 left-0 items-start flex-col",
10
+ "bottom-center": "bottom-0 left-1/2 -translate-x-1/2 items-center flex-col",
11
+ "bottom-right": "bottom-0 right-0 items-end flex-col"
12
+ };
13
+ var UiToasterComponent = class UiToasterComponent {
14
+ position = input("bottom-right", ...ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []);
15
+ timeoutMs = input(null, ...ngDevMode ? [{ debugName: "timeoutMs" }] : /* istanbul ignore next */ []);
16
+ toastService = inject(UiToastService);
17
+ positionClasses = computed(() => POSITION_CLASSES[this.position()], ...ngDevMode ? [{ debugName: "positionClasses" }] : /* istanbul ignore next */ []);
18
+ static ɵfac = i0.ɵɵngDeclareFactory({
19
+ minVersion: "12.0.0",
20
+ version: "22.2.1",
21
+ ngImport: i0,
22
+ type: UiToasterComponent,
23
+ deps: [],
24
+ target: i0.ɵɵFactoryTarget.Component
25
+ });
26
+ static ɵcmp = i0.ɵɵngDeclareComponent({
27
+ minVersion: "17.0.0",
28
+ version: "22.2.1",
29
+ type: UiToasterComponent,
30
+ isStandalone: true,
31
+ selector: "ui-toaster",
32
+ inputs: {
33
+ position: {
34
+ classPropertyName: "position",
35
+ publicName: "position",
36
+ isSignal: true,
37
+ isRequired: false,
38
+ transformFunction: null
39
+ },
40
+ timeoutMs: {
41
+ classPropertyName: "timeoutMs",
42
+ publicName: "timeoutMs",
43
+ isSignal: true,
44
+ isRequired: false,
45
+ transformFunction: null
46
+ }
47
+ },
48
+ ngImport: i0,
49
+ template: "<section\n class=\"z-50 box-content fixed flex px-4 py-2.5 w-full max-w-xs pointer-events-none\"\n [class]=\"positionClasses()\"\n aria-label=\"Notifications\"\n>\n @for (toast of toastService.toasts(); track toast.id) {\n <div\n class=\"ui-toaster--item\"\n animate.enter=\"ui-toaster--enter\"\n animate.leave=\"ui-toaster--leave\"\n >\n <div class=\"ui-toaster--item-inner\">\n <ui-toast\n class=\"block py-1.5 w-full pointer-events-auto\"\n [intent]=\"toast.intent\"\n [dismissable]=\"toast.dismissable\"\n [timeoutMs]=\"toast.timeoutMs === undefined ? timeoutMs() : toast.timeoutMs\"\n (dismissed)=\"toastService.dismiss(toast.id)\"\n >\n @if (typeof toast.message === 'string') {\n {{ toast.message }}\n } @else {\n <ng-container\n *ngTemplateOutlet=\"toast.message; context: toast.templateContext\"\n />\n }\n </ui-toast>\n </div>\n </div>\n }\n</section>\n",
50
+ styles: [".ui-toaster--item{display:grid;grid-template-rows:1fr;width:100%}.ui-toaster--item-inner{min-height:0}.ui-toaster--enter>.ui-toaster--item-inner,.ui-toaster--leave>.ui-toaster--item-inner{overflow:hidden}.ui-toaster--enter{animation:ui-toaster-reveal .3s ease-out}.ui-toaster--leave{animation:ui-toaster-reveal .3s ease-in reverse forwards}@keyframes ui-toaster-reveal{0%{grid-template-rows:0fr;opacity:0}50%{grid-template-rows:1fr;opacity:0}to{grid-template-rows:1fr;opacity:1}}\n"],
51
+ dependencies: [{
52
+ kind: "component",
53
+ type: UiToastComponent,
54
+ selector: "ui-toast",
55
+ inputs: [
56
+ "intent",
57
+ "classes",
58
+ "dismissable",
59
+ "timeoutMs"
60
+ ],
61
+ outputs: ["dismissed"]
62
+ }, {
63
+ kind: "directive",
64
+ type: NgTemplateOutlet,
65
+ selector: "[ngTemplateOutlet]",
66
+ inputs: [
67
+ "ngTemplateOutletContext",
68
+ "ngTemplateOutlet",
69
+ "ngTemplateOutletInjector"
70
+ ]
71
+ }]
72
+ });
73
+ };
74
+ i0.ɵɵngDeclareClassMetadata({
75
+ minVersion: "12.0.0",
76
+ version: "22.2.1",
77
+ ngImport: i0,
78
+ type: UiToasterComponent,
79
+ decorators: [{
80
+ type: Component,
81
+ args: [{
82
+ selector: "ui-toaster",
83
+ imports: [UiToastComponent, NgTemplateOutlet],
84
+ template: "<section\n class=\"z-50 box-content fixed flex px-4 py-2.5 w-full max-w-xs pointer-events-none\"\n [class]=\"positionClasses()\"\n aria-label=\"Notifications\"\n>\n @for (toast of toastService.toasts(); track toast.id) {\n <div\n class=\"ui-toaster--item\"\n animate.enter=\"ui-toaster--enter\"\n animate.leave=\"ui-toaster--leave\"\n >\n <div class=\"ui-toaster--item-inner\">\n <ui-toast\n class=\"block py-1.5 w-full pointer-events-auto\"\n [intent]=\"toast.intent\"\n [dismissable]=\"toast.dismissable\"\n [timeoutMs]=\"toast.timeoutMs === undefined ? timeoutMs() : toast.timeoutMs\"\n (dismissed)=\"toastService.dismiss(toast.id)\"\n >\n @if (typeof toast.message === 'string') {\n {{ toast.message }}\n } @else {\n <ng-container\n *ngTemplateOutlet=\"toast.message; context: toast.templateContext\"\n />\n }\n </ui-toast>\n </div>\n </div>\n }\n</section>\n",
85
+ styles: [".ui-toaster--item{display:grid;grid-template-rows:1fr;width:100%}.ui-toaster--item-inner{min-height:0}.ui-toaster--enter>.ui-toaster--item-inner,.ui-toaster--leave>.ui-toaster--item-inner{overflow:hidden}.ui-toaster--enter{animation:ui-toaster-reveal .3s ease-out}.ui-toaster--leave{animation:ui-toaster-reveal .3s ease-in reverse forwards}@keyframes ui-toaster-reveal{0%{grid-template-rows:0fr;opacity:0}50%{grid-template-rows:1fr;opacity:0}to{grid-template-rows:1fr;opacity:1}}\n"]
86
+ }]
87
+ }],
88
+ propDecorators: {
89
+ position: [{
90
+ type: i0.Input,
91
+ args: [{
92
+ isSignal: true,
93
+ alias: "position",
94
+ required: false
95
+ }]
96
+ }],
97
+ timeoutMs: [{
98
+ type: i0.Input,
99
+ args: [{
100
+ isSignal: true,
101
+ alias: "timeoutMs",
102
+ required: false
103
+ }]
104
+ }]
105
+ }
106
+ });
107
+ const ToasterPositions = [
108
+ "top-left",
109
+ "top-center",
110
+ "top-right",
111
+ "bottom-left",
112
+ "bottom-center",
113
+ "bottom-right"
114
+ ];
115
+ export { ToasterPositions, UiToasterComponent };
116
+
117
+ //# sourceMappingURL=area8975-ui-toaster.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"area8975-ui-toaster.mjs","names":[],"sources":["../../../projects/ui/toaster/toaster.component.ts","../../../projects/ui/toaster/toaster.component.html","../../../projects/ui/toaster/toaster.types.ts"],"sourcesContent":["import { NgTemplateOutlet } from '@angular/common';\nimport { Component, computed, inject, input } from '@angular/core';\n\nimport { UiToastComponent } from '@area8975/ui/toast';\nimport { UiToastService } from '@area8975/ui/toast';\n\nimport { ToasterPosition } from './toaster.types';\n\n\n// top stacks are reversed so the newest toast is always nearest the edge\nconst POSITION_CLASSES: Record<ToasterPosition, string> = {\n 'top-left': 'top-0 left-0 items-start flex-col-reverse',\n 'top-center':\n 'top-0 left-1/2 -translate-x-1/2 items-center flex-col-reverse',\n 'top-right': 'top-0 right-0 items-end flex-col-reverse',\n 'bottom-left': 'bottom-0 left-0 items-start flex-col',\n 'bottom-center': 'bottom-0 left-1/2 -translate-x-1/2 items-center flex-col',\n 'bottom-right': 'bottom-0 right-0 items-end flex-col'\n};\n\n@Component({\n selector: 'ui-toaster',\n templateUrl: './toaster.component.html',\n styleUrl: './toaster.component.css',\n imports: [UiToastComponent, NgTemplateOutlet]\n})\nexport class UiToasterComponent {\n readonly position = input<ToasterPosition>('bottom-right');\n readonly timeoutMs = input<number | null>(null);\n\n protected readonly toastService = inject(UiToastService);\n\n protected readonly positionClasses = computed(() =>\n POSITION_CLASSES[this.position()]\n );\n}\n","<section\n class=\"z-50 box-content fixed flex px-4 py-2.5 w-full max-w-xs pointer-events-none\"\n [class]=\"positionClasses()\"\n aria-label=\"Notifications\"\n>\n @for (toast of toastService.toasts(); track toast.id) {\n <div\n class=\"ui-toaster--item\"\n animate.enter=\"ui-toaster--enter\"\n animate.leave=\"ui-toaster--leave\"\n >\n <div class=\"ui-toaster--item-inner\">\n <ui-toast\n class=\"block py-1.5 w-full pointer-events-auto\"\n [intent]=\"toast.intent\"\n [dismissable]=\"toast.dismissable\"\n [timeoutMs]=\"toast.timeoutMs === undefined ? timeoutMs() : toast.timeoutMs\"\n (dismissed)=\"toastService.dismiss(toast.id)\"\n >\n @if (typeof toast.message === 'string') {\n {{ toast.message }}\n } @else {\n <ng-container\n *ngTemplateOutlet=\"toast.message; context: toast.templateContext\"\n />\n }\n </ui-toast>\n </div>\n </div>\n }\n</section>\n","export const ToasterPositions = [\n 'top-left',\n 'top-center',\n 'top-right',\n 'bottom-left',\n 'bottom-center',\n 'bottom-right'\n] as const;\n\nexport type ToasterPosition = typeof ToasterPositions[number];\n"],"mappings":";;;;AAUA,MAAM,mBAAoD;CACtD,YAAY;CACZ,cACI;CACJ,aAAa;CACb,eAAe;CACf,iBAAiB;CACjB,gBAAgB;AACnB;AAQD,IAAa,qBAAb,MAAa,mBAAkB;CAClB,WAAW,MAAuB,gBAAe,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CACjD,YAAY,MAAqB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CAE5B,eAAe,OAAO,cAAc;CAEpC,kBAAkB,eACjC,iBAAiB,KAAK,SAAQ,IACjC,GAAA,YAAA,CAAA,EAAA,WAAA,kBAAA,CAAA,+BAAA,CAAA,CAAA;CARQ,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAkB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAlB,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAkB,cAAA;EAAA,UAAA;EAAA,QAAA;GAAA,UAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,WAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;EAAA;EAAA,UAAA;EAAA,UC1B/B;EA+BA,QAAA,CAAA,meAAA;EAAA,cAAA,CAAA;GAAA,MAAA;GAAA,MDPc;GAAgB,UAAA;GAAA,QAAA;IAAA;IAAA;IAAA;IAAA;GAAA;GAAA,SAAA,CAAA,WAAA;EAAA,GAAA;GAAA,MAAA;GAAA,MAAE;GAAgB,UAAA;GAAA,QAAA;IAAA;IAAA;IAAA;GAAA;EAAA,CAAA;CAAA,CAAA;;AAEnC,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAkB,YAAA,CAAA;EAN9B,MAAA;EACa,MAAA,CAAA;GAAA,UAAA;GAAY,SAGb,CAAC,kBAAkB,gBAAgB;GAAC,UAAA;GAAA,QAAA,CAAA,meAAA;EAAA,CAAA;;;;;;;;;;;;;;;;;;;;;AExBjD,MAAa,mBAAmB;CAC5B;CACA;CACA;CACA;CACA;CACA;AACM"}
@@ -0,0 +1,196 @@
1
+ import * as i0 from "@angular/core";
2
+ import { Component, ElementRef, computed, inject, input, signal, viewChild } from "@angular/core";
3
+ import { UiOverlayComponent } from "@area8975/ui/overlay";
4
+ var UiTooltipComponent = class UiTooltipComponent {
5
+ anchor = inject(ElementRef);
6
+ content = viewChild("content", {
7
+ ...ngDevMode ? { debugName: "content" } : /* istanbul ignore next */ {},
8
+ read: ElementRef
9
+ });
10
+ text = input.required(...ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []);
11
+ placement = input("top", ...ngDevMode ? [{ debugName: "placement" }] : /* istanbul ignore next */ []);
12
+ trigger = input("hover", ...ngDevMode ? [{ debugName: "trigger" }] : /* istanbul ignore next */ []);
13
+ classes = input("", ...ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []);
14
+ isOpen = input(signal(false), ...ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []);
15
+ closeBehaviour = computed(() => this.trigger() === "click" ? "whenClickOutside" : "none", ...ngDevMode ? [{ debugName: "closeBehaviour" }] : /* istanbul ignore next */ []);
16
+ generatedClasses = computed(() => [
17
+ "ui-tooltip",
18
+ "ui-text-caption",
19
+ this.classes()
20
+ ].filter(Boolean).join(" "), ...ngDevMode ? [{ debugName: "generatedClasses" }] : /* istanbul ignore next */ []);
21
+ onHover(isHovering) {
22
+ if (this.trigger() === "hover") this.isOpen().set(isHovering);
23
+ }
24
+ onFocus(isFocused) {
25
+ if (["hover", "focus"].includes(this.trigger())) this.isOpen().set(isFocused);
26
+ }
27
+ onClick() {
28
+ if (this.trigger() === "click") this.isOpen().update((value) => !value);
29
+ }
30
+ static ɵfac = i0.ɵɵngDeclareFactory({
31
+ minVersion: "12.0.0",
32
+ version: "22.2.1",
33
+ ngImport: i0,
34
+ type: UiTooltipComponent,
35
+ deps: [],
36
+ target: i0.ɵɵFactoryTarget.Component
37
+ });
38
+ static ɵcmp = i0.ɵɵngDeclareComponent({
39
+ minVersion: "17.0.0",
40
+ version: "22.2.1",
41
+ type: UiTooltipComponent,
42
+ isStandalone: true,
43
+ selector: "ui-tooltip",
44
+ inputs: {
45
+ text: {
46
+ classPropertyName: "text",
47
+ publicName: "text",
48
+ isSignal: true,
49
+ isRequired: true,
50
+ transformFunction: null
51
+ },
52
+ placement: {
53
+ classPropertyName: "placement",
54
+ publicName: "placement",
55
+ isSignal: true,
56
+ isRequired: false,
57
+ transformFunction: null
58
+ },
59
+ trigger: {
60
+ classPropertyName: "trigger",
61
+ publicName: "trigger",
62
+ isSignal: true,
63
+ isRequired: false,
64
+ transformFunction: null
65
+ },
66
+ classes: {
67
+ classPropertyName: "classes",
68
+ publicName: "classes",
69
+ isSignal: true,
70
+ isRequired: false,
71
+ transformFunction: null
72
+ },
73
+ isOpen: {
74
+ classPropertyName: "isOpen",
75
+ publicName: "isOpen",
76
+ isSignal: true,
77
+ isRequired: false,
78
+ transformFunction: null
79
+ }
80
+ },
81
+ host: {
82
+ listeners: {
83
+ "mouseenter": "onHover(true)",
84
+ "mouseleave": "onHover(false)",
85
+ "focusin": "onFocus(true)",
86
+ "focusout": "onFocus(false)",
87
+ "click": "onClick()"
88
+ },
89
+ classAttribute: "inline-flex size-fit"
90
+ },
91
+ viewQueries: [{
92
+ propertyName: "content",
93
+ first: true,
94
+ predicate: ["content"],
95
+ descendants: true,
96
+ read: ElementRef,
97
+ isSignal: true
98
+ }],
99
+ exportAs: ["uiTooltip"],
100
+ ngImport: i0,
101
+ template: "<ui-overlay\n [isOpen]=\"isOpen()\"\n [closeBehaviour]=\"closeBehaviour()\"\n [content]=\"content()\"\n [anchor]=\"anchor\"\n [placement]=\"placement()\"\n>\n <ng-content />\n\n @if (isOpen()()) {\n <div #content class=\"p-1.5\" style=\"position: fixed; z-index: 60\">\n <div role=\"tooltip\" [class]=\"generatedClasses()\">{{ text() }}</div>\n </div>\n }\n</ui-overlay>\n",
102
+ styles: ["@layer properties;.ui-tooltip{max-width:var(--container-xs, 20rem);border-radius:var(--radius-md, .375rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--tooltip-line);background-color:var(--tooltip);padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:var(--spacing, .25rem);color:var(--tooltip-foreground);--tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(0 0 0 / .05));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"],
103
+ dependencies: [{
104
+ kind: "component",
105
+ type: UiOverlayComponent,
106
+ selector: "ui-overlay",
107
+ inputs: [
108
+ "content",
109
+ "anchor",
110
+ "closeBehaviour",
111
+ "isOpen",
112
+ "placement",
113
+ "offset",
114
+ "viewportPadding",
115
+ "matchWidth"
116
+ ],
117
+ exportAs: ["uiOverlay"]
118
+ }]
119
+ });
120
+ };
121
+ i0.ɵɵngDeclareClassMetadata({
122
+ minVersion: "12.0.0",
123
+ version: "22.2.1",
124
+ ngImport: i0,
125
+ type: UiTooltipComponent,
126
+ decorators: [{
127
+ type: Component,
128
+ args: [{
129
+ selector: "ui-tooltip",
130
+ exportAs: "uiTooltip",
131
+ imports: [UiOverlayComponent],
132
+ host: {
133
+ class: "inline-flex size-fit",
134
+ "(mouseenter)": "onHover(true)",
135
+ "(mouseleave)": "onHover(false)",
136
+ "(focusin)": "onFocus(true)",
137
+ "(focusout)": "onFocus(false)",
138
+ "(click)": "onClick()"
139
+ },
140
+ template: "<ui-overlay\n [isOpen]=\"isOpen()\"\n [closeBehaviour]=\"closeBehaviour()\"\n [content]=\"content()\"\n [anchor]=\"anchor\"\n [placement]=\"placement()\"\n>\n <ng-content />\n\n @if (isOpen()()) {\n <div #content class=\"p-1.5\" style=\"position: fixed; z-index: 60\">\n <div role=\"tooltip\" [class]=\"generatedClasses()\">{{ text() }}</div>\n </div>\n }\n</ui-overlay>\n",
141
+ styles: ["@layer properties;.ui-tooltip{max-width:var(--container-xs, 20rem);border-radius:var(--radius-md, .375rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--tooltip-line);background-color:var(--tooltip);padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:var(--spacing, .25rem);color:var(--tooltip-foreground);--tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(0 0 0 / .05));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"]
142
+ }]
143
+ }],
144
+ propDecorators: {
145
+ content: [{
146
+ type: i0.ViewChild,
147
+ args: ["content", {
148
+ read: ElementRef,
149
+ isSignal: true
150
+ }]
151
+ }],
152
+ text: [{
153
+ type: i0.Input,
154
+ args: [{
155
+ isSignal: true,
156
+ alias: "text",
157
+ required: true
158
+ }]
159
+ }],
160
+ placement: [{
161
+ type: i0.Input,
162
+ args: [{
163
+ isSignal: true,
164
+ alias: "placement",
165
+ required: false
166
+ }]
167
+ }],
168
+ trigger: [{
169
+ type: i0.Input,
170
+ args: [{
171
+ isSignal: true,
172
+ alias: "trigger",
173
+ required: false
174
+ }]
175
+ }],
176
+ classes: [{
177
+ type: i0.Input,
178
+ args: [{
179
+ isSignal: true,
180
+ alias: "classes",
181
+ required: false
182
+ }]
183
+ }],
184
+ isOpen: [{
185
+ type: i0.Input,
186
+ args: [{
187
+ isSignal: true,
188
+ alias: "isOpen",
189
+ required: false
190
+ }]
191
+ }]
192
+ }
193
+ });
194
+ export { UiTooltipComponent };
195
+
196
+ //# sourceMappingURL=area8975-ui-tooltip.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"area8975-ui-tooltip.mjs","names":[],"sources":["../../../projects/ui/tooltip/tooltip.component.ts","../../../projects/ui/tooltip/tooltip.component.html"],"sourcesContent":["import {\n Component,\n computed,\n ElementRef,\n inject,\n input,\n signal,\n viewChild,\n WritableSignal\n} from '@angular/core';\n\nimport { UiOverlayComponent } from '@area8975/ui/overlay';\nimport { UiOverlayCloseBehaviour } from '@area8975/ui/overlay';\nimport { Placement } from '@floating-ui/dom';\n\nimport { UiTooltipTrigger } from './tooltip.types';\n\n\n@Component({\n selector: 'ui-tooltip',\n exportAs: 'uiTooltip',\n templateUrl: './tooltip.component.html',\n styleUrl: './tooltip.component.css',\n imports: [UiOverlayComponent],\n host: {\n class: 'inline-flex size-fit',\n '(mouseenter)': 'onHover(true)',\n '(mouseleave)': 'onHover(false)',\n '(focusin)': 'onFocus(true)',\n '(focusout)': 'onFocus(false)',\n '(click)': 'onClick()'\n }\n})\nexport class UiTooltipComponent {\n protected readonly anchor = inject(ElementRef<HTMLElement>);\n protected readonly content = viewChild('content', { read: ElementRef });\n\n readonly text = input.required<string>();\n readonly placement = input<Placement>('top');\n readonly trigger = input<UiTooltipTrigger>('hover');\n readonly classes = input<string>('');\n\n readonly isOpen = input<WritableSignal<boolean>>(signal(false));\n\n protected readonly closeBehaviour = computed<UiOverlayCloseBehaviour>(() =>\n this.trigger() === 'click'\n ? 'whenClickOutside'\n : 'none'\n );\n\n protected readonly generatedClasses = computed(() =>\n ['ui-tooltip', 'ui-text-caption', this.classes()]\n .filter(Boolean)\n .join(' ')\n );\n\n protected onHover(isHovering: boolean) {\n if (this.trigger() === 'hover') {\n this.isOpen().set(isHovering);\n }\n }\n\n // Hover also listens to focus so keyboard users still get the tooltip\n protected onFocus(isFocused: boolean) {\n if (['hover', 'focus'].includes(this.trigger())) {\n this.isOpen().set(isFocused);\n }\n }\n\n protected onClick() {\n if (this.trigger() === 'click') {\n this.isOpen().update(value => !value);\n }\n }\n}\n","<ui-overlay\n [isOpen]=\"isOpen()\"\n [closeBehaviour]=\"closeBehaviour()\"\n [content]=\"content()\"\n [anchor]=\"anchor\"\n [placement]=\"placement()\"\n>\n <ng-content />\n\n @if (isOpen()()) {\n <div #content class=\"p-1.5\" style=\"position: fixed; z-index: 60\">\n <div role=\"tooltip\" [class]=\"generatedClasses()\">{{ text() }}</div>\n </div>\n }\n</ui-overlay>\n"],"mappings":";;;AAiCA,IAAa,qBAAb,MAAa,mBAAkB;CACR,SAAS,OAAO,UAAuB;CACvC,UAAU,UAAU,WAAS;EAAA,GAAA,YAAA,EAAA,WAAA,UAAA,+BAAA,CAAA;EAAI,MAAM;CAAU,CAAA;CAE3D,OAAO,MAAM,SAAkB,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;CAC/B,YAAY,MAAiB,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CACnC,UAAU,MAAwB,SAAQ,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CAC1C,UAAU,MAAc,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CAE3B,SAAS,MAA+B,OAAO,KAAK,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;CAE5C,iBAAiB,eAChC,KAAK,QAAO,MAAO,UACb,qBACA,QACT,GAAA,YAAA,CAAA,EAAA,WAAA,iBAAA,CAAA,+BAAA,CAAA,CAAA;CAEkB,mBAAmB,eAClC;EAAC;EAAc;EAAmB,KAAK,QAAO;CAAE,CAAC,CAC5C,OAAO,OAAO,CAAC,CACf,KAAK,GAAG,GAChB,GAAA,YAAA,CAAA,EAAA,WAAA,mBAAA,CAAA,+BAAA,CAAA,CAAA;CAES,QAAQ,YAAmB;EACjC,IAAI,KAAK,QAAO,MAAO,SACnB,KAAK,OAAM,CAAE,CAAC,IAAI,UAAU;CAEpC;CAGU,QAAQ,WAAkB;EAChC,IAAI,CAAC,SAAS,OAAO,CAAC,CAAC,SAAS,KAAK,QAAO,CAAE,GAC1C,KAAK,OAAM,CAAE,CAAC,IAAI,SAAS;CAEnC;CAEU,UAAO;EACb,IAAI,KAAK,QAAO,MAAO,SACnB,KAAK,OAAM,CAAE,CAAC,QAAO,UAAS,CAAC,KAAK;CAE5C;CAxCS,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAkB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAlB,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAkB,cAAA;EAAA,UAAA;EAAA,QAAA;GAAA,MAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,WAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,SAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,SAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,QAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;EAAA;EAAA,MAAA;GAAA,WAAA;IAAA,cAAA;IAAA,cAAA;IAAA,WAAA;IAAA,YAAA;IAAA,SAAA;GAAA;GAAA,gBAAA;EAAA;EAAA,aAAA,CAAA;GAAA,cAAA;GAAA,OAAA;GAAA,WAAA,CAAA,SAAA;GAAA,aAAA;GAAA,MAE+B;GAAU,UAAA;EAAA,CAAA;EAAA,UAAA,CAAA,WAAA;EAAA,UAAA;EAAA,UCnCxE;EAeA,QAAA,CAAA,s2EAAA;EAAA,cAAA,CAAA;GAAA,MAAA;GAAA,MDQc;GAAkB,UAAA;GAAA,QAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;GAAA;GAAA,UAAA,CAAA,WAAA;EAAA,CAAA;CAAA,CAAA;;AAUnB,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAkB,YAAA,CAAA;EAf9B,MAAA;EACa,MAAA,CAAA;GAAA,UAAA;GAAY,UACZ;GAAW,SAGZ,CAAC,kBAAkB;GAAC,MACvB;IACF,OAAO;IACP,gBAAgB;IAChB,gBAAgB;IAChB,aAAa;IACb,cAAc;IACd,WAAW;GACd;GAAA,UAAA;GAAA,QAAA,CAAA,s2EAAA;EAAA,CAAA;CAIsC,CAAA;CAAA,gBAAA;EAAA,SAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA,WAAS;IAAI,MAAM;IAAY,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,MAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,WAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,SAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,SAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,QAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;CAAA;AAAA,CAAA"}