JSFiddle - React, Tailwind, and code Playground

by romantonoff

HTML

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ionic/core@6.6.2/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@6.6.2/dist/ionic/ionic.js"></script>
<html mode="ios">
<head>
 <meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
</head>
  <body class="dark primary">
   <ion-app>
    <ion-content scroll-y="false">
      <!-- Texts -->
      <div class="top-content hide-on-present">
        <div class="titles">
          <h1>$23,165.82</h1>
          <h2 class="result">+$49.56 (0.32%)</h2>
          <h2 class="name">Bitcoin</h2>
        </div>

        <!-- Thanks GUI CHALLENGE for button idea -->
        <button class="theme-toggle" onclick="toggleTheme();" id="theme-toggle" title="Toggles light & dark" aria-label="auto" aria-live="polite">
          <svg class="sun-and-moon" aria-hidden="true" width="24" height="24" viewBox="0 0 24 24">
            <mask class="moon" id="moon-mask">
              <rect x="0" y="0" width="100%" height="100%" fill="white" />
              <circle cx="24" cy="10" r="6" fill="black" />
            </mask>
            <circle class="sun" cx="12" cy="12" r="6" mask="url(#moon-mask)" fill="currentColor" />
            <g class="sun-beams" stroke="currentColor">
              <line x1="12" y1="1" x2="12" y2="3" />
              <line x1="12" y1="21" x2="12" y2="23" />
              <line x1="4.22" y1="4.22" x2="5.64" y2="5.64" />
              <line x1="18.36" y1="18.36" x2="19.78" y2="19.78" />
              <line x1="1" y1="12" x2="3" y2="12" />
              <line x1="21" y1="12" x2="23" y2="12" />
              <line x1="4.22" y1="19.78" x2="5.64" y2="18.36" />
              <line x1="18.36" y1="5.64" x2="19.78" y2="4.22" />
             </g>
          </svg>
        </button>
      </div>

      <!-- Synthwave -->
    ...

CSS

body.dark {
    --ion-background-color: #080317;
    --ion-background-color-rgb: rgb(8 3 23);
    --ion-toolbar-background: #1f1f1f;
    --hide-delay: 400ms;
}

  body.primary {
    --ion-color-primary: #ff69b4;
    --ion-color-primary-rgb: 255, 107, 181;
    --ion-color-primary-contrast: #333333;
    --ion-color-primary-contrast-rgb: 51, 51, 51;
    --ion-color-primary-shade: #f3499e;
    --ion-color-primary-tint: #fa71b5;

    --ion-color-secondary: #add65c;
    --ion-color-secondary-rgb: 173, 214, 92;
    --ion-color-secondary-contrast: #333333;
    --ion-color-secondary-contrast-rgb: 51, 51, 51;
    --ion-color-secondary-shade: #a4d63e;
    --ion-color-secondary-tint: #b5da6b;
  }

  body.secondary {
    --ion-color-primary: #add65c;
    --ion-color-primary-rgb: 173, 214, 92;
    --ion-color-primary-contrast: #333333;
    --ion-color-primary-contrast-rgb: 51, 51, 51;
    --ion-color-primary-shade: #a4d63e;
    --ion-color-primary-tint: #b5da6b;

    --ion-color-secondary: #ff69b4;
    --ion-color-secondary-rgb: 255, 107, 181;
    --ion-color-secondary-contrast: #333333;
    --ion-color-secondary-contrast-rgb: 51, 51, 51;
    --ion-color-secondary-shade: #f3499e;
    --ion-color-secondary-tint: #fa71b5;
  }

  .hide-on-present {
    opacity: 1;
    transition: opacity var(--hide-delay) ease;
  }

  .show-on-present {
    opacity: 0;
    transition: opacity var(--hide-delay) ease;
  }

  body.pane-visible .hide-on-present {
    opacity: 0; 
  }

  body.pane-visible .show-on-present {
    opacity: 1;
  }

  /* Synthwave styles */
  .fade-overlay {
    position: absolute;
    bottom: 183px;
    width: 100vw;
    height: 100px;
    z-index: 1;
    background: linear-gradient(180deg, rgba(8,3,23,1) 0%, rgba(8,3,23,0.8) 37%, rgba(8,3,23,0) 100%); 
  }

  section.synthwave {
    position: absolute;
    bottom: 0px;
    height: 270px;
    overflow: visible;
    z-index: 1;
  }

  section.synthwave div.synth-wrapper {
    height: 100vh;
    width: 140vw;
   ...

JavaScript

// Global scope
let pane;
let presentTransition = {
  duration: 600,
  opacity: 0,
  translateY: 280,
  prespective: 250,
  rotateX: 65,
  scale: 0.3
};
let destroyTransition = {
  duration: 600,
  opacity: 0,
  translateY: 280,
  prespective: 250,
  rotateX: 65,
  scale: 0.3
};


// DOM ready
window.onload = async function () {
  await document.querySelector('ion-app').componentOnReady();
  drawGraphCanvas();
  window.addEventListener('resize', drawGraphCanvas);

  // Calculator
  let price = '23,165.82';
  let amount = document.querySelector('#amount');
  let submitButton = document.querySelector('#submitButton');
  let estPrice = document.querySelector('#estPrice');
  let estBtc = document.querySelector('#estBtc');
  let swipeCancel = document.querySelector('#swipeCancel');
  let sendingOrder = document.querySelector('#sendingOrder');

  // Cupertino-Pane is magic panes for PWA interfaces
  // npm i cupertino-pane
  pane = new CupertinoPane('cupertino-pane', {
    fitHeight: true,
    inverse: true,
    bottomClose: true,
    showDraggable: false,
    bottomOffset: 120,
    upperThanTop: true,
    dragBy: ['.backdrop', '.cupertino-pane-wrapper .pane'],
    backdrop: true,
    backdropOpacity: 0,
    events: {
      onWillPresent: () => {
        amount.value = '$1';
        estPrice.value = `$${price}`;
        estBtc.value = '0.0000431670 BTC';
        submitButton.removeAttribute('disabled');
      },
      onWillDismiss: () => {
        document.body.classList.remove('pane-visible');
      },
      onDidDismiss: () => {
        sendingOrder.classList.add('hidden');
        swipeCancel.classList.remove('hidden');
      }
    }
  });
	
  // Rewrite and customize some transitions to make 
  // pane moved by touchmove events with 
  // custom perspective transitions
  pane.transitions.setPaneElTransform = (params) => setPaneElTransform(params);

  // Set caret
  amount.addEventListener('ionFocus', () => {
    let val = amount.value;
    amount.value = '$1 ';
  ...