Ready components for the Front End Developers

This is a collection of ready-made solutions for developers. It contains code with components, basic and full styles, and vs-code snippets. Copy the necessary code from this resource!

code / style / snippets

Components

Slix slider
version 1.0.3
Slix

The multi-functional slider includes styles and a snippet.

Structure:

js -> slix.js + modules (slix-counter.js, slix-navigation.js slix-pagination.js)

css -> slix-style.css + slix-style-full.css

snippets code add to your vs-code

Get code
JS Core

// slix-pagination.js
export const initPagination = (slides, slidesField, width, moveSlide) => {
    const paginationContainer = document.querySelector('.slix-pagination');

    if (!paginationContainer) {
       console.error('Pagination container not found');
        return;
    }

    slides.forEach((_, index) => {
        const dot = document.createElement('div');
        dot.classList.add('dot');
        if (index === 0) dot.classList.add('active');
        dot.dataset.index = index;
        paginationContainer.appendChild(dot);
    });

    const dots = paginationContainer.querySelectorAll('.dot');

    const updatePagination = (slideIndex) => {
        dots.forEach(dot => dot.classList.remove('active'));
        dots[slideIndex - 1].classList.add('active');
    };

    dots.forEach(dot => {
        dot.addEventListener('click', (e) => {
            const index = parseInt(e.target.dataset.index);
            moveToSlide(index + 1);
        });

        dot.addEventListener('touchstart', (e) => {
            const index = parseInt(e.target.dataset.index);
            moveToSlide(index + 1);
        });
    });

    const moveToSlide = (index) => {
        const offset = width * (index - 1);
        slidesField.style.transform = `translateX(-${offset}px)`;
        moveSlide(index);
        updatePagination(index);
    };

    return updatePagination;
};

/*
    Slix slider 1.0.1
    Snippet (HTML): slix, slixfull
    Author: Mykola Papchenko
*/

    // basic style
    import "../scss/slix-style.scss";
    // full style (Navigation, Pagination, Counter)
    // import "../scss/slix-style-full.scss";

    // connect the function (Navigation, Pagination, Counter)
    // import { initNavigation } from './modules/slix-navigation.js';
    // import { initCounter } from './modules/slix-counter.js';
    // import { initPagination } from './modules/slix-pagination.js';

    const slidesWrapper = document.querySelector('.slix__slider-wrapper');
    const slidesField = document.querySelector('.slix__slider-inner');
    const width = parseInt(window.getComputedStyle(slidesWrapper)
.width);

    let slideIndex = 1;
    let offset = 0;
    let isDragging = false, startPos = 0, currentTranslate = 0, prevTranslate = 0;

    const slides = document.querySelectorAll('.slix__slide');
    slidesField.style.width = `${100 * slides.length}%`;
    slides.forEach(slide => slide.style.width = `${width}px`);

    const moveSlide = (direction) => {
        if (typeof direction === 'number') {
            slideIndex = direction;
            offset = width * (slideIndex - 1);
        } else {
            if (direction === 'next') {
                offset = (offset === width * (slides.length - 1)) ? 0 : offset + width;
                slideIndex = (slideIndex === slides.length) ? 1 : slideIndex + 1;
        } else {
                offset = (offset === 0) ? width * (slides.length - 1) : offset - width;
                slideIndex = (slideIndex === 1) ? slides.length : slideIndex - 1;
        }
    }

    slidesField.style.transform = `translateX(-${offset}px)`;

    if (typeof updateSlideCount === 'function') {
        updateSlideCount(slideIndex);
    }
    if (typeof updatePagination === 'function') {
        updatePagination(slideIndex);
    }
};

    try {
        initNavigation(slides, slidesField, width, moveSlide);
    } catch (e) {
        console.log("Navigation module not loaded");
    }

    let updateSlideCount;
    try {
        updateSlideCount = initCounter();
    } catch (e) {
        console.log("Counter module not loaded");
    }

    let updatePagination;
    try {
        updatePagination = initPagination(slides, slidesField, width, moveSlide);
    } catch (e) {
        console.log("Pagination module not loaded");
    }

    const startDrag = (pos) => {
        isDragging = true;
        startPos = pos;
        slidesField.style.transition = 'none';
    }

    const endDrag = () => {
        isDragging = false;
        const movedBy = currentTranslate - prevTranslate;
        if (movedBy < -width / 4) moveSlide('next');
        if (movedBy > width / 4) moveSlide('prev');
        setPositionByIndex();
    }

    const dragMove = (pos) => {
        if (isDragging) {
            currentTranslate = prevTranslate + pos - startPos;
            slidesField.style.transform = `translateX(${currentTranslate}px)`;
        }
    }

    const setPositionByIndex = () => {
        prevTranslate = -offset;
        slidesField.style.transition = '0.5s all';
        slidesField.style.transform = `translateX(-${offset}px)`;

        if (typeof updateSlideCount === 'function') {
            updateSlideCount(slideIndex);
        }
        if (typeof updatePagination === 'function') {
            updatePagination(slideIndex);
        }
    }

    slides.forEach((slide, index) => {
        const img = slide.querySelector('img');
        img.addEventListener('mousedown', (e) => startDrag(e.clientX));
        img.addEventListener('mousemove', (e) => dragMove(e.clientX));
        img.addEventListener('mouseup', endDrag);
        img.addEventListener('mouseleave', () => isDragging && endDrag());
        img.addEventListener('touchstart', (e) => startDrag(e.touches[0].clientX));
        img.addEventListener('touchmove', (e) => dragMove(e.touches[0].clientX));
        img.addEventListener('touchend', endDrag);
        img.addEventListener('dragstart', (e) => e.preventDefault());
    });

