@block-auth.io/angular 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 (148) hide show
  1. package/.turbo/turbo-build.log +37 -0
  2. package/.turbo/turbo-lint.log +4 -0
  3. package/.turbo/turbo-test.log +82 -0
  4. package/.turbo/turbo-typecheck.log +4 -0
  5. package/CHANGELOG.md +10 -0
  6. package/ng-package.json +6 -0
  7. package/package.json +50 -0
  8. package/scripts/css-to-ts.mjs +14 -0
  9. package/src/lib/__tests__/integration.test.ts +45 -0
  10. package/src/lib/block-auth.service.test.ts +69 -0
  11. package/src/lib/block-auth.service.ts +81 -0
  12. package/src/lib/components/btns/btn-base-provider.component.test.ts +22 -0
  13. package/src/lib/components/btns/btn-base-provider.component.ts +55 -0
  14. package/src/lib/components/btns/btn-block-auth.component.test.ts +79 -0
  15. package/src/lib/components/btns/btn-block-auth.component.ts +104 -0
  16. package/src/lib/components/btns/btn-gmail.component.test.ts +16 -0
  17. package/src/lib/components/btns/btn-gmail.component.ts +41 -0
  18. package/src/lib/components/btns/btn-google-base.component.test.ts +16 -0
  19. package/src/lib/components/btns/btn-google-base.component.ts +73 -0
  20. package/src/lib/components/btns/btn-metamask.component.test.ts +20 -0
  21. package/src/lib/components/btns/btn-metamask.component.ts +98 -0
  22. package/src/lib/components/btns/btn-microsoft.component.test.ts +16 -0
  23. package/src/lib/components/btns/btn-microsoft.component.ts +77 -0
  24. package/src/lib/components/btns/btn-phantom.component.test.ts +20 -0
  25. package/src/lib/components/btns/btn-phantom.component.ts +93 -0
  26. package/src/lib/components/btns/btn-signin.component.test.ts +55 -0
  27. package/src/lib/components/btns/btn-signin.component.ts +108 -0
  28. package/src/lib/components/btns/btn-wallet-connect.component.test.ts +20 -0
  29. package/src/lib/components/btns/btn-wallet-connect.component.ts +109 -0
  30. package/src/lib/components/btns/index.ts +11 -0
  31. package/src/lib/components/contents/content-signin.component.test.ts +33 -0
  32. package/src/lib/components/contents/content-signin.component.ts +68 -0
  33. package/src/lib/components/contents/content-signup.component.test.ts +78 -0
  34. package/src/lib/components/contents/content-signup.component.ts +225 -0
  35. package/src/lib/components/dds/change-account.component.test.ts +66 -0
  36. package/src/lib/components/dds/change-account.component.ts +112 -0
  37. package/src/lib/components/dds/dropdown-profile-btn.component.test.ts +66 -0
  38. package/src/lib/components/dds/dropdown-profile-btn.component.ts +185 -0
  39. package/src/lib/components/dds/dropdown-profile-item.component.test.ts +75 -0
  40. package/src/lib/components/dds/dropdown-profile-item.component.ts +74 -0
  41. package/src/lib/components/dds/dropdown-profile.component.test.ts +98 -0
  42. package/src/lib/components/dds/dropdown-profile.component.ts +258 -0
  43. package/src/lib/components/flow-block-auth.component.test.ts +93 -0
  44. package/src/lib/components/flow-block-auth.component.ts +226 -0
  45. package/src/lib/components/modals/modal-overlay.component.test.ts +81 -0
  46. package/src/lib/components/modals/modal-overlay.component.ts +43 -0
  47. package/src/lib/components/modals/modal-restoration-expired.component.test.ts +71 -0
  48. package/src/lib/components/modals/modal-restoration-expired.component.ts +83 -0
  49. package/src/lib/components/modals/modal-restore.component.test.ts +74 -0
  50. package/src/lib/components/modals/modal-restore.component.ts +104 -0
  51. package/src/lib/components/modals/modal-signin.component.test.ts +66 -0
  52. package/src/lib/components/modals/modal-signin.component.ts +44 -0
  53. package/src/lib/components/modals/modal-signup.component.test.ts +56 -0
  54. package/src/lib/components/modals/modal-signup.component.ts +40 -0
  55. package/src/lib/components/sections/footer-section.component.test.ts +19 -0
  56. package/src/lib/components/sections/footer-section.component.ts +49 -0
  57. package/src/lib/components/sections/internals/providers-buttons.component.test.ts +27 -0
  58. package/src/lib/components/sections/internals/providers-buttons.component.ts +290 -0
  59. package/src/lib/components/sections/internals/providers-filters.component.test.ts +25 -0
  60. package/src/lib/components/sections/internals/providers-filters.component.ts +139 -0
  61. package/src/lib/components/sections/internals/selected-button.component.test.ts +36 -0
  62. package/src/lib/components/sections/internals/selected-button.component.ts +92 -0
  63. package/src/lib/components/sections/login-section.component.test.ts +49 -0
  64. package/src/lib/components/sections/login-section.component.ts +120 -0
  65. package/src/lib/components/sections/providers-section.component.test.ts +22 -0
  66. package/src/lib/components/sections/providers-section.component.ts +187 -0
  67. package/src/lib/components/txns/internals/permissions-required-modal.component.test.ts +14 -0
  68. package/src/lib/components/txns/internals/permissions-required-modal.component.ts +35 -0
  69. package/src/lib/components/txns/internals/solicited-data-modal.component.test.ts +72 -0
  70. package/src/lib/components/txns/internals/solicited-data-modal.component.ts +187 -0
  71. package/src/lib/components/txns/internals/txn-error.component.test.ts +100 -0
  72. package/src/lib/components/txns/internals/txn-error.component.ts +121 -0
  73. package/src/lib/components/txns/internals/txn-type.component.test.ts +52 -0
  74. package/src/lib/components/txns/internals/txn-type.component.ts +51 -0
  75. package/src/lib/components/txns/internals/txn.component.test.ts +188 -0
  76. package/src/lib/components/txns/internals/txn.component.ts +298 -0
  77. package/src/lib/components/txns/txns-overview.component.test.ts +107 -0
  78. package/src/lib/components/txns/txns-overview.component.ts +229 -0
  79. package/src/lib/icons/ai-outline-disconnect.component.ts +21 -0
  80. package/src/lib/icons/bi-logo-gmail.component.ts +21 -0
  81. package/src/lib/icons/cg-profile.component.ts +31 -0
  82. package/src/lib/icons/check-icon.component.ts +27 -0
  83. package/src/lib/icons/ci-clock2.component.ts +31 -0
  84. package/src/lib/icons/fa-arrow-right.component.ts +21 -0
  85. package/src/lib/icons/fa-times.component.ts +21 -0
  86. package/src/lib/icons/fa-undo.component.ts +21 -0
  87. package/src/lib/icons/icons.test.ts +25 -0
  88. package/src/lib/icons/index.ts +22 -0
  89. package/src/lib/icons/io-ios-arrow-back.component.ts +21 -0
  90. package/src/lib/icons/io-ios-arrow-forward.component.ts +21 -0
  91. package/src/lib/icons/io-md-arrow-back.component.ts +19 -0
  92. package/src/lib/icons/io-md-arrow-forward.component.ts +19 -0
  93. package/src/lib/icons/pi-warning-fill.component.ts +21 -0
  94. package/src/lib/icons/tb-arrows-exchange2.component.ts +30 -0
  95. package/src/lib/icons/tb-copy-check-filled.component.ts +21 -0
  96. package/src/lib/icons/tb-copy.component.ts +34 -0
  97. package/src/lib/icons/ti-vendor-microsoft.component.ts +21 -0
  98. package/src/lib/inject-store.test.ts +26 -0
  99. package/src/lib/inject-store.ts +16 -0
  100. package/src/lib/primitives/arrow-icon.component.test.ts +12 -0
  101. package/src/lib/primitives/arrow-icon.component.ts +38 -0
  102. package/src/lib/primitives/btn-arrow-dir.component.test.ts +22 -0
  103. package/src/lib/primitives/btn-arrow-dir.component.ts +65 -0
  104. package/src/lib/primitives/btn-base.component.test.ts +38 -0
  105. package/src/lib/primitives/btn-base.component.ts +140 -0
  106. package/src/lib/primitives/divider-base.component.test.ts +12 -0
  107. package/src/lib/primitives/divider-base.component.ts +74 -0
  108. package/src/lib/primitives/dropdown-arrow.component.test.ts +12 -0
  109. package/src/lib/primitives/dropdown-arrow.component.ts +46 -0
  110. package/src/lib/primitives/dropdown-base.component.test.ts +49 -0
  111. package/src/lib/primitives/dropdown-base.component.ts +329 -0
  112. package/src/lib/primitives/helpers.ts +151 -0
  113. package/src/lib/primitives/horizontal-loader.component.test.ts +19 -0
  114. package/src/lib/primitives/horizontal-loader.component.ts +70 -0
  115. package/src/lib/primitives/icon-base.component.test.ts +19 -0
  116. package/src/lib/primitives/icon-base.component.ts +58 -0
  117. package/src/lib/primitives/img-loader.component.test.ts +12 -0
  118. package/src/lib/primitives/img-loader.component.ts +118 -0
  119. package/src/lib/primitives/index.ts +29 -0
  120. package/src/lib/primitives/input-base.component.test.ts +20 -0
  121. package/src/lib/primitives/input-base.component.ts +210 -0
  122. package/src/lib/primitives/lifetime-slider-base.component.test.ts +88 -0
  123. package/src/lib/primitives/lifetime-slider-base.component.ts +75 -0
  124. package/src/lib/primitives/oval-spinner.component.test.ts +9 -0
  125. package/src/lib/primitives/oval-spinner.component.ts +158 -0
  126. package/src/lib/primitives/pickers/dropdown-picker-animated-base.component.ts +220 -0
  127. package/src/lib/primitives/pickers/picker-button.component.ts +74 -0
  128. package/src/lib/primitives/pickers/time-picker-dropdown-selector.component.ts +188 -0
  129. package/src/lib/primitives/pickers/time-picker.component.ts +124 -0
  130. package/src/lib/primitives/pickers/time-unit-selector.component.ts +82 -0
  131. package/src/lib/primitives/progressbar.component.test.ts +18 -0
  132. package/src/lib/primitives/progressbar.component.ts +93 -0
  133. package/src/lib/primitives/providersStyles.ts +268 -0
  134. package/src/lib/primitives/slider-base.component.ts +56 -0
  135. package/src/lib/provide-block-auth.test.ts +43 -0
  136. package/src/lib/provide-block-auth.ts +43 -0
  137. package/src/lib/runtime/block-auth-runtime.directive.test.ts +89 -0
  138. package/src/lib/runtime/block-auth-runtime.directive.ts +68 -0
  139. package/src/lib/teleport-body.directive.test.ts +29 -0
  140. package/src/lib/teleport-body.directive.ts +21 -0
  141. package/src/lib/testing.ts +15 -0
  142. package/src/lib/transitions.css +23 -0
  143. package/src/public-api.ts +85 -0
  144. package/src/vitest.setup.ts +8 -0
  145. package/tailwind.config.cjs +6 -0
  146. package/tsconfig.json +15 -0
  147. package/tsconfig.lib.json +9 -0
  148. package/vite.config.mts +44 -0
