JSFiddle - React, Tailwind, and code Playground

by romantonoff

HTML

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ionic/core/css/ionic.bundle.css">
<script src="https://unpkg.com/cupertino-pane/dist/cupertino-pane.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@ionic/core/dist/ionic/ionic.js"></script>
<html dir="ltr" mode="ios">
  <body>
    <ion-app>
      <ion-content scroll-y="false">
        <div class="content">
            <ion-header translucent="true">
              <ion-toolbar>
                <ion-buttons slot="start">
                  <ion-button>
                    <ion-icon name="chevron-back-outline"></ion-icon>
                    Frappuccino
                  </ion-button>
                </ion-buttons>
                <ion-buttons slot="end">
                  <ion-button>
                    <ion-icon name="heart-outline"></ion-icon>
                  </ion-button>
                </ion-buttons>
              </ion-toolbar>
            </ion-header>

            <div class="content-body">
              <img draggable="false" src="https://raw.githubusercontent.com/roman-rr/cupertino-pane/master/playground/img/starbucks.png" />
              <h1>Mocha Frappuccino®</h1>
              <p>
                Buttery caramel syrup meets coffee, milk and ice for a rendezvous in the blender.
              </p>

              <div class="line">
                <div class="price">
                  £ <div class="big">3</div>.45
                </div>

                <div class="sizes">
                  <div class="active-frame"></div>
                  <div class="size active" onclick="setActive(this, 3, 0, 'S')">
                    S
                    <ion-icon name="cafe-outline"></ion-icon>
                  </div>
                  <div class="size" onclick="setActive(this, 5, 1, 'M')">
                    M
                    <ion-icon name="cafe-outline"></ion-icon>
                  </div>
                  <div class="size" onclick="setActive(this, 7, 2, 'L')">
                   ...

CSS

ion-toolbar {
  --background: #ffffff;
  --border-color: #ffffff;
}

ion-content {
  --background: rgb(0, 112, 74);
  --cupertino-pane-background: rgb(0, 112, 74);
}

.content {
  background: #ffffff;
  height: 100%;
  border-radius: 0 0 30px 30px;
  border-width: 1px;
  border: 1px solid #ffffff;
  z-index: 12;
  position: relative;
}

ion-toolbar ion-button {
  --color: #292929;
}

.content-body {
  padding-left: 20px;
  padding-right: 20px;
}

.content-body h1 {
  margin-top: 30px;
}

.content-body p {
  color: #828282;
  font-size: 14px;
  line-height: 20px;
}

.content-body img {
  display: block;
  max-width: 100%;
  margin: auto;
  margin-top: 10px;
  
   -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -o-user-select: none;
  user-select: none;
}

.content-body ion-button {
  margin-left: 0;
  margin-right: 0;
  --border-radius: 30px;
  font-weight: 600;
  --background: rgb(0, 112, 74);
  margin-top: 5px;
}

.content-body ion-button:active {
  --background: rgb(39, 92, 65);
}

.content-body .price {
  display: flex;
  align-items: center;
  font-size: 26px;
  font-weight: 600;
  height: 60px;
  margin-left: 5px;
}

.content-body .price .big {
  margin-left: 5px;
  font-size: 50px;
}

.content-body .line {
  height: 60px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-direction: row;
}

.content-body .sizes {
  display: flex;
}

.content-body .sizes .size {
  font-size: 11px;
  font-weight: 700;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 48px;
  height: 48px;
  border: 1px solid #DADADA;
  border-radius: 3px;
  margin-right: 7px;
  color: #DADADA;
  background: rgb(248, 248, 248);
  padding-bottom: 3px;
  transition: all 200ms ease-in-out;
  position: relative;
}    

.content-body .sizes .size.active {
  font-size: 11px;
  background: rgb(232, 240, 236);
  color: rgb(48, 111, 78);
}

.content-body .sizes .active-frame {
  transform: translate3d(0px, 0px,...

JavaScript

const translateYRegex = /\.*translateY\((.*)px\)/i;
let paneY;
let paneEl;
let totalprice = 0;
let itemprice = 3;
let size = 'S';
let bottomer = 20;
const contentEl = document.querySelector('.content');
const firstStep = document.querySelector('.first-step');
const myBag = document.querySelector('.my-bag');
const myBagH2 = document.querySelector('.my-bag h2');
const myBagList = document.querySelector('.my-bag .list');

const firstHeight = 120;
firstStep.style.height = `${firstHeight - 30}px`;
contentEl.style.marginTop = `-${firstHeight + firstHeight/2}px`;
contentEl.style.paddingTop = `${firstHeight/2}px`;
contentEl.style.transform = `translateY(${firstHeight}px) translateZ(0px)`;
contentEl.style.height = `calc(100% + ${firstHeight/2}px + 30px)`;

function checkTransformations() {
  paneEl = document.querySelector('.pane');
  if (!paneEl) return;
  paneY = parseFloat(translateYRegex.exec(paneEl.style.transform)[1]);

  if (window.innerHeight - paneY <= bottomer) {
    drawer.disableDrag();
    drawer.destroy({animate: true});
    return;
  }


  if (window.innerHeight - paneY - 30 > firstHeight) {
    myBagH2.style.transform = 'translate3d(0px, 0px, 0px)';
    myBagList.style.transform = 'translate3d(0px, 0px, 0px)';
    myBag.style.opacity = 1;
    firstStep.style.opacity = 0;
  } else {
    myBagH2.style.transform = 'translate3d(0px, 60px, 0px)';
    myBagList.style.transform = 'translate3d(0px, 60px, 0px)';
    myBag.style.opacity = 0;
    firstStep.style.opacity = 1;
  }
}

let drawer = new CupertinoPane('ion-drawer', { 
    followerElement: '.content',
    breaks: {
      middle: { enabled: true, height: firstHeight, timing: 'ease' },
      bottom: { enabled: true, height: bottomer, timing: 'ease' }
    },
    buttonDestroy: false,
    showDraggable: false,
    bottomClose: true,
    draggableOver: true,
    lowerThanBottom: false,
    dragBy: ['.cupertino-pane-wrapper .pane', '.content'],
    events: {
      onDrag: () => checkTransformations(), 
     ...