@nanahoshi/mona-ui 0.1.0

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 (134) hide show
  1. package/README.md +25 -0
  2. package/fesm2022/nanahoshi-mona-ui-auto-complete.mjs +590 -0
  3. package/fesm2022/nanahoshi-mona-ui-avatar.mjs +168 -0
  4. package/fesm2022/nanahoshi-mona-ui-breadcrumb.mjs +220 -0
  5. package/fesm2022/nanahoshi-mona-ui-button-group.mjs +225 -0
  6. package/fesm2022/nanahoshi-mona-ui-button.mjs +497 -0
  7. package/fesm2022/nanahoshi-mona-ui-calendar.mjs +1569 -0
  8. package/fesm2022/nanahoshi-mona-ui-check-box.mjs +339 -0
  9. package/fesm2022/nanahoshi-mona-ui-chip.mjs +453 -0
  10. package/fesm2022/nanahoshi-mona-ui-circular-progress-bar.mjs +200 -0
  11. package/fesm2022/nanahoshi-mona-ui-color-gradient.mjs +853 -0
  12. package/fesm2022/nanahoshi-mona-ui-color-palette.mjs +923 -0
  13. package/fesm2022/nanahoshi-mona-ui-color-picker.mjs +495 -0
  14. package/fesm2022/nanahoshi-mona-ui-combo-box.mjs +686 -0
  15. package/fesm2022/nanahoshi-mona-ui-common.mjs +642 -0
  16. package/fesm2022/nanahoshi-mona-ui-contextmenu.mjs +485 -0
  17. package/fesm2022/nanahoshi-mona-ui-date-input.mjs +132 -0
  18. package/fesm2022/nanahoshi-mona-ui-date-picker.mjs +460 -0
  19. package/fesm2022/nanahoshi-mona-ui-datetime-picker.mjs +659 -0
  20. package/fesm2022/nanahoshi-mona-ui-dialog.mjs +828 -0
  21. package/fesm2022/nanahoshi-mona-ui-dropdown-button.mjs +523 -0
  22. package/fesm2022/nanahoshi-mona-ui-dropdown-list.mjs +615 -0
  23. package/fesm2022/nanahoshi-mona-ui-dropdowns.mjs +701 -0
  24. package/fesm2022/nanahoshi-mona-ui-editor.mjs +1400 -0
  25. package/fesm2022/nanahoshi-mona-ui-expansion-panel.mjs +245 -0
  26. package/fesm2022/nanahoshi-mona-ui-fieldset.mjs +170 -0
  27. package/fesm2022/nanahoshi-mona-ui-filter.mjs +680 -0
  28. package/fesm2022/nanahoshi-mona-ui-grid-grid-footer-cell.component-B9SQH5N-.mjs +105 -0
  29. package/fesm2022/nanahoshi-mona-ui-grid-grid-footer-table-cell.directive-DlLwcCFT.mjs +42 -0
  30. package/fesm2022/nanahoshi-mona-ui-grid-grid-list.component-Dgea-O0X.mjs +130 -0
  31. package/fesm2022/nanahoshi-mona-ui-grid-grid-toggle.component-DIUutx9s.mjs +773 -0
  32. package/fesm2022/nanahoshi-mona-ui-grid-grid-virtual-list.component-DRHycGIh.mjs +240 -0
  33. package/fesm2022/nanahoshi-mona-ui-grid-nanahoshi-mona-ui-grid-C3eZIaJK.mjs +5374 -0
  34. package/fesm2022/nanahoshi-mona-ui-grid.mjs +2 -0
  35. package/fesm2022/nanahoshi-mona-ui-internal-filter-input.mjs +87 -0
  36. package/fesm2022/nanahoshi-mona-ui-internal-indicator-icon.mjs +154 -0
  37. package/fesm2022/nanahoshi-mona-ui-internal-list.mjs +1356 -0
  38. package/fesm2022/nanahoshi-mona-ui-internal-tree.mjs +2263 -0
  39. package/fesm2022/nanahoshi-mona-ui-internal.mjs +379 -0
  40. package/fesm2022/nanahoshi-mona-ui-list-box.mjs +630 -0
  41. package/fesm2022/nanahoshi-mona-ui-list-view.mjs +527 -0
  42. package/fesm2022/nanahoshi-mona-ui-list.mjs +4 -0
  43. package/fesm2022/nanahoshi-mona-ui-menubar.mjs +966 -0
  44. package/fesm2022/nanahoshi-mona-ui-multi-select.mjs +641 -0
  45. package/fesm2022/nanahoshi-mona-ui-notification.mjs +536 -0
  46. package/fesm2022/nanahoshi-mona-ui-numeric-text-box.mjs +597 -0
  47. package/fesm2022/nanahoshi-mona-ui-pager.mjs +790 -0
  48. package/fesm2022/nanahoshi-mona-ui-placeholder.mjs +83 -0
  49. package/fesm2022/nanahoshi-mona-ui-popover.mjs +325 -0
  50. package/fesm2022/nanahoshi-mona-ui-popup-menu.mjs +1559 -0
  51. package/fesm2022/nanahoshi-mona-ui-popup.mjs +1321 -0
  52. package/fesm2022/nanahoshi-mona-ui-progress-bar.mjs +294 -0
  53. package/fesm2022/nanahoshi-mona-ui-query.mjs +175 -0
  54. package/fesm2022/nanahoshi-mona-ui-radio-button.mjs +339 -0
  55. package/fesm2022/nanahoshi-mona-ui-scroll-view.mjs +565 -0
  56. package/fesm2022/nanahoshi-mona-ui-slider.mjs +1049 -0
  57. package/fesm2022/nanahoshi-mona-ui-split-button.mjs +636 -0
  58. package/fesm2022/nanahoshi-mona-ui-splitter.mjs +843 -0
  59. package/fesm2022/nanahoshi-mona-ui-stepper.mjs +537 -0
  60. package/fesm2022/nanahoshi-mona-ui-switch.mjs +308 -0
  61. package/fesm2022/nanahoshi-mona-ui-tabs.mjs +664 -0
  62. package/fesm2022/nanahoshi-mona-ui-text-area.mjs +111 -0
  63. package/fesm2022/nanahoshi-mona-ui-text-box.mjs +369 -0
  64. package/fesm2022/nanahoshi-mona-ui-theme.mjs +314 -0
  65. package/fesm2022/nanahoshi-mona-ui-time-picker.mjs +450 -0
  66. package/fesm2022/nanahoshi-mona-ui-time-selector.mjs +723 -0
  67. package/fesm2022/nanahoshi-mona-ui-tooltip.mjs +716 -0
  68. package/fesm2022/nanahoshi-mona-ui-tree-view.mjs +733 -0
  69. package/fesm2022/nanahoshi-mona-ui-window.mjs +1329 -0
  70. package/fesm2022/nanahoshi-mona-ui.mjs +9 -0
  71. package/package.json +289 -0
  72. package/types/nanahoshi-mona-ui-auto-complete.d.ts +223 -0
  73. package/types/nanahoshi-mona-ui-avatar.d.ts +642 -0
  74. package/types/nanahoshi-mona-ui-breadcrumb.d.ts +70 -0
  75. package/types/nanahoshi-mona-ui-button-group.d.ts +77 -0
  76. package/types/nanahoshi-mona-ui-button.d.ts +111 -0
  77. package/types/nanahoshi-mona-ui-calendar.d.ts +262 -0
  78. package/types/nanahoshi-mona-ui-check-box.d.ts +133 -0
  79. package/types/nanahoshi-mona-ui-chip.d.ts +130 -0
  80. package/types/nanahoshi-mona-ui-circular-progress-bar.d.ts +113 -0
  81. package/types/nanahoshi-mona-ui-color-gradient.d.ts +201 -0
  82. package/types/nanahoshi-mona-ui-color-palette.d.ts +102 -0
  83. package/types/nanahoshi-mona-ui-color-picker.d.ts +156 -0
  84. package/types/nanahoshi-mona-ui-combo-box.d.ts +232 -0
  85. package/types/nanahoshi-mona-ui-common.d.ts +386 -0
  86. package/types/nanahoshi-mona-ui-contextmenu.d.ts +129 -0
  87. package/types/nanahoshi-mona-ui-date-input.d.ts +60 -0
  88. package/types/nanahoshi-mona-ui-date-picker.d.ts +177 -0
  89. package/types/nanahoshi-mona-ui-datetime-picker.d.ts +199 -0
  90. package/types/nanahoshi-mona-ui-dialog.d.ts +261 -0
  91. package/types/nanahoshi-mona-ui-dropdown-button.d.ts +159 -0
  92. package/types/nanahoshi-mona-ui-dropdown-list.d.ts +219 -0
  93. package/types/nanahoshi-mona-ui-dropdowns.d.ts +176 -0
  94. package/types/nanahoshi-mona-ui-editor.d.ts +113 -0
  95. package/types/nanahoshi-mona-ui-expansion-panel.d.ts +87 -0
  96. package/types/nanahoshi-mona-ui-fieldset.d.ts +68 -0
  97. package/types/nanahoshi-mona-ui-filter.d.ts +115 -0
  98. package/types/nanahoshi-mona-ui-grid.d.ts +1114 -0
  99. package/types/nanahoshi-mona-ui-internal-filter-input.d.ts +25 -0
  100. package/types/nanahoshi-mona-ui-internal-indicator-icon.d.ts +28 -0
  101. package/types/nanahoshi-mona-ui-internal-list.d.ts +269 -0
  102. package/types/nanahoshi-mona-ui-internal-tree.d.ts +391 -0
  103. package/types/nanahoshi-mona-ui-internal.d.ts +136 -0
  104. package/types/nanahoshi-mona-ui-list-box.d.ts +225 -0
  105. package/types/nanahoshi-mona-ui-list-view.d.ts +188 -0
  106. package/types/nanahoshi-mona-ui-list.d.ts +1 -0
  107. package/types/nanahoshi-mona-ui-menubar.d.ts +198 -0
  108. package/types/nanahoshi-mona-ui-multi-select.d.ts +247 -0
  109. package/types/nanahoshi-mona-ui-notification.d.ts +106 -0
  110. package/types/nanahoshi-mona-ui-numeric-text-box.d.ts +161 -0
  111. package/types/nanahoshi-mona-ui-pager.d.ts +238 -0
  112. package/types/nanahoshi-mona-ui-placeholder.d.ts +35 -0
  113. package/types/nanahoshi-mona-ui-popover.d.ts +130 -0
  114. package/types/nanahoshi-mona-ui-popup-menu.d.ts +412 -0
  115. package/types/nanahoshi-mona-ui-popup.d.ts +485 -0
  116. package/types/nanahoshi-mona-ui-progress-bar.d.ts +139 -0
  117. package/types/nanahoshi-mona-ui-query.d.ts +89 -0
  118. package/types/nanahoshi-mona-ui-radio-button.d.ts +128 -0
  119. package/types/nanahoshi-mona-ui-scroll-view.d.ts +166 -0
  120. package/types/nanahoshi-mona-ui-slider.d.ts +305 -0
  121. package/types/nanahoshi-mona-ui-split-button.d.ts +182 -0
  122. package/types/nanahoshi-mona-ui-splitter.d.ts +70 -0
  123. package/types/nanahoshi-mona-ui-stepper.d.ts +173 -0
  124. package/types/nanahoshi-mona-ui-switch.d.ts +125 -0
  125. package/types/nanahoshi-mona-ui-tabs.d.ts +158 -0
  126. package/types/nanahoshi-mona-ui-text-area.d.ts +42 -0
  127. package/types/nanahoshi-mona-ui-text-box.d.ts +164 -0
  128. package/types/nanahoshi-mona-ui-theme.d.ts +23 -0
  129. package/types/nanahoshi-mona-ui-time-picker.d.ts +184 -0
  130. package/types/nanahoshi-mona-ui-time-selector.d.ts +143 -0
  131. package/types/nanahoshi-mona-ui-tooltip.d.ts +130 -0
  132. package/types/nanahoshi-mona-ui-tree-view.d.ts +274 -0
  133. package/types/nanahoshi-mona-ui-window.d.ts +295 -0
  134. package/types/nanahoshi-mona-ui.d.ts +2 -0
