formatDate(date) {
const today = new Date();
return [ 'getFullYear', 'getMonth', 'getDate' ].every(n => date[n]() === today[n]())
? 'Today'
: flatpickr.formatDate(date, 'j M');
},
const Ball = function (x, y, radius, width, height) {
...
this.ballNum = Math.round(Math.random() * imgBalls.length)
Ball.prototype.draw = function (ctx) {
// for (let i = 0; i < imgBalls.length; i++) {
img = new Image();
ballSrc = imgBalls[this.ballNum];
...
// }
};
TBody
в таком случае должен стать дженериком.type TUserInfo = {
id: num,
readonly fname: string,
readonly lname: string
}
type TBody<T> = {
success: boolean,
user?: T
}
const fechUserInfo = (): Promise<TBody<TUserInfo>> => {
return fetch().then(response => response.json()).then((user: TUserInfo) => ({success: true, user}));
}
class MyClass extends React.Component {
constructor(props) {
super(props);
this.state = {
current: 'one'
};
}
render() {
return (
<section className="section">
<Tab value="one" active={this.state.current === 'one'} onClick={() => this.setState({current: 'one'})}>One</Tab>
<Tab value="two" active={this.state.current === 'two'} onClick={() => this.setState({current: 'two'})}>Two</Tab>
</section>
)
}
}
const openSelector = '[data-target]';
const closeSelector = '.modal__close';
const modalSelector = '.modal';
const activeClass = 'modal--active';
document.addEventListener('click', ({ target: t }) => {
const open = t.closest(openSelector);
if (open) {
document.querySelector(`#${open.dataset.target}`).classList.add(activeClass);
} else {
t.closest(closeSelector)?.closest(modalSelector).classList.remove(activeClass);
}
});
const onClick = (selector, handler) => document
.querySelectorAll(selector)
.forEach(n => n.addEventListener('click', handler));
onClick(openSelector, ({ currentTarget: { dataset: { target } } }) => {
document.querySelector(`#${target}`).classList.add(activeClass);
});
onClick(closeSelector, e => {
e.currentTarget.closest(modalSelector).classList.remove(activeClass);
});
(function() {
'use strict';
const formItems = document.querySelectorAll('.form .form__item');
const formRadios = formItems.forEach(item => item.querySelectorAll('.form__label'))
const formProgressLine = document.querySelector('.form .form__progress .form__progress-line');
const formProgressStart = 100 / formItems.length;
const result = document.querySelector('.result');
setTimeout(() => {
formProgressLine.style.width = `${formProgressStart}%`;
}, 0);
formRadios.slice(0, 2).forEach((formRadio, formRadioIndex) => {
formRadios.forEach(radio => {
radio.addEventListener('click', () => {
setTimeout(() => {
formItems[formRadioIndex].classList.remove('form__item--active');
formItems[formRadioIndex + 1].classList.add('form__item--active');
}, 1000);
formProgressLine.style.width = `${formProgressStart * (formRadioIndex + 2)}%`;
});
});
})
formRadios[2].forEach(radio => {
radio.addEventListener('click', () => {
setTimeout(() => {
form.style.display = 'none'
result.classList.add('result--active');
}, 1000);
});
});
})();
const form = document.querySelector('.form');
const items = [...form.querySelectorAll('.form__item')];
form.addEventListener('change', function(e) {
const index = items.indexOf(e.target.closest('.form__item'));
form.querySelector('.form__progress-line').style.width = (index + 2) * 100 / items.length + '%';
setTimeout(() => {
items[index]?.classList.remove('form__item--active');
items[index + 1]?.classList.add('form__item--active');
if (index + 1 === items.length) {
form.style.display = 'none';
document.querySelector('.result').classList.add('result--active');
}
}, 1000);
});
form.dispatchEvent(new Event('change'));