<commit_before><template>
  <transition name="modal" :duration="duration">
    <div v-show="show" class="modal-container">
      <div class="modal" @click.self="clickMask">
        <div class="modal-dialog" :class="modalClass">
          <div class="modal-content">
            <!--Header-->
            <div class="modal-header">
              <slot name="header">
                <div class="modal-title">
                  <slot name="title"></slot>
                </div>
              </slot>
            </div>
            <!--Container-->
            <div class="modal-body">
              <slot></slot>
            </div>
            <!--Footer-->
            <div class="modal-footer">
              <slot name="footer">
                <button type="button" :class="okClass" @click="ok" :disabled="okDisabled">{{okText}}</button>
                <button type="button" :class="cancelClass" @click="cancel" :disabled="cancelDisabled">{{cancelText}}</button>
              </slot>
            </div>
          </div>
        </div>
      </div>
      <div class="modal-backdrop"></div>
    </div>
  </transition>
</template>

<script>
  export default {
    name: 'vuestic-modal',
    props: {
      transition: {
        type: String,
        default: 'modal'
      },
      small: {
        type: Boolean,
        default: false
      },
      large: {
        type: Boolean,
        default: false
      },
      force: {
        type: Boolean,
        default: false
      },
      okText: {
        type: String,
        default: 'CONFIRM'
      },
      cancelText: {
        type: String,
        default: 'CANCEL'
      },
      okClass: {
        type: String,
        default: 'btn btn-primary'
      },
      cancelClass: {
        type: String,
        default: 'btn btn-secondary'
      },
      okDisabled: {
        type: Boolean,
        default: false
      },
      cancelDisabled: {
        type: Boolean,
        default: false
      }
    },
    data () {
      return {
        show: false,
        duration: 500
      }
    },
    computed: {
      modalClass () {
        return {
          'modal-lg': this.large,
          'modal-sm': this.small
        }
      }
    },
    created () {
      if (this.show) {
        document.body.className += ' modal-open'
      }
    },
    beforeDestroy () {
      document.body.className = document.body.className.replace(/\s?modal-open/, '')
    },
    watch: {
      show (value) {
        if (value) {
          document.body.className += ' modal-open'
        } else {
          window.setTimeout(() => {
            document.body.className = document.body.className.replace(/\s?modal-open/, '')
          }, this.duration)
        }
      }
    },
    methods: {
      listenKeyUp (event) {
        if (event.key === 'Escape') {
          this.cancel()
        }
      },
      ok () {
        this.$emit('ok')
        this.show = false
        window.removeEventListener('keyup', this.listenKeyUp)
      },
      cancel () {
        this.$emit('cancel')
        this.show = false
        window.removeEventListener('keyup', this.listenKeyUp)
      },
      clickMask () {
        if (!this.force) {
          this.cancel()
        }
      },
      open () {
        this.show = true
        window.addEventListener('keyup', this.listenKeyUp)
      }
    }
  }
</script>

