@basic-ui/core 0.0.32 → 0.0.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -372,16 +372,30 @@ const initialGestureHandlersState = {
372
372
  yInitial: 0,
373
373
  yPrev: 0,
374
374
  yVelocity: 0,
375
- down: false
375
+ startTime: 0,
376
+ down: false,
377
+ scrollLocked: false
376
378
  };
379
+ const FRAMERATE_CONST = 1000 / 60; // 60 fps
380
+
381
+ const VELOCITY_DEPR_FACTOR = FRAMERATE_CONST * 2;
377
382
  function gestureHandlers(set, containerRef, options = {}) {
378
383
  const {
379
- ensureTargetIsContainer = false
384
+ ensureTargetIsContainer = false,
385
+ minTouchDelta = 0
380
386
  } = options; // Common handlers
381
387
 
382
388
  const handleUp = () => {
383
389
  set(state => {
390
+ const deltaTime = Date.now() - state.startTime;
391
+ const xDelta = state.x - state.xInitial;
392
+ const yDelta = state.y - state.yInitial;
393
+ const xVelocity = calcVelocity(xDelta, deltaTime, state.xVelocity);
394
+ const yVelocity = calcVelocity(yDelta, deltaTime, state.yVelocity);
395
+
384
396
  const newState = _extends__default['default']({}, state, {
397
+ xVelocity,
398
+ yVelocity,
385
399
  target: null,
386
400
  down: false
387
401
  });
@@ -411,42 +425,68 @@ function gestureHandlers(set, containerRef, options = {}) {
411
425
  yVelocity: 0,
412
426
  yInitial: pageY,
413
427
  yPrev: pageY,
414
- down: true
428
+ startTime: Date.now(),
429
+ down: true,
430
+ scrollLocked: false
415
431
  });
416
432
 
417
433
  return newState;
418
434
  });
419
435
  };
420
436
 
