Bootstrap test

by Julien Chebance

HTML

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<!DOCTYPE html>
<html>
  <body class="p-3">
    <h3>Normal</h3>
    <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#normalModal">Launch normal modal</button>
    <p class="mb-4">No issue outside of a Web Component</p>
    <div class="modal fade" id="normalModal" tabindex="-1" aria-labelledby="normalModalLabel" aria-hidden="true">
      <div class="modal-dialog">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title" id="normalModalLabel">Modal title</h5>
            <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
          </div>
          <div class="modal-body">
            ...
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
            <button type="button" class="btn btn-primary">Save changes</button>
          </div>
        </div>
      </div>
    </div>


    <h3>Web Components</h3>
    <modal-attributes>Does not work 😟</modal-attributes>
    <hr>
	
    <modal-method>
      Works only once πŸ˜•<br>
      <small>
        The first call to the show() method will move the modal element from the Shadow DOM to the body element.<br>
        Then, the next calls to "shadowRoot.querySelector('#shadowModal')" will return null, as the modal is not anymore a descendant of the Shadow root.
      </small>
    </modal-method>
    <hr>
	
    <modal-instance>
      Works πŸ˜€, but the modal can't be styled with css files attached to the Shadow DOM 😒
      <small>
        The modal being moved to the body element, CSS of the Shadow DOM don't apply.<br>
        ie: the modal should be styled like the following one:
      </small>
      <div...

JavaScript

customElements.define('modal-attributes', class extends HTMLElement {
  constructor() {
    super()
    const shadowRoot = this.attachShadow({
      mode: 'open'
    })
    shadowRoot.innerHTML = `
<button type="button" class="btn btn-secondary" data-bs-toggle="modal" data-bs-target="#shadowModal">Launch shadow modal <small>using attributes</small></button>
<p>${this.innerHTML}</p>

<div class="modal fade" id="shadowModal" tabindex="-1" aria-labelledby="shadowModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="shadowModalLabel">Modal title</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        ...
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div>
  </div>
</div>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
		`
  }
})

customElements.define('modal-method', class extends HTMLElement {
  constructor() {
    super()
    const shadowRoot = this.attachShadow({
      mode: 'open'
    })
    shadowRoot.innerHTML = `
<button type="button" class="btn btn-primary">Launch shadow modal <small>using bootstrap.Modal.getOrCreateInstance()</small></button>
<p>${this.innerHTML}</p>

<div class="modal fade" id="shadowModal" tabindex="-1" aria-labelledby="shadowModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="shadowModalLabel">Modal title</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        ...
      </div>
     ...