JS Functionals (counter, navigation, pagination)

// slix-counter.js
const formatNumber = num => num < 10 ? `0${num}` : num;
const total = document.querySelector('#total');
const current = document.querySelector('#current');
const slides = document.querySelectorAll('.slix__slide');

export const initCounter = () => {
    const updateSlideCount = (slideIndex) => {
        total.textContent = formatNumber(slides.length);
        current.textContent = formatNumber(slideIndex);
    };

    updateSlideCount(1);

    return updateSlideCount;
};

// slix-navigation.js
export function initNavigation(slides, slidesField, width, moveSlide) {
    const prev = document.querySelector('.slides-prev');
    const next = document.querySelector('.slides-next');

    let slideIndex = 1;
    let offset = 0;

    const prevSlide = () => moveSlide('prev');
    const nextSlide = () => moveSlide('next');

    if (prev) {
        prev.addEventListener('click', prevSlide);
    } else {
        console.error("Previous button not found");
    }

    if (next) {
        next.addEventListener('click', nextSlide);
    } else {
        console.error("Next button not found");
    }

    return {
        getSlideIndex: () => slideIndex,
        getOffset: () => offset
    };
}

// slix-pagination.js
export const initPagination = (slides, slidesField, width, moveSlide) => {
    const paginationContainer = document.querySelector('.slix-pagination');

    if (!paginationContainer) {
        console.error('Pagination container not found');
        return;
    }

    slides.forEach((_, index) => {
        const dot = document.createElement('div');
        dot.classList.add('dot');
        if (index === 0) dot.classList.add('active');
        dot.dataset.index = index;
        paginationContainer.appendChild(dot);
    });

    const dots = paginationContainer.querySelectorAll('.dot');

    const updatePagination = (slideIndex) => {
        dots.forEach(dot => dot.classList.remove('active'));
        dots[slideIndex - 1].classList.add('active');
    };

    dots.forEach(dot => {
        dot.addEventListener('click', (e) => {
            const index = parseInt(e.target.dataset.index);
            moveToSlide(index + 1);
        });

        dot.addEventListener('touchstart', (e) => {
            const index = parseInt(e.target.dataset.index);
            moveToSlide(index + 1);
        });
    });

    const moveToSlide = (index) => {
        const offset = width * (index - 1);
        slidesField.style.transform = `translateX(-${offset}px)`;
        moveSlide(index);
        updatePagination(index);
    };

    return updatePagination;
};

CSS Basic

.slix {
    position: relative;
    max-width: 800px; // change the width for your project
}

.slix__slide {
    width: 100%;
    height: 400px; // change the height for your project
}

.slix__slide img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    cursor: grab;
}

.slix__slider-wrapper {
    overflow: hidden;
}

.slix__slider-inner {
    display: flex;
    transition: 0.5s all; // set glide speed
}

CSS Full

.slix {
    position: relative;
    max-width: 800px; // change the width for your project
}

.slix__slide {
    width: 100%;
    height: 400px; // change the height for your project
}

.slix__slide img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    cursor: grab;
}

.slix__slider-wrapper {
    overflow: hidden;
}

.slix__slider-inner {
    display: flex;
    transition: 0.5s all; // set glide speed
}

.slides-prev, .slides-next {
    width: 54px;
    height: 54px;
    border-radius: 50%;
    border: none;
    background-color: #f0f0f0;
    display: flex;
    align-items: center;
    position: relative;
    justify-content: center;
    cursor: pointer;
    font-size: 0;
}

.slides-prev::before, .slides-next::before {
    content: '';
    display: inline-block;
    width: 14px;
    height: 14px;
    border-top: 5px solid #333;
    border-right: 5px solid #333;
}

.slides-prev::before {
    position: absolute;
    left: 21px;
    transform: rotate(-135deg);
}

.slides-next::before {
    right: 21px;
    transform: rotate(45deg);
}

.slix-navigations {
    display: flex;
    justify-content: space-around;
    padding: 10px;
}

.slix-counter {
    display: flex;
    justify-content: center;
    color: #fff;
    font-size: 24px;
    gap: 10px;
}

.slix-pagination {
    position: absolute;
    bottom: 10px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    gap: 10px;
}

.dot {
    width: 16px;
    height: 16px;
    background-color: gray;
    border-radius: 50%;
    cursor: pointer;
}

.dot.active {
    background-color: white;
}

Snippet

