refactor(useResizable): refactor and fix useCallback dependency warning
This commit is contained in:
parent
fd0ecf579d
commit
387576c16c
7 changed files with 548 additions and 144 deletions
|
@ -44,6 +44,7 @@
|
|||
"@typescript-eslint/no-misused-promises": "off",
|
||||
"@typescript-eslint/consistent-type-assertions": "off",
|
||||
"import/no-absolute-path": "off",
|
||||
"@typescript-eslint/no-base-to-string": "off",
|
||||
"@typescript-eslint/no-unused-vars": "warn"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
"peerjs": "^1.5.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-markdown": "^9.0.0",
|
||||
"react-markdown": "^9.0.1",
|
||||
"react-nice-avatar": "^1.4.1",
|
||||
"react-use": "^17.4.0",
|
||||
"remark-breaks": "^4.0.0",
|
||||
|
@ -74,7 +74,7 @@
|
|||
"type-fest": "^4.7.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^18.4.0",
|
||||
"@commitlint/cli": "^18.4.1",
|
||||
"@commitlint/config-conventional": "^18.4.0",
|
||||
"@types/node": "^20.9.0",
|
||||
"@types/react": "^18.2.37",
|
||||
|
@ -96,13 +96,13 @@
|
|||
"lint-staged": "^15.1.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss": "^8.4.31",
|
||||
"prettier": "^3.0.3",
|
||||
"prettier": "^3.1.0",
|
||||
"rimraf": "^5.0.5",
|
||||
"tailwindcss": "^3.3.5",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"typescript": "^5.2.2",
|
||||
"webext-bridge": "^6.0.1",
|
||||
"wxt": "^0.9.0"
|
||||
"wxt": "^0.10.0"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{js,jsx,ts,tsx}": "eslint --fix"
|
||||
|
|
573
pnpm-lock.yaml
573
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
@ -12,8 +12,8 @@ export default defineContentScript({
|
|||
matches: ['*://*.example.com/*', '*://*.google.com/*', '*://*.v2ex.com/*'],
|
||||
async main(ctx) {
|
||||
const store = Remesh.store({
|
||||
externs: [StorageImpl],
|
||||
inspectors: [RemeshLogger()]
|
||||
externs: [StorageImpl]
|
||||
// inspectors: [RemeshLogger()]
|
||||
})
|
||||
|
||||
const ui = await createContentScriptUi(ctx, {
|
||||
|
|
|
@ -7,7 +7,7 @@ export interface AppContainerProps {
|
|||
const AppContainer: FC<AppContainerProps> = ({ children }) => {
|
||||
const { size, ref } = useResizable({
|
||||
initSize: 375,
|
||||
maxSize: 1000,
|
||||
maxSize: 750,
|
||||
minSize: 375,
|
||||
direction: 'left'
|
||||
})
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { useCallback, useRef, useState } from 'react'
|
||||
import { isInRange } from '@/utils'
|
||||
|
||||
export interface ResizableOptions {
|
||||
minSize: number
|
||||
|
@ -12,73 +13,79 @@ const useResizable = (options: ResizableOptions) => {
|
|||
|
||||
const [size, setSize] = useState(initSize)
|
||||
|
||||
const [position, setPosition] = useState(0)
|
||||
const position = useRef(0)
|
||||
|
||||
const [isMove, setIsMove] = useState(false)
|
||||
const isMove = useRef(false)
|
||||
|
||||
const directionXY = direction === 'left' || direction === 'right' ? 'X' : 'Y'
|
||||
const isHorizontal = direction === 'left' || direction === 'right'
|
||||
|
||||
const handleStart = (e: MouseEvent) => {
|
||||
const { screenY, screenX } = e
|
||||
setIsMove(true)
|
||||
setPosition(directionXY === 'Y' ? screenY : screenX)
|
||||
document.documentElement.style.userSelect = 'none'
|
||||
document.documentElement.style.cursor = directionXY === 'Y' ? 'ns-resize' : 'ew-resize'
|
||||
}
|
||||
const handleEnd = () => {
|
||||
setIsMove(false)
|
||||
document.documentElement.style.cursor = ''
|
||||
document.documentElement.style.userSelect = ''
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const handleMove = (e: MouseEvent) => {
|
||||
if (isMove) {
|
||||
console.log('move')
|
||||
const handleMove = useCallback(
|
||||
(e: MouseEvent) => {
|
||||
if (isMove.current) {
|
||||
const { screenY, screenX } = e
|
||||
let delta = 0
|
||||
switch (direction) {
|
||||
case 'left':
|
||||
delta = position - screenX
|
||||
delta = position.current - screenX
|
||||
break
|
||||
case 'right':
|
||||
delta = screenX - position
|
||||
delta = screenX - position.current
|
||||
break
|
||||
case 'top':
|
||||
delta = position - screenY
|
||||
delta = position.current - screenY
|
||||
break
|
||||
case 'bottom':
|
||||
delta = screenY - position
|
||||
delta = screenY - position.current
|
||||
break
|
||||
}
|
||||
|
||||
const newSize = size + delta
|
||||
if (size !== newSize && newSize >= minSize && newSize <= maxSize) {
|
||||
setSize(newSize)
|
||||
if (isInRange(newSize, minSize, maxSize)) {
|
||||
position.current = isHorizontal ? screenX : screenY
|
||||
}
|
||||
if (newSize !== size) {
|
||||
setSize(clamp(newSize, minSize, maxSize))
|
||||
}
|
||||
} else {
|
||||
document.removeEventListener('mousemove', handleMove)
|
||||
}
|
||||
}
|
||||
},
|
||||
[direction, isHorizontal, maxSize, minSize, size]
|
||||
)
|
||||
|
||||
document.addEventListener('mousemove', handleMove)
|
||||
return () => {
|
||||
document.removeEventListener('mousemove', handleMove)
|
||||
}
|
||||
}, [isMove])
|
||||
const handleEnd = useCallback(() => {
|
||||
isMove.current = false
|
||||
document.documentElement.style.cursor = ''
|
||||
document.documentElement.style.userSelect = ''
|
||||
}, [])
|
||||
|
||||
const handleStart = useCallback(
|
||||
(e: MouseEvent) => {
|
||||
const { screenY, screenX } = e
|
||||
isMove.current = true
|
||||
position.current = isHorizontal ? screenX : screenY
|
||||
document.documentElement.style.userSelect = 'none'
|
||||
document.documentElement.style.cursor = isHorizontal ? 'ew-resize' : 'ns-resize'
|
||||
},
|
||||
[isHorizontal]
|
||||
)
|
||||
|
||||
const ref = useRef<HTMLElement | null>(null)
|
||||
const setRef = useCallback((node: HTMLElement | null) => {
|
||||
if (ref.current) {
|
||||
ref.current.removeEventListener('mousedown', handleStart)
|
||||
document.removeEventListener('mouseup', handleEnd)
|
||||
}
|
||||
if (node) {
|
||||
node.addEventListener('mousedown', handleStart)
|
||||
document.addEventListener('mouseup', handleEnd)
|
||||
}
|
||||
ref.current = node
|
||||
}, [])
|
||||
|
||||
// Watch ref: https://medium.com/@teh_builder/ref-objects-inside-useeffect-hooks-eb7c15198780
|
||||
const setRef = useCallback(
|
||||
(node: HTMLElement | null) => {
|
||||
if (ref.current) {
|
||||
ref.current.removeEventListener('mousedown', handleStart)
|
||||
document.removeEventListener('mouseup', handleEnd)
|
||||
document.removeEventListener('mousemove', handleMove)
|
||||
}
|
||||
if (node) {
|
||||
node.addEventListener('mousedown', handleStart)
|
||||
document.addEventListener('mouseup', handleEnd)
|
||||
document.addEventListener('mousemove', handleMove)
|
||||
}
|
||||
ref.current = node
|
||||
},
|
||||
[handleEnd, handleMove, handleStart]
|
||||
)
|
||||
|
||||
return { size, ref: setRef }
|
||||
}
|
||||
|
|
|
@ -22,6 +22,9 @@ export const createElement = <T extends Element>(template: string) => {
|
|||
export const chunk = <T = any>(array: T[], size: number) =>
|
||||
Array.from({ length: Math.ceil(array.length / size) }, (_v, i) => array.slice(i * size, i * size + size))
|
||||
|
||||
export const clamp = (number: number, min: number, max: number) => Math.min(Math.max(number, min), max)
|
||||
export const isInRange = (number: number, min: number, max: number) => number >= min && number <= max
|
||||
|
||||
export const getWebSiteInfo = (): WebSiteInfo => {
|
||||
return {
|
||||
host: document.location.host,
|
||||
|
|
Loading…
Reference in a new issue