@basis-ng/primitives 0.0.1-alpha.83 → 0.0.1-alpha.84
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/fesm2022/basis-ng-primitives.mjs +258 -1
- package/fesm2022/basis-ng-primitives.mjs.map +1 -1
- package/index.d.ts +125 -2
- package/package.json +1 -1
|
@@ -1537,6 +1537,263 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImpor
|
|
|
1537
1537
|
}]
|
|
1538
1538
|
}], ctorParameters: () => [] });
|
|
1539
1539
|
|
|
1540
|
+
/**
|
|
1541
|
+
* Component representing a One-Time Password (OTP) input group.
|
|
1542
|
+
*
|
|
1543
|
+
* This component manages a set of digit inputs for entering OTP codes, handling keyboard navigation,
|
|
1544
|
+
* paste events, and integration with Angular Forms via ControlValueAccessor.
|
|
1545
|
+
*
|
|
1546
|
+
* @example
|
|
1547
|
+
* <b-otp>
|
|
1548
|
+
* <input otp-digit />
|
|
1549
|
+
* <input otp-digit />
|
|
1550
|
+
* <input otp-digit />
|
|
1551
|
+
* <input otp-digit />
|
|
1552
|
+
* </b-otp>
|
|
1553
|
+
*/
|
|
1554
|
+
/**
|
|
1555
|
+
* OtpComponent manages a group of digit inputs for OTP entry.
|
|
1556
|
+
* Implements keyboard navigation, paste handling, and ControlValueAccessor for Angular Forms.
|
|
1557
|
+
*/
|
|
1558
|
+
class OtpComponent {
|
|
1559
|
+
/**
|
|
1560
|
+
* The visual size of the OTP inputs. Accepts '1', '2', or '3'. Default is '2'.
|
|
1561
|
+
*/
|
|
1562
|
+
size = model('2', ...(ngDevMode ? [{ debugName: "size" }] : []));
|
|
1563
|
+
/**
|
|
1564
|
+
* Computed signal for the number of digit inputs.
|
|
1565
|
+
*/
|
|
1566
|
+
length = computed(() => this.digitInputs().length, ...(ngDevMode ? [{ debugName: "length" }] : []));
|
|
1567
|
+
/**
|
|
1568
|
+
* Emits the full OTP value when changed.
|
|
1569
|
+
*/
|
|
1570
|
+
otpChange = output();
|
|
1571
|
+
/**
|
|
1572
|
+
* Query for all child digit inputs (OtpDigitDirective).
|
|
1573
|
+
*/
|
|
1574
|
+
digitInputs = contentChildren(OtpDigitDirective, ...(ngDevMode ? [{ debugName: "digitInputs" }] : []));
|
|
1575
|
+
/**
|
|
1576
|
+
* Internal array holding the current values of each digit input.
|
|
1577
|
+
*/
|
|
1578
|
+
values = [];
|
|
1579
|
+
/**
|
|
1580
|
+
* Model indicating whether the OTP input group is disabled.
|
|
1581
|
+
*/
|
|
1582
|
+
disabled = model(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
1583
|
+
/**
|
|
1584
|
+
* Callback for propagating value changes to Angular Forms.
|
|
1585
|
+
*/
|
|
1586
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
1587
|
+
onChange = () => { };
|
|
1588
|
+
/**
|
|
1589
|
+
* Callback for marking the component as touched in Angular Forms.
|
|
1590
|
+
*/
|
|
1591
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
1592
|
+
onTouched = () => { };
|
|
1593
|
+
ngAfterContentInit() {
|
|
1594
|
+
// Inicializar listeners en los inputs hijos
|
|
1595
|
+
this.digitInputs().forEach((input, idx) => {
|
|
1596
|
+
const el = input.el.nativeElement;
|
|
1597
|
+
// maxLength y type se aplican por la directiva
|
|
1598
|
+
el.disabled = this.disabled();
|
|
1599
|
+
el.classList.remove('size-1', 'size-2', 'size-3');
|
|
1600
|
+
el.classList.add(`size-${this.size()}`);
|
|
1601
|
+
el.addEventListener('input', (event) => {
|
|
1602
|
+
this.onInput(event, idx);
|
|
1603
|
+
});
|
|
1604
|
+
el.addEventListener('keydown', (event) => {
|
|
1605
|
+
this.onKeyDown(event, idx);
|
|
1606
|
+
});
|
|
1607
|
+
el.addEventListener('paste', (event) => {
|
|
1608
|
+
this.onPaste(event);
|
|
1609
|
+
});
|
|
1610
|
+
});
|
|
1611
|
+
this.resetValues();
|
|
1612
|
+
}
|
|
1613
|
+
/**
|
|
1614
|
+
* Handles input event for each digit input.
|
|
1615
|
+
* Moves focus to next input if value entered.
|
|
1616
|
+
*
|
|
1617
|
+
* @param event - Input event
|
|
1618
|
+
*
|
|
1619
|
+
* @param idx - Index of the digit input
|
|
1620
|
+
*/
|
|
1621
|
+
onInput(event, idx) {
|
|
1622
|
+
const input = event.target;
|
|
1623
|
+
const val = input.value;
|
|
1624
|
+
this.values[idx] = val;
|
|
1625
|
+
if (val && idx < this.length() - 1) {
|
|
1626
|
+
this.focusDigit(idx + 1);
|
|
1627
|
+
}
|
|
1628
|
+
this.emitValue();
|
|
1629
|
+
}
|
|
1630
|
+
/**
|
|
1631
|
+
* Handles keyboard navigation for digit inputs.
|
|
1632
|
+
* Supports Backspace, ArrowLeft, ArrowRight.
|
|
1633
|
+
*
|
|
1634
|
+
* @param event - Keyboard event
|
|
1635
|
+
*
|
|
1636
|
+
* @param idx - Index of the digit input
|
|
1637
|
+
*/
|
|
1638
|
+
onKeyDown(event, idx) {
|
|
1639
|
+
const input = event.target;
|
|
1640
|
+
if (event.key === 'Backspace') {
|
|
1641
|
+
if (!input.value && idx > 0) {
|
|
1642
|
+
this.focusDigit(idx - 1);
|
|
1643
|
+
}
|
|
1644
|
+
this.values[idx] = '';
|
|
1645
|
+
this.emitValue();
|
|
1646
|
+
}
|
|
1647
|
+
else if (event.key === 'ArrowLeft' && idx > 0) {
|
|
1648
|
+
this.focusDigit(idx - 1);
|
|
1649
|
+
}
|
|
1650
|
+
else if (event.key === 'ArrowRight' && idx < this.length() - 1) {
|
|
1651
|
+
this.focusDigit(idx + 1);
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
/**
|
|
1655
|
+
* Handles paste event for the OTP input group.
|
|
1656
|
+
* Distributes pasted characters across digit inputs.
|
|
1657
|
+
*
|
|
1658
|
+
* @param event - Clipboard event
|
|
1659
|
+
*/
|
|
1660
|
+
onPaste(event) {
|
|
1661
|
+
event.preventDefault();
|
|
1662
|
+
const paste = event.clipboardData?.getData('text') ?? '';
|
|
1663
|
+
const chars = paste.slice(0, this.length()).split('');
|
|
1664
|
+
chars.forEach((c, i) => {
|
|
1665
|
+
this.values[i] = c;
|
|
1666
|
+
const input = this.digitInputs()[i];
|
|
1667
|
+
if (input) {
|
|
1668
|
+
input.el.nativeElement.value = c;
|
|
1669
|
+
}
|
|
1670
|
+
});
|
|
1671
|
+
this.emitValue();
|
|
1672
|
+
this.focusDigit(chars.length - 1);
|
|
1673
|
+
}
|
|
1674
|
+
/**
|
|
1675
|
+
* Focuses the digit input at the given index.
|
|
1676
|
+
*
|
|
1677
|
+
* @param idx - Index of the digit input to focus
|
|
1678
|
+
*/
|
|
1679
|
+
focusDigit(idx) {
|
|
1680
|
+
const input = this.digitInputs()[idx];
|
|
1681
|
+
if (input) {
|
|
1682
|
+
input.el.nativeElement.focus();
|
|
1683
|
+
}
|
|
1684
|
+
}
|
|
1685
|
+
/**
|
|
1686
|
+
* Emits the full OTP value via output and ControlValueAccessor.
|
|
1687
|
+
*/
|
|
1688
|
+
emitValue() {
|
|
1689
|
+
const otp = this.values.join('');
|
|
1690
|
+
this.otpChange.emit(otp);
|
|
1691
|
+
this.onChange(otp);
|
|
1692
|
+
this.onTouched();
|
|
1693
|
+
}
|
|
1694
|
+
/**
|
|
1695
|
+
* Resets all digit input values to empty.
|
|
1696
|
+
*/
|
|
1697
|
+
resetValues() {
|
|
1698
|
+
this.values = Array(this.length()).fill('');
|
|
1699
|
+
this.digitInputs().forEach(input => {
|
|
1700
|
+
input.el.nativeElement.value = '';
|
|
1701
|
+
});
|
|
1702
|
+
}
|
|
1703
|
+
// ControlValueAccessor implementation
|
|
1704
|
+
/**
|
|
1705
|
+
* Writes a new value to the OTP input group.
|
|
1706
|
+
* Called by Angular Forms to update the value.
|
|
1707
|
+
*
|
|
1708
|
+
* @param value - New OTP value
|
|
1709
|
+
*/
|
|
1710
|
+
writeValue(value) {
|
|
1711
|
+
this.values = Array(this.length()).fill('');
|
|
1712
|
+
if (value) {
|
|
1713
|
+
value
|
|
1714
|
+
.slice(0, this.length())
|
|
1715
|
+
.split('')
|
|
1716
|
+
.forEach((c, i) => {
|
|
1717
|
+
this.values[i] = c;
|
|
1718
|
+
const input = this.digitInputs()[i];
|
|
1719
|
+
if (input) {
|
|
1720
|
+
input.el.nativeElement.value = c;
|
|
1721
|
+
}
|
|
1722
|
+
});
|
|
1723
|
+
}
|
|
1724
|
+
else {
|
|
1725
|
+
this.resetValues();
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1728
|
+
/**
|
|
1729
|
+
* Registers a callback to be called when the value changes.
|
|
1730
|
+
*
|
|
1731
|
+
* @param fn - Callback function
|
|
1732
|
+
*/
|
|
1733
|
+
registerOnChange(fn) {
|
|
1734
|
+
this.onChange = fn;
|
|
1735
|
+
}
|
|
1736
|
+
/**
|
|
1737
|
+
* Registers a callback to be called when the component is touched.
|
|
1738
|
+
*
|
|
1739
|
+
* @param fn - Callback function
|
|
1740
|
+
*/
|
|
1741
|
+
registerOnTouched(fn) {
|
|
1742
|
+
this.onTouched = fn;
|
|
1743
|
+
}
|
|
1744
|
+
/**
|
|
1745
|
+
* Sets the disabled state of the OTP input group.
|
|
1746
|
+
* Called by Angular Forms to enable/disable the component.
|
|
1747
|
+
*
|
|
1748
|
+
* @param isDisabled - Boolean indicating disabled state
|
|
1749
|
+
*/
|
|
1750
|
+
setDisabledState(isDisabled) {
|
|
1751
|
+
this.disabled.set(isDisabled);
|
|
1752
|
+
this.digitInputs().forEach(input => {
|
|
1753
|
+
input.el.nativeElement.disabled = isDisabled;
|
|
1754
|
+
input.el.nativeElement.classList.remove('size-1', 'size-2', 'size-3');
|
|
1755
|
+
input.el.nativeElement.classList.add(`size-${this.size()}`);
|
|
1756
|
+
});
|
|
1757
|
+
}
|
|
1758
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: OtpComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1759
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.2.3", type: OtpComponent, isStandalone: true, selector: "b-otp", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { size: "sizeChange", otpChange: "otpChange", disabled: "disabledChange" }, providers: [
|
|
1760
|
+
{
|
|
1761
|
+
provide: NG_VALUE_ACCESSOR,
|
|
1762
|
+
useExisting: forwardRef(() => OtpComponent),
|
|
1763
|
+
multi: true,
|
|
1764
|
+
},
|
|
1765
|
+
], queries: [{ propertyName: "digitInputs", predicate: OtpDigitDirective, isSignal: true }], ngImport: i0, template: `<ng-content />`, isInline: true });
|
|
1766
|
+
}
|
|
1767
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: OtpComponent, decorators: [{
|
|
1768
|
+
type: Component,
|
|
1769
|
+
args: [{
|
|
1770
|
+
selector: 'b-otp',
|
|
1771
|
+
template: `<ng-content />`,
|
|
1772
|
+
providers: [
|
|
1773
|
+
{
|
|
1774
|
+
provide: NG_VALUE_ACCESSOR,
|
|
1775
|
+
useExisting: forwardRef(() => OtpComponent),
|
|
1776
|
+
multi: true,
|
|
1777
|
+
},
|
|
1778
|
+
],
|
|
1779
|
+
}]
|
|
1780
|
+
}] });
|
|
1781
|
+
class OtpDigitDirective {
|
|
1782
|
+
/** Reference to the native input element. */
|
|
1783
|
+
el = inject((ElementRef));
|
|
1784
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: OtpDigitDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1785
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.3", type: OtpDigitDirective, isStandalone: true, selector: "input[otp-digit]", host: { attributes: { "maxlength": "1" } }, ngImport: i0 });
|
|
1786
|
+
}
|
|
1787
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: OtpDigitDirective, decorators: [{
|
|
1788
|
+
type: Directive,
|
|
1789
|
+
args: [{
|
|
1790
|
+
selector: 'input[otp-digit]',
|
|
1791
|
+
host: {
|
|
1792
|
+
maxlength: '1',
|
|
1793
|
+
},
|
|
1794
|
+
}]
|
|
1795
|
+
}] });
|
|
1796
|
+
|
|
1540
1797
|
class BadgeComponent {
|
|
1541
1798
|
/** The variant of the badge. */
|
|
1542
1799
|
variant = input('primary', ...(ngDevMode ? [{ debugName: "variant" }] : []));
|
|
@@ -3515,5 +3772,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImpor
|
|
|
3515
3772
|
* Generated bundle index. Do not edit.
|
|
3516
3773
|
*/
|
|
3517
3774
|
|
|
3518
|
-
export { AlertComponent, BadgeComponent, ButtonComponent, ButtonGroupComponent, CardComponent, CardContentComponent, CardDescriptionComponent, CardFooterComponent, CardHeaderComponent, CardSubtitleComponent, CardTitleComponent, Checkbox, ColorPickerComponent, ComboboxComponent, CommandComponent, CommandOptionsComponent, DialogDirective, DialogService, DrawerComponent, IconComponent, InViewportDirective, InViewportService, InputComponent, InputGroupComponent, LazyContentDirective, MenuComponent, MenuGroupComponent, MenuItemCheckboxComponent, MenuItemComponent, MenuItemRadioComponent, MenuLabelComponent, MenuTriggerDirective, OptionComponent, OverlayDirective, OverlayTriggerDirective, RangeComponent, ResponsiveService, RowComponent, RowItemComponent, SelectComponent, SelectOptionsComponent, SheetComponent, SpinnerComponent, SwitchComponent, TabComponent, TableComponent, TabsComponent, TextareaComponent, ThemeService, TooltipDirective, TreeComponent, TreeNodeComponent };
|
|
3775
|
+
export { AlertComponent, BadgeComponent, ButtonComponent, ButtonGroupComponent, CardComponent, CardContentComponent, CardDescriptionComponent, CardFooterComponent, CardHeaderComponent, CardSubtitleComponent, CardTitleComponent, Checkbox, ColorPickerComponent, ComboboxComponent, CommandComponent, CommandOptionsComponent, DialogDirective, DialogService, DrawerComponent, IconComponent, InViewportDirective, InViewportService, InputComponent, InputGroupComponent, LazyContentDirective, MenuComponent, MenuGroupComponent, MenuItemCheckboxComponent, MenuItemComponent, MenuItemRadioComponent, MenuLabelComponent, MenuTriggerDirective, OptionComponent, OtpComponent, OtpDigitDirective, OverlayDirective, OverlayTriggerDirective, RangeComponent, ResponsiveService, RowComponent, RowItemComponent, SelectComponent, SelectOptionsComponent, SheetComponent, SpinnerComponent, SwitchComponent, TabComponent, TableComponent, TabsComponent, TextareaComponent, ThemeService, TooltipDirective, TreeComponent, TreeNodeComponent };
|
|
3519
3776
|
//# sourceMappingURL=basis-ng-primitives.mjs.map
|