UNPKG

@tldraw/editor

Version:

tldraw infinite canvas SDK (editor).

8 lines (7 loc) 3.51 kB
{ "version": 3, "sources": ["../../../src/lib/hooks/useCoarsePointer.ts"], "sourcesContent": ["import { useEffect } from 'react'\nimport { tlenv } from '../globals/environment'\nimport { useEditor } from './useEditor'\n\n/** @internal */\nexport function useCoarsePointer() {\n\tconst editor = useEditor()\n\n\tuseEffect(() => {\n\t\t// We'll track our own state for the pointer type\n\t\tlet isCoarse = editor.getInstanceState().isCoarsePointer\n\n\t\t// 1.\n\t\t// We'll use pointer events to detect coarse pointer.\n\n\t\tconst handlePointerDown = (e: PointerEvent) => {\n\t\t\t// when the user interacts with a mouse, we assume they have a fine pointer.\n\t\t\t// otherwise, we assume they have a coarse pointer.\n\t\t\tconst isCoarseEvent = e.pointerType !== 'mouse'\n\t\t\tif (isCoarse === isCoarseEvent) return\n\t\t\tisCoarse = isCoarseEvent\n\t\t\teditor.updateInstanceState({ isCoarsePointer: isCoarseEvent })\n\t\t}\n\n\t\t// we need `capture: true` here because the tldraw component itself stops propagation on\n\t\t// pointer events it receives.\n\t\twindow.addEventListener('pointerdown', handlePointerDown, { capture: true })\n\n\t\t// 2.\n\t\t// We can also use the media query to detect / set the initial pointer type\n\t\t// and update the state if the pointer type changes.\n\n\t\t// We want the touch / mouse events to run even if the browser does not\n\t\t// support matchMedia. We'll have to handle the media query changes\n\t\t// conditionally in the code below.\n\t\tconst mql = window.matchMedia && window.matchMedia('(any-pointer: coarse)')\n\n\t\t// This is a workaround for a Firefox bug where we don't correctly\n\t\t// detect coarse VS fine pointer. For now, let's assume that you have a fine\n\t\t// pointer if you're on Firefox on desktop.\n\t\tconst isForcedFinePointer = tlenv.isFirefox && !tlenv.isAndroid && !tlenv.isIos\n\n\t\tconst handleMediaQueryChange = () => {\n\t\t\tconst next = isForcedFinePointer ? false : mql.matches // get the value from the media query\n\t\t\tif (isCoarse !== next) return // bail if the value hasn't changed\n\t\t\tisCoarse = next // update the local value\n\t\t\teditor.updateInstanceState({ isCoarsePointer: next }) // update the value in state\n\t\t}\n\n\t\tif (mql) {\n\t\t\t// set up the listener\n\t\t\tmql.addEventListener('change', handleMediaQueryChange)\n\n\t\t\t// and run the handler once to set the initial value\n\t\t\thandleMediaQueryChange()\n\t\t}\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener('pointerdown', handlePointerDown, { capture: true })\n\n\t\t\tif (mql) {\n\t\t\t\tmql.removeEventListener('change', handleMediaQueryChange)\n\t\t\t}\n\t\t}\n\t}, [editor])\n}\n"], "mappings": "AAAA,SAAS,iBAAiB;AAC1B,SAAS,aAAa;AACtB,SAAS,iBAAiB;AAGnB,SAAS,mBAAmB;AAClC,QAAM,SAAS,UAAU;AAEzB,YAAU,MAAM;AAEf,QAAI,WAAW,OAAO,iBAAiB,EAAE;AAKzC,UAAM,oBAAoB,CAAC,MAAoB;AAG9C,YAAM,gBAAgB,EAAE,gBAAgB;AACxC,UAAI,aAAa,cAAe;AAChC,iBAAW;AACX,aAAO,oBAAoB,EAAE,iBAAiB,cAAc,CAAC;AAAA,IAC9D;AAIA,WAAO,iBAAiB,eAAe,mBAAmB,EAAE,SAAS,KAAK,CAAC;AAS3E,UAAM,MAAM,OAAO,cAAc,OAAO,WAAW,uBAAuB;AAK1E,UAAM,sBAAsB,MAAM,aAAa,CAAC,MAAM,aAAa,CAAC,MAAM;AAE1E,UAAM,yBAAyB,MAAM;AACpC,YAAM,OAAO,sBAAsB,QAAQ,IAAI;AAC/C,UAAI,aAAa,KAAM;AACvB,iBAAW;AACX,aAAO,oBAAoB,EAAE,iBAAiB,KAAK,CAAC;AAAA,IACrD;AAEA,QAAI,KAAK;AAER,UAAI,iBAAiB,UAAU,sBAAsB;AAGrD,6BAAuB;AAAA,IACxB;AAEA,WAAO,MAAM;AACZ,aAAO,oBAAoB,eAAe,mBAAmB,EAAE,SAAS,KAAK,CAAC;AAE9E,UAAI,KAAK;AACR,YAAI,oBAAoB,UAAU,sBAAsB;AAAA,MACzD;AAAA,IACD;AAAA,EACD,GAAG,CAAC,MAAM,CAAC;AACZ;", "names": [] }