Input label animation fix

This commit is contained in:
morethanwords 2021-01-19 21:49:01 +04:00
parent 9ff81dd157
commit 7c85f932e2
8 changed files with 224 additions and 134 deletions

View File

@ -24,7 +24,7 @@ import animationIntersector from "../animationIntersector";
import { months } from "../../helpers/date";
import RichTextProcessor from "../../lib/richtextprocessor";
import mediaSizes from "../../helpers/mediaSizes";
import { isAndroid, isApple, isSafari } from "../../helpers/userAgent";
import { isAndroid, isApple, isSafari, isAppleMobile } from "../../helpers/userAgent";
import { langPack } from "../../lib/langPack";
import AvatarElement from "../avatar";
import { formatPhoneNumber } from "../misc";
@ -2428,9 +2428,11 @@ export default class ChatBubbles {
//this.scrollable.scrollTop = this.scrollable.scrollHeight;
isTouchSupported && isApple && (this.scrollable.container.style.overflow = '');
this.scrollable.container.style.display = 'none';
void this.scrollable.container.offsetLeft; // reflow
this.scrollable.container.style.display = '';
if(isSafari && !isAppleMobile) { // * fix blinking and jumping
this.scrollable.container.style.display = 'none';
void this.scrollable.container.offsetLeft; // reflow
this.scrollable.container.style.display = '';
}
/* if(DEBUG) {
this.log('performHistoryResult: have set up scrollTop:', newScrollTop, this.scrollable.scrollTop, this.isHeavyAnimationInProgress);
@ -2707,14 +2709,18 @@ export default class ChatBubbles {
const promises = [topRes.animationPromise, middleRes.animationPromise, bottomRes.animationPromise];
const delays: number[] = [topRes.lastMsDelay, middleRes.lastMsDelay, bottomRes.lastMsDelay];
let promise: Promise<any>;
if(topIds.length || middleIds.length || bottomIds.length) {
dispatchHeavyAnimationEvent(Promise.all(promises), Math.max(...delays) + 200); // * 200 - transition time
promise = Promise.all(promises);
dispatchHeavyAnimationEvent(promise, Math.max(...delays) + 200); // * 200 - transition time
}
}
setTimeout(() => {
this.loadMoreHistory(true, true);
}, 0);
(promise || Promise.resolve()).then(() => {
setTimeout(() => { // preload messages
this.loadMoreHistory(reverse, true);
}, 0);
});
}
});
}

View File

@ -39,25 +39,6 @@
</div>
<h4>Sign in to Telegram</h4>
<p class="subtitle">Please confirm your country and<br> enter your phone number.</p>
<div class="input-wrapper">
{{!-- <form action=""> --}}
<div class="input-field input-select">
<input type="text" name="countryCode" id="countryCode" autocomplete="rrRandomRR" required />
<label for="countryCode">Country</label>
<span class="arrow arrow-down"></span>
</div>
<div class="input-field">
<input type="tel" name="phone" id="phone" autocomplete="rr55RandomRR55" required />
<label for="phone">Phone Number</label>
</div>
<label class="checkbox-field">
<input type="checkbox" id="keepSigned" checked="checked">
<span>Keep me signed in</span>
</label>
<button class="btn-primary rp" style="visibility: hidden;">NEXT</button>
{{!-- </form> --}}
<div class="qr"><a href="#" class="a-qr">Quick log in using QR code</a></div>
</div>
</div>
</div>
<div class="page-signQR">
@ -78,12 +59,7 @@
<span class="phone-edit tgico-edit"></span>
</div>
<p class="subtitle sent-type"></p>
<div class="input-wrapper">
<div class="input-field">
<input type="tel" name="code" id="code" autocomplete="off" required />
<label for="code">Code</label>
</div>
</div>
<div class="input-wrapper"></div>
</div>
</div>
<div class="page-password">
@ -91,14 +67,7 @@
<div class="auth-image"></div>
<h4 class="phone">Enter Your Password</h4>
<p class="subtitle">Your account is protected with<br>an additional password</p>
<div class="input-wrapper">
<div class="input-field">
<input type="password" name="password" id="password" autocomplete="off" required />
<label for="password">Password</label>
<span class="toggle-visible tgico"></span>
</div>
<button class="btn-primary rp">NEXT</button>
</div>
<div class="input-wrapper"></div>
</div>
</div>
<div class="page-signUp">

View File

@ -10,6 +10,7 @@ import CryptoWorker from "../crypto/cryptoworker";
import { logger, LogLevels } from "../logger";
import { bytesCmp, bytesToHex, bytesFromHex, bytesXor } from "../../helpers/bytes";
import { DEBUG } from "./mtproto_config";
//import { bigInt2str, greater, int2bigInt, one, powMod, str2bigInt, sub } from "../../vendor/leemon";
/* let fNewNonce: any = bytesFromHex('8761970c24cb2329b5b2459752c502f3057cb7e8dbab200e526e8767fdc73b3c').reverse();
@ -100,10 +101,14 @@ export class Authorizer {
transport: transport
};
this.log('mtpSendPlainRequest: creating requestPromise');
if(DEBUG) {
this.log('mtpSendPlainRequest: creating requestPromise');
}
return transport.send(resultArray).then(result => {
this.log('mtpSendPlainRequest: in good sector', result);
if(DEBUG) {
this.log('mtpSendPlainRequest: in good sector', result);
}
if(!result || !result.byteLength) {
return Promise.reject(baseError);
@ -148,7 +153,9 @@ export class Authorizer {
// need
rsaKeysManager.prepare().then(() => {});
this.log('Send req_pq', auth.nonce.hex);
if(DEBUG) {
this.log('Send req_pq', auth.nonce.hex);
}
try {
var deserializer = await this.mtpSendPlainRequest(auth.dcId, request.getBytes(true));
} catch(error) {
@ -172,7 +179,9 @@ export class Authorizer {
auth.pq = response.pq;
auth.fingerprints = response.server_public_key_fingerprints;
this.log('Got ResPQ', bytesToHex(auth.serverNonce), bytesToHex(auth.pq), auth.fingerprints);
if(DEBUG) {
this.log('Got ResPQ', bytesToHex(auth.serverNonce), bytesToHex(auth.pq), auth.fingerprints);
}
let publicKey = await rsaKeysManager.select(auth.fingerprints);
if(!publicKey) {
@ -181,7 +190,9 @@ export class Authorizer {
auth.publicKey = publicKey;
this.log('PQ factorization start', auth.pq);
if(DEBUG) {
this.log('PQ factorization start', auth.pq);
}
try {
var pAndQ = await CryptoWorker.factorize(auth.pq);
@ -193,7 +204,9 @@ export class Authorizer {
auth.p = pAndQ[0];
auth.q = pAndQ[1];
this.log('PQ factorization done', pAndQ);
if(DEBUG) {
this.log('PQ factorization done', pAndQ);
}
/* let p = new Uint32Array(new Uint8Array(auth.p).buffer)[0];
let q = new Uint32Array(new Uint8Array(auth.q).buffer)[0];
console.log(dT(), 'PQ factorization done', pAndQ, p.toString(16), q.toString(16)); */
@ -258,18 +271,22 @@ export class Authorizer {
let requestBytes = request.getBytes(true);
this.log('Send req_DH_params', req_DH_params/* , requestBytes.hex */);
if(DEBUG) {
this.log('Send req_DH_params', req_DH_params/* , requestBytes.hex */);
}
try {
var deserializer = await this.mtpSendPlainRequest(auth.dcId, requestBytes);
} catch(error) {
this.log('Send req_DH_params FAIL!', error);
this.log.error('Send req_DH_params FAIL!', error);
throw error;
}
var response = deserializer.fetchObject('Server_DH_Params', 'RESPONSE');
this.log('Sent req_DH_params, response:', response);
if(DEBUG) {
this.log('Sent req_DH_params, response:', response);
}
if(response._ != 'server_DH_params_fail' && response._ != 'server_DH_params_ok') {
throw new Error('[MT] Server_DH_Params response invalid: ' + response._);
@ -347,7 +364,9 @@ export class Authorizer {
throw new Error('[MT] server_DH_inner_data serverNonce mismatch');
}
this.log('Done decrypting answer');
if(DEBUG) {
this.log('Done decrypting answer');
}
auth.g = response.g;
auth.dhPrime = response.dh_prime;
auth.gA = response.g_a;
@ -367,13 +386,19 @@ export class Authorizer {
}
public mtpVerifyDhParams(g: number, dhPrime: Uint8Array, gA: Uint8Array) {
this.log('Verifying DH params', g, dhPrime, gA);
if(DEBUG) {
this.log('Verifying DH params', g, dhPrime, gA);
}
var dhPrimeHex = bytesToHex(dhPrime);
if(g != 3 || dhPrimeHex !== 'c71caeb9c6b1c9048e6c522f70f13f73980d40238e3e21c14934d037563d930f48198a0aa7c14058229493d22530f4dbfa336f6e0ac925139543aed44cce7c3720fd51f69458705ac68cd4fe6b6b13abdc9746512969328454f18faf8c595f642477fe96bb2a941d5bcd1d4ac8cc49880708fa9b378e3c4f3a9060bee67cf9a4a4a695811051907e162753b56b0f6b410dba74d8a84b2a14b3144e0ef1284754fd17ed950d5965b4b9dd46582db1178d169c6bc465b0d6ff9ca3928fef5b9ae4e418fc15e83ebea0f87fa9ff5eed70050ded2849f47bf959d956850ce929851f0d8115f635b105ee2e4e15d04b2454bf6f4fadf034b10403119cd8e3b92fcc5b') {
// The verified value is from https://core.telegram.org/mtproto/security_guidelines
throw new Error('[MT] DH params are not verified: unknown dhPrime');
}
this.log('dhPrime cmp OK');
if(DEBUG) {
this.log('dhPrime cmp OK');
}
var gABigInt = new BigInteger(bytesToHex(gA), 16);
//const _gABigInt = str2bigInt(bytesToHex(gA), 16);
@ -392,7 +417,10 @@ export class Authorizer {
//if(greater(gABigInt, sub(_dhPrimeBigInt, one))) {
throw new Error('[MT] DH params are not verified: gA >= dhPrime - 1');
}
this.log('1 < gA < dhPrime-1 OK');
if(DEBUG) {
this.log('1 < gA < dhPrime-1 OK');
}
var two = new BigInteger(/* null */'');
@ -410,7 +438,10 @@ export class Authorizer {
if(gABigInt.compareTo(dhPrimeBigInt.subtract(twoPow)) >= 0) {
throw new Error('[MT] DH params are not verified: gA > dhPrime - 2^{2048-64}');
}
this.log('2^{2048-64} < gA < dhPrime-2^{2048-64} OK');
if(DEBUG) {
this.log('2^{2048-64} < gA < dhPrime-2^{2048-64} OK');
}
return true;
}
@ -450,7 +481,9 @@ export class Authorizer {
encrypted_data: encryptedData
});
this.log('Send set_client_DH_params');
if(DEBUG) {
this.log('Send set_client_DH_params');
}
try {
var deserializer = await this.mtpSendPlainRequest(auth.dcId, request.getBytes(true));
@ -483,7 +516,9 @@ export class Authorizer {
authKeyAux = authKeyHash.slice(0, 8),
authKeyId = authKeyHash.slice(-8);
this.log('Got Set_client_DH_params_answer', response._, authKey);
if(DEBUG) {
this.log('Got Set_client_DH_params_answer', response._, authKey);
}
switch(response._) {
case 'dh_gen_ok':
var newNonceHash1 = (await CryptoWorker.sha1Hash(auth.newNonce.concat([1], authKeyAux))).slice(-16);
@ -494,7 +529,9 @@ export class Authorizer {
}
var serverSalt = bytesXor(auth.newNonce.slice(0, 8), auth.serverNonce.slice(0, 8));
this.log('Auth successfull!', authKeyId, authKey, serverSalt);
if(DEBUG) {
this.log('Auth successfull!', authKeyId, authKey, serverSalt);
}
auth.authKeyId = authKeyId;
auth.authKey = authKey;

View File

@ -109,7 +109,7 @@ ctx.addEventListener('message', async(e) => {
case 'gzipUncompress':
// @ts-ignore
return cryptoWorker[task.task].apply(cryptoWorker, task.args).then(result => {
respond({taskId: taskId, result: result});
respond({taskId, result});
});
case 'setQueueId':
@ -127,16 +127,18 @@ ctx.addEventListener('message', async(e) => {
result = await result;
}
respond({taskId: taskId, result: result});
} catch(err) {
respond({taskId: taskId, error: err});
respond({taskId, result});
} catch(error) {
respond({taskId, error});
}
}
case 'getNetworker': {
// @ts-ignore
apiManager[task.task].apply(apiManager, task.args);
respond({taskId: taskId, result: null});
apiManager[task.task].apply(apiManager, task.args).finally(() => {
respond({taskId, result: null});
});
break;
}
@ -149,9 +151,9 @@ ctx.addEventListener('message', async(e) => {
result = await result;
}
respond({taskId: taskId, result: result});
} catch(err) {
respond({taskId: taskId, error: err});
respond({taskId, result});
} catch(error) {
respond({taskId, error});
}
//throw new Error('Unknown task: ' + task.task);

View File

@ -11,6 +11,7 @@ import pageIm from './pageIm';
import pagePassword from './pagePassword';
import pageSignIn from './pageSignIn';
import pageSignUp from './pageSignUp';
import InputField from '../components/inputField';
let authCode: AuthSentCode.authSentCode = null;
@ -28,7 +29,19 @@ let onFirstMount = (): Promise<any> => {
const CODELENGTH = (authCode.type as AuthSentCodeType.authSentCodeTypeApp).length;
codeInput = page.pageEl.querySelector('#code') as HTMLInputElement;
const codeInputField = new InputField({
label: 'Code',
name: 'code',
plainText: true
});
codeInput = codeInputField.input as HTMLInputElement;
codeInput.type = 'tel';
codeInput.setAttribute('required', '');
codeInput.autocomplete = 'off';
page.pageEl.querySelector('.input-wrapper').append(codeInputField.container);
const codeInputLabel = codeInput.nextElementSibling as HTMLLabelElement;
const editButton = page.pageEl.querySelector('.phone-edit') as HTMLElement;

View File

@ -12,6 +12,8 @@ import passwordManager from '../lib/mtproto/passwordManager';
import { cancelEvent } from '../helpers/dom';
import Page from './page';
import pageIm from './pageIm';
import InputField from '../components/inputField';
import Button from '../components/button';
const TEST = false;
let passwordInput: HTMLInputElement;
@ -22,10 +24,28 @@ let onFirstMount = (): Promise<any> => {
let passwordVisible = false;
const btnNext = page.pageEl.querySelector('button') as HTMLButtonElement;
passwordInput = document.getElementById('password') as HTMLInputElement;
const btnNext = Button('btn-primary', {text: 'NEXT'});
const passwordInputField = new InputField({
label: 'Password',
name: 'password',
plainText: true
});
passwordInput = passwordInputField.input as HTMLInputElement;
passwordInput.type = 'password';
passwordInput.setAttribute('required', '');
passwordInput.autocomplete = 'off';
const passwordInputLabel = passwordInput.nextElementSibling as HTMLLabelElement;
const toggleVisible = page.pageEl.querySelector('.toggle-visible') as HTMLSpanElement;
const toggleVisible = document.createElement('span');
toggleVisible.classList.add('toggle-visible', 'tgico');
passwordInputField.container.append(toggleVisible);
page.pageEl.querySelector('.input-wrapper').append(passwordInputField.container, btnNext);
let getStateInterval: number;
let getState = () => {

View File

@ -9,6 +9,10 @@ import { findUpTag } from "../helpers/dom";
import Page from "./page";
import pageAuthCode from "./pageAuthCode";
import pageSignQR from './pageSignQR';
import InputField from "../components/inputField";
import CheckboxField from "../components/checkbox";
import Button from "../components/button";
import { isAppleMobile } from "../helpers/userAgent";
type Country = _Country & {
li?: HTMLLIElement[]
@ -35,24 +39,34 @@ let onFirstMount = () => {
let lastCountrySelected: Country = null;
var selectCountryCode = page.pageEl.querySelector('input[name="countryCode"]')! as HTMLInputElement;
var parent = selectCountryCode.parentElement;
const inputWrapper = document.createElement('div');
inputWrapper.classList.add('input-wrapper');
var wrapper = document.createElement('div');
wrapper.classList.add('select-wrapper', 'z-depth-3', 'hide');
const countryInputField = new InputField({
label: 'Country',
name: 'countryCode',
plainText: true
});
var list = document.createElement('ul');
wrapper.appendChild(list);
countryInputField.container.classList.add('input-select');
//let wrapperScroll = OverlayScrollbars(wrapper, (window as any).scrollbarOptions);
let scroll = new Scrollable(wrapper);
const countryInput = countryInputField.input as HTMLInputElement;
countryInput.autocomplete = 'rrRandomRR';
const selectWrapper = document.createElement('div');
selectWrapper.classList.add('select-wrapper', 'z-depth-3', 'hide');
const arrowDown = document.createElement('span');
arrowDown.classList.add('arrow', 'arrow-down');
countryInputField.container.append(arrowDown);
const selectList = document.createElement('ul');
selectWrapper.appendChild(selectList);
const scroll = new Scrollable(selectWrapper);
let initedSelect = false;
page.pageEl.querySelector('.a-qr').addEventListener('click', () => {
pageSignQR.mount();
});
let initSelect = () => {
initSelect = null;
@ -88,20 +102,20 @@ let onFirstMount = () => {
li.appendChild(span);
liArr.push(li);
list.append(li);
selectList.append(li);
});
c.li = liArr;
});
list.addEventListener('mousedown', function(e) {
selectList.addEventListener('mousedown', function(e) {
let target = e.target as HTMLElement;
if(target.tagName != 'LI') target = findUpTag(target, 'LI');
let countryName = target.childNodes[1].textContent;//target.innerText.split('\n').shift();
let phoneCode = target.querySelector<HTMLElement>('.phone-code').innerText;
selectCountryCode.value = countryName;
countryInput.value = countryName;
lastCountrySelected = countries.find(c => c.name == countryName);
telEl.value = lastValue = phoneCode;
@ -109,14 +123,14 @@ let onFirstMount = () => {
//console.log('clicked', e, countryName, phoneCode);
});
parent.appendChild(wrapper);
countryInputField.container.appendChild(selectWrapper);
};
initSelect();
let hideTimeout: number;
selectCountryCode.addEventListener('focus', function(this: typeof selectCountryCode, e) {
countryInput.addEventListener('focus', function(this: typeof countryInput, e) {
if(initSelect) {
initSelect();
} else {
@ -127,20 +141,20 @@ let onFirstMount = () => {
clearTimeout(hideTimeout);
wrapper.classList.remove('hide');
void wrapper.offsetWidth; // reflow
wrapper.classList.add('active');
selectWrapper.classList.remove('hide');
void selectWrapper.offsetWidth; // reflow
selectWrapper.classList.add('active');
});
selectCountryCode.addEventListener('blur', function(this: typeof selectCountryCode, e) {
wrapper.classList.remove('active');
countryInput.addEventListener('blur', function(this: typeof countryInput, e) {
selectWrapper.classList.remove('active');
hideTimeout = window.setTimeout(() => {
wrapper.classList.add('hide');
selectWrapper.classList.add('hide');
}, 200);
e.cancelBubble = true;
}, {capture: true});
selectCountryCode.addEventListener('keyup', function(this: typeof selectCountryCode, e) {
countryInput.addEventListener('keyup', function(this: typeof countryInput, e) {
if(e.ctrlKey || e.key == 'Control') return false;
//let i = new RegExp('^' + this.value, 'i');
@ -169,24 +183,31 @@ let onFirstMount = () => {
}
});
let arrowDown = page.pageEl.querySelector('.arrow-down') as HTMLSpanElement;
arrowDown.addEventListener('mousedown', function(this: typeof arrowDown, e) {
e.cancelBubble = true;
e.preventDefault();
if(selectCountryCode.matches(':focus')) selectCountryCode.blur();
else selectCountryCode.focus();
if(countryInput.matches(':focus')) countryInput.blur();
else countryInput.focus();
});
let pasted = false;
let lastValue = '';
let telEl = page.pageEl.querySelector('input[name="phone"]') as HTMLInputElement;
const telInputField = new InputField({
label: 'Phone Number',
plainText: true,
name: 'phone'
});
let telEl = telInputField.input as HTMLInputElement;
telEl.type = 'tel';
telEl.autocomplete = 'rr55RandomRR55';
const telLabel = telEl.nextElementSibling as HTMLLabelElement;
telEl.addEventListener('input', function(this: typeof telEl, e) {
//console.log('input', this.value);
this.classList.remove('error');
const diff = Math.abs(this.value.length - lastValue.length);
if(diff > 1 && !pasted) {
if(diff > 1 && !pasted && isAppleMobile) {
this.value = lastValue + this.value;
}
@ -200,8 +221,8 @@ let onFirstMount = () => {
//console.log(formatted, country);
let countryName = country ? country.name : ''/* 'Unknown' */;
if(countryName != selectCountryCode.value && (!lastCountrySelected || !country || lastCountrySelected.phoneCode != country.phoneCode)) {
selectCountryCode.value = countryName;
if(countryName != countryInput.value && (!lastCountrySelected || !country || lastCountrySelected.phoneCode != country.phoneCode)) {
countryInput.value = countryName;
lastCountrySelected = country;
}
@ -226,7 +247,7 @@ let onFirstMount = () => {
//console.log('keypress', this.value);
if(!btnNext.style.visibility &&/* this.value.length >= 9 && */ e.key == 'Enter') {
return btnNext.click();
} else if(/\D/.test(e.key)) {
} else if(/\D/.test(e.key) && !(e.metaKey || e.ctrlKey)) {
e.preventDefault();
return false;
}
@ -236,8 +257,11 @@ let onFirstMount = () => {
this.removeAttribute('readonly'); // fix autocomplete
});*/
/* authorizer.auth(2);
networkerFactory.startAll(); */
const signedCheckboxField = CheckboxField('Keep me signed in', 'keepSession');
signedCheckboxField.input.checked = true;
btnNext = Button('btn-primary', {text: 'NEXT'});
btnNext.style.visibility = 'hidden';
btnNext.addEventListener('click', function(this: HTMLElement, e) {
this.setAttribute('disabled', 'true');
@ -277,33 +301,56 @@ let onFirstMount = () => {
}
});
});
const qrDiv = document.createElement('div');
qrDiv.classList.add('qr');
const qrLink = document.createElement('a');
qrLink.href = '#';
qrLink.classList.add('a-qr');
qrLink.innerText = 'Quick log in using QR code';
qrDiv.append(qrLink);
qrLink.addEventListener('click', () => {
pageSignQR.mount();
});
inputWrapper.append(countryInputField.container, telInputField.container, signedCheckboxField.label, btnNext, qrDiv);
page.pageEl.querySelector('.container').append(inputWrapper);
let tryAgain = () => {
apiManager.invokeApi('help.getNearestDc').then((nearestDcResult) => {
const dcs = [1, 2, 3, 4, 5];
//dcs.splice(nearestDcResult.this_dc - 1, 1);
const done: number[] = [nearestDcResult.this_dc];
let promise: Promise<any>;
if(nearestDcResult.nearest_dc != nearestDcResult.this_dc) {
//MTProto.apiManager.baseDcID = nearestDcResult.nearest_dc;
promise = apiManager.getNetworker(nearestDcResult.nearest_dc).then(() => {
done.push(nearestDcResult.nearest_dc)
});
}
(promise || Promise.resolve()).then(() => {
dcs.forEach(dcId => {
apiManager.getNetworker(dcId, {fileDownload: true});
});
const g = () => {
const dcId = dcs.shift();
if(!dcId) return;
setTimeout(() => { // * если одновременно запросить все нетворкеры, не будет проходить запрос на код
apiManager.getNetworker(dcId, {fileDownload: true}).finally(g);
}, done.includes(dcId) ? 0 : 3000);
};
g();
});
return nearestDcResult;
}).then((nearestDcResult) => {
let country = countries.find((c) => c.code == nearestDcResult.country);
let country = countries.find((c) => c.code === nearestDcResult.country);
if(country) {
if(!selectCountryCode.value.length && !telEl.value.length) {
selectCountryCode.value = country.name;
if(!countryInput.value.length && !telEl.value.length) {
countryInput.value = country.name;
lastCountrySelected = country;
telEl.value = lastValue = '+' + country.phoneCode.split(' and ').shift();
}
@ -317,12 +364,10 @@ let onFirstMount = () => {
};
const page = new Page('page-sign', true, onFirstMount, () => {
if(!btnNext) {
btnNext = page.pageEl.querySelector('button');
if(btnNext) {
btnNext.textContent = 'NEXT';
btnNext.removeAttribute('disabled');
}
btnNext.textContent = 'NEXT';
btnNext.removeAttribute('disabled');
appStateManager.pushToState('authState', {_: 'authStateSignIn'});
appStateManager.saveState();

View File

@ -4,7 +4,12 @@
}
.input-field {
--height: 54px;
position: relative;
@include respond-to(handhelds) {
--height: 50px;
}
.arrow-down {
position: absolute;
@ -35,24 +40,24 @@
label {
position: absolute;
color: $placeholder-color;
top: 0;
left: 1rem;
right: auto;
z-index: 2;
top: 50%;
height: 1.5rem;
transform: translateY(-50%);
transform: translate(0, 0);
background-color: #fff;
transition: .2s transform, .2s padding, .1s opacity, .2s top, .2s left;
transition: .2s transform, .2s padding, .1s opacity;
transform-origin: left center;
pointer-events: none;
margin-top: calc((var(--height) - 1.5rem) / 2); // * Center of first line
body.animation-level-0 & {
transition: none;
}
}
input, &-input {
--height: 54px;
&-input {
--padding: 1rem;
--border-width: 1px;
--border-width-top: 2px;
@ -80,9 +85,6 @@
}
}
@include respond-to(handhelds) {
--height: 50px;
}
/* font-weight: 500; */
/* &:hover {
@ -133,13 +135,9 @@
}
&:focus ~ label, &:valid ~ label, &:not(:empty) ~ label, &:disabled ~ label {
//transform: translate(-.3125rem, -2.375rem) scale(.75);
//transform: translate(-.3125rem, -50%) scale(.75);
transform: translateY(-50%) scale(.75);
top: 1px;
transform: translate(-.25rem, calc(var(--height) / -2 + .125rem)) scale(.75);
padding: 0 6px;
opacity: 1;
left: .75rem;
font-weight: 500;
}
}