"Slix": {
    "scope": "html",
    "prefix": "slix",
    "body": [
        "<div class="${1:block-name}__slider slix">
            <div class="${1:block-name}__wrapper slix__slider-wrapper">
                <div class="${1:block-name}__inner slix__slider-inner">
                    <div class="${1:block-name}__slide slix__slider-slide"></div>
                </div>
            </div>"
    ],
    "description": "Add basic HTML-code of slider Slix"
},
"Slix Full": {
    "scope": "html",
    "prefix": "slixfull",
    "body": [
        "<div class="${1:block-name}__slider slix">
            <div class="slix-counter">
                <span id="current">00</span>
                /
                <span id="total">00</span>
        </div>
            <div class="${1:block-name}__wrapper slix__slider-wrapper">
                <div class="${1:block-name}__inner slix__slider-inner">
                    <div class="${1:block-name}__slide slix__slider-slide"></div>
                </div>
        </div>
        <div class="slix-pagination"></div>
        <div class="slix-navigations">
            <button type="button" class="slides-prev"></button>
            <button type="button" class="slides-next"></button>
        </div>
    </div>"
    ],
    "description": "Add full HTML-code of slider Slix"
},

inSort sorter
version 1.0.2
inSort

The multi-functional sorter includes styles and a snippet.

Structure:

js -> insort.js + modules (insort.active.js)

css -> insort-style.css + insort-style-full.css

snippets code add to your vs-code

Get code
JS Core

/*
    inSort 1.0.1
    Snippet (HTML): insort
    Author: Mykola Papchenko
*/

// basic style
import "../scss/insort-style.scss";
// full style
// import "../scss/insort-style-full.scss";

// connect the function (active)
// import "./modules/insort-active.js"

const buttonAll = document.querySelector('.all'),
    buttonEmpty = document.querySelector('.empty-button'),
    buttonYourName = document.querySelector('.yourname'), // add as much as you need to the project and rename it as needed.

const insortWrapper = document.querySelector('.insort-wrapper'),

    markAll = insortWrapper.querySelectorAll('.all'),
    markEmpty = document.querySelector('.empty'),
    markYourName = insortWrapper.querySelectorAll('.yourname'); // add as much as you need to the project and rename it as needed

const typeFilter = (markType) => {
    markAll.forEach(mark => {
        mark.style.display = 'none';
    });

    markEmpty.style.display = 'none';

    if (markType) {
        markType.forEach(mark => {mark.style.display = 'block'
    });
    } else {
        markEmpty.style.display = 'block'
    };
};

buttonAll.addEventListener('click', () => {
    typeFilter(markAll);
});

buttonEmpty.addEventListener('click', () => {
    typeFilter();
});

// add buttons with corresponding blocks here
buttonYourName.addEventListener('click', () => {
    typeFilter(markYourName);
});

JS Functionals (active)

/* insort-active v 1.0 */
export const insortMenu = document.querySelector('.insort-menu').addEventListener('click', (e) => {
    const items = document.querySelectorAll('li');
    let target = e.target;

    if (target && target.tagName == 'LI') {
        items.forEach(btn => btn.classList.remove('active'));
        target.classList.add('active');
    }
});

CSS basic

.insort-menu {
    list-style: none;
}

.active {
    color: #ffff00;
}

.empty {
    display: none;
}

CSS Full

.insort-menu {
    list-style-type: none;
    padding: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 16px;
    &:not(:last-child) {
        padding-bottom: 20px;
    }
}

.button-menu {
    padding: 10px 20px;
    background-color: #4a4e69;
    border: 1px solid #ccc;
    cursor: pointer;
    transition: transform 0.3s ease, background-color 0.3s ease;
    border-radius: 8px;
    min-width: 50px;
    display: flex;
    justify-content: center;
    align-items: center;
}

.button-menu:active {
    transform: scale(1.1);
    background-color: #5d627e;
}

.active {
    color: #ffff00;
}

.empty {
    display: none;
}

.insort-wrapper {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 30px;
}

Snippet

"insort": {
    "scope": "html",
    "prefix": "insort",
    "body": [
        "<div class="${1:block-name}__sort insort">
            <ul class="${1:block-name}__menu insort-menu">
                <li class="button-menu all active">All</li>
                <li id="button-menu yourname">yourname</li>
                <li id="button-menu empty-button">empty</li>
        </ul>
        <div class="${1:block-name}__wrapper insort-wrapper">
            <div class="insort-block all"></div>
            <div class="insort-block all yourname"></div>
        </div>
        <div class="empty"></div>
    </div>"
    ],
    "description": "Add HTML-code of inSort"
},

Our

Products

LetsFind.fun

Ready to find secret locations in limited time!? It looks like it's going to be a great adventure!

Read the rules before starting the game! and watch the video tutorial. After pressing I am ready!, you will have 45 minutes to find the first secret location!

RecRun.pro

This web resource is designed to record your running, swimming or cycling achievements. Take photos of the area or the race route, share your impressions with friends!

10Page.online

The screen-by-screen web resource is built on a full-page basis.

In this app I only use slide based pages with navigation buttons. Swipe to the side to see photos from the current album swipe down or up to view another album