{"version":3,"file":"useGanttSelect.mjs","sources":["../../../src/composables/useGanttSelect.ts"],"sourcesContent":["import { ref, provide, onMounted, onBeforeUnmount, watch } from 'vue';\nimport type { Ref } from 'vue';\n\nexport const useGanttSelect = ({\n  vGanttRef,\n  visibleRowIds,\n  rowHeight,\n  rowSelection,\n  rowClass,\n  emitGanttMouseDown,\n  emitSelectChange\n}: {\n  vGanttRef: Ref<HTMLDivElement | undefined>,\n  visibleRowIds: Ref<string[], string[]>,\n  rowHeight: Ref<number>,\n  rowSelection: Ref<'single' | 'multiple' | 'none'>,\n  rowClass: string,\n  emitGanttMouseDown: (event: MouseEvent, rowId: string | null) => void,\n  emitSelectChange: (ids: string[]) => void\n}) => {\n  const selectedRowIds = ref<Set<string>>(new Set());\n  let lastMouseMoveTarget: HTMLElement | null = null;\n  let lastClickedRowId = '';\n  let lastClickedRowIndex = 0;\n\n  provide(\n    'selectedRowIds',\n    selectedRowIds\n  );\n\n  watch(selectedRowIds, (val) => {\n    emitSelectChange([...val]);\n  }, { deep: true });\n\n  onMounted(() => {\n    vGanttRef.value?.addEventListener('mousedown', handleGanttMouseDown);\n  });\n\n  onBeforeUnmount(() => {\n    vGanttRef.value?.removeEventListener('mousedown', handleGanttMouseDown);\n  });\n\n  function handleGanttMouseDown (this: HTMLElement, event: MouseEvent) {\n    if (rowSelection.value === 'none') return;\n    const { target, attributeValue: rowId, rowIndex } = getTargetElementInfo(event.target as HTMLElement | null, rowClass, 'data-row-id');\n    emitGanttMouseDown(event, rowId);\n    if (target) {\n      const isLeftMouse = event.button === 0;\n      if (rowId) {\n        handleRowSelect(rowId, event, rowIndex);\n      } else {\n        // click empty table view row to clear select\n        selectedRowIds.value.clear();\n        return;\n      }\n      if (isLeftMouse && rowSelection.value === 'multiple') {\n        this.addEventListener('mousemove', handleGanttMouseMove);\n        document.addEventListener('mouseup', handleGanttMouseUp);\n      }\n    } else {\n      // click empty gantt view row to clear select\n      const { target: ganttBodyRef } = getTargetElementInfo(event.target as HTMLElement | null, 'vg-body');\n      if (ganttBodyRef) {\n        selectedRowIds.value.clear();\n      }\n\n    }\n  }\n\n  function handleGanttMouseMove(event: MouseEvent) {\n    const { target, attributeValue: rowId, rowIndex } = getTargetElementInfo(event.target as HTMLElement | null, rowClass, 'data-row-id');\n    if (target && lastMouseMoveTarget !== target) {\n      lastMouseMoveTarget = target;\n      if (rowId) {\n        handleRowSelect(rowId, event, rowIndex, true);\n      }\n    }\n  }\n\n  function handleGanttMouseUp() {\n    vGanttRef.value?.removeEventListener('mousemove', handleGanttMouseMove);\n    document.removeEventListener('mouseup', handleGanttMouseUp);\n  }\n\n  /**\n   * select function core, support multi select by using ctrl and shift\n   * @param rowId\n   * @param event\n   * @param rowIndex\n   * @param onShift\n   * @returns\n   */\n  const handleRowSelect = (rowId: string, event: MouseEvent, rowIndex:number, onShift?: boolean) => {\n    const pressCtrl = event?.ctrlKey;\n    const pressShift = event?.shiftKey || onShift;\n    const isContextmenuClick = event?.type === 'contextmenu';\n    const selectedRowIdSize = selectedRowIds.value.size;\n\n    if (!pressCtrl || isContextmenuClick) {\n      selectedRowIds.value.clear();\n    }\n\n    if (pressCtrl && !pressShift) {\n      if (selectedRowIds.value.has(rowId)) {\n        selectedRowIds.value.delete(rowId);\n        return;\n      }\n    }\n\n    // handle shift\n    if (pressShift && !isContextmenuClick && selectedRowIdSize > 0 && lastClickedRowId !== rowId) {\n      const bigRowIndex = Math.max(rowIndex, lastClickedRowIndex);\n      const smallRowIndex = Math.min(rowIndex, lastClickedRowIndex);\n      const willSelectedRowIds = visibleRowIds.value.slice(smallRowIndex, bigRowIndex + 1);\n      for (let id of willSelectedRowIds) {\n        selectedRowIds.value.add(id);\n      }\n    } else {\n      selectedRowIds.value.add(rowId);\n      lastClickedRowId = rowId;\n      lastClickedRowIndex = rowIndex;\n    }\n  };\n\n  /**\n   * get target dom attribute and row index\n   * @param initialTarget\n   * @param targetClass\n   * @param attribute\n   * @returns\n   */\n  const getTargetElementInfo = (initialTarget: HTMLElement | null, targetClass: string, attribute?: string) => {\n    let target = initialTarget;\n    let attributeValue: string | null = '';\n    let rowIndex = 0;\n    while (target && !target.classList.contains(targetClass)) {\n      target = target?.parentElement;\n    }\n\n    // calculate row index by transformY / rowHeight\n    if (target && attribute) {\n      attributeValue = target.getAttribute(attribute);\n      const transform = target.style.transform;\n      const transformYStr = transform.match(/translateY\\((.+)px\\)/)?.[1];\n      if (transformYStr) {\n        const transformY = parseFloat(transformYStr);\n        // Rounding is required here to prevent the last bit of the browser's scientific count from being intercepted\n        // when the value is too large, resulting in incorrect calculation of the rowIndex\n        rowIndex = parseInt((transformY / rowHeight.value).toFixed(0));\n      }\n    }\n\n    return {\n      target,\n      attributeValue,\n      rowIndex\n    };\n  };\n\n  const handleSetSelect = (id: string) => {\n    if (rowSelection.value === 'none') return;\n    selectedRowIds.value.clear();\n    selectedRowIds.value.add(id);\n  };\n\n  const selectRows = (ids: string[]) => {\n    selectedRowIds.value = new Set(ids);\n  };\n\n  return {\n    handleSetSelect,\n    selectRows,\n    getTargetElementInfo,\n  };\n};"],"names":[],"mappings":";AAGO,MAAM,iBAAiB,CAAC;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAQM;AACJ,QAAM,iBAAiB,IAAqB,oBAAA,KAAK;AACjD,MAAI,sBAA0C;AAC9C,MAAI,mBAAmB;AACvB,MAAI,sBAAsB;AAE1B;AAAA,IACE;AAAA,IACA;AAAA,EACF;AAEM,QAAA,gBAAgB,CAAC,QAAQ;AACZ,qBAAA,CAAC,GAAG,GAAG,CAAC;AAAA,EAAA,GACxB,EAAE,MAAM,MAAM;AAEjB,YAAU,MAAM;;AACJ,oBAAA,UAAA,mBAAO,iBAAiB,aAAa;AAAA,EAAoB,CACpE;AAED,kBAAgB,MAAM;;AACV,oBAAA,UAAA,mBAAO,oBAAoB,aAAa;AAAA,EAAoB,CACvE;AAED,WAAS,qBAAyC,OAAmB;AAC/D,QAAA,aAAa,UAAU,OAAQ;AAC7B,UAAA,EAAE,QAAQ,gBAAgB,OAAO,SAAA,IAAa,qBAAqB,MAAM,QAA8B,UAAU,aAAa;AACpI,uBAAmB,OAAO,KAAK;AAC/B,QAAI,QAAQ;AACJ,YAAA,cAAc,MAAM,WAAW;AACrC,UAAI,OAAO;AACO,wBAAA,OAAO,OAAO,QAAQ;AAAA,MAAA,OACjC;AAEL,uBAAe,MAAM,MAAM;AAC3B;AAAA,MAAA;AAEE,UAAA,eAAe,aAAa,UAAU,YAAY;AAC/C,aAAA,iBAAiB,aAAa,oBAAoB;AAC9C,iBAAA,iBAAiB,WAAW,kBAAkB;AAAA,MAAA;AAAA,IACzD,OACK;AAEL,YAAM,EAAE,QAAQ,iBAAiB,qBAAqB,MAAM,QAA8B,SAAS;AACnG,UAAI,cAAc;AAChB,uBAAe,MAAM,MAAM;AAAA,MAAA;AAAA,IAC7B;AAAA,EAEF;AAGF,WAAS,qBAAqB,OAAmB;AACzC,UAAA,EAAE,QAAQ,gBAAgB,OAAO,SAAA,IAAa,qBAAqB,MAAM,QAA8B,UAAU,aAAa;AAChI,QAAA,UAAU,wBAAwB,QAAQ;AACtB,4BAAA;AACtB,UAAI,OAAO;AACO,wBAAA,OAAO,OAAO,UAAU,IAAI;AAAA,MAAA;AAAA,IAC9C;AAAA,EACF;AAGF,WAAS,qBAAqB;;AAClB,oBAAA,UAAA,mBAAO,oBAAoB,aAAa;AACzC,aAAA,oBAAoB,WAAW,kBAAkB;AAAA,EAAA;AAW5D,QAAM,kBAAkB,CAAC,OAAe,OAAmB,UAAiB,YAAsB;AAChG,UAAM,YAAY,+BAAO;AACnB,UAAA,cAAa,+BAAO,aAAY;AAChC,UAAA,sBAAqB,+BAAO,UAAS;AACrC,UAAA,oBAAoB,eAAe,MAAM;AAE3C,QAAA,CAAC,aAAa,oBAAoB;AACpC,qBAAe,MAAM,MAAM;AAAA,IAAA;AAGzB,QAAA,aAAa,CAAC,YAAY;AAC5B,UAAI,eAAe,MAAM,IAAI,KAAK,GAAG;AACpB,uBAAA,MAAM,OAAO,KAAK;AACjC;AAAA,MAAA;AAAA,IACF;AAIF,QAAI,cAAc,CAAC,sBAAsB,oBAAoB,KAAK,qBAAqB,OAAO;AAC5F,YAAM,cAAc,KAAK,IAAI,UAAU,mBAAmB;AAC1D,YAAM,gBAAgB,KAAK,IAAI,UAAU,mBAAmB;AAC5D,YAAM,qBAAqB,cAAc,MAAM,MAAM,eAAe,cAAc,CAAC;AACnF,eAAS,MAAM,oBAAoB;AAClB,uBAAA,MAAM,IAAI,EAAE;AAAA,MAAA;AAAA,IAC7B,OACK;AACU,qBAAA,MAAM,IAAI,KAAK;AACX,yBAAA;AACG,4BAAA;AAAA,IAAA;AAAA,EAE1B;AASA,QAAM,uBAAuB,CAAC,eAAmC,aAAqB,cAAuB;;AAC3G,QAAI,SAAS;AACb,QAAI,iBAAgC;AACpC,QAAI,WAAW;AACf,WAAO,UAAU,CAAC,OAAO,UAAU,SAAS,WAAW,GAAG;AACxD,eAAS,iCAAQ;AAAA,IAAA;AAInB,QAAI,UAAU,WAAW;AACN,uBAAA,OAAO,aAAa,SAAS;AACxC,YAAA,YAAY,OAAO,MAAM;AAC/B,YAAM,iBAAgB,eAAU,MAAM,sBAAsB,MAAtC,mBAA0C;AAChE,UAAI,eAAe;AACX,cAAA,aAAa,WAAW,aAAa;AAG3C,mBAAW,UAAU,aAAa,UAAU,OAAO,QAAQ,CAAC,CAAC;AAAA,MAAA;AAAA,IAC/D;AAGK,WAAA;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEM,QAAA,kBAAkB,CAAC,OAAe;AAClC,QAAA,aAAa,UAAU,OAAQ;AACnC,mBAAe,MAAM,MAAM;AACZ,mBAAA,MAAM,IAAI,EAAE;AAAA,EAC7B;AAEM,QAAA,aAAa,CAAC,QAAkB;AACrB,mBAAA,QAAQ,IAAI,IAAI,GAAG;AAAA,EACpC;AAEO,SAAA;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;"}