@basic-ui/core 0.0.33 → 0.0.36

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@basic-ui/core",
3
- "version": "0.0.33",
3
+ "version": "0.0.36",
4
4
  "description": "Accessible React Components used as building blocks for UI patterns",
5
5
  "author": "Lucas Terra <lucasterra7@gmail.com>",
6
6
  "license": "MIT",
@@ -14,7 +14,7 @@
14
14
  ],
15
15
  "sideEffects": false,
16
16
  "scripts": {
17
- "build": "concurrently \"yarn:build:*\"",
17
+ "build": "run -T concurrently \"yarn:build:*\"",
18
18
  "build:dts": "tsc -p ./tsconfig.json --isolatedModules false --declaration --emitDeclarationOnly",
19
19
  "build:cjs": "rollup -c ../../rollup.config.js",
20
20
  "build:esm": "cross-env NODE_ENV=production BABEL_ENV=esm babel --config-file ../../babel.config.js ./src --extensions \".ts,.tsx,.js,.jsx\" --source-maps --out-dir ./build/esm --ignore \"**/*.story.tsx,**/*.story.ts,**/*.test.tsx,**/*.test.ts\"",
@@ -33,8 +33,8 @@
33
33
  },
34
34
  "peerDependencies": {
35
35
  "@babel/runtime": "^7.0.0",
36
- "react": ">=16.14.0 || >=17.0.0",
37
- "react-dom": ">=16.14.0 || >=17.0.0"
36
+ "react": "^16.14.0 || ^17.0.0 || ^18.0.0",
37
+ "react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0"
38
38
  },
39
- "gitHead": "5aa740f6686e8ed8b633d4e0d173a6dd91d28bef"
39
+ "gitHead": "255161ee895cdd62ff5de0a539562d593d215cdb"
40
40
  }
@@ -1,4 +1,4 @@
1
- import React, { useRef, RefAttributes, useEffect, useState } from 'react';
1
+ import { useRef, RefAttributes, useEffect, useState } from 'react';
2
2
  import { assignMultipleRefs } from '../utils/assignRef';
3
3
  import { wrapEvent } from '../utils/wrapEvent';
4
4
  import { useId } from '../hooks/useId';
@@ -15,7 +15,9 @@ export interface GestureHandlersState {
15
15
  yInitial: number;
16
16
  yPrev: number;
17
17
  yVelocity: number;
18
+ startTime: number;
18
19
  down: boolean;
20
+ scrollLocked: boolean;
19
21
  }
20
22
 
