-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ (@hzcore/hook-press) add hook-press
Ref GH-24
- Loading branch information
Showing
5 changed files
with
251 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Change Log | ||
|
||
All notable changes to this project will be documented in this file. | ||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
--- | ||
name: usePress | ||
menu: Hooks | ||
route: /use-press | ||
--- | ||
|
||
import {Playground} from 'docz'; | ||
import {useState} from 'react'; | ||
import usePress from '@hzcore/hook-press'; | ||
|
||
# usePress | ||
|
||
A [hook] that tracks events when the user presses the mouse button over a component. | ||
|
||
Main features: | ||
- Determines when an element is being pressed | ||
- Records the number of times an element has been pressed | ||
- Consumes a callback handler when an element is pressed | ||
|
||
--- | ||
|
||
## Installation | ||
|
||
```shell | ||
yarn add @hzcore/hook-press | ||
``` | ||
|
||
--- | ||
|
||
## Options | ||
```js | ||
const {isPressed, pressCount, pressibleEl, pressProps} = usePress({defaultCount, handler}); | ||
|
||
interface UsePressReturn { | ||
// If element is pressed | ||
isPressed: boolean; | ||
|
||
// Number of how many times the element was pressed | ||
pressCount: number; | ||
|
||
// Listeners of the press event | ||
pressProps: PressPropsReturn; | ||
|
||
// Element reference | ||
pressibleEl: object; | ||
} | ||
|
||
interface UsePressProps { | ||
// Default count number to start from, optional, default = 0 | ||
defaultCount: number; | ||
|
||
// Direct handler attached to the element, optional, default = null | ||
handler: (args: {isPressed: boolean, pressCount: number}) => void; | ||
} | ||
``` | ||
|
||
--- | ||
|
||
## Usage | ||
|
||
### Simple Usage | ||
```js | ||
export default Button = () => { | ||
const {isPressed, pressProps} = usePress(); | ||
return ( | ||
<button | ||
style={{background: isPressed ? 'orange' : 'gray'}} | ||
{...pressProps} | ||
> | ||
Press Me | ||
</button> | ||
); | ||
} | ||
``` | ||
|
||
### Using Count | ||
<Playground> | ||
{() => { | ||
|
||
const plainStyles = { | ||
color: 'white', | ||
padding: '10px 20px', | ||
fontSize: '16px', | ||
borderRadius: '3px', | ||
outline: 'none', | ||
cursor: 'pointer', | ||
} | ||
|
||
const Button = () => { | ||
|
||
const {isPressed, pressCount, pressProps} = usePress({defaultCount: 7}); | ||
|
||
return ( | ||
<> | ||
<button | ||
style={{ | ||
background: isPressed ? '#f38230' : '#43454d', | ||
...plainStyles, | ||
}} | ||
{...pressProps} | ||
ref={null} | ||
> | ||
Press Me | ||
</button> | ||
<p>I have been pressed {pressCount} time{pressCount > 1 ? 's': ''}.</p> | ||
</> | ||
); | ||
} | ||
|
||
return <Button />; | ||
}} | ||
</Playground> | ||
|
||
|
||
### Using Handlers | ||
<Playground> | ||
{() => { | ||
|
||
const plainStyles = { | ||
color: 'white', | ||
padding: '10px 20px', | ||
fontSize: '16px', | ||
borderRadius: '3px', | ||
outline: 'none', | ||
cursor: 'pointer', | ||
} | ||
|
||
const Button = () => { | ||
// Saving the current color of the button | ||
const [color, setColor] = useState('#43454d'); | ||
|
||
// Generate and set a random color for the button when clicked | ||
const handleClick = (event, args) => { | ||
const newColor = '#'+(Math.random()*0xFFFFFF<<0).toString(16); | ||
setColor(newColor); | ||
} | ||
|
||
// Setting press features with a default count number as 1 | ||
// and attaching the handler specific to this press | ||
const {pressCount, pressProps} = usePress({handler: handleClick}); | ||
|
||
return ( | ||
<> | ||
<button | ||
style={{ | ||
background: color, | ||
...plainStyles, | ||
}} | ||
{...pressProps} | ||
> | ||
Press Me | ||
</button> | ||
<p>I have been pressed {pressCount} time{pressCount > 1 ? 's': ''}.</p> | ||
</> | ||
) | ||
} | ||
|
||
return <Button />; | ||
}} | ||
</Playground> | ||
|
||
|
||
|
||
|
||
[hook]: https://reactjs.org/docs/hooks-overview.html |
14 changes: 14 additions & 0 deletions
14
packages/behaviors/hzcore-hook-press/__tests__/usePress_test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
/* eslint-env jest, browser */ | ||
import React from 'react'; | ||
import {render} from 'react-testing-library'; | ||
import usePress from '../src'; | ||
|
||
test('usePress is implemented', () => { | ||
const PressUser = (): JSX.Element => { | ||
usePress(); | ||
return <div />; | ||
} | ||
const {container} = render(<PressUser />); | ||
expect(container).toBeInTheDocument(); | ||
throw new Error('implement usePress and write some tests!'); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"name": "@hzcore/hook-press", | ||
"version": "0.0.1", | ||
"main": "cjs/index.js", | ||
"module": "es/index.js", | ||
"typings": "src/index.tsx", | ||
"license": "MIT", | ||
"publishConfig": { | ||
"registry": "http://npmregistry.hzdg.com" | ||
}, | ||
"files": [ | ||
"cjs", | ||
"es", | ||
"src", | ||
"!*/__test*" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import {useState, useEffect, useRef} from 'react'; | ||
|
||
interface UsePressReturn { | ||
isPressed: boolean; | ||
pressCount: number; | ||
pressProps: { | ||
onMouseDown: () => void; | ||
onMouseUp: () => void; | ||
}; | ||
pressibleEl: React.MutableRefObject<JSX.Element | null>; | ||
} | ||
|
||
const usePress = (props: { | ||
defaultCount: number; | ||
handler: (args: {isPressed: boolean; pressCount: number}) => void | null; | ||
}): UsePressReturn => { | ||
const {defaultCount, handler} = props; | ||
const [isPressed, setIsPressed] = useState(false); | ||
const [pressCount, setPressCount] = useState(defaultCount); | ||
const pressibleEl = useRef(null); | ||
|
||
const pressProps = { | ||
ref: pressibleEl, | ||
onMouseDown: () => { | ||
if (!isPressed) { | ||
setIsPressed(true); | ||
setPressCount(pressCount + 1); | ||
} | ||
}, | ||
onMouseUp: () => { | ||
if (isPressed) { | ||
setIsPressed(false); | ||
} | ||
}, | ||
}; | ||
|
||
useEffect(() => { | ||
if (handler && isPressed) { | ||
handler.call(pressibleEl, {isPressed, pressCount}); | ||
} | ||
}, [isPressed, pressCount]); | ||
|
||
return {isPressed, pressCount, pressProps, pressibleEl}; | ||
}; | ||
|
||
usePress.defaultProps = { | ||
defaultCount: 0, | ||
handler: null, | ||
}; | ||
|
||
export default usePress; |