@masterkeymaterial/ui 0.0.2 → 0.0.3

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 (140) hide show
  1. package/fesm2022/masterkeymaterial-ui.mjs +6457 -0
  2. package/fesm2022/masterkeymaterial-ui.mjs.map +1 -0
  3. package/package.json +14 -5
  4. package/types/masterkeymaterial-ui.d.ts +928 -0
  5. package/ng-package.json +0 -10
  6. package/src/elements/ui-button/ui-button.css +0 -229
  7. package/src/elements/ui-button/ui-button.html +0 -12
  8. package/src/elements/ui-button/ui-button.ts +0 -133
  9. package/src/elements/ui-check-box/ui-check-box.css +0 -66
  10. package/src/elements/ui-check-box/ui-check-box.html +0 -5
  11. package/src/elements/ui-check-box/ui-check-box.ts +0 -65
  12. package/src/elements/ui-chip/ui-chip.css +0 -24
  13. package/src/elements/ui-chip/ui-chip.html +0 -3
  14. package/src/elements/ui-chip/ui-chip.ts +0 -25
  15. package/src/elements/ui-drop-zone/ui-drop-zone.css +0 -91
  16. package/src/elements/ui-drop-zone/ui-drop-zone.html +0 -8
  17. package/src/elements/ui-drop-zone/ui-drop-zone.ts +0 -153
  18. package/src/elements/ui-file-list/ui-file-list.css +0 -43
  19. package/src/elements/ui-file-list/ui-file-list.html +0 -17
  20. package/src/elements/ui-file-list/ui-file-list.ts +0 -22
  21. package/src/elements/ui-list-errors/ui-list-errors.css +0 -30
  22. package/src/elements/ui-list-errors/ui-list-errors.html +0 -10
  23. package/src/elements/ui-list-errors/ui-list-errors.ts +0 -14
  24. package/src/elements/ui-loading/ui-loading.css +0 -13
  25. package/src/elements/ui-loading/ui-loading.html +0 -1
  26. package/src/elements/ui-loading/ui-loading.ts +0 -10
  27. package/src/elements/ui-menu/ui-menu.css +0 -69
  28. package/src/elements/ui-menu/ui-menu.html +0 -20
  29. package/src/elements/ui-menu/ui-menu.ts +0 -267
  30. package/src/elements/ui-procurar/ui-procurar.css +0 -48
  31. package/src/elements/ui-procurar/ui-procurar.html +0 -14
  32. package/src/elements/ui-procurar/ui-procurar.ts +0 -82
  33. package/src/elements/ui-progress/ui-progress.css +0 -0
  34. package/src/elements/ui-progress/ui-progress.html +0 -1
  35. package/src/elements/ui-progress/ui-progress.ts +0 -15
  36. package/src/elements/ui-select/ui-select.css +0 -211
  37. package/src/elements/ui-select/ui-select.html +0 -46
  38. package/src/elements/ui-select/ui-select.ts +0 -482
  39. package/src/elements/ui-slide/ui-slide.css +0 -75
  40. package/src/elements/ui-slide/ui-slide.html +0 -7
  41. package/src/elements/ui-slide/ui-slide.ts +0 -61
  42. package/src/fields/Base/BaseFieldsForm/BaseFieldsForm.component.ts +0 -113
  43. package/src/fields/Base/BaseFieldsValues/BaseFieldsValues.ts +0 -112
  44. package/src/fields/Formulario/Formulario.ts +0 -1056
  45. package/src/fields/Formulario/form-action/form-action.css +0 -98
  46. package/src/fields/Formulario/form-action/form-action.html +0 -75
  47. package/src/fields/Formulario/form-action/form-action.ts +0 -187
  48. package/src/fields/Formulario/form-controls/form-controls.css +0 -108
  49. package/src/fields/Formulario/form-controls/form-controls.html +0 -105
  50. package/src/fields/Formulario/form-controls/form-controls.ts +0 -122
  51. package/src/fields/Formulario/form-fase/form-fase.css +0 -84
  52. package/src/fields/Formulario/form-fase/form-fase.html +0 -24
  53. package/src/fields/Formulario/form-fase/form-fase.ts +0 -157
  54. package/src/fields/Formulario/form-filter/form-filter.css +0 -50
  55. package/src/fields/Formulario/form-filter/form-filter.html +0 -25
  56. package/src/fields/Formulario/form-filter/form-filter.ts +0 -53
  57. package/src/fields/Formulario/form-no-action/form-no-action.css +0 -32
  58. package/src/fields/Formulario/form-no-action/form-no-action.html +0 -12
  59. package/src/fields/Formulario/form-no-action/form-no-action.ts +0 -21
  60. package/src/fields/Formulario/formated-values/formated-values.css +0 -104
  61. package/src/fields/Formulario/formated-values/formated-values.html +0 -15
  62. package/src/fields/Formulario/formated-values/formated-values.ts +0 -186
  63. package/src/fields/Formulario/single-values/single-values.css +0 -88
  64. package/src/fields/Formulario/single-values/single-values.html +0 -11
  65. package/src/fields/Formulario/single-values/single-values.ts +0 -65
  66. package/src/fields/autocomplete/autocomplete.css +0 -94
  67. package/src/fields/autocomplete/autocomplete.html +0 -38
  68. package/src/fields/autocomplete/autocomplete.ts +0 -294
  69. package/src/fields/button/button.css +0 -7
  70. package/src/fields/button/button.html +0 -19
  71. package/src/fields/button/button.ts +0 -38
  72. package/src/fields/checkbox/checkbox.css +0 -27
  73. package/src/fields/checkbox/checkbox.html +0 -20
  74. package/src/fields/checkbox/checkbox.ts +0 -44
  75. package/src/fields/color/CirculoColorido/circulocolorido.css +0 -50
  76. package/src/fields/color/CirculoColorido/circulocolorido.html +0 -8
  77. package/src/fields/color/CirculoColorido/circulocolorido.ts +0 -24
  78. package/src/fields/color/color.css +0 -15
  79. package/src/fields/color/color.html +0 -24
  80. package/src/fields/color/color.ts +0 -47
  81. package/src/fields/date/date.html +0 -19
  82. package/src/fields/date/date.ts +0 -29
  83. package/src/fields/datetime/datetime.html +0 -19
  84. package/src/fields/datetime/datetime.ts +0 -29
  85. package/src/fields/display/display.css +0 -7
  86. package/src/fields/display/display.html +0 -20
  87. package/src/fields/display/display.ts +0 -43
  88. package/src/fields/editor/editor.css +0 -51
  89. package/src/fields/editor/editor.html +0 -37
  90. package/src/fields/editor/editor.ts +0 -218
  91. package/src/fields/email/email.html +0 -19
  92. package/src/fields/email/email.ts +0 -29
  93. package/src/fields/fields.css +0 -180
  94. package/src/fields/generic/generic.html +0 -3
  95. package/src/fields/generic/generic.ts +0 -91
  96. package/src/fields/hidden/hidden.html +0 -3
  97. package/src/fields/hidden/hidden.ts +0 -20
  98. package/src/fields/icon/icon.css +0 -19
  99. package/src/fields/icon/icon.html +0 -27
  100. package/src/fields/icon/icon.ts +0 -31
  101. package/src/fields/multifactor/multifactor.css +0 -21
  102. package/src/fields/multifactor/multifactor.html +0 -39
  103. package/src/fields/multifactor/multifactor.ts +0 -106
  104. package/src/fields/multikv/multikv.css +0 -43
  105. package/src/fields/multikv/multikv.html +0 -47
  106. package/src/fields/multikv/multikv.ts +0 -88
  107. package/src/fields/multitext/multitext.css +0 -36
  108. package/src/fields/multitext/multitext.html +0 -38
  109. package/src/fields/multitext/multitext.ts +0 -75
  110. package/src/fields/number/number.html +0 -20
  111. package/src/fields/number/number.ts +0 -35
  112. package/src/fields/password/password.html +0 -23
  113. package/src/fields/password/password.ts +0 -37
  114. package/src/fields/search/search.css +0 -0
  115. package/src/fields/search/search.html +0 -19
  116. package/src/fields/search/search.ts +0 -54
  117. package/src/fields/select/select.css +0 -15
  118. package/src/fields/select/select.html +0 -18
  119. package/src/fields/select/select.ts +0 -52
  120. package/src/fields/slide/slide.css +0 -27
  121. package/src/fields/slide/slide.html +0 -20
  122. package/src/fields/slide/slide.ts +0 -45
  123. package/src/fields/text/text.html +0 -19
  124. package/src/fields/text/text.ts +0 -30
  125. package/src/fields/textarea/textarea.css +0 -4
  126. package/src/fields/textarea/textarea.html +0 -20
  127. package/src/fields/textarea/textarea.ts +0 -31
  128. package/src/fields/time/time.html +0 -19
  129. package/src/fields/time/time.ts +0 -29
  130. package/src/fields/upload/upload.css +0 -24
  131. package/src/fields/upload/upload.html +0 -41
  132. package/src/fields/upload/upload.ts +0 -137
  133. package/src/interfaces/interfaces.ts +0 -61
  134. package/src/public-api.ts +0 -38
  135. package/src/util/ClassOf.pipe.ts +0 -11
  136. package/src/util/JsonColorido.pipe.ts +0 -11
  137. package/src/util/util.ts +0 -2151
  138. package/tsconfig.lib.json +0 -16
  139. package/tsconfig.lib.prod.json +0 -9
  140. package/tsconfig.spec.json +0 -13
