@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,294 +0,0 @@
1
- import { Component, computed, effect, ElementRef, HostListener, inject, OnDestroy, signal, viewChild } from '@angular/core';
2
- import { computePosition, flip, offset, shift } from '@floating-ui/dom';
3
- import { LibUtil, LOG } from '../../util/util';
4
- import { BaseFieldsForm } from '../Base/BaseFieldsForm/BaseFieldsForm.component';
5
- import { IKV } from '../../interfaces/interfaces';
6
- import { UiListErrors } from "../../elements/ui-list-errors/ui-list-errors";
7
-
8
- export interface IKVAutoCompletador extends IKV {
9
- selected: boolean;
10
- choosing: boolean;
11
- }
12
-
13
- @Component({
14
- selector: 'fields-autocomplete',
15
- templateUrl: './autocomplete.html',
16
- styleUrls: ['../fields.css', './autocomplete.css'],
17
- imports: [UiListErrors],
18
- })
19
- export class FieldsAutocomplete extends BaseFieldsForm implements OnDestroy {
20
-
21
- elementRef: ElementRef = inject(ElementRef);
22
-
23
- isOpenedOptions = signal(false);
24
- markedOptionKey = signal<string | number | null | undefined>(null);
25
-
26
- options = computed<IKVAutoCompletador[]>(() => {
27
- const options = this.campo()?.options?.() || [];
28
- // Autocompletar não exibe opções sem valor
29
- return options.filter((op: IKV) => op.v != null && op.v !== '').map((op: IKV) => ({
30
- ...op,
31
- selected: op.k === this.value(),
32
- choosing: op.k === this.markedOptionKey()
33
- }));
34
- });
35
- optionsFiltered = computed<IKVAutoCompletador[]>(() => {
36
- let words = this.value()?.toString().trim().split(" ").filter((t: string) => t != "");
37
- const options = (this.options() || []).map(o => ({ ...o, html: o.v || `⚠️ Chave: ${o.k}` }));
38
- // Sem filtro, retorna tudo
39
- if (words.length === 0) return options;
40
-
41
- return options.filter(op => {
42
- for (const w of words) {
43
- let encontrado = false;
44
- if (op.v != null && LibUtil.contem(op.v, w)) {
45
- encontrado = true;
46
- }
47
-
48
- // Termo não encontrado na opção
49
- if (!encontrado) return false;
50
- }
51
-
52
- // Todos os termos encontrados
53
- return true;
54
- }).map(op => {
55
- let data = op.v?.toString() || '';
56
- // Substitui o valor do html, colocando uma mark em volta do texto buscado.
57
- if (words.length > 0) {
58
- for (let word of words) {
59
- let w = word.toLowerCase();
60
- let preparedData = LibUtil.removeAcentos(data).toLowerCase();
61
- if (w != "" && preparedData.includes(w)) {
62
- // Se w estiver dentro de < ou >, ignora (para não interferir em tags HTML)
63
- if (new RegExp(`<[^>]*${w}[^>]*>`, 'i').test(preparedData.toString())) continue;
64
- // Se a palavra for encontrada, envolve com a tag <mark>
65
- let pos = preparedData.indexOf(w);
66
- data = data.slice(0, pos)
67
- + "<mark>"
68
- + data.slice(pos, pos + w.length)
69
- + "</mark>"
70
- + data.slice(pos + w.length);
71
- data = data.replaceAll("</mark><mark>", "");
72
- }
73
- };
74
- }
75
-
76
- return {
77
- ...op,
78
- html: data,
79
- };
80
- });
81
- });
82
-
83
- readonly displayText = viewChild<ElementRef>('displayText');
84
- readonly triggerElement = viewChild<ElementRef>('triggerElement');
85
- readonly optionsContainer = viewChild<ElementRef>('optionsContainer');
86
- offsetWidth = signal<number>(0);
87
- menuPosition = signal<{ top: string; left: string }>({ top: '0px', left: '0px' });
88
-
89
- scrollCleanup: (() => void) | null = null;
90
-
91
- constructor() {
92
- super();
93
- effect(() => {
94
- const val = this.value();
95
- let empty = val === null || val === undefined || val === '';
96
- this.updateCampo({ empty });
97
- });
98
- effect(() => {
99
- const el = this.triggerElement()?.nativeElement as HTMLElement;
100
- if (!el) return;
101
-
102
- const resizeObserver = new ResizeObserver((entries) => {
103
- for (const entry of entries) {
104
- this.offsetWidth.set(entry.target.clientWidth - 4); // -4 para compensar borda
105
- }
106
- // Atualiza a posição do menu quando redimensiona
107
- if (this.isOpenedOptions()) {
108
- this.updatePosition();
109
- }
110
- });
111
- resizeObserver.observe(el);
112
- return () => resizeObserver.disconnect();
113
- });
114
-
115
- // Atualiza posição quando o menu abre
116
- effect(() => {
117
- if (this.isOpenedOptions()) {
118
- setTimeout(() => {
119
- this.updatePosition();
120
- this.setupScrollListeners();
121
- }, 1);
122
- } else {
123
- this.cleanupScrollListeners();
124
- }
125
- });
126
- }
127
- override ngOnDestroy() {
128
- super.ngOnDestroy();
129
- this.closeOverlay();
130
- this.cleanupScrollListeners();
131
- }
132
-
133
- onInput(newValue: string) {
134
- if (newValue != "") {
135
- this.isOpenedOptions.set(true);
136
- } else {
137
- this.isOpenedOptions.set(false);
138
- }
139
- if (this.campo()?.mask) newValue = LibUtil.mascarar(newValue, this.campo()?.mask) ?? '';
140
- if (this.campo()?.onMatchOption) {
141
- let option = this.campo()?.options?.()?.find((op: IKV) => op.v === newValue);
142
- try {
143
- this.campo()?.onMatchOption?.(this.form(), option);
144
- } catch (err) {
145
- LOG(1, `❌ Erro ao executar onMatchOption do campo '${this.name.toString()}'`, err);
146
- }
147
- }
148
- this.updateValue(newValue);
149
- this.campo()?.onInput?.(this.form());
150
- }
151
-
152
- override onClickLabel() {
153
- super.onClickLabel();
154
- this.closeOverlay();
155
- }
156
-
157
- // Fecha o overlay de opções
158
- protected closeOverlay() {
159
- this.isOpenedOptions.set(false);
160
- this.markedOptionKey.set(null);
161
- }
162
-
163
- // Seleciona uma opção
164
- onSelectOption(option?: IKV) {
165
- if (!option || option.k == null) {
166
- LOG(1, `❌ Chave nula (${option?.k}, classof: '${LibUtil.classof(option?.k)}'). Valor corresponde ${option?.v}`);
167
- return;
168
- }
169
- this.onInput(option.v?.toString() ?? '');
170
- this.closeOverlay();
171
- }
172
-
173
- // Navegação por teclado
174
- markKey(event: KeyboardEvent) {
175
- const options = this.optionsFiltered();
176
- if (options.length === 0) return;
177
- let currentIndex = options.findIndex(op => op.k === this.markedOptionKey());
178
- let currentKV = options.find(op => op.k === this.markedOptionKey());
179
- if (event.key === 'ArrowDown') {
180
- event.preventDefault();
181
- this.isOpenedOptions.set(true);
182
- currentIndex = (currentIndex + 1) % options.length;
183
- this.markedOptionKey.set(options[currentIndex].k);
184
- this.moveScrollToMarkedOption();
185
- } else if (event.key === 'ArrowUp') {
186
- event.preventDefault();
187
- this.isOpenedOptions.set(true);
188
- currentIndex = (currentIndex - 1 + options.length) % options.length;
189
- this.markedOptionKey.set(options[currentIndex].k);
190
- this.moveScrollToMarkedOption();
191
- } else if (event.key === 'Enter') {
192
- event.preventDefault();
193
- if (this.markedOptionKey() != null) {
194
- this.onSelectOption(currentKV);
195
- }
196
- this.closeOverlay();
197
- }
198
- }
199
-
200
-
201
- // ----------------------------------------------------
202
- // Funções de Suporte ao Overlay
203
- // ----------------------------------------------------
204
-
205
- // Fecha o overlay ao clicar fora
206
- @HostListener('document:click', ['$event'])
207
- onDocumentClick(event: MouseEvent): void {
208
- const clickedInside = this.elementRef.nativeElement.contains(event.target);
209
- if (!clickedInside && this.isOpenedOptions()) {
210
- this.isOpenedOptions.set(false);
211
- this.markedOptionKey.set(null);
212
- }
213
- }
214
-
215
- // Configura os listeners de scroll
216
- private setupScrollListeners() {
217
- const trigger = this.triggerElement()?.nativeElement;
218
- if (!trigger) return;
219
-
220
- const updatePositionHandler = () => this.updatePosition();
221
- const scrollElements: HTMLElement[] = [];
222
- window.addEventListener('scroll', updatePositionHandler, { passive: true });
223
- let parent = trigger.parentElement;
224
- while (parent) {
225
- const overflow = window.getComputedStyle(parent).overflow;
226
- const overflowY = window.getComputedStyle(parent).overflowY;
227
- const overflowX = window.getComputedStyle(parent).overflowX;
228
- if (
229
- overflow === 'auto' || overflow === 'scroll' ||
230
- overflowY === 'auto' || overflowY === 'scroll' ||
231
- overflowX === 'auto' || overflowX === 'scroll'
232
- ) {
233
- parent.addEventListener('scroll', updatePositionHandler, { passive: true });
234
- scrollElements.push(parent);
235
- }
236
- parent = parent.parentElement;
237
- }
238
- this.scrollCleanup = () => {
239
- window.removeEventListener('scroll', updatePositionHandler);
240
- scrollElements.forEach(el => {
241
- el.removeEventListener('scroll', updatePositionHandler);
242
- });
243
- };
244
- }
245
-
246
- // Limpa os listeners de scroll
247
- private cleanupScrollListeners() {
248
- if (this.scrollCleanup) {
249
- this.scrollCleanup();
250
- this.scrollCleanup = null;
251
- }
252
- }
253
-
254
- // Atualiza a posição do menu de opções
255
- private async updatePosition() {
256
- const trigger = this.triggerElement()?.nativeElement;
257
- const optionsContainer = this.optionsContainer()?.nativeElement;
258
- if (!trigger || !optionsContainer) return;
259
- const { x, y } = await computePosition(trigger, optionsContainer, {
260
- placement: 'bottom-start',
261
- middleware: [
262
- offset(2),
263
- flip({
264
- fallbackPlacements: ['top-start', 'bottom-end', 'top-end'],
265
- }),
266
- shift({ padding: 10 }),
267
- ],
268
- });
269
- this.menuPosition.set({
270
- left: `${x}px`,
271
- top: `${y}px`
272
- });
273
- }
274
-
275
- // Move o scroll para a opção marcada
276
- private moveScrollToMarkedOption() {
277
- setTimeout(() => {
278
- const optionsContainer = this.optionsContainer()?.nativeElement?.querySelector(".options-list") as HTMLElement;
279
- const markedOption = optionsContainer?.querySelector('.option-item.choosing') as HTMLElement;
280
- if (optionsContainer && markedOption) {
281
- const containerTop = optionsContainer.scrollTop;
282
- const containerBottom = containerTop + optionsContainer.clientHeight;
283
- const optionTop = markedOption.offsetTop;
284
- const optionBottom = optionTop + markedOption.offsetHeight;
285
- if (optionTop < containerTop) {
286
- optionsContainer.scrollTop = optionTop - 40; // 40px do elemento Search
287
- } else if (optionBottom > containerBottom) {
288
- optionsContainer.scrollTop = optionBottom - optionsContainer.clientHeight;
289
- }
290
- }
291
- }, 1);
292
- }
293
-
294
- }
@@ -1,7 +0,0 @@
1
- .fieldField.FieldButton {
2
- border: none;
3
- }
4
-
5
- .FieldButton ui-button {
6
- width: 100%;
7
- }
@@ -1,19 +0,0 @@
1
- <div class="fieldContainer" [class.isTouched]="campo()?.touched" [class.showTouched]="form().showTouched()"
2
- [class.isInvalid]="campo()?.invalid" [class.isDisabled]="campo()?.disabled" [class.isReadonly]="campo()?.readonly"
3
- [class.isNeed]="campo()?.need" [class.isPending]="campo()?.pending" [class.isEmpty]="campo()?.empty">
4
- <div class="fieldLabel" (click)="onClickLabel()" [class.hideLabel]="campo()?.hideLabel">
5
- @if(campo()?.icone){ <div class="fieldIcon"><i [class]="campo()?.icone"></i></div> }
6
- {{ campo()?.titulo ?? '&nbsp;' }}
7
- </div>
8
- <div class="fieldControl doCampo">
9
- <div class="fieldEffect">
10
- <div class="fieldField FieldButton">
11
- <ui-button [tipo]="campo()?.tipoBotao" [tema]="campo()?.tema" [style]="campo()?.style"
12
- (click)="onClickButton($event)" [disabled]="campo()?.disabled" [icone]="campo()?.icone">
13
- <div [innerHTML]="campo()?.tituloClicavel"></div>
14
- </ui-button>
15
- </div>
16
- </div>
17
- </div>
18
- <ui-list-errors [errors]="campo()?.errors" [dica]="campo()?.dica" [show]="campo()?.touched"></ui-list-errors>
19
- </div>
@@ -1,38 +0,0 @@
1
- import { Component, effect } from '@angular/core';
2
- import { BaseFieldsForm } from '../Base/BaseFieldsForm/BaseFieldsForm.component';
3
- import { UiButton } from "../../elements/ui-button/ui-button";
4
- import { UiListErrors } from "../../elements/ui-list-errors/ui-list-errors";
5
- import { LOG } from '../../util/util';
6
-
7
- @Component({
8
- selector: 'fields-button',
9
- templateUrl: './button.html',
10
- styleUrls: ['../fields.css', './button.css'],
11
- imports: [UiButton, UiListErrors]
12
- })
13
- export class FieldsButton extends BaseFieldsForm {
14
-
15
- constructor() {
16
- super();
17
- effect(() => {
18
- const val = this.value();
19
- let empty = val === null || val === undefined || val === '';
20
- this.updateCampo({ empty });
21
- });
22
- }
23
-
24
- onClickButton(ev: Event) {
25
- this.tocarCampo();
26
- if (this.campo()?.onClick) {
27
- try {
28
- this.campo()?.onClick?.(this.form());
29
- } catch (err) {
30
- LOG(1, '❌ Erro ao executar onClick do botão:', err);
31
- }
32
- }
33
- this.campo()?.onInput?.(this.form());
34
- this.onChangeEmit();
35
- }
36
-
37
-
38
- }
@@ -1,27 +0,0 @@
1
- .FieldCheckbox {
2
- padding-left: 10px;
3
- display: flex;
4
- flex-wrap: nowrap;
5
- align-items: center;
6
- transition: outline 0s;
7
- transition-delay: 0.2s;
8
- }
9
-
10
- .tituloClicavel {
11
- display: flex;
12
- align-items: center;
13
- padding-left: 10px;
14
- padding-right: 10px;
15
- font-size: 0.875rem;
16
- cursor: pointer;
17
- user-select: none;
18
- flex: 1;
19
- line-height: 30px;
20
- text-align: var(--ui-text-align, center);
21
- }
22
-
23
- .FieldCheckbox:has(ui-check-box.focused) {
24
- outline: 2px solid var(--sys-primary);
25
- transition: outline 0s;
26
-
27
- }
@@ -1,20 +0,0 @@
1
- <div class="fieldContainer" [class.isTouched]="campo()?.touched" [class.showTouched]="form().showTouched()"
2
- [class.isInvalid]="campo()?.invalid" [class.isDisabled]="campo()?.disabled" [class.isReadonly]="campo()?.readonly"
3
- [class.isNeed]="campo()?.need" [class.isPending]="campo()?.pending" [class.isEmpty]="campo()?.empty">
4
- <div class="fieldLabel" (click)="onClickLabel()" [class.hideLabel]="campo()?.hideLabel">
5
- @if(campo()?.icone){ <div class="fieldIcon"><i [class]="campo()?.icone"></i></div> }
6
- {{ campo()?.titulo }}
7
- </div>
8
- <div class="fieldControl doCampo">
9
- <div class="fieldEffect">
10
- <div class="fieldField FieldCheckbox microPos4">
11
- <ui-check-box [value]="value()" (changed)="onChange($event)" [focus]="signalFocus()"></ui-check-box>
12
- <div class="tituloClicavel" (click)="toogleAtivo()">
13
- {{ value() ? (campo()?.textoAtivo ?? campo()?.tituloClicavel ) : (campo()?.textoInativo ??
14
- campo()?.tituloClicavel) }}
15
- </div>
16
- </div>
17
- </div>
18
- </div>
19
- <ui-list-errors [errors]="campo()?.errors" [dica]="campo()?.dica" [show]="campo()?.touched"></ui-list-errors>
20
- </div>
@@ -1,44 +0,0 @@
1
- import { Component, effect, signal } from '@angular/core';
2
- import { BaseFieldsForm } from '../Base/BaseFieldsForm/BaseFieldsForm.component';
3
- import { UiCheckBox } from "../../elements/ui-check-box/ui-check-box";
4
- import { UiListErrors } from "../../elements/ui-list-errors/ui-list-errors";
5
-
6
- @Component({
7
- selector: 'fields-checkbox',
8
- templateUrl: './checkbox.html',
9
- styleUrls: ['../fields.css', './checkbox.css'],
10
- imports: [UiCheckBox, UiListErrors],
11
- })
12
- export class FieldsCheckbox extends BaseFieldsForm {
13
-
14
- signalFocus = signal<boolean>(false);
15
-
16
- constructor() {
17
- super();
18
- effect(() => {
19
- const val = this.value();
20
- let empty = val === null || val === undefined || val === '';
21
- this.updateCampo({ empty });
22
- });
23
- }
24
-
25
- onChange(newValue: boolean) {
26
- this.updateValue(newValue);
27
- this.campo()?.onInput?.(this.form());
28
- this.onChangeEmit();
29
- }
30
-
31
- ngAfterViewInit(): void {
32
- let val = this.value();
33
- this.updateValue(val === true || val === 'true' || val === 1 || val === '1', false);
34
- }
35
-
36
- toogleAtivo() {
37
- this.onChange(!this.value());
38
- this.signalFocus.set(true);
39
- setTimeout(() => {
40
- this.signalFocus.set(false);
41
- }, 1)
42
- }
43
-
44
- }
@@ -1,50 +0,0 @@
1
- .container {
2
- position: relative;
3
- display: flex;
4
- height: 60px;
5
- aspect-ratio: 1 / 1;
6
- }
7
-
8
- .circulo {
9
- position: absolute;
10
- top: 0;
11
- left: 0;
12
- height: 100%;
13
- width: 100%;
14
- background: conic-gradient(hsl(0 100% 50%),
15
- hsl(60 100% 50%),
16
- hsl(120 100% 50%),
17
- hsl(180 100% 50%),
18
- hsl(240 100% 50%),
19
- hsl(300 100% 50%),
20
- hsl(360 100% 50%));
21
- clip-path: circle(closest-side);
22
- mask: radial-gradient(circle at center, transparent 20%, black 35%, black 55%, transparent 70%, transparent 100%);
23
- transition: 200ms ease-in-out;
24
- }
25
-
26
- .circulo.hide {
27
- opacity: 0.2;
28
- mask: radial-gradient(circle at center, transparent 30%, black 50%, transparent 70%);
29
- transition: 200ms ease-in-out;
30
- }
31
-
32
- .arrow {
33
- position: absolute;
34
- border-radius: 50%;
35
- top: calc(50% - 10px);
36
- left: calc(50% - 10px);
37
- height: 20px;
38
- width: 20px;
39
- display: flex;
40
- justify-content: center;
41
- align-items: center;
42
- transition: 0.3s;
43
- font-size: 24px;
44
- transform: rotate(var(--arrowAngle));
45
- z-index: 2;
46
- }
47
-
48
- .arrow i {
49
- color: hsl(var(--atualColor) 100% 50%);
50
- }
@@ -1,8 +0,0 @@
1
- <div class="container" [style.--atualColor]="angle()">
2
- <div class="circulo {{ angle() != null ? 'show' : 'hide' }}"></div>
3
- @if(angle() != null){
4
- <div class="arrow" [style.--arrowAngle]="(angle()! - 47) + 'deg'">
5
- <i class="bi bi-cursor-fill"></i>
6
- </div>
7
- }
8
- </div>
@@ -1,24 +0,0 @@
1
- import { Component, computed, input } from '@angular/core';
2
- import { LibUtil } from '../../../util/util';
3
-
4
- @Component({
5
- selector: 'field-color-circulocolorido',
6
- templateUrl: './circulocolorido.html',
7
- styleUrls: ['./circulocolorido.css'],
8
- })
9
- export class CirculoColorido {
10
-
11
- valor = input<string | number | null>(null);
12
-
13
- angle = computed<number | null>(() => {
14
- let angle = this.valor();
15
- if (!angle) return null;
16
- if (LibUtil.classof(angle) === 'string') {
17
- let num = Number(angle);
18
- if (isNaN(num)) return 0;
19
- angle = num;
20
- }
21
- return angle as number | null;
22
- });
23
-
24
- }
@@ -1,15 +0,0 @@
1
- .fieldComRange {
2
- display: flex;
3
- align-items: center;
4
- width: 100%;
5
- gap: 0.5rem;
6
- flex-direction: column;
7
- }
8
-
9
- input[type="range"] {
10
- opacity: 0.7;
11
- }
12
-
13
- input[type="range"]:disabled {
14
- opacity: 0.1;
15
- }
@@ -1,24 +0,0 @@
1
- <div class="fieldContainer" [class.isTouched]="campo()?.touched" [class.showTouched]="form().showTouched()"
2
- [class.isInvalid]="campo()?.invalid" [class.isDisabled]="campo()?.disabled" [class.isReadonly]="campo()?.readonly"
3
- [class.isNeed]="campo()?.need" [class.isPending]="campo()?.pending" [class.isEmpty]="campo()?.empty">
4
- <div class="fieldLabel" (click)="onClickLabel()" [class.hideLabel]="campo()?.hideLabel">
5
- @if(campo()?.icone){ <div class="fieldIcon"><i [class]="campo()?.icone"></i></div> }
6
- {{ campo()?.titulo }}
7
- </div>
8
- <div class="fieldControl doCampo">
9
- <field-color-circulocolorido [valor]="value()"></field-color-circulocolorido>
10
- <div class="fieldComRange">
11
- <div class="fieldEffect">
12
- <div class="fieldField FieldColor">
13
- <input type="number" [value]="value()" (input)="onInput($event.target.value)" (change)="onChangeEmit()"
14
- [name]="campo()?.prop" [disabled]="campo()?.disabled" [placeholder]="campo()?.placeholder ?? ''"
15
- [attr.maxLength]="campo()?.maxl" [attr.minLength]="campo()?.minl" [class]="campo()?.classe"
16
- [style]="campo()?.style" min="0" max="360" [class.outlined]="true" [class.input]="true" />
17
- </div>
18
- </div>
19
- <input type="range" [value]="value() ?? 0" (input)="onInputRange($event)" min="0" max="360"
20
- [disabled]="campo()?.disabled" (change)="onChangeEmit()" />
21
- </div>
22
- </div>
23
- <ui-list-errors [errors]="campo()?.errors" [dica]="campo()?.dica" [show]="campo()?.touched"></ui-list-errors>
24
- </div>
@@ -1,47 +0,0 @@
1
- import { Component, effect, OnInit } from '@angular/core';
2
- import { BaseFieldsForm } from '../Base/BaseFieldsForm/BaseFieldsForm.component';
3
- import { CirculoColorido } from './CirculoColorido/circulocolorido';
4
- import { UiListErrors } from "../../elements/ui-list-errors/ui-list-errors";
5
-
6
- @Component({
7
- selector: 'fields-color',
8
- templateUrl: './color.html',
9
- styleUrls: ['../fields.css', './color.css'],
10
- imports: [CirculoColorido, UiListErrors],
11
- })
12
- export class FieldsColor extends BaseFieldsForm implements OnInit {
13
-
14
- constructor() {
15
- super();
16
- effect(() => {
17
- const val = this.value();
18
- let empty = val === null || val === undefined || val === '' || val === 0;
19
- // if (val && LibUtil.classof(val) === 'number' && (val < 0 || val > 360)) {
20
- // errors = [...errors, Valide.msg.apenasEntre(0, 360)];
21
- // }
22
- this.updateCampo({ empty });
23
- });
24
- }
25
-
26
- override ngOnInit() {
27
- super.ngOnInit();
28
- this.onInput(this.value(), false);
29
- }
30
-
31
- onInput(newValue: string, touch: boolean = true) {
32
- let num = Number(newValue);
33
- if (isNaN(num)) num = 0;
34
- this.updateValue(num, touch);
35
- this.campo()?.onInput?.(this.form());
36
- }
37
-
38
- onInputRange(event: any) {
39
- let num = Number(event.target.value);
40
- if (isNaN(num)) num = 0;
41
- if (num < 0) num = 0;
42
- if (num > 360) num = 360;
43
- this.updateValue(num);
44
- this.campo()?.onInput?.(this.form());
45
- }
46
-
47
- }
@@ -1,19 +0,0 @@
1
- <div class="fieldContainer" [class.isTouched]="campo()?.touched" [class.showTouched]="form().showTouched()"
2
- [class.isInvalid]="campo()?.invalid" [class.isDisabled]="campo()?.disabled" [class.isReadonly]="campo()?.readonly"
3
- [class.isNeed]="campo()?.need" [class.isPending]="campo()?.pending" [class.isEmpty]="campo()?.empty">
4
- <div class="fieldLabel" (click)="onClickLabel()" [class.hideLabel]="campo()?.hideLabel">
5
- @if(campo()?.icone){ <div class="fieldIcon"><i [class]="campo()?.icone"></i></div> }
6
- {{ campo()?.titulo }}
7
- </div>
8
- <div class="fieldControl doCampo">
9
- <div class="fieldEffect">
10
- <div class="fieldField FieldDate">
11
- <input type="date" [value]="value()" (input)="onInput($event.target.value)" (change)="onChangeEmit()"
12
- [name]="campo()?.prop" [disabled]="campo()?.disabled" [placeholder]="campo()?.placeholder ?? ''"
13
- [attr.maxLength]="campo()?.maxl" [attr.minLength]="campo()?.minl" [class]="campo()?.classe"
14
- [style]="campo()?.style" [class.outlined]="true" [class.input]="true" />
15
- </div>
16
- </div>
17
- </div>
18
- <ui-list-errors [errors]="campo()?.errors" [dica]="campo()?.dica" [show]="campo()?.touched"></ui-list-errors>
19
- </div>
@@ -1,29 +0,0 @@
1
- import { Component, effect } from '@angular/core';
2
- import { LibUtil } from '../../util/util';
3
- import { BaseFieldsForm } from '../Base/BaseFieldsForm/BaseFieldsForm.component';
4
- import { UiListErrors } from "../../elements/ui-list-errors/ui-list-errors";
5
-
6
- @Component({
7
- selector: 'fields-date',
8
- templateUrl: './date.html',
9
- styleUrls: ['../fields.css'],
10
- imports: [UiListErrors],
11
- })
12
- export class FieldsDate extends BaseFieldsForm {
13
-
14
- constructor() {
15
- super();
16
- effect(() => {
17
- const val = this.value();
18
- let empty = val === null || val === undefined || val === '';
19
- this.updateCampo({ empty });
20
- });
21
- }
22
-
23
- onInput(newValue: string) {
24
- if (this.campo()?.mask) newValue = LibUtil.mascarar(newValue, this.campo()?.mask) ?? '';
25
- this.updateValue(newValue);
26
- this.campo()?.onInput?.(this.form());
27
- }
28
-
29
- }