437
+ function calcVelocity(deltaSpace, deltaTime, prevVelocity) {
438
+ if (deltaTime < 1) {
439
+ deltaTime = 1;
440
+ }
441
+
442
+ const speed = deltaSpace / deltaTime;
443
+ const depr = 0.5 + Math.min(deltaTime / VELOCITY_DEPR_FACTOR, 0.5);
444
+ return speed * depr + prevVelocity * (1 - depr);
445
+ }
446
+
421
447
  function handleMove(e) {
422
448
  const {
423
449
  pageX,
424
- movementX,
425
- pageY,
426
- movementY
450
+ pageY
427
451
  } = e;
428
- e.preventDefault && e.preventDefault(); // prevent drag & drop behaviour from browser
452
+
453
+ if (e.cancelable) {
454
+ // prevent drag & drop behaviour from browser
455
+ e.preventDefault && e.preventDefault();
456
+ }
429
457
 
430
458
  set(state => {
459
+ function getDeltaSum(currentPos, initialPos, prevPos) {
460
+ if (state.scrollLocked || Math.abs(currentPos - initialPos) >= minTouchDelta) {
461
+ state.scrollLocked = true;
462
+ return currentPos - prevPos;
463
+ }
464
+
465
+ return 0;
466
+ }
467
+
431
468
  const target = containerRef && containerRef.current || e.target;
469
+ const deltaTime = Date.now() - state.startTime;
432
470
  const width = target ? target.offsetWidth : NaN;
433
- const xDelta = pageX - state.xInitial;
471
+ const xDelta = state.xDelta + getDeltaSum(pageX, state.xInitial, state.x);
434
472
  const xDeltaPercent = xDelta * 100 / width;
473
+ const xVelocity = calcVelocity(xDelta, deltaTime, state.xVelocity);
435
474
  const height = target ? target.offsetHeight : NaN;
436
- const yDelta = pageY - state.yInitial;
475
+ const yDelta = state.yDelta + getDeltaSum(pageY, state.yInitial, state.y);
437
476
  const yDeltaPercent = yDelta * 100 / height;
477
+ const yVelocity = calcVelocity(yDelta, deltaTime, state.yVelocity);
438
478
 
439
479
  const newState = _extends__default['default']({}, state, {
440
480
  xDelta,
441
481
  xDeltaPercent,
442
482
  x: pageX,
443
483
  xPrev: state.x,
444
- xVelocity: movementX,
484
+ xVelocity,
445
485
  yDelta,
446
486
  yDeltaPercent,
447
487
  y: pageY,
448
488
  yPrev: state.y,
449
- yVelocity: movementY
489
+ yVelocity
450
490
  });
451
491
 
452
492
  return newState;
@@ -457,7 +497,11 @@ function gestureHandlers(set, containerRef, options = {}) {
457
497
 
458
498
 
459
499
  function handleTouchMove(e) {
460
- e.preventDefault();
500
+ if (e.cancelable) {
501
+ // prevent drag & drop behaviour from browser
502
+ e.preventDefault();
503
+ }
504
+
461
505
  handleMove(e.touches.item(0));
462
506
  }
463
507
 
@@ -2755,7 +2799,7 @@ let restTimeout;
2755
2799
  function startRestTimer() {
2756
2800
  window.clearTimeout(restTimeout);
2757
2801
  restTimeout = window.setTimeout(() => {
2758
- send(TooltipEventTypes.Rest, undefined);
2802
+ send(Rest, undefined);
2759
2803
  }, 200);
2760
2804
  }
2761
2805
 
@@ -2768,7 +2812,7 @@ let leavingVisibleTimer;
2768
2812
 
2769
2813
  function startLeavingVisibleTimer() {
2770
2814
  window.clearTimeout(leavingVisibleTimer);
2771
- leavingVisibleTimer = window.setTimeout(() => send(TooltipEventTypes.TimeComplete, undefined), 100);
2815
+ leavingVisibleTimer = window.setTimeout(() => send(TimeComplete, undefined), 100);
2772
2816
  }
2773
2817
 
2774
2818
  function clearLeavingVisibleTimer() {
@@ -2777,35 +2821,31 @@ function clearLeavingVisibleTimer() {
2777
2821
  // State machine
2778
2822
 
2779
2823
 
2780
- let TooltipStates;
2824
+ // Nothing goin' on
2825
+ const Idle = 'IDLE'; // We're considering showing the tooltip, but we're gonna wait a sec
2781
2826
 
2782
- (function (TooltipStates) {
2783
- TooltipStates["Idle"] = "IDLE";
2784
- TooltipStates["Focused"] = "FOCUSED";
2785
- TooltipStates["Visible"] = "VISIBLE";
2786
- TooltipStates["LeavingVisible"] = "LEAVING_VISIBLE";
2787
- TooltipStates["Dismissed"] = "DISMISSED";
2788
- })(TooltipStates || (TooltipStates = {}));
2827
+ const Focused = 'FOCUSED'; // It's on!
2789
2828
 
2790
- let TooltipEventTypes;
2829
+ const Visible = 'VISIBLE'; // Focus has left, but we want to keep it visible for a sec
2791
2830
 
2792
- (function (TooltipEventTypes) {
2793
- TooltipEventTypes["Blur"] = "BLUR";
2794
- TooltipEventTypes["Focus"] = "FOCUS";
2795
- TooltipEventTypes["GlobalMouseMove"] = "GLOBAL_MOUSE_MOVE";
2796
- TooltipEventTypes["MouseDown"] = "MOUSE_DOWN";
2797
- TooltipEventTypes["MouseEnter"] = "MOUSE_ENTER";
2798
- TooltipEventTypes["MouseLeave"] = "MOUSE_LEAVE";
2799
- TooltipEventTypes["MouseMove"] = "MOUSE_MOVE";
2800
- TooltipEventTypes["Rest"] = "REST";
2801
- TooltipEventTypes["SelectWithKeyboard"] = "SELECT_WITH_KEYBOARD";
2802
- TooltipEventTypes["TimeComplete"] = "TIME_COMPLETE";
2803
- })(TooltipEventTypes || (TooltipEventTypes = {}));
2831
+ const LeavingVisible = 'LEAVING_VISIBLE'; // The user clicked the tool, so we want to hide the thing, we can't just use
2832
+ // IDLE because we need to ignore mousemove, etc.
2804
2833
 
2834
+ const Dismissed = 'DISMISSED';
2835
+ const Blur = 'BLUR';
2836
+ const Focus = 'FOCUS';
2837
+ const GlobalMouseMove = 'GLOBAL_MOUSE_MOVE';
2838
+ const MouseDown = 'MOUSE_DOWN';
2839
+ const MouseEnter = 'MOUSE_ENTER';
2840
+ const MouseLeave = 'MOUSE_LEAVE';
2841
+ const MouseMove = 'MOUSE_MOVE';
2842
+ const Rest = 'REST';
2843
+ const SelectWithKeyboard = 'SELECT_WITH_KEYBOARD';
2844
+ const TimeComplete = 'TIME_COMPLETE';
2805
2845
  const subscription = createSubscription();
2806
2846
  const state = {
2807
2847
  current: {
2808
- state: TooltipStates.Idle,
2848
+ state: Idle,
2809
2849
  id: ''
2810
2850
  }
2811
2851
  };
@@ -2815,40 +2855,40 @@ function clearContextId() {
2815
2855
  }
2816
2856
 
2817
2857
  const chart = {
2818
- initial: TooltipStates.Idle,
2858
+ initial: Idle,
2819
2859
  states: {
2820
- [TooltipStates.Idle]: {
2860
+ [Idle]: {
2821
2861
  enter: () => {
2822
2862
  clearContextId();
2823
2863
  },
2824
2864
  on: {
2825
- [TooltipEventTypes.MouseEnter]: TooltipStates.Focused,
2826
- [TooltipEventTypes.Focus]: TooltipStates.Visible
2865
+ [MouseEnter]: Focused,
2866
+ [Focus]: Visible
2827
2867
  }
2828
2868
  },
2829
- [TooltipStates.Focused]: {
2869
+ [Focused]: {
2830
2870
  enter: startRestTimer,
2831
2871
  leave: clearRestTimer,
2832
2872
  on: {
2833
- [TooltipEventTypes.MouseMove]: TooltipStates.Focused,
2834
- [TooltipEventTypes.MouseLeave]: TooltipStates.Idle,
2835
- [TooltipEventTypes.MouseDown]: TooltipStates.Dismissed,
2836
- [TooltipEventTypes.Blur]: TooltipStates.Idle,
2837
- [TooltipEventTypes.Rest]: TooltipStates.Visible
2873
+ [MouseMove]: Focused,
2874
+ [MouseLeave]: Idle,
2875
+ [MouseDown]: Dismissed,
2876
+ [Blur]: Idle,
2877
+ [Rest]: Visible
2838
2878
  }
2839
2879
  },
2840
- [TooltipStates.Visible]: {
2880
+ [Visible]: {
2841
2881
  on: {
2842
- [TooltipEventTypes.Focus]: TooltipStates.Focused,
2843
- [TooltipEventTypes.MouseEnter]: TooltipStates.Focused,
2844
- [TooltipEventTypes.MouseLeave]: TooltipStates.LeavingVisible,
2845
- [TooltipEventTypes.Blur]: TooltipStates.LeavingVisible,
2846
- [TooltipEventTypes.MouseDown]: TooltipStates.Dismissed,
2847
- [TooltipEventTypes.SelectWithKeyboard]: TooltipStates.Dismissed,
2848
- [TooltipEventTypes.GlobalMouseMove]: TooltipStates.LeavingVisible
2882
+ [Focus]: Focused,
2883
+ [MouseEnter]: Focused,
2884
+ [MouseLeave]: LeavingVisible,
2885
+ [Blur]: LeavingVisible,
2886
+ [MouseDown]: Dismissed,
2887
+ [SelectWithKeyboard]: Dismissed,
2888
+ [GlobalMouseMove]: LeavingVisible
2849
2889
  }
2850
2890
  },
2851
- [TooltipStates.LeavingVisible]: {
2891
+ [LeavingVisible]: {
2852
2892
  enter: () => {
2853
2893
  startLeavingVisibleTimer();
2854
2894
  },
@@ -2857,18 +2897,18 @@ const chart = {
2857
2897
  clearContextId();
2858
2898
  },
2859
2899
  on: {
2860
- [TooltipEventTypes.MouseEnter]: TooltipStates.Visible,
2861
- [TooltipEventTypes.Focus]: TooltipStates.Visible,
2862
- [TooltipEventTypes.TimeComplete]: TooltipStates.Idle
2900
+ [MouseEnter]: Visible,
2901
+ [Focus]: Visible,
2902
+ [TimeComplete]: Idle
2863
2903
  }
2864
2904
  },
2865
- [TooltipStates.Dismissed]: {
2905
+ [Dismissed]: {
2866
2906
  leave: () => {
2867
2907
  clearContextId();
2868
2908
  },
2869
2909
  on: {
2870
- [TooltipEventTypes.MouseLeave]: TooltipStates.Idle,
2871
- [TooltipEventTypes.Blur]: TooltipStates.Idle
2910
+ [MouseLeave]: Idle,
2911
+ [Blur]: Idle
2872
2912
  }
2873
2913
  }
2874
2914
  }
@@ -2931,35 +2971,35 @@ function useTooltip(childProps, childRef, tooltipProps) {
2931
2971
  const id = useId('');
2932
2972
  react.useEffect(() => {
2933
2973
  subscription.subscribe(() => {
2934
- setVisible((state.current.state === TooltipStates.Visible || state.current.state === TooltipStates.LeavingVisible) && state.current.id === id);
2974
+ setVisible((state.current.state === Visible || state.current.state === LeavingVisible) && state.current.id === id);
2935
2975
  });
2936
2976
  }, [id]);
2937
2977
 
2938
2978
  function handleMouseEnter() {
2939
- send(TooltipEventTypes.MouseEnter, {
2979
+ send(MouseEnter, {
2940
2980
  id
2941
2981
  });
2942
2982
  }
2943
2983
 
2944
2984
  function handleMouseMove() {
2945
- send(TooltipEventTypes.MouseMove, {
2985
+ send(MouseMove, {
2946
2986
  id
2947
2987
  });
2948
2988
  }
2949
2989
 
2950
2990
  function handleMouseLeave() {
2951
- send(TooltipEventTypes.MouseLeave);
2991
+ send(MouseLeave);
2952
2992
  }
2953
2993
 
2954
2994
  function handleMouseDown() {
2955
2995
  // Allow quick click from one tool to another
2956
2996
  if (state.current.id === id) {
2957
- send(TooltipEventTypes.MouseDown);
2997
+ send(MouseDown);
2958
2998
  }
2959
2999
  }
2960
3000
 
2961
3001
  function handleFocus() {
2962
- send(TooltipEventTypes.Focus, {
3002
+ send(Focus, {
2963
3003
  id
2964
3004
  });
2965
3005
  }
@@ -2967,13 +3007,13 @@ function useTooltip(childProps, childRef, tooltipProps) {
2967
3007
  function handleBlur() {
2968
3008
  // Allow quick click from one tool to another
2969
3009
  if (state.current.id === id) {
2970
- send(TooltipEventTypes.Blur, undefined);
3010
+ send(Blur, undefined);
2971
3011
  }
2972
3012
  }
2973
3013
 
2974
3014
  function handleKeyDown(event) {
2975
3015
  if (event.key === 'Enter' || event.key === ' ') {
2976
- send(TooltipEventTypes.SelectWithKeyboard);
3016
+ send(SelectWithKeyboard);
2977
3017
  }
2978
3018
  }
2979
3019