bootstrap icon indicating copy to clipboard operation
bootstrap copied to clipboard

Provide a Bottom Sheet component

Open nina-alin opened this issue 11 months ago • 5 comments

Prerequisites

Proposal

I believe a Bottom Sheet component would be a valuable addition to Bootstrap’s component library.

For context, a Bottom Sheet is a mobile-only component that behaves like a sliding panel, which emerges from the bottom of the screen and can be dragged upwards. A well-known example of a Bottom Sheet is the one used in Google Maps. You can refer to the Material Design specification for more details.

Motivation and context

In today’s development environment, web applications need to be fully responsive, and sometimes they require mobile-specific features. The Bottom Sheet is a common and useful component, yet it can be challenging to implement from scratch.

Currently, there are very few vanilla JavaScript libraries that offer a reliable Bottom Sheet component. For those who use plain JavaScript or less popular frameworks, the available options are often poorly documented and/or not well maintained.

nina-alin avatar Jan 22 '25 10:01 nina-alin

I used Modal to have a Bottom Sheet-kind-of-element with that:

.modal.fade.modal-fade--reverse .modal-dialog {
  --modal-fade-transform: translate(0, 50px);
}

If that can help in any way!

CyrilKrylatov avatar Jan 23 '25 12:01 CyrilKrylatov

Bottom-positioned offcanvas does work well for this task.

https://getbootstrap.com/docs/5.3/components/offcanvas/#placement

marisk avatar Jan 23 '25 12:01 marisk

Yeah, offcanvas with bottom placement works ok, but it would be nicer if we can hold upper part and slide down and close the offcanvas (bottom sheet).

alinlinca10 avatar Apr 02 '25 09:04 alinlinca10

Yeah, offcanvas with bottom placement works ok, but it would be nicer if we can hold upper part and slide down and close the offcanvas (bottom sheet).

I don't think it's gonna happen anytime soon as it's kinda difficult to do that with non-native code.

CyrilKrylatov avatar Apr 02 '25 09:04 CyrilKrylatov

@CyrilKrylatov No, ChatGPT help me to write some code and works ok, but an official component would be much better.

Close modal on drag

let startY = 0;
let currentY = 0;
let isDragging = false;
let modalElement = null;

$('body').on('touchstart', '.modal-header', function (e) {
  startY = e.touches[0].clientY;
  modalElement = $(this).closest('.modal')[0]; // Găsește modalul părinte
  isDragging = true;
});

$('body').on('touchmove', function (e) {
  if (!isDragging || !modalElement) return;

  currentY = e.touches[0].clientY;
  let translateY = Math.max(0, currentY - startY); // Evită mișcarea în sus

  // Aplică efectul de tragere doar pe modal
  modalElement.style.transform = `translateY(${translateY}px)`;
  modalElement.style.transition = `none`; // Dezactivează animația în timpul dragului
});

$('body').on('touchend', function () {
  if (!modalElement) return;

  let threshold = 100; // Pragul de 100px pentru închidere

  if (currentY - startY > threshold) {
    let modalInstance = bootstrap.Modal.getInstance(modalElement);
    if (modalInstance) {
      modalInstance.hide();
    }
  } else {
    // Resetează poziția modalului dacă nu a fost tras suficient
    modalElement.style.transition = `transform 0.3s ease`;
    modalElement.style.transform = `translateY(0)`;
  }

  isDragging = false;
  modalElement = null;
});

Close modal on drag

alinlinca10 avatar Apr 02 '25 09:04 alinlinca10