<style lang="scss" scoped>
  @import "../../../sass/_variables.scss";
  @import "~bootstrap/scss/functions";
  @import "~bootstrap/scss/variables";

  // For Transitioning
  .modal {
    display: block;
  }

  .modal-dialog, .modal-backdrop {
    transition: all .5s ease;
  }

  .modal-enter .modal-dialog, .modal-leave-active .modal-dialog {
    opacity: 0;
    transform: translateY(-30%);
  }

  .modal-enter .modal-backdrop, .modal-leave-active .modal-backdrop {
    opacity: 0;
  }

  .modal-backdrop {
    opacity: 0.5;
  }

  //Modal styles

  .modal-header {
    height: $modal-header-height;
    padding: $modal-header-padding-y $modal-header-padding-x;
    border-bottom: $modal-header-border;
    font-size: $font-size-larger;
    display: flex;
    align-items: center;
  }

  .modal-content {
    border-radius: $modal-content-border-radius;
  }

  .modal-footer {
    justify-content: center;
    padding: 0 $modal-inner-padding;
    padding-bottom: calc(#{$modal-inner-padding} - #{$modal-footer-btns-padding-bottom});
    flex-wrap: wrap;
    .btn {
      margin: 0 $modal-footer-btns-margin-x $modal-footer-btns-padding-bottom $modal-footer-btns-margin-x;
    }
  }

  .modal-dialog {
    box-shadow: $modal-content-box-shadow-sm-up;
  }
</style><commit_msg>feat(vuestic modal): using .vuestic-modal class instead of scoped styles for better slots styling<commit_after><template>
  <div class="vuestic-modal">
    <transition name="modal" :duration="duration">
      <div v-show="show" class="modal-container">
        <div class="modal" @click.self="clickMask">
          <div class="modal-dialog" :class="modalClass">
            <div class="modal-content">
              <!--Header-->
              <div class="modal-header">
                <slot name="header">
                  <div class="modal-title">
                    <slot name="title"></slot>
                  </div>
                </slot>
              </div>
              <!--Container-->
              <div class="modal-body">
                <slot></slot>
              </div>
              <!--Footer-->
              <div class="modal-footer">
                <slot name="footer">
                  <button type="button" :class="okClass" @click="ok" :disabled="okDisabled">{{okText}}</button>
                  <button type="button" :class="cancelClass" @click="cancel" :disabled="cancelDisabled">{{cancelText}}</button>
                </slot>
              </div>
            </div>
          </div>
        </div>
        <div class="modal-backdrop"></div>
      </div>
    </transition>
  </div>
</template>

<script>
  export default {
    name: 'vuestic-modal',
    props: {
      transition: {
        type: String,
        default: 'modal'
      },
      small: {
        type: Boolean,
        default: false
      },
      large: {
        type: Boolean,
        default: false
      },
      force: {
        type: Boolean,
        default: false
      },
      okText: {
        type: String,
        default: 'CONFIRM'
      },
      cancelText: {
        type: String,
        default: 'CANCEL'
      },
      okClass: {
        type: String,
        default: 'btn btn-primary'
      },
      cancelClass: {
        type: String,
        default: 'btn btn-secondary'
      },
      okDisabled: {
        type: Boolean,
        default: false
      },
      cancelDisabled: {
        type: Boolean,
        default: false
      }
    },
    data () {
      return {
        show: false,
        duration: 500
      }
    },
    computed: {
      modalClass () {
        return {
          'modal-lg': this.large,
          'modal-sm': this.small
        }
      }
    },
    created () {
      if (this.show) {
        document.body.className += ' modal-open'
      }
    },
    beforeDestroy () {
      document.body.className = document.body.className.replace(/\s?modal-open/, '')
    },
    watch: {
      show (value) {
        if (value) {
          document.body.className += ' modal-open'
        } else {
          window.setTimeout(() => {
            document.body.className = document.body.className.replace(/\s?modal-open/, '')
          }, this.duration)
        }
      }
    },
    methods: {
      listenKeyUp (event) {
        if (event.key === 'Escape') {
          this.cancel()
        }
      },
      ok () {
        this.$emit('ok')
        this.show = false
        window.removeEventListener('keyup', this.listenKeyUp)
      },
      cancel () {
        this.$emit('cancel')
        this.show = false
        window.removeEventListener('keyup', this.listenKeyUp)
      },
      clickMask () {
        if (!this.force) {
          this.cancel()
        }
      },
      open () {
        this.show = true
        window.addEventListener('keyup', this.listenKeyUp)
      }
    }
  }
</script>

<style lang="scss">
  @import "../../../sass/_variables.scss";
  @import "~bootstrap/scss/functions";
  @import "~bootstrap/scss/variables";

  .vuestic-modal {
    height: 0;
    width: 0;

    // For Transitioning
    .modal {
      display: block;
    }

    .modal-dialog, .modal-backdrop {
      transition: all .5s ease;
    }

    .modal-enter .modal-dialog, .modal-leave-active .modal-dialog {
      opacity: 0;
      transform: translateY(-30%);
    }

    .modal-enter .modal-backdrop, .modal-leave-active .modal-backdrop {
      opacity: 0;
    }

    .modal-backdrop {
      opacity: 0.5;
    }

    //Modal styles

    .modal-header {
      height: $modal-header-height;
      padding: $modal-header-padding-y $modal-header-padding-x;
      border-bottom: $modal-header-border;
      font-size: $font-size-larger;
      display: flex;
      align-items: center;
    }

    .modal-content {
      border-radius: $modal-content-border-radius;
    }

    .modal-footer {
      justify-content: center;
      padding: 0 $modal-inner-padding;
      padding-bottom: calc(#{$modal-inner-padding} - #{$modal-footer-btns-padding-bottom});
      flex-wrap: wrap;
      .btn {
        margin: 0 $modal-footer-btns-margin-x $modal-footer-btns-padding-bottom $modal-footer-btns-margin-x;
      }
    }

    .modal-dialog {
      box-shadow: $modal-content-box-shadow-sm-up;
    }
  }
</style>
{'fraction_non_alphanumeric': 0.15392659207361706, 'fraction_numerical': 0.002718812088256823, 'mean_word_length': 1.6267508926119199, 'pattern_counts': {'":': 0, '<': 87, '<?xml version=': 0, '>': 89, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2404978', 'n_tokens_mistral': 2940, 'n_tokens_neox': 2868, 'n_words': 526}