text: function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
  
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
  
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
  
  import Vue from '../../utils/vue';
  import { BVFormBtnLabelControl, dropdownProps } from '../../utils/bv-form-btn-label-control';
  import { getComponentConfig } from '../../utils/config';
  import { isUndefinedOrNull } from '../../utils/inspect';
  import idMixin from '../../mixins/id';
  import { BButton } from '../button/button';
  import { BTime } from '../time/time';
  import { BIconClock, BIconClockFill } from '../../icons/icons';
  var NAME = 'BFormTimepicker'; // Fallback to BTime/BFormSpinbutton prop if no value found
  
  var getConfigFallback = function getConfigFallback(prop) {
    return getComponentConfig(NAME, prop) || getComponentConfig('BTime', prop) || getComponentConfig('BFormSpinbutton', prop);
  }; // We create our props as a mixin so that we can control
  // where they appear in the props listing reference section
  
  
  var propsMixin = {
    props: _objectSpread({
      value: {
        type: String,
        default: ''
      },
      resetValue: {
        type: String,
        default: ''
      },
      placeholder: {
        type: String,
        // Defaults to `labelNoTime` from BTime context
        default: null
      },
      size: {
        type: String,
        default: null
      },
      disabled: {
        type: Boolean,
        default: false
      },
      readonly: {
        type: Boolean,
        default: false
      },
      required: {
        // If true adds the `aria-required` attribute
        type: Boolean,
        default: false
      },
      name: {
        type: String,
        default: null
      },
      form: {
        type: String,
        default: null
      },
      state: {
        // Tri-state prop: `true`, `false` or `null`
        type: Boolean,
        default: null
      },
      hour12: {
        // Tri-state prop: `true` => 12 hour, `false` => 24 hour, `null` => auto
        type: Boolean,
        default: null
      },
      locale: {
        type: [String, Array],
        default: null
      },
      showSeconds: {
        type: Boolean,
        default: false
      },
      hideHeader: {
        type: Boolean,
        default: false
      },
      secondsStep: {
        type: [Number, String],
        default: 1
      },
      minutesStep: {
        type: [Number, String],
        default: 1
      },
      buttonOnly: {
        type: Boolean,
        default: false
      },
      buttonVariant: {
        // Applicable in button only mode
        type: String,
        default: 'secondary'
      },
      nowButton: {
        type: Boolean,
        default: false
      },
      labelNowButton: {
        type: String,
        default: function _default() {
          return getComponentConfig(NAME, 'labelNowButton');
        }
      },
      nowButtonVariant: {
        type: String,
        default: 'outline-primary'
      },
      resetButton: {
        type: Boolean,
        default: false
      },
      labelResetButton: {
        type: String,
        default: function _default() {
          return getComponentConfig(NAME, 'labelResetButton');
        }
      },
      resetButtonVariant: {
        type: String,
        default: 'outline-danger'
      },
      noCloseButton: {
        type: Boolean,
        default: false
      },
      labelCloseButton: {
        type: String,
        default: function _default() {
          return getComponentConfig(NAME, 'labelCloseButton');
        }
      },
      closeButtonVariant: {
        type: String,
        default: 'outline-secondary'
      },
      // Labels
      // These fallback to BTime values
      labelSelected: {
        type: String,
        default: function _default() {
          return getConfigFallback('labelSelected');
        }
      },
      labelNoTimeSelected: {
        type: String,
        default: function _default() {
          return getConfigFallback('labelNoTimeSelected');
        }
      },
      labelHours: {
        type: String,
        default: function _default() {
          return getConfigFallback('labelHours');
        }
      },
      labelMinutes: {
        type: String,
        default: function _default() {
          return getConfigFallback('labelMinutes');
        }
      },
      labelSeconds: {
        type: String,
        default: function _default() {
          return getConfigFallback('labelSeconds');
        }
      },
      labelAmpm: {
        type: String,
        default: function _default() {
          return getConfigFallback('labelAmpm');
        }
      },
      labelAm: {
        type: String,
        default: function _default() {
          return getConfigFallback('labelAm');
        }
      },
      labelPm: {
        type: String,
        default: function _default() {
          return getConfigFallback('labelPm');
        }
      },
      // These pick BTime or BFormSpinbutton global config if no BFormTimepicker global config
      labelIncrement: {
        type: String,
        default: function _default() {
          return getConfigFallback('labelIncrement');
        }
      },
      labelDecrement: {
        type: String,
        default: function _default() {
          return getConfigFallback('labelDecrement');
        }
      },
      // extra dropdown stuff
      menuClass: {
        type: [String, Array, Object],
        default: null
      }
    }, dropdownProps)
  }; // --- BFormDate component ---
  // @vue/component
  
  export var BFormTimepicker = /*#__PURE__*/Vue.extend({
    name: NAME,
    // The mixins order determines the order of appearance in the props reference section
    mixins: [idMixin, propsMixin],
    model: {
      prop: 'value',
      event: 'input'
    },
    data: function data() {
      return {
        // We always use `HH:mm:ss` value internally
        localHMS: this.value || '',
        // Context data from BTime
        localLocale: null,
        isRTL: false,
        formattedValue: '',
        // If the menu is opened
        isVisible: false
      };
    },
    computed: {
      computedLang: function computedLang() {
        return (this.localLocale || '').replace(/-u-.*$/i, '') || null;
      },
      timeProps: function timeProps() {
        // Props we pass to BTime
        // Use self for better minification, as `this` won't
        // minimize and we reference it many times below
        var self = this;
        return {
          hidden: !self.isVisible,
          value: self.localHMS,
          // Passthrough props
          readonly: self.readonly,
          disabled: self.disabled,
          locale: self.locale,
          hour12: self.hour12,
          hideHeader: self.hideHeader,
          showSeconds: self.showSeconds,
          secondsStep: self.secondsStep,
          minutesStep: self.minutesStep,
          labelNoTimeSelected: self.labelNoTimeSelected,
          labelSelected: self.labelSelected,
          labelHours: self.labelHours,
          labelMinutes: self.labelMinutes,
          labelSeconds: self.labelSeconds,
          labelAmpm: self.labelAmpm,
          labelAm: self.labelAm,
          labelPm: self.labelPm,
          labelIncrement: self.labelIncrement,
          labelDecrement: self.labelDecrement
        };
      }
    },
    watch: {
      value: function value(newVal) {
        this.localHMS = newVal || '';
      },
      localHMS: function localHMS(newVal) {
        // We only update hte v-model value when the timepicker
        // is open, to prevent cursor jumps when bound to a
        // text input in button only mode
        if (this.isVisible) {
          this.$emit('input', newVal || '');
        }
      }
    },
    methods: {
      // Public methods
      focus: function focus() {
        if (!this.disabled) {
          try {
            this.$refs.control.focus();
          } catch (_unused) {}
        }
      },
      blur: function blur() {
        if (!this.disabled) {
          try {
            this.$refs.control.blur();
          } catch (_unused2) {}
        }
      },
      // Private methods
      setAndClose: function setAndClose(value) {
        var _this = this;
  
        this.localHMS = value;
        this.$nextTick(function () {
          _this.$refs.control.hide(true);
        });
      },
      onInput: function onInput(hms) {
        if (this.localHMS !== hms) {
          this.localHMS = hms;
        }
      },
      onContext: function onContext(ctx) {
        var isRTL = ctx.isRTL,
            locale = ctx.locale,
            value = ctx.value,
            formatted = ctx.formatted;
        this.isRTL = isRTL;
        this.localLocale = locale;
        this.formattedValue = formatted;
        this.localHMS = value || ''; // Re-emit the context event
  
        this.$emit('context', ctx);
      },
      onNowButton: function onNowButton() {
        var now = new Date();
        var hours = now.getHours();
        var minutes = now.getMinutes();
        var seconds = this.showSeconds ? now.getSeconds() : 0;
        var value = [hours, minutes, seconds].map(function (v) {
          return "00".concat(v || '').slice(-2);
        }).join(':');
        this.setAndClose(value);
      },
      onResetButton: function onResetButton() {
        this.setAndClose(this.resetValue);
      },
      onCloseButton: function onCloseButton() {
        this.$refs.control.hide(true);
      },
      onShow: function onShow() {
        this.isVisible = true;
      },
      onShown: function onShown() {
        var _this2 = this;
  
        this.$nextTick(function () {
          try {
            _this2.$refs.time.focus();
          } catch (_unused3) {}
  
          _this2.$emit('shown');
        });
      },
      onHidden: function onHidden() {
        this.isVisible = false;
        this.$emit('hidden');
      },
      // Render function helpers
      defaultButtonFn: function defaultButtonFn(_ref) {
        var isHovered = _ref.isHovered,
            hasFocus = _ref.hasFocus;
        return this.$createElement(isHovered || hasFocus ? BIconClockFill : BIconClock, {
          attrs: {
            'aria-hidden': 'true'
          }
        });
      }
    },
    render: function render(h) {
      var localHMS = this.localHMS;
      var disabled = this.disabled;
      var readonly = this.readonly;
      var placeholder = isUndefinedOrNull(this.placeholder) ? this.labelNoTimeSelected : this.placeholder; // Footer buttons
  
      var $footer = [];
  
      if (this.nowButton) {
        var label = this.labelNowButton;
        $footer.push(h(BButton, {
          staticClass: 'mx-1',
          props: {
            size: 'sm',
            disabled: disabled || readonly,
            variant: this.nowButtonVariant
          },
          attrs: {
            'aria-label': label || null
          },
          on: {
            click: this.onNowButton
          }
        }, label));
      }
  
      if (this.resetButton) {
        var _label = this.labelResetButton;
        $footer.push(h(BButton, {
          staticClass: 'mx-1',
          props: {
            size: 'sm',
            disabled: disabled || readonly,
            variant: this.resetButtonVariant
          },
          attrs: {
            'aria-label': _label || null
          },
          on: {
            click: this.onResetButton
          }
        }, _label));
      }
  
      if (!this.noCloseButton) {
        var _label2 = this.labelCloseButton;
        $footer.push(h(BButton, {
          staticClass: 'mx-1',
          props: {
            size: 'sm',
            disabled: disabled,
            variant: this.closeButtonVariant
          },
          attrs: {
            'aria-label': _label2 || null
          },
          on: {
            click: this.onCloseButton
          }
        }, _label2));
      }
  
      if ($footer.length > 0) {
        $footer = [h('div', {
          staticClass: 'b-form-date-controls d-flex flex-wrap mx-n1',
          class: {
            'justify-content-between': $footer.length > 1,
            'justify-content-end': $footer.length < 2
          }
        }, $footer)];
      }
  
      var $time = h(BTime, {
        ref: 'time',
        staticClass: 'b-form-time-control',
        props: this.timeProps,
        on: {
          input: this.onInput,
          context: this.onContext
        }
      }, $footer);
      return h(BVFormBtnLabelControl, {
        ref: 'control',
        staticClass: 'b-form-timepicker',
        props: _objectSpread({}, this.$props, {
          // Overridden / computed props
          id: this.safeId(),
          rtl: this.isRTL,
          lang: this.computedLang,
          value: localHMS || '',
          formattedValue: localHMS ? this.formattedValue : '',
          placeholder: placeholder || ''
        }),
        on: {
          show: this.onShow,
          shown: this.onShown,
          hidden: this.onHidden
        },
        scopedSlots: {
          'button-content': this.$scopedSlots['button-content'] || this.defaultButtonFn
        }
      }, [$time]);
    }
  });