@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.
- package/.turbo/turbo-build.log +37 -0
- package/.turbo/turbo-lint.log +4 -0
- package/.turbo/turbo-test.log +82 -0
- package/.turbo/turbo-typecheck.log +4 -0
- package/CHANGELOG.md +10 -0
- package/ng-package.json +6 -0
- package/package.json +50 -0
- package/scripts/css-to-ts.mjs +14 -0
- package/src/lib/__tests__/integration.test.ts +45 -0
- package/src/lib/block-auth.service.test.ts +69 -0
- package/src/lib/block-auth.service.ts +81 -0
- package/src/lib/components/btns/btn-base-provider.component.test.ts +22 -0
- package/src/lib/components/btns/btn-base-provider.component.ts +55 -0
- package/src/lib/components/btns/btn-block-auth.component.test.ts +79 -0
- package/src/lib/components/btns/btn-block-auth.component.ts +104 -0
- package/src/lib/components/btns/btn-gmail.component.test.ts +16 -0
- package/src/lib/components/btns/btn-gmail.component.ts +41 -0
- package/src/lib/components/btns/btn-google-base.component.test.ts +16 -0
- package/src/lib/components/btns/btn-google-base.component.ts +73 -0
- package/src/lib/components/btns/btn-metamask.component.test.ts +20 -0
- package/src/lib/components/btns/btn-metamask.component.ts +98 -0
- package/src/lib/components/btns/btn-microsoft.component.test.ts +16 -0
- package/src/lib/components/btns/btn-microsoft.component.ts +77 -0
- package/src/lib/components/btns/btn-phantom.component.test.ts +20 -0
- package/src/lib/components/btns/btn-phantom.component.ts +93 -0
- package/src/lib/components/btns/btn-signin.component.test.ts +55 -0
- package/src/lib/components/btns/btn-signin.component.ts +108 -0
- package/src/lib/components/btns/btn-wallet-connect.component.test.ts +20 -0
- package/src/lib/components/btns/btn-wallet-connect.component.ts +109 -0
- package/src/lib/components/btns/index.ts +11 -0
- package/src/lib/components/contents/content-signin.component.test.ts +33 -0
- package/src/lib/components/contents/content-signin.component.ts +68 -0
- package/src/lib/components/contents/content-signup.component.test.ts +78 -0
- package/src/lib/components/contents/content-signup.component.ts +225 -0
- package/src/lib/components/dds/change-account.component.test.ts +66 -0
- package/src/lib/components/dds/change-account.component.ts +112 -0
- package/src/lib/components/dds/dropdown-profile-btn.component.test.ts +66 -0
- package/src/lib/components/dds/dropdown-profile-btn.component.ts +185 -0
- package/src/lib/components/dds/dropdown-profile-item.component.test.ts +75 -0
- package/src/lib/components/dds/dropdown-profile-item.component.ts +74 -0
- package/src/lib/components/dds/dropdown-profile.component.test.ts +98 -0
- package/src/lib/components/dds/dropdown-profile.component.ts +258 -0
- package/src/lib/components/flow-block-auth.component.test.ts +93 -0
- package/src/lib/components/flow-block-auth.component.ts +226 -0
- package/src/lib/components/modals/modal-overlay.component.test.ts +81 -0
- package/src/lib/components/modals/modal-overlay.component.ts +43 -0
- package/src/lib/components/modals/modal-restoration-expired.component.test.ts +71 -0
- package/src/lib/components/modals/modal-restoration-expired.component.ts +83 -0
- package/src/lib/components/modals/modal-restore.component.test.ts +74 -0
- package/src/lib/components/modals/modal-restore.component.ts +104 -0
- package/src/lib/components/modals/modal-signin.component.test.ts +66 -0
- package/src/lib/components/modals/modal-signin.component.ts +44 -0
- package/src/lib/components/modals/modal-signup.component.test.ts +56 -0
- package/src/lib/components/modals/modal-signup.component.ts +40 -0
- package/src/lib/components/sections/footer-section.component.test.ts +19 -0
- package/src/lib/components/sections/footer-section.component.ts +49 -0
- package/src/lib/components/sections/internals/providers-buttons.component.test.ts +27 -0
- package/src/lib/components/sections/internals/providers-buttons.component.ts +290 -0
- package/src/lib/components/sections/internals/providers-filters.component.test.ts +25 -0
- package/src/lib/components/sections/internals/providers-filters.component.ts +139 -0
- package/src/lib/components/sections/internals/selected-button.component.test.ts +36 -0
- package/src/lib/components/sections/internals/selected-button.component.ts +92 -0
- package/src/lib/components/sections/login-section.component.test.ts +49 -0
- package/src/lib/components/sections/login-section.component.ts +120 -0
- package/src/lib/components/sections/providers-section.component.test.ts +22 -0
- package/src/lib/components/sections/providers-section.component.ts +187 -0
- package/src/lib/components/txns/internals/permissions-required-modal.component.test.ts +14 -0
- package/src/lib/components/txns/internals/permissions-required-modal.component.ts +35 -0
- package/src/lib/components/txns/internals/solicited-data-modal.component.test.ts +72 -0
- package/src/lib/components/txns/internals/solicited-data-modal.component.ts +187 -0
- package/src/lib/components/txns/internals/txn-error.component.test.ts +100 -0
- package/src/lib/components/txns/internals/txn-error.component.ts +121 -0
- package/src/lib/components/txns/internals/txn-type.component.test.ts +52 -0
- package/src/lib/components/txns/internals/txn-type.component.ts +51 -0
- package/src/lib/components/txns/internals/txn.component.test.ts +188 -0
- package/src/lib/components/txns/internals/txn.component.ts +298 -0
- package/src/lib/components/txns/txns-overview.component.test.ts +107 -0
- package/src/lib/components/txns/txns-overview.component.ts +229 -0
- package/src/lib/icons/ai-outline-disconnect.component.ts +21 -0
- package/src/lib/icons/bi-logo-gmail.component.ts +21 -0
- package/src/lib/icons/cg-profile.component.ts +31 -0
- package/src/lib/icons/check-icon.component.ts +27 -0
- package/src/lib/icons/ci-clock2.component.ts +31 -0
- package/src/lib/icons/fa-arrow-right.component.ts +21 -0
- package/src/lib/icons/fa-times.component.ts +21 -0
- package/src/lib/icons/fa-undo.component.ts +21 -0
- package/src/lib/icons/icons.test.ts +25 -0
- package/src/lib/icons/index.ts +22 -0
- package/src/lib/icons/io-ios-arrow-back.component.ts +21 -0
- package/src/lib/icons/io-ios-arrow-forward.component.ts +21 -0
- package/src/lib/icons/io-md-arrow-back.component.ts +19 -0
- package/src/lib/icons/io-md-arrow-forward.component.ts +19 -0
- package/src/lib/icons/pi-warning-fill.component.ts +21 -0
- package/src/lib/icons/tb-arrows-exchange2.component.ts +30 -0
- package/src/lib/icons/tb-copy-check-filled.component.ts +21 -0
- package/src/lib/icons/tb-copy.component.ts +34 -0
- package/src/lib/icons/ti-vendor-microsoft.component.ts +21 -0
- package/src/lib/inject-store.test.ts +26 -0
- package/src/lib/inject-store.ts +16 -0
- package/src/lib/primitives/arrow-icon.component.test.ts +12 -0
- package/src/lib/primitives/arrow-icon.component.ts +38 -0
- package/src/lib/primitives/btn-arrow-dir.component.test.ts +22 -0
- package/src/lib/primitives/btn-arrow-dir.component.ts +65 -0
- package/src/lib/primitives/btn-base.component.test.ts +38 -0
- package/src/lib/primitives/btn-base.component.ts +140 -0
- package/src/lib/primitives/divider-base.component.test.ts +12 -0
- package/src/lib/primitives/divider-base.component.ts +74 -0
- package/src/lib/primitives/dropdown-arrow.component.test.ts +12 -0
- package/src/lib/primitives/dropdown-arrow.component.ts +46 -0
- package/src/lib/primitives/dropdown-base.component.test.ts +49 -0
- package/src/lib/primitives/dropdown-base.component.ts +329 -0
- package/src/lib/primitives/helpers.ts +151 -0
- package/src/lib/primitives/horizontal-loader.component.test.ts +19 -0
- package/src/lib/primitives/horizontal-loader.component.ts +70 -0
- package/src/lib/primitives/icon-base.component.test.ts +19 -0
- package/src/lib/primitives/icon-base.component.ts +58 -0
- package/src/lib/primitives/img-loader.component.test.ts +12 -0
- package/src/lib/primitives/img-loader.component.ts +118 -0
- package/src/lib/primitives/index.ts +29 -0
- package/src/lib/primitives/input-base.component.test.ts +20 -0
- package/src/lib/primitives/input-base.component.ts +210 -0
- package/src/lib/primitives/lifetime-slider-base.component.test.ts +88 -0
- package/src/lib/primitives/lifetime-slider-base.component.ts +75 -0
- package/src/lib/primitives/oval-spinner.component.test.ts +9 -0
- package/src/lib/primitives/oval-spinner.component.ts +158 -0
- package/src/lib/primitives/pickers/dropdown-picker-animated-base.component.ts +220 -0
- package/src/lib/primitives/pickers/picker-button.component.ts +74 -0
- package/src/lib/primitives/pickers/time-picker-dropdown-selector.component.ts +188 -0
- package/src/lib/primitives/pickers/time-picker.component.ts +124 -0
- package/src/lib/primitives/pickers/time-unit-selector.component.ts +82 -0
- package/src/lib/primitives/progressbar.component.test.ts +18 -0
- package/src/lib/primitives/progressbar.component.ts +93 -0
- package/src/lib/primitives/providersStyles.ts +268 -0
- package/src/lib/primitives/slider-base.component.ts +56 -0
- package/src/lib/provide-block-auth.test.ts +43 -0
- package/src/lib/provide-block-auth.ts +43 -0
- package/src/lib/runtime/block-auth-runtime.directive.test.ts +89 -0
- package/src/lib/runtime/block-auth-runtime.directive.ts +68 -0
- package/src/lib/teleport-body.directive.test.ts +29 -0
- package/src/lib/teleport-body.directive.ts +21 -0
- package/src/lib/testing.ts +15 -0
- package/src/lib/transitions.css +23 -0
- package/src/public-api.ts +85 -0
- package/src/vitest.setup.ts +8 -0
- package/tailwind.config.cjs +6 -0
- package/tsconfig.json +15 -0
- package/tsconfig.lib.json +9 -0
- 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
|
+
}
|