{"version":3,"file":"panel-time-range.mjs","sources":["../../../../../../../packages/components/time-picker/src/time-picker-com/panel-time-range.vue"],"sourcesContent":["<template>\r\n  <div v-if=\"actualVisible\" class=\"sg-time-range-picker sg-picker-panel\">\r\n    <div class=\"sg-time-range-picker__content\">\r\n      <div class=\"sg-time-range-picker__cell\">\r\n        <div class=\"sg-time-range-picker__header\">\r\n          {{ t('sg.datepicker.startTime') }}\r\n        </div>\r\n        <div\r\n          :class=\"{ 'has-seconds': showSeconds }\"\r\n          class=\"sg-time-range-picker__body sg-time-panel__content\"\r\n        >\r\n          <time-spinner\r\n            ref=\"minSpinner\"\r\n            role=\"start\"\r\n            :show-seconds=\"showSeconds\"\r\n            :am-pm-mode=\"amPmMode\"\r\n            :arrow-control=\"arrowControl\"\r\n            :spinner-date=\"minDate\"\r\n            :disabled-hours=\"disabledHours_\"\r\n            :disabled-minutes=\"disabledMinutes_\"\r\n            :disabled-seconds=\"disabledSeconds_\"\r\n            :step=\"step\"\r\n            @change=\"handleMinChange\"\r\n            @set-option=\"onSetOption\"\r\n            @select-range=\"setMinSelectionRange\"\r\n          />\r\n        </div>\r\n      </div>\r\n      <div class=\"sg-time-range-picker__cell\">\r\n        <div class=\"sg-time-range-picker__header\">\r\n          {{ t('sg.datepicker.endTime') }}\r\n        </div>\r\n        <div\r\n          :class=\"{ 'has-seconds': showSeconds }\"\r\n          class=\"sg-time-range-picker__body sg-time-panel__content\"\r\n        >\r\n          <time-spinner\r\n            ref=\"maxSpinner\"\r\n            role=\"end\"\r\n            :show-seconds=\"showSeconds\"\r\n            :am-pm-mode=\"amPmMode\"\r\n            :arrow-control=\"arrowControl\"\r\n            :spinner-date=\"maxDate\"\r\n            :disabled-hours=\"disabledHours_\"\r\n            :disabled-minutes=\"disabledMinutes_\"\r\n            :disabled-seconds=\"disabledSeconds_\"\r\n            :step=\"step\"\r\n            @change=\"handleMaxChange\"\r\n            @set-option=\"onSetOption\"\r\n            @select-range=\"setMaxSelectionRange\"\r\n          />\r\n        </div>\r\n      </div>\r\n    </div>\r\n    <div class=\"sg-time-panel__footer\">\r\n      <sg-button\r\n          text\r\n          @click=\"handleCancel\"\r\n        >\r\n          {{ t('sg.datepicker.cancel') }}\r\n        </sg-button>\r\n        <sg-button\r\n          type=\"primary\"\r\n          @click=\"handleConfirm()\"\r\n        >\r\n          {{ t('sg.datepicker.confirm') }}\r\n        </sg-button>\r\n    </div>\r\n  </div>\r\n</template>\r\n\r\n<script lang=\"ts\">\r\nimport { defineComponent, ref, computed, inject } from 'vue'\r\nimport dayjs from 'dayjs'\r\nimport { union } from 'lodash'\r\nimport { useLocale } from '@sgui-plus/hooks'\r\nimport { EVENT_CODE } from '@sgui-plus/utils/aria'\r\nimport { TimePickerContextKey } from '../common/constant'\r\nimport TimeSpinner from './basic-time-spinner.vue'\r\nimport SgButton from '@sgui-plus/components/button'\r\nimport { getAvailableArrs, useOldValue } from './useTimePicker'\r\n\r\nimport type { PropType } from 'vue'\r\nimport type { Dayjs } from 'dayjs'\r\n\r\nconst makeSelectRange = (start: number, end: number) => {\r\n  const result = []\r\n  for (let i = start; i <= end; i++) {\r\n    result.push(i as never)\r\n  }\r\n  return result\r\n}\r\nexport default defineComponent({\r\n  components: { TimeSpinner,SgButton },\r\n\r\n  props: {\r\n    visible: Boolean,\r\n    actualVisible: Boolean,\r\n    parsedValue: {\r\n      type: [Array] as PropType<Array<Dayjs>>,\r\n    },\r\n    format: {\r\n      type: String,\r\n      default: '',\r\n    },\r\n  },\r\n\r\n  emits: ['pick', 'select-range', 'set-picker-option'],\r\n\r\n  setup(props, ctx) {\r\n    const { t, lang } = useLocale()\r\n    const minDate = computed(() => props.parsedValue![0])\r\n    const maxDate = computed(() => props.parsedValue![1])\r\n    const oldValue = useOldValue(props)\r\n    const handleCancel = () => {\r\n      ctx.emit('pick', oldValue.value, null)\r\n    }\r\n    const showSeconds = computed(() => {\r\n      return props.format.includes('ss')\r\n    })\r\n    const amPmMode = computed(() => {\r\n      if (props.format.includes('A')) return 'A'\r\n      if (props.format.includes('a')) return 'a'\r\n      return ''\r\n    })\r\n\r\n    const minSelectableRange = ref([])\r\n    const maxSelectableRange = ref([])\r\n\r\n    const handleConfirm = (visible = false) => {\r\n      ctx.emit('pick', [minDate.value, maxDate.value], visible)\r\n    }\r\n\r\n    const handleMinChange = (date) => {\r\n      handleChange(date.millisecond(0), maxDate.value)\r\n    }\r\n    const handleMaxChange = (date) => {\r\n      handleChange(minDate.value, date.millisecond(0))\r\n    }\r\n\r\n    const isValidValue = (_date: Dayjs[]) => {\r\n      const parsedDate = _date.map((_) => dayjs(_).locale(lang.value))\r\n      const result = getRangeAvailableTime(parsedDate)\r\n      return parsedDate[0].isSame(result[0]) && parsedDate[1].isSame(result[1])\r\n    }\r\n\r\n    const handleChange = (_minDate, _maxDate) => {\r\n      // todo getRangeAvailableTime(_date).millisecond(0)\r\n      ctx.emit('pick', [_minDate, _maxDate], true)\r\n    }\r\n    const btnConfirmDisabled = computed(() => {\r\n      return minDate.value > maxDate.value\r\n    })\r\n\r\n    const selectionRange = ref([0, 2])\r\n    const setMinSelectionRange = (start, end) => {\r\n      ctx.emit('select-range', start, end, 'min')\r\n      selectionRange.value = [start, end]\r\n    }\r\n\r\n    const offset = computed(() => (showSeconds.value ? 11 : 8))\r\n    const setMaxSelectionRange = (start, end) => {\r\n      ctx.emit('select-range', start, end, 'max')\r\n      selectionRange.value = [start + offset.value, end + offset.value]\r\n    }\r\n\r\n    const changeSelectionRange = (step) => {\r\n      const list = showSeconds.value ? [0, 3, 6, 11, 14, 17] : [0, 3, 8, 11]\r\n      const mapping = ['hours', 'minutes'].concat(\r\n        showSeconds.value ? ['seconds'] : []\r\n      )\r\n      const index = list.indexOf(selectionRange.value[0])\r\n      const next = (index + step + list.length) % list.length\r\n      const half = list.length / 2\r\n      if (next < half) {\r\n        timePickerOptions['start_emitSelectRange'](mapping[next])\r\n      } else {\r\n        timePickerOptions['end_emitSelectRange'](mapping[next - half])\r\n      }\r\n    }\r\n\r\n    const handleKeydown = (event: KeyboardEvent) => {\r\n      const code = event.code\r\n\r\n      if (code === EVENT_CODE.left || code === EVENT_CODE.right) {\r\n        const step = code === EVENT_CODE.left ? -1 : 1\r\n        changeSelectionRange(step)\r\n        event.preventDefault()\r\n        return\r\n      }\r\n\r\n      if (code === EVENT_CODE.up || code === EVENT_CODE.down) {\r\n        const step = code === EVENT_CODE.up ? -1 : 1\r\n        const role = selectionRange.value[0] < offset.value ? 'start' : 'end'\r\n        timePickerOptions[`${role}_scrollDown`](step)\r\n        event.preventDefault()\r\n        return\r\n      }\r\n    }\r\n\r\n    const disabledHours_ = (role, compare) => {\r\n      const defaultDisable = disabledHours ? disabledHours(role) : []\r\n      const isStart = role === 'start'\r\n      const compareDate = compare || (isStart ? maxDate.value : minDate.value)\r\n      const compareHour = compareDate.hour()\r\n      const nextDisable = isStart\r\n        ? makeSelectRange(compareHour + 1, 23)\r\n        : makeSelectRange(0, compareHour - 1)\r\n      return union(defaultDisable, nextDisable)\r\n    }\r\n    const disabledMinutes_ = (hour, role, compare) => {\r\n      const defaultDisable = disabledMinutes ? disabledMinutes(hour, role) : []\r\n      const isStart = role === 'start'\r\n      const compareDate = compare || (isStart ? maxDate.value : minDate.value)\r\n      const compareHour = compareDate.hour()\r\n      if (hour !== compareHour) {\r\n        return defaultDisable\r\n      }\r\n      const compareMinute = compareDate.minute()\r\n      const nextDisable = isStart\r\n        ? makeSelectRange(compareMinute + 1, 59)\r\n        : makeSelectRange(0, compareMinute - 1)\r\n      return union(defaultDisable, nextDisable)\r\n    }\r\n    const disabledSeconds_ = (hour, minute, role, compare) => {\r\n      const defaultDisable = disabledSeconds\r\n        ? disabledSeconds(hour, minute, role)\r\n        : []\r\n      const isStart = role === 'start'\r\n      const compareDate = compare || (isStart ? maxDate.value : minDate.value)\r\n      const compareHour = compareDate.hour()\r\n      const compareMinute = compareDate.minute()\r\n      if (hour !== compareHour || minute !== compareMinute) {\r\n        return defaultDisable\r\n      }\r\n      const compareSecond = compareDate.second()\r\n      const nextDisable = isStart\r\n        ? makeSelectRange(compareSecond + 1, 59)\r\n        : makeSelectRange(0, compareSecond - 1)\r\n      return union(defaultDisable, nextDisable)\r\n    }\r\n\r\n    const getRangeAvailableTime = (dates: Array<Dayjs>) => {\r\n      return dates.map((_, index) =>\r\n        getRangeAvailableTimeEach(\r\n          dates[0],\r\n          dates[1],\r\n          index === 0 ? 'start' : 'end'\r\n        )\r\n      )\r\n    }\r\n\r\n    const { getAvailableHours, getAvailableMinutes, getAvailableSeconds } =\r\n      getAvailableArrs(disabledHours_, disabledMinutes_, disabledSeconds_)\r\n\r\n    const getRangeAvailableTimeEach = (\r\n      startDate: Dayjs,\r\n      endDate: Dayjs,\r\n      role\r\n    ) => {\r\n      const availableMap = {\r\n        hour: getAvailableHours,\r\n        minute: getAvailableMinutes,\r\n        second: getAvailableSeconds,\r\n      }\r\n      const isStart = role === 'start'\r\n      let result = isStart ? startDate : endDate\r\n      const compareDate = isStart ? endDate : startDate\r\n      ;['hour', 'minute', 'second'].forEach((_) => {\r\n        if (availableMap[_]) {\r\n          let availableArr\r\n          const method = availableMap[_]\r\n          if (_ === 'minute') {\r\n            availableArr = method(result.hour(), role, compareDate)\r\n          } else if (_ === 'second') {\r\n            availableArr = method(\r\n              result.hour(),\r\n              result.minute(),\r\n              role,\r\n              compareDate\r\n            )\r\n          } else {\r\n            availableArr = method(role, compareDate)\r\n          }\r\n          if (\r\n            availableArr &&\r\n            availableArr.length &&\r\n            !availableArr.includes(result[_]())\r\n          ) {\r\n            const pos = isStart ? 0 : availableArr.length - 1\r\n            result = result[_](availableArr[pos])\r\n          }\r\n        }\r\n      })\r\n      return result\r\n    }\r\n\r\n    const parseUserInput = (value: Dayjs[] | Dayjs) => {\r\n      if (!value) return null\r\n      if (Array.isArray(value)) {\r\n        return value.map((_) => dayjs(_, props.format).locale(lang.value))\r\n      }\r\n      return dayjs(value, props.format).locale(lang.value)\r\n    }\r\n\r\n    const formatToString = (value: Dayjs[] | Dayjs) => {\r\n      if (!value) return null\r\n      if (Array.isArray(value)) {\r\n        return value.map((_) => _.format(props.format))\r\n      }\r\n      return value.format(props.format)\r\n    }\r\n\r\n    const getDefaultValue = () => {\r\n      if (Array.isArray(defaultValue)) {\r\n        return defaultValue.map((_) => dayjs(_).locale(lang.value))\r\n      }\r\n      const defaultDay = dayjs(defaultValue).locale(lang.value)\r\n      return [defaultDay, defaultDay.add(60, 'm')]\r\n    }\r\n\r\n    ctx.emit('set-picker-option', ['formatToString', formatToString])\r\n    ctx.emit('set-picker-option', ['parseUserInput', parseUserInput])\r\n    ctx.emit('set-picker-option', ['isValidValue', isValidValue])\r\n    ctx.emit('set-picker-option', ['handleKeydown', handleKeydown])\r\n    ctx.emit('set-picker-option', ['getDefaultValue', getDefaultValue])\r\n    ctx.emit('set-picker-option', [\r\n      'getRangeAvailableTime',\r\n      getRangeAvailableTime,\r\n    ])\r\n\r\n    const timePickerOptions = {} as any\r\n    const onSetOption = (e) => {\r\n      timePickerOptions[e[0]] = e[1]\r\n    }\r\n\r\n    const pickerBase = inject(TimePickerContextKey) as any\r\n    const {\r\n      arrowControl,\r\n      disabledHours,\r\n      disabledMinutes,\r\n      disabledSeconds,\r\n      defaultValue,\r\n      step,\r\n    } = pickerBase.props\r\n\r\n    return {\r\n      arrowControl,\r\n      onSetOption,\r\n      setMaxSelectionRange,\r\n      setMinSelectionRange,\r\n      btnConfirmDisabled,\r\n      handleCancel,\r\n      handleConfirm,\r\n      t,\r\n      showSeconds,\r\n      minDate,\r\n      maxDate,\r\n      amPmMode,\r\n      handleMinChange,\r\n      handleMaxChange,\r\n      minSelectableRange,\r\n      maxSelectableRange,\r\n      disabledHours_,\r\n      disabledMinutes_,\r\n      disabledSeconds_,\r\n      step\r\n    }\r\n  },\r\n})\r\n</script>\r\n"],"names":["_resolveComponent","_openBlock","_createElementBlock","_createElementVNode","_toDisplayString","_normalizeClass","_createVNode"],"mappings":"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"}