21
23
  type SetStateFunc<S> = (
@@ -30,6 +32,7 @@ export interface GestureHandlersReturn {
30
32
 
31
33
  export interface GestureHandlerOptions {
32
34
  ensureTargetIsContainer?: boolean;
35
+ minTouchDelta?: number;
33
36
  }
34
37
 
35
38
  export const initialGestureHandlersState: GestureHandlersState = {
@@ -46,21 +49,33 @@ export const initialGestureHandlersState: GestureHandlersState = {
46
49
  yInitial: 0,
47
50
  yPrev: 0,
48
51
  yVelocity: 0,
52
+ startTime: 0,
49
53
  down: false,
54
+ scrollLocked: false,
50
55
  };
51
56
 
57
+ const FRAMERATE_CONST = 1000 / 60; // 60 fps
58
+ const VELOCITY_DEPR_FACTOR = FRAMERATE_CONST * 2;
59
+
52
60
  export function gestureHandlers(
53
61
  set: SetStateFunc<GestureHandlersState>,
54
62
  containerRef?: React.MutableRefObject<HTMLElement | null>,
55
63
  options: GestureHandlerOptions = {}
56
64
  ): GestureHandlersReturn {
57
- const { ensureTargetIsContainer = false } = options;
65
+ const { ensureTargetIsContainer = false, minTouchDelta = 0 } = options;
58
66
 
59
67
  // Common handlers
60
68
  const handleUp = () => {
61
69
  set((state: GestureHandlersState) => {
70
+ const deltaTime = Date.now() - state.startTime;
71
+ const xDelta = state.x - state.xInitial;
72
+ const yDelta = state.y - state.yInitial;
73
+ const xVelocity = calcVelocity(xDelta, deltaTime, state.xVelocity);
74
+ const yVelocity = calcVelocity(yDelta, deltaTime, state.yVelocity);
62
75
  const newState: GestureHandlersState = {
63
76
  ...state,
77
+ xVelocity,
78
+ yVelocity,
64
79
  target: null,
65
80
  down: false,
66
81
  };
@@ -88,28 +103,65 @@ export function gestureHandlers(
88
103
  yVelocity: 0,
89
104
  yInitial: pageY,
90
105
  yPrev: pageY,
106
+ startTime: Date.now(),
91
107
  down: true,
108
+ scrollLocked: false,
92
109
  };
93
110
 
94
111
  return newState;
95
112
  });
96
113
  };
97
114
 
115
+ function calcVelocity(
116
+ deltaSpace: number,
117
+ deltaTime: number,
118
+ prevVelocity: number
119
+ ) {
120
+ if (deltaTime < 1) {
121
+ deltaTime = 1;
122
+ }
123
+ const speed = deltaSpace / deltaTime;
124
+ const depr = 0.5 + Math.min(deltaTime / VELOCITY_DEPR_FACTOR, 0.5);
125
+ return speed * depr + prevVelocity * (1 - depr);
126
+ }
127
+
98
128
  function handleMove(e: MouseEvent) {
99
- const { pageX, movementX, pageY, movementY } = e;
100
- e.preventDefault && e.preventDefault(); // prevent drag & drop behaviour from browser
129
+ const { pageX, pageY } = e;
130
+ if (e.cancelable) {
131
+ // prevent drag & drop behaviour from browser
132
+ e.preventDefault && e.preventDefault();
133
+ }
101
134
 
102
135
  set((state: GestureHandlersState) => {
136
+ function getDeltaSum(
137
+ currentPos: number,
138
+ initialPos: number,
139
+ prevPos: number
140
+ ): number {
141
+ if (
142
+ state.scrollLocked ||
143
+ Math.abs(currentPos - initialPos) >= minTouchDelta
144
+ ) {
145
+ state.scrollLocked = true;
146
+ return currentPos - prevPos;
147
+ }
148
+ return 0;
149
+ }
150
+
103
151
  const target =
104
152
  (containerRef && containerRef.current) || (e as any).target;
105
153
 
154
+ const deltaTime = Date.now() - state.startTime;
155
+
106
156
  const width = target ? target.offsetWidth : NaN;
107
- const xDelta = pageX - state.xInitial;
157
+ const xDelta = state.xDelta + getDeltaSum(pageX, state.xInitial, state.x);
108
158
  const xDeltaPercent = (xDelta * 100) / width;
159
+ const xVelocity = calcVelocity(xDelta, deltaTime, state.xVelocity);
109
160
 
110
161
  const height = target ? target.offsetHeight : NaN;
111
- const yDelta = pageY - state.yInitial;
162
+ const yDelta = state.yDelta + getDeltaSum(pageY, state.yInitial, state.y);
112
163
  const yDeltaPercent = (yDelta * 100) / height;
164
+ const yVelocity = calcVelocity(yDelta, deltaTime, state.yVelocity);
113
165
 
114
166
  const newState = {
115
167
  ...state,
@@ -117,12 +169,12 @@ export function gestureHandlers(
117
169
  xDeltaPercent,
118
170
  x: pageX,
119
171
  xPrev: state.x,
120
- xVelocity: movementX,
172
+ xVelocity,
121
173
  yDelta,
122
174
  yDeltaPercent,
123
175
  y: pageY,
124
176
  yPrev: state.y,
125
- yVelocity: movementY,
177
+ yVelocity,
126
178
  };
127
179
 
128
180
  return newState;
@@ -133,7 +185,10 @@ export function gestureHandlers(
133
185
 
134
186
  /* eslint-disable @typescript-eslint/no-use-before-define */
135
187
  function handleTouchMove(e: TouchEvent) {
136
- e.preventDefault();
188
+ if (e.cancelable) {
189
+ // prevent drag & drop behaviour from browser
190
+ e.preventDefault();
191
+ }
137
192
  handleMove(e.touches.item(0) as any);
138
193
  }
139
194