feat(forms): add useMaskedField and useMaskedInput composables for input masking

This commit is contained in:
2026-06-09 13:54:52 +07:00
parent 6de7c72fb3
commit 07937e26db
426 changed files with 12981 additions and 311 deletions
+1
View File
@@ -1,2 +1,3 @@
export * from './luhn';
export * from './reed-solomon';
export * from './qr';
+21
View File
@@ -0,0 +1,21 @@
import { describe, expect, it } from 'vitest';
import { luhn } from './index';
describe(luhn, () => {
it('passes valid checksums (separators ignored)', () => {
expect(luhn('4111 1111 1111 1111')).toBe(true);
expect(luhn('5500005555555559')).toBe(true);
expect(luhn('371449635398431')).toBe(true);
expect(luhn('79927398713')).toBe(true); // classic Luhn example
});
it('fails bad checksums', () => {
expect(luhn('4111 1111 1111 1112')).toBe(false);
expect(luhn('79927398710')).toBe(false);
});
it('returns false for empty input', () => {
expect(luhn('')).toBe(false);
expect(luhn('----')).toBe(false);
});
});
+39
View File
@@ -0,0 +1,39 @@
const NON_DIGIT = /\D/g;
const ASCII_ZERO = 0x30;
/**
* @name luhn
* @category Encoding
* @description Validate a number string against the Luhn (mod 10) checksum — the
* check digit used by payment cards, IMEIs, SIM ICCIDs, and more. Non-digits are
* ignored; an empty input is `false`.
*
* @param {string} value The number (separators allowed)
* @returns {boolean} Whether the Luhn checksum passes
*
* @example
* luhn('4111 1111 1111 1111'); // true
* luhn('4111 1111 1111 1112'); // false
*
* @since 0.0.2
*/
export function luhn(value: string): boolean {
const digits = value.replaceAll(NON_DIGIT, '');
if (!digits)
return false;
let sum = 0;
let double = false;
for (let i = digits.length - 1; i >= 0; i--) {
let digit = digits.charCodeAt(i) - ASCII_ZERO;
if (double) {
digit *= 2;
if (digit > 9)
digit -= 9;
}
sum += digit;
double = !double;
}
return sum % 10 === 0;
}