JSFiddle - React, Tailwind, and code Playground

by Vladymyr Shevchuk

HTML

<div id="root"></div>

CSS

:root {
  --blue: #109cf1;
  --dark-blue: #334d6e;
  --light-blue: #cfebfc;
  --middle-blue: #9fd7f9;
  --yellow: #ffb946;
  --red: #f7685b;
  --green: #2ed47a;
  --purple: #885af8;
  --black: #192a3e;
  --table-black: #323c47;
  --table-grey: #707683;
  --grey: #90a0b7;
  --grey-light: #c2cfe0;
  --grey-extra-light: #eff1f4;
  --grey-skeleton: #f5f6f8;
  --white: #ffffff;
}

.sortable-table {
  background-color: var(--white);
  max-width: 100%;
  border-radius: 4px;
  margin-bottom: 40px;
  overflow: hidden;
}

.sortable-table__row {
  display: grid;
  grid: auto-flow / 80px calc(50% - 80px) 25% 15% 15%;
  text-decoration: none;
}
.sortable-table__row.bold {
  font-weight: bold;
}

.sortable-table__cell {
  padding: 16px;
  font-size: 16px;
  line-height: 20px;
  color: var(--table-black);
  display: flex;
  align-items: center;
  border-top: 1px solid var(--grey-light);
}

.sortable-table__cell:first-child {
  padding-left: 32px;
}

.sortable-table__cell:last-child {
  padding-right: 32px;
}

.sortable-table__header .sortable-table__cell {
  color: var(--grey-light);
  border-top: none;
}

.sortable-table__header .sortable-table__cell[data-sortable] {
  cursor: pointer;
}

.sortable-table__cell-img {
  height: 40px;
  max-width: 100%;
  padding: 4px;
  border: 1px solid var(--grey-light);
  border-radius: 2px;
}

.sortable-table__sort-arrow {
  padding: 8px;
  display: inline-flex;
  cursor: pointer;
}

.sortable-table__cell[data-order='asc'] .sort-arrow {
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-bottom: 4px solid var(--grey-light);
}

.sortable-table__cell[data-order='desc'] .sort-arrow {
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 4px solid var(--grey-light);
}

.sortable-table.sortable-table_loading {
  grid-template-columns: auto;
}

.sortable-table__loading-line {
  grid-column: 1 / 7;
  display: none;
  margin:...

JavaScript

const data = [
    {
      "id": "soska-(pustyshka)-nuk-10729357",
      "title": "Соска (пустышка) NUK 10729357",
      "description": "кольцо; Материал: силикон; Форма: ортодонтическая; Возраст: 0m+; Тип: пустышка",
      "quantity": 20,
      "subcategory": {
        "id": "kormlenie-i-gigiena",
        "title": "Кормление и гигиена",
        "count": 18,
        "category": {
          "id": "detskie-tovary-i-igrushki",
          "title": "Детские товары и игрушки",
          "count": 83,
          "weight": 1
        },
        "weight": 2
      },
      "status": 1,
      "images": [
        {
          "url": "http://magazilla.ru/jpg_zoom1/872403.jpg",
          "source": "872403.jpg"
        },
        {
          "url": "http://mzimg.com/big/y1/f60itzsrly1.jpg",
          "source": "f60itzsrly1.jpg"
        },
        {
          "url": "http://mzimg.com/big/r1/f60iuj3g7r1.jpg",
          "source": "f60iuj3g7r1.jpg"
        },
        {
          "url": "http://mzimg.com/big/11/f60iuorc111.jpg",
          "source": "f60iuorc111.jpg"
        },
        {
          "url": "http://mzimg.com/big/41/f60iur65k41.jpg",
          "source": "f60iur65k41.jpg"
        }
      ],
      "price": 3,
      "discount": 0,
      "sales": 14
    },
    {
      "id": "tv-tyuner-d-color--dc1301hd",
      "title": "ТВ тюнер D-COLOR  DC1301HD",
      "description": "Габариты (мм): 132х32х100; Пульт ДУ; USB; HDMI: 1 шт; композитный; Телетекст; Телегид; Time shift; Запись видео; Разрешение видео: 576i, 576p, 720p, 1080i, 1080p; DVB-T2 (эфирное); DVB-T (эфирное); Тип: внешний тюнер ",
      "quantity": 90,
      "subcategory": {
        "id": "tv-tyunery",
        "title": "ТВ тюнеры",
        "count": 18,
        "category": {
          "id": "tv-i-videotehnika",
          "title": "ТВ и видеотехника",
          "count": 133,
          "weight": 5
        },
        "weight": 4
      },
      "status": 1,
      "images": [
        {
          "url":...