@@ -0,0 +1,495 @@
1
+ import { NgTemplateOutlet } from '@angular/common';
2
+ import * as i0 from '@angular/core';
3
+ import { Directive, inject, DestroyRef, ElementRef, signal, computed, viewChild, contentChild, TemplateRef, input, output, model, Component } from '@angular/core';
4
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
5
+ import * as i1 from '@fortawesome/angular-fontawesome';
6
+ import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
7
+ import { faTimes, faChevronDown } from '@fortawesome/free-solid-svg-icons';
8
+ import { take, fromEvent, takeUntil } from 'rxjs';
9
+ import { ButtonDirective } from '@nanahoshi/mona-ui/button';
10
+ import { PopupService, dropdownPopupAnimation } from '@nanahoshi/mona-ui/popup';
11
+ import { ThemeService } from '@nanahoshi/mona-ui/theme';
12
+ import { createElementControlId } from '@nanahoshi/mona-ui/internal';
13
+ import { ColorGradientComponent } from '@nanahoshi/mona-ui/color-gradient';
14
+ import { ColorPaletteComponent } from '@nanahoshi/mona-ui/color-palette';
15
+ import { cva } from 'class-variance-authority';
16
+
17
+ class ColorPickerValueTemplateDirective {
18
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: ColorPickerValueTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
19
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.6", type: ColorPickerValueTemplateDirective, isStandalone: true, selector: "ng-template[monaColorPickerValueTemplate]", ngImport: i0 }); }
20
+ }
21
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: ColorPickerValueTemplateDirective, decorators: [{
22
+ type: Directive,
23
+ args: [{
24
+ selector: "ng-template[monaColorPickerValueTemplate]"
25
+ }]
26
+ }] });
27
+
28
+ const colorPickerBaseVariants = cva(`
29
+ flex items-center
30
+ border border-input-border
31
+ bg-background outline-none
32
+ shadow-xs
33
+ cursor-pointer
34
+
35
+ hover:bg-accent hover:text-accent-foreground
36
+
37
+ transition-[color,box-shadow,border] ease-in-out duration-300
38
+
39
+ data-[disabled='true']:pointer-events-none
40
+ data-[disabled='true']:cursor-not-allowed
41
+ data-[disabled='true']:opacity-50
42
+ data-[readonly='true']:cursor-default
43
+ data-[invalid='true']:border-error
44
+ data-[invalid='true']:ring-1
45
+ data-[invalid='true']:ring-error
46
+
47
+ focus-within:ring-1 focus-within:ring-primary/40
48
+
49
+ [&.ng-touched.ng-invalid]:border-error
50
+ `, {
51
+ variants: {
52
+ expanded: {
53
+ true: "ring-1 ring-primary/40"
54
+ },
55
+ rounded: {
56
+ none: "rounded-none",
57
+ small: "rounded-sm",
58
+ medium: "rounded-md",
59
+ large: "rounded-lg",
60
+ full: "rounded-full"
61
+ },
62
+ size: {
63
+ large: "h-10 text-md",
64
+ medium: "h-9 text-sm",
65
+ small: "h-8 text-xs"
66
+ }
67
+ }
68
+ });
69
+ const colorPickerColorVariants = cva(`
70
+ flex items-center justify-center
71
+ mx-1
72
+ `, {
73
+ variants: {
74
+ rounded: {
75
+ none: "rounded-none",
76
+ small: "rounded-sm",
77
+ medium: "rounded-md",
78
+ large: "rounded-lg",
79
+ full: "rounded-full"
80
+ },
81
+ size: {
82
+ large: "w-6 h-6 mx-2",
83
+ medium: "w-5 h-5 mx-2",
84
+ small: "w-4 h-4 mx-1"
85
+ }
86
+ }
87
+ });
88
+
89
+ const colorPickerBaseThemeVariants = (theme) => {
90
+ switch (theme) {
91
+ case "mona":
92
+ return colorPickerBaseVariants;
93
+ default:
94
+ return colorPickerBaseVariants;
95
+ }
96
+ };
97
+ const colorPickerColorThemeVariants = (theme) => {
98
+ switch (theme) {
99
+ case "mona":
100
+ return colorPickerColorVariants;
101
+ default:
102
+ return colorPickerColorVariants;
103
+ }
104
+ };
105
+
106
+ class ColorPickerComponent {
107
+ constructor() {
108
+ this.#destroyRef = inject(DestroyRef);
109
+ this.#hostElementRef = inject(ElementRef);
110
+ this.#popupService = inject(PopupService);
111
+ this.#popupRef = signal(null, /* @ts-ignore */
112
+ ...(ngDevMode ? [{ debugName: "#popupRef" }] : /* istanbul ignore next */ []));
113
+ this.#themeService = inject(ThemeService);
114
+ this.baseClasses = computed(() => {
115
+ const theme = this.#themeService.theme();
116
+ const expanded = this.expanded();
117
+ const rounded = this.rounded();
118
+ const size = this.size();
119
+ return colorPickerBaseThemeVariants(theme)({ expanded, rounded, size });
120
+ }, /* @ts-ignore */
121
+ ...(ngDevMode ? [{ debugName: "baseClasses" }] : /* istanbul ignore next */ []));
122
+ this.colorClasses = computed(() => {
123
+ const theme = this.#themeService.theme();
124
+ const rounded = this.rounded();
125
+ const size = this.size();
126
+ return colorPickerColorThemeVariants(theme)({ rounded, size });
127
+ }, /* @ts-ignore */
128
+ ...(ngDevMode ? [{ debugName: "colorClasses" }] : /* istanbul ignore next */ []));
129
+ this.expanded = computed(() => this.#popupRef() !== null, /* @ts-ignore */
130
+ ...(ngDevMode ? [{ debugName: "expanded" }] : /* istanbul ignore next */ []));
131
+ this.invalidState = computed(() => this.invalid() || (this.required() && this.touched() && !this.value()), /* @ts-ignore */
132
+ ...(ngDevMode ? [{ debugName: "invalidState" }] : /* istanbul ignore next */ []));
133
+ this.noColorIcon = faTimes;
134
+ this.dropdownIcon = faChevronDown;
135
+ this.popupId = createElementControlId();
136
+ this.popupTemplate = viewChild.required("popupTemplate", /* @ts-ignore */
137
+ ...(ngDevMode ? [{ debugName: "popupTemplate" }] : /* istanbul ignore next */ []));
138
+ this.valueTemplate = contentChild(ColorPickerValueTemplateDirective, { ...(ngDevMode ? { debugName: "valueTemplate" } : /* istanbul ignore next */ {}), read: TemplateRef });
139
+ /**
140
+ * @description Whether to close the color picker when a color is selected.
141
+ * Only applies when the view is set to "palette".
142
+ * @default true
143
+ */
144
+ this.closeOnSelect = input(true, /* @ts-ignore */
145
+ ...(ngDevMode ? [{ debugName: "closeOnSelect" }] : /* istanbul ignore next */ []));
146
+ /**
147
+ * @description The number of columns to display in the color palette.
148
+ * Only applies when the view is set to "palette" and the palette is a custom array of colors.
149
+ * @default 10
150
+ */
151
+ this.columns = input(10, /* @ts-ignore */
152
+ ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
153
+ /**
154
+ * @description Renders the component with reduced visual emphasis and removes pointer interaction.
155
+ * @default false
156
+ */
157
+ this.disabled = input(false, /* @ts-ignore */
158
+ ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
159
+ /**
160
+ * @description Marks the color picker as invalid. When bound to a signal form field via `[formField]`,
161
+ * this is written by the `FormField` directive.
162
+ * @default false
163
+ */
164
+ this.invalid = input(false, /* @ts-ignore */
165
+ ...(ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []));
166
+ /**
167
+ * @description Whether to display the opacity slider.
168
+ * Only applies when the view is set to "gradient".
169
+ * @default true
170
+ */
171
+ this.opacity = input(true, /* @ts-ignore */
172
+ ...(ngDevMode ? [{ debugName: "opacity" }] : /* istanbul ignore next */ []));
173
+ /**
174
+ * @description The type of color palette to use.
175
+ * This can be a predefined palette type like "flat", "material", or "websafe",
176
+ * or a custom iterable of colors.
177
+ * @default "flat"
178
+ */
179
+ this.palette = input("flat", /* @ts-ignore */
180
+ ...(ngDevMode ? [{ debugName: "palette" }] : /* istanbul ignore next */ []));
181
+ /**
182
+ * @description Prevents value changes while preserving the component's visual state. When bound to a signal
183
+ * form field via `[formField]`, this is written by the `FormField` directive.
184
+ * @default false
185
+ */
186
+ this.readonly = input(false, /* @ts-ignore */
187
+ ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
188
+ /**
189
+ * @description Border-radius preset applied to the color picker.
190
+ * @default "medium"
191
+ */
192
+ this.rounded = input("medium", /* @ts-ignore */
193
+ ...(ngDevMode ? [{ debugName: "rounded" }] : /* istanbul ignore next */ []));
194
+ /**
195
+ * @description Whether to show the clear button to reset the color.
196
+ * This is only applicable when the view is set to "palette".
197
+ * @default false
198
+ */
199
+ this.showClearButton = input(false, /* @ts-ignore */
200
+ ...(ngDevMode ? [{ debugName: "showClearButton" }] : /* istanbul ignore next */ []));
201
+ /**
202
+ * @description Size preset controlling the color picker's dimensions.
203
+ * @default "medium"
204
+ */
205
+ this.size = input("medium", /* @ts-ignore */
206
+ ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
207
+ /**
208
+ * @description The view mode of the color picker.
209
+ * This can be either "palette" or "gradient".
210
+ * @default "gradient"
211
+ */
212
+ this.view = input("gradient", /* @ts-ignore */
213
+ ...(ngDevMode ? [{ debugName: "view" }] : /* istanbul ignore next */ []));
214
+ /**
215
+ * @description Sets whether the color picker is required. When bound to a signal form field via `[formField]`,
216
+ * this is written by the `FormField` directive.
217
+ * @default false
218
+ */
219
+ this.required = input(false, /* @ts-ignore */
220
+ ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
221
+ /**
222
+ * @description Emitted when the color picker is interacted with on blur or color selection.
223
+ * The `FormField` directive listens to this to mark the field as touched.
224
+ */
225
+ this.touch = output();
226
+ /**
227
+ * @description Sets the touched state of the color picker. When bound to a signal form field via `[formField]`,
228
+ * this is written by the `FormField` directive.
229
+ * @default false
230
+ */
231
+ this.touched = input(false, /* @ts-ignore */
232
+ ...(ngDevMode ? [{ debugName: "touched" }] : /* istanbul ignore next */ []));
233
+ /**
234
+ * @description Two-way bindable current color value.
235
+ * @default null
236
+ */
237
+ this.value = model(null, /* @ts-ignore */
238
+ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
239
+ }
240
+ #destroyRef;
241
+ #hostElementRef;
242
+ #popupService;
243
+ #popupRef;
244
+ #themeService;
245
+ ngOnInit() {
246
+ this.setEventListeners();
247
+ this.setKeyboardEventListeners();
248
+ }
249
+ onClearClick() {
250
+ if (this.disabled() || this.readonly()) {
251
+ return;
252
+ }
253
+ this.value.set(null);
254
+ this.touch.emit();
255
+ if (this.#popupRef() && this.closeOnSelect()) {
256
+ this.close();
257
+ }
258
+ }
259
+ onColorGradientApply() {
260
+ this.#popupRef()?.close();
261
+ }
262
+ onColorGradientCancel() {
263
+ this.#popupRef()?.close();
264
+ }
265
+ onColorGradientValueChange(value) {
266
+ if (value === undefined) {
267
+ return;
268
+ }
269
+ if (this.disabled() || this.readonly()) {
270
+ return;
271
+ }
272
+ this.value.set(value);
273
+ }
274
+ onColorGradientTouch() {
275
+ this.touch.emit();
276
+ }
277
+ onColorPaletteValueChange(value) {
278
+ if (this.disabled() || this.readonly()) {
279
+ return;
280
+ }
281
+ this.value.set(value);
282
+ if (this.closeOnSelect()) {
283
+ this.#popupRef()?.close();
284
+ }
285
+ }
286
+ onColorPaletteTouch() {
287
+ this.touch.emit();
288
+ }
289
+ onPaletteContainerKeyDown(event) {
290
+ switch (event.key) {
291
+ case "ArrowDown":
292
+ case "ArrowRight":
293
+ case "ArrowUp":
294
+ case "ArrowLeft":
295
+ case "Enter":
296
+ case " ":
297
+ case "Home":
298
+ case "End":
299
+ // Focus on the first color tile when the user starts navigating
300
+ event.preventDefault();
301
+ event.stopPropagation();
302
+ this.focusFirstColorTile();
303
+ break;
304
+ case "Escape":
305
+ event.preventDefault();
306
+ event.stopPropagation();
307
+ this.close();
308
+ break;
309
+ case "Tab":
310
+ // Close popup when tabbing out
311
+ this.close();
312
+ break;
313
+ }
314
+ }
315
+ open() {
316
+ if (this.disabled() || this.readonly()) {
317
+ return;
318
+ }
319
+ const popupRef = this.#popupService.create({
320
+ anchor: this.#hostElementRef.nativeElement,
321
+ anchorConnectionPoint: "bottomleft",
322
+ animation: dropdownPopupAnimation,
323
+ closeOnOutsideClick: true,
324
+ content: this.popupTemplate(),
325
+ hasBackdrop: false,
326
+ offset: { horizontal: -1, vertical: 2 },
327
+ popupConnectionPoint: "topleft",
328
+ withPush: false
329
+ });
330
+ popupRef.opened.pipe(take(1), takeUntilDestroyed(this.#destroyRef)).subscribe(() => {
331
+ // Deferred so this runs after the browser's default focus-on-click behavior for the
332
+ // (focusable) host element, otherwise that default action steals focus back from the popup.
333
+ setTimeout(() => {
334
+ this.focusPopupContent();
335
+ this.setupPopupKeyboardHandling();
336
+ });
337
+ });
338
+ this.#popupRef.set(popupRef);
339
+ popupRef.closed.pipe(take(1)).subscribe(() => {
340
+ this.#popupRef.set(null);
341
+ this.#hostElementRef.nativeElement.focus();
342
+ });
343
+ }
344
+ close() {
345
+ if (this.#popupRef()) {
346
+ this.#popupRef()?.close();
347
+ }
348
+ }
349
+ focusFirstColorTile() {
350
+ if (!this.#popupRef()) {
351
+ return;
352
+ }
353
+ const overlayElement = this.#popupRef()?.overlayRef.overlayElement;
354
+ if (!overlayElement) {
355
+ return;
356
+ }
357
+ const firstColorTile = overlayElement.querySelector('[data-color-index="0"]');
358
+ if (firstColorTile) {
359
+ firstColorTile.focus();
360
+ }
361
+ }
362
+ focusPopupContent() {
363
+ if (!this.#popupRef()) {
364
+ return;
365
+ }
366
+ const overlayElement = this.#popupRef()?.overlayRef.overlayElement;
367
+ if (!overlayElement) {
368
+ return;
369
+ }
370
+ if (this.view() === "palette") {
371
+ // Focus the palette container, not individual colors
372
+ const paletteContainer = overlayElement.querySelector("[data-palette-container]");
373
+ if (paletteContainer) {
374
+ paletteContainer.focus();
375
+ }
376
+ }
377
+ else if (this.view() === "gradient") {
378
+ // Focus the HSV handle in the gradient picker
379
+ const hsvHandle = overlayElement.querySelector('[role="slider"]');
380
+ if (hsvHandle) {
381
+ hsvHandle.focus();
382
+ }
383
+ }
384
+ }
385
+ setEventListeners() {
386
+ fromEvent(this.#hostElementRef.nativeElement, "click")
387
+ .pipe(takeUntilDestroyed(this.#destroyRef))
388
+ .subscribe(() => {
389
+ if (this.disabled() || this.readonly()) {
390
+ return;
391
+ }
392
+ if (this.#popupRef()) {
393
+ this.close();
394
+ return;
395
+ }
396
+ this.open();
397
+ });
398
+ }
399
+ setKeyboardEventListeners() {
400
+ fromEvent(this.#hostElementRef.nativeElement, "keydown")
401
+ .pipe(takeUntilDestroyed(this.#destroyRef))
402
+ .subscribe((event) => {
403
+ if (this.disabled() || this.readonly()) {
404
+ return;
405
+ }
406
+ switch (event.key) {
407
+ case "Enter":
408
+ case " ":
409
+ case "ArrowDown":
410
+ case "ArrowUp":
411
+ event.preventDefault();
412
+ event.stopPropagation();
413
+ if (!this.#popupRef()) {
414
+ this.open();
415
+ }
416
+ break;
417
+ case "Escape":
418
+ event.preventDefault();
419
+ event.stopPropagation();
420
+ if (this.#popupRef()) {
421
+ this.close();
422
+ }
423
+ break;
424
+ case "Tab":
425
+ if (this.#popupRef()) {
426
+ this.close();
427
+ }
428
+ break;
429
+ }
430
+ });
431
+ // Handle blur events for touched callback
432
+ fromEvent(this.#hostElementRef.nativeElement, "blur")
433
+ .pipe(takeUntilDestroyed(this.#destroyRef))
434
+ .subscribe(() => {
435
+ this.touch.emit();
436
+ });
437
+ }
438
+ setupPopupKeyboardHandling() {
439
+ const popupRef = this.#popupRef();
440
+ if (!popupRef) {
441
+ return;
442
+ }
443
+ const overlayElement = popupRef.overlayRef.overlayElement;
444
+ if (!overlayElement) {
445
+ return;
446
+ }
447
+ fromEvent(overlayElement, "keydown")
448
+ .pipe(takeUntil(popupRef.closed), takeUntilDestroyed(this.#destroyRef))
449
+ .subscribe(event => {
450
+ const keyEvent = event;
451
+ if (keyEvent.key === "Tab") {
452
+ this.close();
453
+ }
454
+ else if (keyEvent.key === "Escape") {
455
+ keyEvent.preventDefault();
456
+ keyEvent.stopPropagation();
457
+ this.close();
458
+ }
459
+ });
460
+ }
461
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: ColorPickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
462
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: ColorPickerComponent, isStandalone: true, selector: "mona-color-picker", inputs: { closeOnSelect: { classPropertyName: "closeOnSelect", publicName: "closeOnSelect", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, opacity: { classPropertyName: "opacity", publicName: "opacity", isSignal: true, isRequired: false, transformFunction: null }, palette: { classPropertyName: "palette", publicName: "palette", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, showClearButton: { classPropertyName: "showClearButton", publicName: "showClearButton", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { touch: "touch", value: "valueChange" }, host: { properties: { "class": "baseClasses()", "attr.tabindex": "disabled() ? -1 : 0", "attr.data-disabled": "disabled()", "attr.data-invalid": "invalidState() || null", "attr.data-open": "expanded() || null", "attr.data-readonly": "readonly()", "attr.data-required": "required() || null", "attr.role": "'combobox'", "attr.aria-controls": "popupId", "attr.aria-expanded": "expanded() || null", "attr.aria-haspopup": "'dialog'", "attr.aria-label": "'Color picker'", "attr.aria-disabled": "disabled()", "attr.aria-invalid": "invalidState() ? 'true' : null", "attr.aria-readonly": "readonly()", "attr.aria-required": "required()" } }, queries: [{ propertyName: "valueTemplate", first: true, predicate: ColorPickerValueTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }], viewQueries: [{ propertyName: "popupTemplate", first: true, predicate: ["popupTemplate"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (valueTemplate()) {\n <ng-container\n [ngTemplateOutlet]=\"valueTemplate() ?? null\"\n [ngTemplateOutletContext]=\"{ $implicit: value() }\"></ng-container>\n} @else {\n <div [style.background]=\"value()\" [class]=\"colorClasses()\">\n @if (!value()) {\n <fa-icon [icon]=\"noColorIcon\"></fa-icon>\n }\n </div>\n}\n<div>\n <button monaButton look=\"link\" [tabindex]=\"-1\" class=\"px-2 py-1\">\n <fa-icon [icon]=\"dropdownIcon\"></fa-icon>\n </button>\n</div>\n\n<ng-template #popupTemplate>\n @if (view() === \"palette\") {\n <div\n [id]=\"popupId\"\n class=\"flex flex-col border border-input-border bg-background shadow-lg p-0.5 outline-none\"\n tabindex=\"0\"\n role=\"dialog\"\n aria-label=\"Color palette picker\"\n data-palette-container\n (keydown)=\"onPaletteContainerKeyDown($event)\">\n @if (showClearButton()) {\n <div class=\"flex items-center justify-end p-1\">\n <button monaButton look=\"ghost\" size=\"small\" (click)=\"onClearClick()\">\n <i class=\"ri-blur-off-line\"></i>\n </button>\n </div>\n }\n <mona-color-palette\n [palette]=\"palette()\"\n [columns]=\"columns()\"\n [readonly]=\"readonly()\"\n [value]=\"value()\"\n (valueChange)=\"onColorPaletteValueChange($event)\"\n (touch)=\"onColorPaletteTouch()\"></mona-color-palette>\n </div>\n } @else if (view() === \"gradient\") {\n <div\n [id]=\"popupId\"\n class=\"border border-input-border bg-background shadow-lg\"\n tabindex=\"0\"\n role=\"dialog\"\n aria-label=\"Color gradient picker\">\n <mona-color-gradient\n [opacity]=\"opacity()\"\n [rounded]=\"rounded()\"\n [disabled]=\"disabled() || readonly()\"\n [value]=\"value()\"\n (valueChange)=\"onColorGradientValueChange($event)\"\n (touch)=\"onColorGradientTouch()\"\n (apply)=\"onColorGradientApply()\"\n (cancel)=\"onColorGradientCancel()\"></mona-color-gradient>\n </div>\n }\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: FontAwesomeModule }, { kind: "component", type: i1.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"], outputs: ["iconChange", "titleChange", "animationChange", "maskChange", "flipChange", "sizeChange", "pullChange", "borderChange", "inverseChange", "symbolChange", "rotateChange", "fixedWidthChange", "transformChange", "a11yRoleChange"] }, { kind: "directive", type: ButtonDirective, selector: "button[monaButton]", inputs: ["aria-haspopup", "disabled", "iconOnly", "loading", "look", "rounded", "selected", "size", "tabindex", "toggleable", "class"], outputs: ["disabledChange", "loadingChange", "lookChange", "selectedChange"] }, { kind: "component", type: ColorPaletteComponent, selector: "mona-color-palette", inputs: ["columns", "disabled", "invalid", "palette", "readonly", "rounded", "required", "tileSize", "touched", "value"], outputs: ["touch", "valueChange"] }, { kind: "component", type: ColorGradientComponent, selector: "mona-color-gradient", inputs: ["disabled", "format", "invalid", "opacity", "required", "rounded", "showButtons", "showHexInput", "showColorInputs", "touched", "value"], outputs: ["apply", "cancel", "touch", "valueChange"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] }); }
463
+ }
464
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: ColorPickerComponent, decorators: [{
465
+ type: Component,
466
+ args: [{ selector: "mona-color-picker", imports: [FontAwesomeModule, ButtonDirective, ColorPaletteComponent, ColorGradientComponent, NgTemplateOutlet], host: {
467
+ "[class]": "baseClasses()",
468
+ "[attr.tabindex]": "disabled() ? -1 : 0",
469
+ "[attr.data-disabled]": "disabled()",
470
+ "[attr.data-invalid]": "invalidState() || null",
471
+ "[attr.data-open]": "expanded() || null",
472
+ "[attr.data-readonly]": "readonly()",
473
+ "[attr.data-required]": "required() || null",
474
+ "[attr.role]": "'combobox'",
475
+ "[attr.aria-controls]": "popupId",
476
+ "[attr.aria-expanded]": "expanded() || null",
477
+ "[attr.aria-haspopup]": "'dialog'",
478
+ "[attr.aria-label]": "'Color picker'",
479
+ "[attr.aria-disabled]": "disabled()",
480
+ "[attr.aria-invalid]": "invalidState() ? 'true' : null",
481
+ "[attr.aria-readonly]": "readonly()",
482
+ "[attr.aria-required]": "required()"
483
+ }, template: "@if (valueTemplate()) {\n <ng-container\n [ngTemplateOutlet]=\"valueTemplate() ?? null\"\n [ngTemplateOutletContext]=\"{ $implicit: value() }\"></ng-container>\n} @else {\n <div [style.background]=\"value()\" [class]=\"colorClasses()\">\n @if (!value()) {\n <fa-icon [icon]=\"noColorIcon\"></fa-icon>\n }\n </div>\n}\n<div>\n <button monaButton look=\"link\" [tabindex]=\"-1\" class=\"px-2 py-1\">\n <fa-icon [icon]=\"dropdownIcon\"></fa-icon>\n </button>\n</div>\n\n<ng-template #popupTemplate>\n @if (view() === \"palette\") {\n <div\n [id]=\"popupId\"\n class=\"flex flex-col border border-input-border bg-background shadow-lg p-0.5 outline-none\"\n tabindex=\"0\"\n role=\"dialog\"\n aria-label=\"Color palette picker\"\n data-palette-container\n (keydown)=\"onPaletteContainerKeyDown($event)\">\n @if (showClearButton()) {\n <div class=\"flex items-center justify-end p-1\">\n <button monaButton look=\"ghost\" size=\"small\" (click)=\"onClearClick()\">\n <i class=\"ri-blur-off-line\"></i>\n </button>\n </div>\n }\n <mona-color-palette\n [palette]=\"palette()\"\n [columns]=\"columns()\"\n [readonly]=\"readonly()\"\n [value]=\"value()\"\n (valueChange)=\"onColorPaletteValueChange($event)\"\n (touch)=\"onColorPaletteTouch()\"></mona-color-palette>\n </div>\n } @else if (view() === \"gradient\") {\n <div\n [id]=\"popupId\"\n class=\"border border-input-border bg-background shadow-lg\"\n tabindex=\"0\"\n role=\"dialog\"\n aria-label=\"Color gradient picker\">\n <mona-color-gradient\n [opacity]=\"opacity()\"\n [rounded]=\"rounded()\"\n [disabled]=\"disabled() || readonly()\"\n [value]=\"value()\"\n (valueChange)=\"onColorGradientValueChange($event)\"\n (touch)=\"onColorGradientTouch()\"\n (apply)=\"onColorGradientApply()\"\n (cancel)=\"onColorGradientCancel()\"></mona-color-gradient>\n </div>\n }\n</ng-template>\n" }]
484
+ }], propDecorators: { popupTemplate: [{ type: i0.ViewChild, args: ["popupTemplate", { isSignal: true }] }], valueTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => ColorPickerValueTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], closeOnSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnSelect", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], opacity: [{ type: i0.Input, args: [{ isSignal: true, alias: "opacity", required: false }] }], palette: [{ type: i0.Input, args: [{ isSignal: true, alias: "palette", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], showClearButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showClearButton", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], touch: [{ type: i0.Output, args: ["touch"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }] } });
485
+
486
+ /*
487
+ * Public API Surface of @nanahoshi/mona-ui/color-picker
488
+ */
489
+
490
+ /**
491
+ * Generated bundle index. Do not edit.
492
+ */
493
+
494
+ export { ColorPickerComponent, ColorPickerValueTemplateDirective };
495
+ //# sourceMappingURL=nanahoshi-mona-ui-color-picker.mjs.map