@@ -0,0 +1,124 @@
1
+ import { ChangeDetectionStrategy, Component, computed, input, output } from '@angular/core';
2
+ import { convertSecondsToTime, formatNumberToString } from '../helpers';
3
+ import { CiClock2Component } from '../../icons';
4
+ import { DropdownPickerAnimatedBaseComponent } from './dropdown-picker-animated-base.component';
5
+ import {
6
+ TimePickerDropdownSelectorComponent,
7
+ type TimeArrays,
8
+ } from './time-picker-dropdown-selector.component';
9
+
10
+ // Picker de tiempo `HH:MM:SS`. Construye los rangos de horas/minutos/segundos a
11
+ // partir de los límites `min`/`max` en segundos y los renderiza dentro del
12
+ // `<ba-dropdown-picker-animated-base>`. El label de Guardar llega por
13
+ // `btnSaveText`. El icono del reloj usa `<ba-ci-clock2>`.
14
+ // `:host { display: contents }`: el shell del picker es el hijo real del
15
+ // contenedor.
16
+ @Component({
17
+ selector: 'ba-time-picker',
18
+ standalone: true,
19
+ changeDetection: ChangeDetectionStrategy.OnPush,
20
+ host: { style: 'display: contents' },
21
+ imports: [
22
+ DropdownPickerAnimatedBaseComponent,
23
+ TimePickerDropdownSelectorComponent,
24
+ CiClock2Component,
25
+ ],
26
+ template: `
27
+ <ba-dropdown-picker-animated-base
28
+ [isOpen]="isOpen()"
29
+ [size]="size()"
30
+ [enableError]="enableError()"
31
+ [enableWhiteSpaces]="enableWhiteSpaces()"
32
+ [error]="error()"
33
+ [errorMessage]="errorMessage()"
34
+ [btnId]="id() + '-btn'"
35
+ [inputId]="id() + '-time-input'"
36
+ [inputValue]="timeInputValue()"
37
+ [container]="container()"
38
+ [exceptions]="exceptions()"
39
+ [width]="width()"
40
+ [isInsideModal]="isInsideModal()"
41
+ [modalId]="modalId()"
42
+ [dropdownDirection]="dropdownDirection()"
43
+ [classNames]="classNames()"
44
+ [btnZIndexClassNames]="btnZIndexClassNames()"
45
+ [dropdownZIndexClassNames]="dropdownZIndexClassNames()"
46
+ (isOpenChange)="isOpenChange.emit($event)"
47
+ (toggleDropdown)="toggleTimerDropdown.emit()"
48
+ >
49
+ <ba-ci-clock2
50
+ slot="icon"
51
+ class="bal-ba-transition-150 bas-h-6 bas-w-6 bas-cursor-pointer bas-text-[#468faf] hover:bas-text-[#014f86]"
52
+ />
53
+
54
+ <ba-time-picker-dropdown-selector
55
+ [id]="id()"
56
+ [hoursArray]="hoursArray()"
57
+ [minutesArrays]="minutesArrays()"
58
+ [secondsArrays]="secondsArrays()"
59
+ [defaultValues]="timeInputValue()"
60
+ [btnSaveText]="btnSaveText()"
61
+ (timeChanged)="timeChanged.emit($event)"
62
+ (toggleTimerDropdown)="toggleTimerDropdown.emit()"
63
+ />
64
+ </ba-dropdown-picker-animated-base>
65
+ `,
66
+ })
67
+ export class TimePickerComponent {
68
+ id = input('time-picker');
69
+ size = input<'xxs' | 'xs' | 'small' | 'base' | 'large'>('base');
70
+ isOpen = input(false);
71
+ min = input(10);
72
+ max = input(29100);
73
+ enableError = input(false);
74
+ enableWhiteSpaces = input(true);
75
+ error = input(false);
76
+ errorMessage = input('');
77
+ timeInputValue = input('01:00:00');
78
+ container = input<HTMLElement | null>(null);
79
+ exceptions = input<(HTMLElement | null)[]>([]);
80
+ btnSaveText = input('Save');
81
+ width = input<number | string>(152);
82
+ isInsideModal = input(false);
83
+ modalId = input('txns-overview');
84
+ dropdownDirection = input<'up' | 'down'>('down');
85
+ classNames = input('');
86
+ btnZIndexClassNames = input('bas-z-0');
87
+ dropdownZIndexClassNames = input('bas-z-50');
88
+
89
+ isOpenChange = output<boolean>();
90
+ toggleTimerDropdown = output<void>();
91
+ timeChanged = output<number>();
92
+
93
+ protected readonly hoursArray = computed(() =>
94
+ this.getHoursArray(this.min(), this.max()),
95
+ );
96
+ protected readonly minutesArrays = computed(() =>
97
+ this.getTimeArrays(this.min(), this.max(), 'minutes'),
98
+ );
99
+ protected readonly secondsArrays = computed(() =>
100
+ this.getTimeArrays(this.min(), this.max(), 'seconds'),
101
+ );
102
+
103
+ private getHoursArray(minSeconds: number, maxSeconds: number): string[] {
104
+ const minHours = convertSecondsToTime(minSeconds).hours;
105
+ const maxHours = convertSecondsToTime(maxSeconds).hours;
106
+ return Array.from({ length: maxHours - minHours + 1 }, (_, i) =>
107
+ formatNumberToString(i + minHours),
108
+ );
109
+ }
110
+
111
+ private getTimeArrays(
112
+ minSeconds: number,
113
+ maxSeconds: number,
114
+ timeType: 'minutes' | 'seconds',
115
+ ): TimeArrays {
116
+ const minTime = convertSecondsToTime(minSeconds)[timeType];
117
+ const maxTime = convertSecondsToTime(maxSeconds)[timeType];
118
+ return {
119
+ minRange: Array.from({ length: 60 - minTime }, (_, i) => formatNumberToString(i + minTime)),
120
+ defaultRange: Array.from({ length: 60 }, (_, i) => formatNumberToString(i)),
121
+ maxRange: Array.from({ length: maxTime + 1 }, (_, i) => formatNumberToString(i)),
122
+ };
123
+ }
124
+ }
@@ -0,0 +1,82 @@
1
+ import {
2
+ ChangeDetectionStrategy,
3
+ Component,
4
+ ElementRef,
5
+ effect,
6
+ input,
7
+ output,
8
+ signal,
9
+ viewChild,
10
+ } from '@angular/core';
11
+
12
+ // Una columna scrolleable (horas | minutos | segundos) del time picker: al
13
+ // hacer click en un valor lo emite; la columna auto-scrollea para alinear el
14
+ // valor seleccionado arriba (fila de 32px). El `useState(hovered)` +
15
+ // `useEffect(scrollTop)` de react -> signal + effect. `onChangeTimeUnit`
16
+ // (callback prop) -> output `changeTimeUnit`.
17
+ // `:host { display: contents }`: el `<div>` scrolleable es el hijo real del
18
+ // grid de 3 columnas (como en react/vue).
19
+ @Component({
20
+ selector: 'ba-time-unit-selector',
21
+ standalone: true,
22
+ changeDetection: ChangeDetectionStrategy.OnPush,
23
+ host: { style: 'display: contents' },
24
+ template: `
25
+ <div
26
+ #scrollableContainer
27
+ [id]="id() + '-' + timeUnit() + '-selector-container'"
28
+ [class]="
29
+ 'bas-overflow-y-scroll bas-scroll-smooth ' +
30
+ (hovered() ? 'bal-ba-scroll-base' : 'bal-ba-no-scrollbar')
31
+ "
32
+ (mouseenter)="hovered.set(true)"
33
+ (mouseleave)="hovered.set(false)"
34
+ >
35
+ <div class="bas-flex bas-h-full bas-w-[38px] bas-flex-col">
36
+ @for (timeValue of timeUnitArray(); track $index) {
37
+ <button
38
+ type="button"
39
+ [id]="id() + '-' + timeUnit() + '-' + timeValue"
40
+ [class]="
41
+ 'bal-ba-transition-150 bas-min-h-8 bas-flex bas-w-full bas-cursor-pointer ' +
42
+ 'bas-items-center bas-justify-center bas-rounded-md bas-border-none ' +
43
+ 'bas-text-sm bas-text-[--bal-primary-800] hover:bas-text-[--bal-primary-900] ' +
44
+ (selectedValue() === timeValue
45
+ ? 'bas-bg-[#caf0f8]'
46
+ : 'bas-bg-transparent hover:bas-bg-[#e1f6fb]')
47
+ "
48
+ (click)="changeTimeUnit.emit({ timeUnit: timeUnit(), value: timeValue })"
49
+ >
50
+ <p class="bas-m-0">{{ timeValue }}</p>
51
+ </button>
52
+ }
53
+ <span class="bas-min-h-[200px] bas-w-full"></span>
54
+ </div>
55
+ </div>
56
+ `,
57
+ })
58
+ export class TimeUnitSelectorComponent {
59
+ id = input('time-picker');
60
+ timeUnitArray = input<string[]>([]);
61
+ timeUnit = input<'hours' | 'minutes' | 'seconds' | ''>('');
62
+ selectedValue = input('');
63
+ firstValue = input(0);
64
+
65
+ changeTimeUnit = output<{ timeUnit: string; value: string }>();
66
+
67
+ protected readonly hovered = signal(false);
68
+ private readonly scrollableContainer =
69
+ viewChild<ElementRef<HTMLDivElement>>('scrollableContainer');
70
+
71
+ constructor() {
72
+ // Alinea el valor seleccionado arriba (32px por fila).
73
+ effect(() => {
74
+ const selectedNumber = parseInt(this.selectedValue(), 10);
75
+ const firstNumber = Number(this.firstValue());
76
+ const el = this.scrollableContainer()?.nativeElement;
77
+ if (el && !Number.isNaN(selectedNumber)) {
78
+ el.scrollTop = 32 * (selectedNumber - firstNumber);
79
+ }
80
+ });
81
+ }
82
+ }
@@ -0,0 +1,18 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { Component } from '@angular/core';
3
+ import { render, screen } from '@testing-library/angular';
4
+ import { ProgressbarComponent } from './progressbar.component';
5
+ describe('ProgressbarComponent', () => {
6
+ it('percent 100 cuando step3', async () => {
7
+ @Component({ standalone: true, imports: [ProgressbarComponent], template: `<ba-progressbar [step3]="true" />` })
8
+ class Host {}
9
+ await render(Host);
10
+ expect(screen.getByTestId('progressbar-fill').getAttribute('data-percent')).toBe('100');
11
+ });
12
+ it('percent 15 cuando step1', async () => {
13
+ @Component({ standalone: true, imports: [ProgressbarComponent], template: `<ba-progressbar [step1]="true" />` })
14
+ class Host {}
15
+ await render(Host);
16
+ expect(screen.getByTestId('progressbar-fill').getAttribute('data-percent')).toBe('15');
17
+ });
18
+ });
@@ -0,0 +1,93 @@
1
+ import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';
2
+
3
+ // El original orquesta 12
4
+ // AnimationControls de framer-motion; siguiendo el port Vue, esa coreografía
5
+ // se sustituye por un único porcentaje derivado de los mismos props (`percent`)
6
+ // que revela una capa coloreada superpuesta a la de fondo mediante `clip-path`,
7
+ // animado con `transition` CSS. El subrayado decorativo no se reproduce.
8
+ //
9
+ // `activeUnderlineWhenFillStep1`/`activeUnderlineWhenFillToStep2` se aceptan
10
+ // por paridad de API pero no afectan a `percent` (solo controlaban el
11
+ // subrayado). Prioridad de `percent`: gana el flag del paso más avanzado
12
+ // (misma elección deliberada documentada en Progressbar.vue).
13
+ @Component({
14
+ selector: 'ba-progressbar',
15
+ standalone: true,
16
+ changeDetection: ChangeDetectionStrategy.OnPush,
17
+ template: `
18
+ <div class="bas-relative bas-flex bas-h-[54px] bas-w-60 bas-flex-row bas-items-center bas-justify-between">
19
+ <!-- Fondo apagado (siempre visible) -->
20
+ <svg height="30" width="30" style="z-index: 1" xmlns="http://www.w3.org/2000/svg">
21
+ <path d="M4,15a11,11 0 1,0 22,0a11,11 0 1,0 -22,0" stroke="#acd4e4" stroke-width="5" fill="transparent" />
22
+ </svg>
23
+ <svg width="82" height="8" style="position: absolute; left: 26px; z-index: 0" xmlns="http://www.w3.org/2000/svg">
24
+ <path fill="#c4e0ec" d="M0 0h90v10H0Z" />
25
+ </svg>
26
+ <svg height="30" width="30" style="z-index: 1" xmlns="http://www.w3.org/2000/svg">
27
+ <path d="M4,15a11,11 0 1,0 22,0a11,11 0 1,0 -22,0" stroke="#acd4e4" stroke-width="5" fill="transparent" />
28
+ </svg>
29
+ <svg width="82" height="8" style="position: absolute; left: 130px; z-index: 0" xmlns="http://www.w3.org/2000/svg">
30
+ <path fill="#c4e0ec" d="M0 0h90v10H0Z" />
31
+ </svg>
32
+ <svg height="30" width="30" style="z-index: 1" xmlns="http://www.w3.org/2000/svg">
33
+ <path d="M4,15a11,11 0 1,0 22,0a11,11 0 1,0 -22,0" stroke="#acd4e4" stroke-width="5" fill="transparent" />
34
+ </svg>
35
+
36
+ <!-- Capa coloreada, revelada según percent -->
37
+ <div
38
+ class="bas-absolute bas-flex bas-h-full bas-w-full bas-flex-row bas-items-center bas-justify-between bas-progress-fill"
39
+ [style.clip-path]="'inset(0 ' + (100 - percent()) + '% 0 0)'"
40
+ data-testid="progressbar-fill"
41
+ [attr.data-percent]="percent()"
42
+ >
43
+ <svg height="30" width="30" style="z-index: 1" xmlns="http://www.w3.org/2000/svg">
44
+ <path d="M4,15a11,11 0 1,0 22,0a11,11 0 1,0 -22,0" stroke="#1961a4" stroke-width="5" fill="transparent" />
45
+ <circle r="5" cx="15" cy="15" fill="#1961a4" />
46
+ </svg>
47
+ <svg width="84" height="8" style="position: absolute; left: 26px; z-index: 0" xmlns="http://www.w3.org/2000/svg">
48
+ <path fill="#1961a4" d="M0 0h90v10H0Z" />
49
+ </svg>
50
+ <svg height="30" width="30" style="z-index: 1" xmlns="http://www.w3.org/2000/svg">
51
+ <path d="M4,15a11,11 0 1,0 22,0a11,11 0 1,0 -22,0" stroke="#1961a4" stroke-width="5" fill="transparent" />
52
+ <circle r="5" cx="15" cy="15" fill="#1961a4" />
53
+ </svg>
54
+ <svg width="84" height="8" style="position: absolute; left: 130px; z-index: 0" xmlns="http://www.w3.org/2000/svg">
55
+ <path fill="#1961a4" d="M0 0h90v10H0Z" />
56
+ </svg>
57
+ <svg height="30" width="30" style="z-index: 1" xmlns="http://www.w3.org/2000/svg">
58
+ <path d="M4,15a11,11 0 1,0 22,0a11,11 0 1,0 -22,0" stroke="#1961a4" stroke-width="5" fill="transparent" />
59
+ <circle r="5" cx="15" cy="15" fill="#1961a4" />
60
+ </svg>
61
+ </div>
62
+ </div>
63
+ `,
64
+ styles: [
65
+ `
66
+ .bas-progress-fill {
67
+ transition: clip-path 0.6s ease;
68
+ }
69
+ `,
70
+ ],
71
+ })
72
+ export class ProgressbarComponent {
73
+ step1 = input(false);
74
+ step2 = input(false);
75
+ step3 = input(false);
76
+ goBackToStep1 = input(false);
77
+ goBackToStep2 = input(false);
78
+ fillStep1 = input(false);
79
+ activeUnderlineWhenFillStep1 = input(false);
80
+ fillToStep2 = input(false);
81
+ activeUnderlineWhenFillToStep2 = input(false);
82
+
83
+ percent = computed(() => {
84
+ if (this.step3()) return 100;
85
+ if (this.step2()) return 50;
86
+ if (this.step1()) return 15;
87
+ if (this.goBackToStep2()) return 50;
88
+ if (this.goBackToStep1()) return 15;
89
+ if (this.fillToStep2()) return 50;
90
+ if (this.fillStep1()) return 15;
91
+ return 0;
92
+ });
93
+ }
@@ -0,0 +1,268 @@
1
+ // Port literal de packages/react/src/primitives/providersStyles.ts: mapa de
2
+ // estilos por provider, TS puro sin dependencias de React, copiado tal cual.
3
+ import { imgUrlByService } from './helpers';
4
+
5
+ export interface ProviderStyle {
6
+ /** Nombre para mostrar del provider. */
7
+ name: string;
8
+ /** Slug del provider. */
9
+ value: string;
10
+ /** URL del icono. */
11
+ imgSrc: string;
12
+ /** Color de fondo detrás del icono del provider en el loader. */
13
+ imgBgColor: string;
14
+ /** Color del loader (spinner). */
15
+ loaderColor: string;
16
+ /** Color base de marca. */
17
+ colorBase: string;
18
+ /** Clase `bas-*` de borde aplicada cuando el provider está seleccionado. */
19
+ borderStyles: string;
20
+ /** Clase `bas-*` de borde aplicada en hover. */
21
+ hoverBorderStyles: string;
22
+ }
23
+
24
+ export const providersStyles: Record<string, ProviderStyle> = {
25
+ blockauth: {
26
+ name: 'BlockAuth',
27
+ value: 'blockauth',
28
+ imgSrc: imgUrlByService('blockauth'),
29
+ imgBgColor: '#eff6ff',
30
+ loaderColor: '#1961a4',
31
+ colorBase: '#1961a4',
32
+ borderStyles: 'bas-border-[var(--bal-primary-100)]',
33
+ hoverBorderStyles: 'hover:bas-border-[var(--bal-primary-300)]',
34
+ },
35
+ google: {
36
+ name: 'Google',
37
+ value: 'google',
38
+ imgSrc: imgUrlByService('google'),
39
+ imgBgColor: '#fef2f2',
40
+ loaderColor: '#ef4444',
41
+ colorBase: '#dc2626',
42
+ borderStyles: 'bas-border-red-400',
43
+ hoverBorderStyles: 'hover:bas-border-red-600',
44
+ },
45
+ metamask: {
46
+ name: 'MetaMask',
47
+ value: 'metamask',
48
+ imgSrc: imgUrlByService('metamask'),
49
+ imgBgColor: '#fff7ed',
50
+ loaderColor: '#f97316',
51
+ colorBase: '#ea580c',
52
+ borderStyles: 'bas-border-orange-400',
53
+ hoverBorderStyles: 'hover:bas-border-orange-600',
54
+ },
55
+ microsoft: {
56
+ name: 'Microsoft',
57
+ value: 'microsoft',
58
+ imgSrc: imgUrlByService('microsoft'),
59
+ imgBgColor: '#eff6ff',
60
+ loaderColor: '#106ebe',
61
+ colorBase: '#106ebe',
62
+ borderStyles: 'bas-border-[#1d8dec]',
63
+ hoverBorderStyles: 'hover:bas-border-[#106ebe]',
64
+ },
65
+ phantom: {
66
+ name: 'Phantom',
67
+ value: 'phantom',
68
+ imgSrc: imgUrlByService('phantom'),
69
+ imgBgColor: '#faf5ff',
70
+ loaderColor: '#9333ea',
71
+ colorBase: '#9333ea',
72
+ borderStyles: 'bas-border-purple-400',
73
+ hoverBorderStyles: 'hover:bas-border-purple-600',
74
+ },
75
+ trustWallet: {
76
+ name: 'Trust Wallet',
77
+ value: 'trustwallet',
78
+ imgSrc: 'https://dashboard.block-auth.io/img/providers/trust-wallet.png',
79
+ imgBgColor: '#f0f9ff',
80
+ loaderColor: '#0b69ff',
81
+ colorBase: '#0b69ff',
82
+ borderStyles: 'bas-border-blue-400',
83
+ hoverBorderStyles: 'hover:bas-border-blue-600',
84
+ },
85
+ binance: {
86
+ name: 'Binance',
87
+ value: 'binance',
88
+ imgSrc: 'https://dashboard.block-auth.io/img/providers/binance.png',
89
+ imgBgColor: '#f0f9ff',
90
+ loaderColor: '#0b69ff',
91
+ colorBase: '#0b69ff',
92
+ borderStyles: 'bas-border-blue-400',
93
+ hoverBorderStyles: 'hover:bas-border-blue-600',
94
+ },
95
+ uniswap: {
96
+ name: 'Uniswap',
97
+ value: 'uniswap',
98
+ imgSrc: 'https://dashboard.block-auth.io/img/providers/uniswap.png',
99
+ imgBgColor: '#f0f9ff',
100
+ loaderColor: '#0b69ff',
101
+ colorBase: '#0b69ff',
102
+ borderStyles: 'bas-border-blue-400',
103
+ hoverBorderStyles: 'hover:bas-border-blue-600',
104
+ },
105
+ bitget: {
106
+ name: 'Bitget',
107
+ value: 'bitget',
108
+ imgSrc: 'https://dashboard.block-auth.io/img/providers/bitget.png',
109
+ imgBgColor: '#f0f9ff',
110
+ loaderColor: '#0b69ff',
111
+ colorBase: '#0b69ff',
112
+ borderStyles: 'bas-border-blue-400',
113
+ hoverBorderStyles: 'hover:bas-border-blue-600',
114
+ },
115
+ legder: {
116
+ name: 'Legder',
117
+ value: 'legder',
118
+ imgSrc: 'https://dashboard.block-auth.io/img/providers/legder.png',
119
+ imgBgColor: '#f0f9ff',
120
+ loaderColor: '#0b69ff',
121
+ colorBase: '#0b69ff',
122
+ borderStyles: 'bas-border-blue-400',
123
+ hoverBorderStyles: 'hover:bas-border-blue-600',
124
+ },
125
+ robinhood: {
126
+ name: 'Robinhood',
127
+ value: 'robinhood',
128
+ imgSrc: 'https://dashboard.block-auth.io/img/providers/robinhood.png',
129
+ imgBgColor: '#f0f9ff',
130
+ loaderColor: '#0b69ff',
131
+ colorBase: '#0b69ff',
132
+ borderStyles: 'bas-border-blue-400',
133
+ hoverBorderStyles: 'hover:bas-border-blue-600',
134
+ },
135
+ blockchaincom: {
136
+ name: 'Blockchain.com',
137
+ value: 'blockchaincom',
138
+ imgSrc: 'https://dashboard.block-auth.io/img/providers/blockchaincom.png',
139
+ imgBgColor: '#f0f9ff',
140
+ loaderColor: '#0b69ff',
141
+ colorBase: '#0b69ff',
142
+ borderStyles: 'bas-border-blue-400',
143
+ hoverBorderStyles: 'hover:bas-border-blue-600',
144
+ },
145
+ magiceden: {
146
+ name: 'Magic Eden',
147
+ value: 'magiceden',
148
+ imgSrc: 'https://dashboard.block-auth.io/img/providers/magiceden.png',
149
+ imgBgColor: '#f0f9ff',
150
+ loaderColor: '#0b69ff',
151
+ colorBase: '#0b69ff',
152
+ borderStyles: 'bas-border-blue-400',
153
+ hoverBorderStyles: 'hover:bas-border-blue-600',
154
+ },
155
+ kraken: {
156
+ name: 'Kraken',
157
+ value: 'kraken',
158
+ imgSrc: 'https://dashboard.block-auth.io/img/providers/kraken.png',
159
+ imgBgColor: '#f0f9ff',
160
+ loaderColor: '#0b69ff',
161
+ colorBase: '#0b69ff',
162
+ borderStyles: 'bas-border-blue-400',
163
+ hoverBorderStyles: 'hover:bas-border-blue-600',
164
+ },
165
+ coinbase: {
166
+ name: 'Coinbase',
167
+ value: 'coinbase',
168
+ imgSrc: 'https://dashboard.block-auth.io/img/providers/coinbase.png',
169
+ imgBgColor: '#f0f9ff',
170
+ loaderColor: '#0b69ff',
171
+ colorBase: '#0b69ff',
172
+ borderStyles: 'bas-border-blue-400',
173
+ hoverBorderStyles: 'hover:bas-border-blue-600',
174
+ },
175
+ enjin: {
176
+ name: 'Enjin',
177
+ value: 'enjin',
178
+ imgSrc: 'https://dashboard.block-auth.io/img/providers/enjin.png',
179
+ imgBgColor: '#f0f9ff',
180
+ loaderColor: '#0b69ff',
181
+ colorBase: '#0b69ff',
182
+ borderStyles: 'bas-border-blue-400',
183
+ hoverBorderStyles: 'hover:bas-border-blue-600',
184
+ },
185
+ coincircle: {
186
+ name: 'Coincircle',
187
+ value: 'coincircle',
188
+ imgSrc: 'https://dashboard.block-auth.io/img/providers/coincircle.png',
189
+ imgBgColor: '#f0f9ff',
190
+ loaderColor: '#0b69ff',
191
+ colorBase: '#0b69ff',
192
+ borderStyles: 'bas-border-blue-400',
193
+ hoverBorderStyles: 'hover:bas-border-blue-600',
194
+ },
195
+ crossmint: {
196
+ name: 'Crossmint',
197
+ value: 'crossmint',
198
+ imgSrc: 'https://dashboard.block-auth.io/img/providers/crossmint.png',
199
+ imgBgColor: '#f0f9ff',
200
+ loaderColor: '#0b69ff',
201
+ colorBase: '#0b69ff',
202
+ borderStyles: 'bas-border-blue-400',
203
+ hoverBorderStyles: 'hover:bas-border-blue-600',
204
+ },
205
+ ronin: {
206
+ name: 'Ronin',
207
+ value: 'ronin',
208
+ imgSrc: 'https://dashboard.block-auth.io/img/providers/ronin.png',
209
+ imgBgColor: '#f0f9ff',
210
+ loaderColor: '#0b69ff',
211
+ colorBase: '#0b69ff',
212
+ borderStyles: 'bas-border-blue-400',
213
+ hoverBorderStyles: 'hover:bas-border-blue-600',
214
+ },
215
+ thirdweb: {
216
+ name: 'Thirdweb',
217
+ value: 'thirdweb',
218
+ imgSrc: 'https://dashboard.block-auth.io/img/providers/thirdweb.png',
219
+ imgBgColor: '#f0f9ff',
220
+ loaderColor: '#0b69ff',
221
+ colorBase: '#0b69ff',
222
+ borderStyles: 'bas-border-blue-400',
223
+ hoverBorderStyles: 'hover:bas-border-blue-600',
224
+ },
225
+ wemix: {
226
+ name: 'Wemix',
227
+ value: 'wemix',
228
+ imgSrc: 'https://dashboard.block-auth.io/img/providers/wemix.png',
229
+ imgBgColor: '#f0f9ff',
230
+ loaderColor: '#0b69ff',
231
+ colorBase: '#0b69ff',
232
+ borderStyles: 'bas-border-blue-400',
233
+ hoverBorderStyles: 'hover:bas-border-blue-600',
234
+ },
235
+ bitbox: {
236
+ name: 'Bitbox',
237
+ value: 'bitbox',
238
+ imgSrc: 'https://dashboard.block-auth.io/img/providers/bitbox.png',
239
+ imgBgColor: '#f0f9ff',
240
+ loaderColor: '#0b69ff',
241
+ colorBase: '#0b69ff',
242
+ borderStyles: 'bas-border-blue-400',
243
+ hoverBorderStyles: 'hover:bas-border-blue-600',
244
+ },
245
+ moonpay: {
246
+ name: 'Moonpay',
247
+ value: 'moonpay',
248
+ imgSrc: 'https://dashboard.block-auth.io/img/providers/moonpay.png',
249
+ imgBgColor: '#f0f9ff',
250
+ loaderColor: '#0b69ff',
251
+ colorBase: '#0b69ff',
252
+ borderStyles: 'bas-border-blue-400',
253
+ hoverBorderStyles: 'hover:bas-border-blue-600',
254
+ },
255
+ };
256
+
257
+ /** Etiquetas del panel editable, port literal de `editableTxts`. */
258
+ export const editableTxts: Record<string, { es: string; en: string }> = {
259
+ edit: { es: 'Editar', en: 'Edit' },
260
+ searchEngine: { es: 'Buscador', en: 'Search engine' },
261
+ webTypes: { es: 'Tipos de web', en: 'Web types' },
262
+ columns: { es: 'Columnas', en: 'Columns' },
263
+ order: { es: 'Orden', en: 'Order' },
264
+ activate: { es: 'Activar', en: 'Activate' },
265
+ providerName: { es: 'Nombre del provider', en: 'Provider name' },
266
+ };
267
+
268
+ export default providersStyles;
@@ -0,0 +1,56 @@
1
+ import { ChangeDetectionStrategy, Component, computed, input, output } from '@angular/core';
2
+
3
+ // Slider de rango sobre un `<input type="range">` nativo cuyo track/relleno/thumb
4
+ // se estilan vía las reglas `.bas-slider-base` de `@block-auth.io/ui-styles`
5
+ // (src/input.css). La porción rellenada la maneja la custom property
6
+ // `--bas-slider-fill` (porcentaje del valor actual entre min/max), calculada
7
+ // acá para que el gradiente del track de WebKit y el `::-moz-range-progress`
8
+ // de Firefox queden alineados.
9
+ //
10
+ // `onSliderValueChanged` (callback prop en react) -> output `sliderValueChanged`.
11
+ // `:host { display: contents }`: el `<input>` es el hijo real del grid/flex del
12
+ // padre (como en react/vue), así `bas-w-full` mide el 100% del contenedor.
13
+ @Component({
14
+ selector: 'ba-slider-base',
15
+ standalone: true,
16
+ changeDetection: ChangeDetectionStrategy.OnPush,
17
+ host: { style: 'display: contents' },
18
+ template: `
19
+ <input
20
+ [id]="id()"
21
+ type="range"
22
+ [attr.aria-label]="ariaLabel()"
23
+ [min]="min()"
24
+ [max]="max()"
25
+ [step]="step()"
26
+ [value]="sliderValue()"
27
+ [disabled]="disabled()"
28
+ [class]="'bas-slider-base bas-h-6 bas-w-full ' + classNames()"
29
+ [style.--bas-slider-fill.%]="fillPct()"
30
+ (input)="onInput($event)"
31
+ />
32
+ `,
33
+ })
34
+ export class SliderBaseComponent {
35
+ id = input('slider-id');
36
+ sliderValue = input(150);
37
+ step = input(1);
38
+ min = input(0);
39
+ max = input(100);
40
+ disabled = input(false);
41
+ ariaLabel = input('slider');
42
+ classNames = input('');
43
+
44
+ sliderValueChanged = output<number>();
45
+
46
+ protected readonly fillPct = computed(() => {
47
+ const range = this.max() - this.min();
48
+ return range > 0
49
+ ? Math.min(100, Math.max(0, ((this.sliderValue() - this.min()) / range) * 100))
50
+ : 0;
51
+ });
52
+
53
+ onInput(e: Event): void {
54
+ this.sliderValueChanged.emit(Number((e.target as HTMLInputElement).value));
55
+ }
56
+ }