@@ -1,482 +0,0 @@
1
- import { AfterViewInit, Component, computed, effect, ElementRef, HostListener, inject, input, model, OnDestroy, output, signal, viewChild } from '@angular/core';
2
- import { computePosition, flip, offset, shift, detectOverflow, Elements, autoUpdate } from '@floating-ui/dom';
3
- import { LibUtil, LOG } from '../../util/util';
4
- import { IKV } from '../../interfaces/interfaces';
5
- import { UiButton } from "../ui-button/ui-button";
6
-
7
- export interface IOptionValue {
8
- optionChanged?: IKV;
9
- keys: string | number | string[] | number[];
10
- values: string | number | string[] | number[];
11
- }
12
-
13
- interface IKVSeletor extends IKV {
14
- selected: boolean;
15
- choosing: boolean;
16
- }
17
-
18
- @Component({
19
- selector: 'ui-select',
20
- templateUrl: './ui-select.html',
21
- styleUrl: './ui-select.css',
22
- host: { '[class]': 'hostClasses()' },
23
- imports: [UiButton],
24
- })
25
- export class UiSelect implements OnDestroy, AfterViewInit {
26
-
27
- elementRef: ElementRef = inject(ElementRef);
28
-
29
- value = model<string | number | string[] | number[] | undefined>();
30
- options = input<IKV[] | undefined | null>();
31
-
32
- name = input<string | number | undefined>();
33
- placeholder = input<string>();
34
- disabled = input<boolean>();
35
- multiple = input<boolean>(false);
36
- canUnselect = input<boolean | undefined>(false);
37
- textEmpty = input<string | undefined>("Nada selecionado");
38
-
39
- changed = output<IOptionValue>();
40
-
41
- isOpenedOptions = signal(false);
42
- markedOptionKey = signal<string | number | null | undefined>(null);
43
- elementoAcima: HTMLElement | null = null;
44
- // isUnderOverflow = signal(false);
45
- isSmallScreen = signal(window.innerWidth < 500);
46
-
47
-
48
- textoFiltrado = signal<string>("");
49
-
50
- readonly optionsList = computed<IKVSeletor[]>(() => {
51
- const options = this.options?.() ?? [];
52
- if (this.multiple() !== true) {
53
- let valor = (this.value() as string | number | undefined);
54
- return options.map(op => ({
55
- ...op,
56
- selected: String(op.k) == String(valor),
57
- choosing: op.k == this.markedOptionKey()
58
- }));
59
- } else {
60
- let valor = (this.value() as string[] | number[] | undefined);
61
- if (!Array.isArray(valor)) {
62
- valor = [];
63
- }
64
- return options.map(op => ({
65
- ...op,
66
- selected: op.k != null ? valor.some(v => String(op.k) == String(v)) : false,
67
- choosing: op.k == this.markedOptionKey()
68
- }));
69
- }
70
- });
71
- readonly optionsFiltered = computed<IKVSeletor[]>(() => {
72
- let words = this.textoFiltrado().trim().split(" ").filter(t => t != "");
73
- const options = (this.optionsList() || []).map(o => ({ ...o, html: o.v || `⚠️ Chave: ${o.k}` }));
74
- // Sem filtro, retorna tudo
75
- if (words.length === 0) return options;
76
- return options.filter(op => {
77
- for (const w of words) {
78
- let encontrado = false;
79
- if (op.v != null && LibUtil.contem(op.v, w)) {
80
- encontrado = true;
81
- }
82
- // Termo não encontrado na opção
83
- if (!encontrado) return false;
84
- }
85
- // Todos os termos encontrados
86
- return true;
87
- }).map(op => {
88
- let data = op.v?.toString() || '';
89
-
90
- // Substitui o valor do html, colocando uma mark em volta do texto buscado.
91
- if (words.length > 0) {
92
- for (let word of words) {
93
- let w = word.toLowerCase();
94
- let preparedData = LibUtil.removeAcentos(data).toLowerCase();
95
- if (w != "" && preparedData.includes(w)) {
96
- // Se w estiver dentro de < ou >, ignora (para não interferir em tags HTML)
97
- if (new RegExp(`<[^>]*${w}[^>]*>`, 'i').test(preparedData.toString())) continue;
98
- // Se a palavra for encontrada, envolve com a tag <mark>
99
- let pos = preparedData.indexOf(w);
100
- data = data.slice(0, pos)
101
- + "<mark>"
102
- + data.slice(pos, pos + w.length)
103
- + "</mark>"
104
- + data.slice(pos + w.length);
105
- data = data.replaceAll("</mark><mark>", "");
106
- }
107
- };
108
- }
109
- return {
110
- ...op,
111
- html: data,
112
- };
113
- });
114
- });
115
-
116
- readonly textoExibindo = computed<string>(() => {
117
- const val = this.value();
118
- if (this.multiple() !== true) {
119
- let selectedOption = this.optionsList().find(op => String(op.k) == String(val));
120
- return selectedOption?.v ?? (selectedOption?.k ? `⚠️ Chave: ${selectedOption?.k}` : (this.textEmpty() ?? 'Nada selecionado'));
121
- }
122
-
123
- let valor = (this.value() as string[] | number[] | undefined);
124
- if (valor == undefined || !Array.isArray(valor)) {
125
- valor = [];
126
- }
127
- const textosSelecionados = this.optionsList()
128
- .filter(op => valor.some(v => String(v) == String(op.k)))
129
- .map(op => op.v);
130
- return textosSelecionados.length > 0 ? `[${textosSelecionados.length}] ${textosSelecionados.join(", ")}` : (this.textEmpty() ?? 'Nada selecionado');
131
-
132
- });
133
-
134
- readonly displayText = viewChild<ElementRef>('displayText');
135
- readonly triggerElement = viewChild<ElementRef>('triggerElement');
136
- readonly optionsOverlay = viewChild<ElementRef>('optionsOverlay');
137
- readonly optionsContainer = viewChild<ElementRef>('optionsContainer');
138
- readonly optionSearchInput = viewChild<ElementRef>('optionSearchInput');
139
- optionMinWidth = signal<number>(0);
140
- menuPosition = signal<{ top: string; left: string }>({ top: '0px', left: '0px' });
141
-
142
- // scrollCleanup: (() => void) | null = null;
143
-
144
- constructor() {
145
- effect(() => {
146
- const eTrigger = this.triggerElement()?.nativeElement as HTMLElement;
147
- if (!eTrigger) return;
148
-
149
- if (!this.isOpenedOptions()) return;
150
-
151
- const cleanupAutoUpdate = autoUpdate(
152
- eTrigger,
153
- this.optionsContainer()?.nativeElement,
154
- () => this.updatePosition()
155
- );
156
- return () => {
157
- cleanupAutoUpdate();
158
- };
159
-
160
-
161
- // const resizeObserver = new ResizeObserver((entries) => {
162
- // // Atualiza a posição do menu quando redimensiona
163
- // if (this.isOpenedOptions()) {
164
- // this.updatePosition();
165
- // }
166
- // });
167
- // resizeObserver.observe(eTrigger);
168
- // return () => resizeObserver.disconnect();
169
- });
170
-
171
- // Atualiza posição quando o menu abre
172
- effect(() => {
173
- if (this.isOpenedOptions()) {
174
- setTimeout(() => {
175
- this.updatePosition();
176
- // this.setupScrollListeners();
177
- this.focusToSearchInput();
178
- }, 1);
179
- } else {
180
- // this.cleanupScrollListeners();
181
- }
182
- });
183
- }
184
-
185
- ngOnDestroy() {
186
- if (this.isOpenedOptions() == true) this.closeOverlay();
187
- // this.cleanupScrollListeners();
188
- }
189
- ngAfterViewInit() {
190
- this.checkScreenSize();
191
- this.setOverlaySizeToSizeViewport();
192
-
193
-
194
- this.updatePosition();
195
- }
196
-
197
-
198
- // Manipula mudança de valor (valueOfK não chegará nulo ou undefined)
199
- onChange(valueOfK: string | number | null): string | number | string[] | number[] {
200
- if (valueOfK == null) return '';
201
-
202
- let optionChanged = this.options?.()?.find(op => String(op.k) === String(valueOfK));
203
- let newKeys = valueOfK;
204
- let newValues = optionChanged?.v ?? newKeys;
205
-
206
- // SINGLE
207
- if (this.multiple() !== true) {
208
- if (this.canUnselect() === true && this.value() === newKeys) {
209
- newKeys = '';
210
- newValues = '';
211
- }
212
- this.changed.emit({ optionChanged, keys: newKeys, values: newValues });
213
- return newKeys;
214
- }
215
-
216
- // MULTIPLE (canUnselect sempre é true)
217
- let currentKeys = this.value() ?? [] as any[];
218
- let currentValues = [];
219
- if (!Array.isArray(currentKeys)) {
220
- currentKeys = [];
221
- }
222
-
223
- if (currentKeys.indexOf(newKeys) === -1) {
224
- currentKeys = [...currentKeys, newKeys];
225
- } else {
226
- currentKeys = currentKeys.filter(v => v !== newKeys);
227
- }
228
- setTimeout(() => {
229
- this.updatePosition();
230
- }, 1);
231
-
232
- currentValues = currentKeys.map(k => this.options?.()?.find(op => op.k === k)?.v ?? k);
233
- this.changed.emit({ optionChanged, keys: currentKeys, values: currentValues });
234
- return currentKeys;
235
- }
236
-
237
- // Abre ou fecha o overlay de opções
238
- onOpenOrCloseOptions() {
239
- if (!this.disabled()) {
240
- if (this.isOpenedOptions()) {
241
- this.closeOverlay();
242
- } else {
243
- this.openOverlay();
244
- }
245
- }
246
- }
247
-
248
- // Fecha o overlay de opções
249
- protected closeOverlay() {
250
- setTimeout(() => {
251
- this.isOpenedOptions.set(false);
252
- }, 2)
253
-
254
- this.textoFiltrado.set("");
255
- this.markedOptionKey.set(null);
256
- this.focusToDisplayText();
257
- }
258
-
259
- // Abre o overlay de opções
260
- protected openOverlay() {
261
- this.updatePosition();
262
- setTimeout(() => {
263
- this.isOpenedOptions.set(true);
264
- }, 2)
265
- }
266
-
267
- // Seleciona uma opção
268
- onSelectOption(option?: IKV) {
269
- if (!option || option.k == null) {
270
- LOG(1, `❌ (SelectOption) Chave nula! (${option?.k}, classof: '${LibUtil.classof(option?.k)}'). Valor corresponde ${option?.v}`);
271
- return;
272
- }
273
- this.value.set(this.onChange(option.k));
274
- if (this.multiple() !== true) {
275
- this.closeOverlay();
276
- } else {
277
- this.focusToSearchInput();
278
- }
279
- }
280
-
281
- // Filtra as opções
282
- onInputSearch(text: string) {
283
- this.textoFiltrado.set(text);
284
- this.markedOptionKey.set(null);
285
- }
286
-
287
- // Limpa o filtro de opções
288
- onClearSearch() {
289
- this.textoFiltrado.set("");
290
- this.focusToSearchInput();
291
- }
292
-
293
- focusToSearchInput() {
294
- this.optionSearchInput()?.nativeElement?.focus();
295
- }
296
-
297
- focusToDisplayText() {
298
- this.displayText()?.nativeElement?.focus();
299
- }
300
-
301
- // Navegação por teclado
302
- markKey(event: KeyboardEvent) {
303
- const options = this.optionsFiltered();
304
- if (options.length === 0) return;
305
- let currentIndex = options.findIndex(op => op.k === this.markedOptionKey());
306
- let currentKV = options.find(op => op.k === this.markedOptionKey());
307
-
308
- if (event.key === 'ArrowDown') {
309
- event.preventDefault();
310
- currentIndex = (currentIndex + 1) % options.length;
311
- this.markedOptionKey.set(options[currentIndex].k);
312
- this.moveScrollToMarkedOption();
313
- } else if (event.key === 'ArrowUp') {
314
- event.preventDefault();
315
- currentIndex = (currentIndex - 1 + options.length) % options.length;
316
- this.markedOptionKey.set(options[currentIndex].k);
317
- this.moveScrollToMarkedOption();
318
- } else if (event.key === 'Escape' || event.key === 'Tab') {
319
- event.preventDefault();
320
- this.closeOverlay();
321
- } else if (event.key === 'Enter') {
322
- event.preventDefault();
323
- if (this.markedOptionKey() != null) {
324
- this.onSelectOption(currentKV);
325
- }
326
- this.closeOverlay();
327
- }
328
- }
329
-
330
- // ----------------------------------------------------
331
- // Funções de Suporte ao Overlay
332
- // ----------------------------------------------------
333
-
334
- // Quando o overlay estiver aberto, define a classe showing no host
335
- readonly hostClasses = computed(() => {
336
- return this.isOpenedOptions() ? 'opened' : '';
337
- })
338
-
339
-
340
- // Fecha o overlay ao clicar fora
341
- @HostListener('document:click', ['$event'])
342
- onDocumentClick(event: MouseEvent): void {
343
- const clickedInside = this.elementRef.nativeElement.contains(event.target);
344
- if (!clickedInside && this.isOpenedOptions()) {
345
- setTimeout(() => {
346
- this.isOpenedOptions.set(false);
347
- }, 2)
348
- this.textoFiltrado.set("");
349
- this.markedOptionKey.set(null);
350
- }
351
- }
352
-
353
- // Configura os listeners de scroll (Só necessita se não utilizar o autoUpdate do floating-ui, que já faz isso automaticamente)
354
- // private setupScrollListeners() {
355
- // const trigger = this.triggerElement()?.nativeElement;
356
- // if (!trigger) return;
357
-
358
- // const updatePositionHandler = () => this.updatePosition();
359
- // const scrollElements: HTMLElement[] = [];
360
- // window.addEventListener('scroll', updatePositionHandler, { passive: true });
361
- // let parent = trigger.parentElement;
362
- // while (parent) {
363
- // const overflow = window.getComputedStyle(parent).overflow;
364
- // const overflowY = window.getComputedStyle(parent).overflowY;
365
- // const overflowX = window.getComputedStyle(parent).overflowX;
366
- // if (
367
- // overflow === 'auto' || overflow === 'scroll' ||
368
- // overflowY === 'auto' || overflowY === 'scroll' ||
369
- // overflowX === 'auto' || overflowX === 'scroll'
370
- // ) {
371
- // parent.addEventListener('scroll', updatePositionHandler, { passive: true });
372
- // scrollElements.push(parent);
373
- // }
374
- // parent = parent.parentElement;
375
- // }
376
- // this.scrollCleanup = () => {
377
- // window.removeEventListener('scroll', updatePositionHandler);
378
- // scrollElements.forEach(el => {
379
- // el.removeEventListener('scroll', updatePositionHandler);
380
- // });
381
- // };
382
- // }
383
-
384
- // Limpa os listeners de scroll (Só necessita se não utilizar o autoUpdate do floating-ui, que já faz isso automaticamente)
385
- // private cleanupScrollListeners() {
386
- // if (this.scrollCleanup) {
387
- // this.scrollCleanup();
388
- // this.scrollCleanup = null;
389
- // }
390
- // }
391
-
392
- // Atualiza a posição do menu de opções
393
- private async updatePosition() {
394
- if (this.isSmallScreen()) return;
395
-
396
- const trigger = this.triggerElement()?.nativeElement;
397
- const optionsContainer = this.optionsContainer()?.nativeElement;
398
- if (!trigger || !optionsContainer) return;
399
-
400
- const { x, y } = await computePosition(trigger, optionsContainer, {
401
- placement: 'bottom-start',
402
- middleware: [
403
- offset(2),
404
- flip({
405
- fallbackPlacements: ['top-start', 'bottom-end', 'top-end'],
406
- }),
407
- shift({ padding: 10 }),
408
- ],
409
- });
410
- this.menuPosition.set({
411
- left: `${x}px`,
412
- top: `${y}px`
413
- });
414
- }
415
-
416
- setOverlaySizeToSizeViewport() {
417
- // if (!this.isOpenedOptions()) return;
418
-
419
- // Obtem o tamanho da largura da viewport
420
- const viewportWidth = window.innerWidth;
421
- const parcialViewport = viewportWidth * 0.92;
422
-
423
- const overlay = this.optionsOverlay()?.nativeElement as HTMLElement;
424
- if (overlay) {
425
- let currentElement = overlay.parentElement as HTMLElement | null;
426
- while (currentElement) {
427
- let larguraOverlay = overlay.clientWidth;
428
-
429
- // Se chegar no body, para (para evitar mover o overlay para fora do body)
430
- if (currentElement.tagName.toLowerCase() === "body") break;
431
-
432
- // Move o overlay para o próximo nível acima
433
- currentElement.appendChild(overlay);
434
-
435
- if (larguraOverlay >= parcialViewport) {
436
- currentElement = null;
437
- break;
438
- }
439
-
440
- currentElement = currentElement.parentElement as HTMLElement;
441
- }
442
-
443
- }
444
- }
445
-
446
- onChangeMediaQuery(e: MediaQueryListEvent | MediaQueryList) {
447
- this.isSmallScreen.set(e.matches);
448
- const eTrigger = this.triggerElement()?.nativeElement as HTMLElement;
449
- if (eTrigger) {
450
- if (this.isSmallScreen()) {
451
- this.optionMinWidth.set(0);
452
- } else {
453
- this.optionMinWidth.set(eTrigger.offsetWidth - 4);
454
- }
455
- }
456
- }
457
-
458
- checkScreenSize() {
459
- const mediaQuery = window.matchMedia('(max-width: 500px)');
460
- this.onChangeMediaQuery(mediaQuery);
461
- mediaQuery.addEventListener('change', this.onChangeMediaQuery.bind(this));
462
- }
463
-
464
- // Move o scroll para a opção marcada
465
- private moveScrollToMarkedOption() {
466
- setTimeout(() => {
467
- const optionsContainer = this.optionsContainer()?.nativeElement?.querySelector(".e-select-options-list") as HTMLElement;
468
- const markedOption = optionsContainer?.querySelector('.e-select-option.choosing') as HTMLElement;
469
- if (optionsContainer && markedOption) {
470
- const containerTop = optionsContainer.scrollTop;
471
- const containerBottom = containerTop + optionsContainer.clientHeight;
472
- const optionTop = markedOption.offsetTop;
473
- const optionBottom = optionTop + markedOption.offsetHeight;
474
- if (optionTop < containerTop) {
475
- optionsContainer.scrollTop = optionTop - 40; // 40px do elemento Search
476
- } else if (optionBottom > containerBottom) {
477
- optionsContainer.scrollTop = optionBottom - optionsContainer.clientHeight;
478
- }
479
- }
480
- }, 1);
481
- }
482
- }
@@ -1,75 +0,0 @@
1
- .sliderbox {
2
- --height: 28px;
3
- min-width: calc(var(--height) * 2.2);
4
- display: flex;
5
- align-items: center;
6
- cursor: pointer;
7
- height: var(--height);
8
- width: calc(var(--height) * 2.2);
9
- border-radius: calc(var(--height) / 2);
10
- background-color: var(--sys-primary-15);
11
- transition: background-color 0.3s ease;
12
- }
13
-
14
- .sliderbox.ativo {
15
- background-color: var(--sys-primary);
16
- }
17
-
18
- .slidercircle {
19
- height: calc(var(--height) - 6px);
20
- width: calc(var(--height) - 6px);
21
- background-color: var(--sys-card);
22
- border-radius: 50%;
23
- margin: 3px;
24
- transition: transform 0.3s ease;
25
- outline: 1px dashed var(--sys-primary);
26
- display: flex;
27
- align-items: center;
28
- justify-content: center;
29
- }
30
-
31
- .sliderbox.ativo .slidercircle {
32
- transform: translateX(calc(var(--height) * 1.2)) scale(1.1);
33
- outline: 2px solid var(--sys-primary);
34
- }
35
-
36
- .sliderbox.disabled {
37
- cursor: not-allowed;
38
- opacity: 0.6;
39
- filter: grayscale(1);
40
- pointer-events: none;
41
- }
42
-
43
-
44
-
45
- .sliderbox .slidercircle .nocheckmark {
46
- display: block;
47
- color: var(--sys-primary);
48
- margin: 2px 0 0 1px;
49
- font-size: 1.2rem;
50
- }
51
-
52
- .sliderbox.ativo .slidercircle .nocheckmark {
53
- display: none;
54
- }
55
-
56
-
57
- .sliderbox .slidercircle .checkmark {
58
- display: none;
59
- }
60
-
61
- .sliderbox.ativo .slidercircle .checkmark {
62
- display: block;
63
- color: var(--sys-primary);
64
- margin: 2px 0 0 1px;
65
- font-size: 1.2rem;
66
- }
67
-
68
- .sliderbox:focus-visible {
69
- outline: none;
70
- }
71
-
72
- .sliderbox:focus-visible .slidercircle,
73
- .sliderbox:hover .slidercircle {
74
- outline: 1px solid var(--sys-primary);
75
- }
@@ -1,7 +0,0 @@
1
- <div #sliderbox class="sliderbox" tabindex="0" (click)="onClickSlide()" [class.ativo]="ativo()"
2
- [class.disabled]="disabled()" (focus)="onFocus($event)" (blur)="onBlur($event)">
3
- <div class="slidercircle">
4
- <i class="checkmark bi bi-check-lg"></i>
5
- <i class="nocheckmark bi bi-dash"></i>
6
- </div>
7
- </div>
@@ -1,61 +0,0 @@
1
- import { AfterViewInit, Component, computed, effect, ElementRef, input, model, output, viewChild } from '@angular/core';
2
-
3
- @Component({
4
- selector: 'ui-slide',
5
- templateUrl: './ui-slide.html',
6
- styleUrl: './ui-slide.css',
7
- host: { '[class.focused]': 'focused()' }
8
- })
9
- export class UiSlide implements AfterViewInit {
10
-
11
- sliderbox = viewChild('sliderbox', { read: ElementRef });
12
-
13
- value = model<boolean>(false);
14
- disabled = input<boolean>();
15
- focused = model<boolean>(false);
16
- focus = input<boolean>(false);
17
- changed = output<boolean>();
18
-
19
- ativo = computed(() => {
20
- const val = (this.value() as any);
21
- return val === true || val === 'true' || val === 1 || val === '1';
22
- });
23
-
24
- constructor() {
25
- effect(() => {
26
- if (this.focus()) {
27
- this.sliderbox()?.nativeElement.focus();
28
- }
29
- });
30
- }
31
-
32
- ngAfterViewInit(): void {
33
- this.sliderbox()?.nativeElement.addEventListener('keydown', (event: KeyboardEvent) => {
34
- if (event.key === ' ' || event.key === 'Enter') {
35
- event.preventDefault();
36
- this.onClickSlide();
37
- }
38
- });
39
- }
40
-
41
- onClickSlide() {
42
- if (this.disabled()) return;
43
-
44
- const currentValue = (this.value() as any);
45
- const newValue = !(currentValue === true || currentValue === 'true' || currentValue === 1 || currentValue === '1');
46
- this.value.set(newValue);
47
- this.changed.emit(newValue);
48
- }
49
-
50
- onFocus(ev: FocusEvent) {
51
- if (this.disabled()) return;
52
-
53
- this.focused.set(true);
54
- }
55
-
56
- onBlur(ev: FocusEvent) {
57
- this.focused.set(false);
58
- }
59
-
60
-
61
- }