Browse Source

Phone number placeholder

master
Eduard Kuzmenko 3 years ago
parent
commit
2de396521e
  1. 16
      src/components/misc.ts
  2. 4
      src/helpers/dom/placeCaretAtEnd.ts
  3. 2
      src/index.hbs
  4. 75
      src/pages/pageSignIn.ts
  5. 13
      src/scss/partials/_input.scss

16
src/components/misc.ts

@ -52,8 +52,8 @@ export function setButtonLoader(elem: HTMLButtonElement, icon = 'check') {
} }
let sortedCountries: Country[]; let sortedCountries: Country[];
export function formatPhoneNumber(str: string) { export function formatPhoneNumber(originalStr: string) {
str = str.replace(/\D/g, ''); let str = originalStr.replace(/\D/g, '');
let phoneCode = str.slice(0, 6); let phoneCode = str.slice(0, 6);
////console.log('str', str, phoneCode); ////console.log('str', str, phoneCode);
@ -65,7 +65,7 @@ export function formatPhoneNumber(str: string) {
return c.phoneCode.split(' and ').find((c) => phoneCode.indexOf(c.replace(/\D/g, '')) === 0); return c.phoneCode.split(' and ').find((c) => phoneCode.indexOf(c.replace(/\D/g, '')) === 0);
}); });
if(!country) return {formatted: str, country}; if(!country) return {formatted: str, country, leftPattern: ''};
country = PhoneCodesMain[country.phoneCode] || country; country = PhoneCodesMain[country.phoneCode] || country;
@ -80,7 +80,15 @@ export function formatPhoneNumber(str: string) {
str = str.slice(0, country.pattern.length); str = str.slice(0, country.pattern.length);
} */ } */
return {formatted: str, country}; let leftPattern = pattern && pattern.length > str.length ? pattern.slice(str.length) : '';
if(leftPattern) {
/* const length = str.length;
leftPattern = leftPattern.split('').map((_, idx) => (length + idx).toString().slice(-1)).join(''); */
leftPattern = leftPattern.replace(/X/g, '‒');
// leftPattern = leftPattern.replace(/X/g, '0');
}
return {formatted: str, country, leftPattern};
} }
/* export function parseMenuButtonsTo(to: {[name: string]: HTMLElement}, elements: HTMLCollection | NodeListOf<HTMLElement>) { /* export function parseMenuButtonsTo(to: {[name: string]: HTMLElement}, elements: HTMLCollection | NodeListOf<HTMLElement>) {

4
src/helpers/dom/placeCaretAtEnd.ts

@ -11,8 +11,8 @@
import { isTouchSupported } from "../touchSupport"; import { isTouchSupported } from "../touchSupport";
export default function placeCaretAtEnd(el: HTMLElement) { export default function placeCaretAtEnd(el: HTMLElement, ignoreTouchCheck = false) {
if(isTouchSupported) { if(isTouchSupported && (!ignoreTouchCheck || document.activeElement !== el)) {
return; return;
} }

2
src/index.hbs

@ -40,7 +40,7 @@
<div class="scrollable scrollable-y"> <div class="scrollable scrollable-y">
<div class="tabs-container auth-pages__container" data-animation="tabs"> <div class="tabs-container auth-pages__container" data-animation="tabs">
<div class="tabs-tab page-sign"> <div class="tabs-tab page-sign">
<div class="container center-align"> <div class="container">
<div class="auth-image"> <div class="auth-image">
<svg class="sign-logo" xmlns="http://www.w3.org/2000/svg" width="160" height="160" viewBox="0 0 160 160"> <svg class="sign-logo" xmlns="http://www.w3.org/2000/svg" width="160" height="160" viewBox="0 0 160 160">
<use href="#logo" /> <use href="#logo" />

75
src/pages/pageSignIn.ts

@ -35,6 +35,7 @@ import replaceContent from "../helpers/dom/replaceContent";
import toggleDisability from "../helpers/dom/toggleDisability"; import toggleDisability from "../helpers/dom/toggleDisability";
import sessionStorage from "../lib/sessionStorage"; import sessionStorage from "../lib/sessionStorage";
import { DcAuthKey } from "../types"; import { DcAuthKey } from "../types";
import placeCaretAtEnd from "../helpers/dom/placeCaretAtEnd";
type Country = _Country & { type Country = _Country & {
li?: HTMLLIElement[] li?: HTMLLIElement[]
@ -142,9 +143,12 @@ let onFirstMount = () => {
countryInput.value = countryName; countryInput.value = countryName;
lastCountrySelected = countries.find(c => c.name === countryName); lastCountrySelected = countries.find(c => c.name === countryName);
telEl.value = lastValue = phoneCode; telInputField.value = lastValue = phoneCode;
hidePicker(); hidePicker();
setTimeout(() => telEl.focus(), 0); setTimeout(() => {
telEl.focus();
placeCaretAtEnd(telEl, true);
}, 0);
}; };
initSelect(); initSelect();
@ -250,38 +254,61 @@ let onFirstMount = () => {
const telInputField = new InputField({ const telInputField = new InputField({
label: 'Login.PhoneLabel', label: 'Login.PhoneLabel',
plainText: true, //plainText: true,
name: 'phone' name: 'phone'
}); });
let telEl = telInputField.input as HTMLInputElement;
telInputField.container.classList.add('input-field-phone');
let telEl = telInputField.input;
if(telEl instanceof HTMLInputElement) {
telEl.type = 'tel'; telEl.type = 'tel';
telEl.autocomplete = 'rr55RandomRR55'; telEl.autocomplete = 'rr55RandomRR55';
telEl.addEventListener('input', function(this: typeof telEl, e) { } else {
telEl.inputMode = 'decimal';
const pixelRatio = window.devicePixelRatio;
if(pixelRatio > 1) {
const letterSpacing = -(pixelRatio * .16) + 'px';
telEl.style.setProperty('--letter-spacing', letterSpacing);
}
const originalFunc = telInputField.setValueSilently.bind(telInputField);
telInputField.setValueSilently = (value) => {
originalFunc(value);
placeCaretAtEnd(telInputField.input, true);
};
}
telEl.addEventListener('input', () => {
//console.log('input', this.value); //console.log('input', this.value);
this.classList.remove('error'); telEl.classList.remove('error');
lottieLoader.loadLottieWorkers(); lottieLoader.loadLottieWorkers();
const value = this.value; const value = telInputField.value;
const diff = Math.abs(value.length - lastValue.length); const diff = Math.abs(value.length - lastValue.length);
if(diff > 1 && !pasted && isAppleMobile) { if(diff > 1 && !pasted && isAppleMobile) {
this.value = lastValue + value; telInputField.setValueSilently(lastValue + value);
} }
pasted = false; pasted = false;
telInputField.setLabel(); telInputField.setLabel();
let formatted: string, country: Country; let formatted: string, country: Country, leftPattern = '';
if(this.value.replace(/\++/, '+') === '+') { if(telInputField.value.replace(/\++/, '+') === '+') {
this.value = '+'; telInputField.setValueSilently('+');
} else { } else {
const o = formatPhoneNumber(this.value); const o = formatPhoneNumber(telInputField.value);
formatted = o.formatted; formatted = o.formatted;
country = o.country; country = o.country;
this.value = lastValue = formatted ? '+' + formatted : ''; leftPattern = o.leftPattern;
telInputField.setValueSilently(lastValue = formatted ? '+' + formatted : '');
} }
telEl.dataset.leftPattern = leftPattern/* .replace(/X/g, '0') */;
//console.log(formatted, country); //console.log(formatted, country);
let countryName = country ? country.name : ''/* 'Unknown' */; let countryName = country ? country.name : ''/* 'Unknown' */;
@ -290,15 +317,15 @@ let onFirstMount = () => {
lastCountrySelected = country; lastCountrySelected = country;
} }
//if(country && (this.value.length - 1) >= (country.pattern ? country.pattern.length : 9)) { //if(country && (telInputField.value.length - 1) >= (country.pattern ? country.pattern.length : 9)) {
if(country || (this.value.length - 1) > 1) { if(country || (telInputField.value.length - 1) > 1) {
btnNext.style.visibility = ''; btnNext.style.visibility = '';
} else { } else {
btnNext.style.visibility = 'hidden'; btnNext.style.visibility = 'hidden';
} }
}); });
telEl.addEventListener('paste', (e) => { telEl.addEventListener('paste', () => {
pasted = true; pasted = true;
//console.log('paste', telEl.value); //console.log('paste', telEl.value);
}); });
@ -307,7 +334,7 @@ let onFirstMount = () => {
console.log('change', telEl.value); console.log('change', telEl.value);
}); */ }); */
telEl.addEventListener('keypress', function(this: typeof telEl, e) { telEl.addEventListener('keypress', (e) => {
//console.log('keypress', this.value); //console.log('keypress', this.value);
if(!btnNext.style.visibility &&/* this.value.length >= 9 && */ e.key === 'Enter') { if(!btnNext.style.visibility &&/* this.value.length >= 9 && */ e.key === 'Enter') {
return onSubmit(); return onSubmit();
@ -362,7 +389,7 @@ let onFirstMount = () => {
//return; //return;
let phone_number = telEl.value; let phone_number = telInputField.value;
apiManager.invokeApi('auth.sendCode', { apiManager.invokeApi('auth.sendCode', {
phone_number: phone_number, phone_number: phone_number,
api_id: App.id, api_id: App.id,
@ -424,10 +451,11 @@ let onFirstMount = () => {
inputWrapper.append(countryInputField.container, telInputField.container, signedCheckboxField.label, btnNext, btnQr); inputWrapper.append(countryInputField.container, telInputField.container, signedCheckboxField.label, btnNext, btnQr);
const h4 = document.createElement('h4'); const h4 = document.createElement('h4');
h4.classList.add('text-center');
_i18n(h4, 'Login.Title'); _i18n(h4, 'Login.Title');
const subtitle = document.createElement('div'); const subtitle = document.createElement('div');
subtitle.classList.add('subtitle'); subtitle.classList.add('subtitle', 'text-center');
_i18n(subtitle, 'Login.StartText'); _i18n(subtitle, 'Login.StartText');
page.pageEl.querySelector('.container').append(h4, subtitle, inputWrapper); page.pageEl.querySelector('.container').append(h4, subtitle, inputWrapper);
@ -470,12 +498,15 @@ let onFirstMount = () => {
return nearestDcResult; return nearestDcResult;
}).then((nearestDcResult) => { }).then((nearestDcResult) => {
let country = countries.find((c) => c.code === nearestDcResult.country); if(!countryInput.value.length && !telInputField.value.length) {
const country = countries.find((c) => c.code === nearestDcResult.country);
if(country) { if(country) {
if(!countryInput.value.length && !telEl.value.length) {
countryInput.value = country.name; countryInput.value = country.name;
lastCountrySelected = country; lastCountrySelected = country;
telEl.value = lastValue = '+' + country.phoneCode.split(' and ').shift(); const str = '+' + country.phoneCode.split(' and ').shift();
const {leftPattern} = formatPhoneNumber(str);
telInputField.setValueSilently(lastValue = str);
telEl.dataset.leftPattern = leftPattern;
} }
} }

13
src/scss/partials/_input.scss

@ -433,3 +433,16 @@ input:focus, button:focus {
} }
} }
} }
.input-field-phone {
.input-field-input {
--letter-spacing: .24px;
&:after {
content: attr(data-left-pattern);
// opacity: .4;
color: $placeholder-color;
letter-spacing: var(--letter-spacing);
}
}
}

Loading…
Cancel
Save