-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #63 from trinhthinh388/master
Publish packages
- Loading branch information
Showing
15 changed files
with
488 additions
and
26 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
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
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
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,27 @@ | ||
--- | ||
title: About | ||
--- | ||
|
||
# About React Awesome Components | ||
|
||
Hi guys! My name is [Thinh](https://github.com/trinhthinh388), I've been working as a Fronend Developer for more than {new Date().getFullYear() - 2020} years. During my career, there are so many | ||
components or UI logic that could be reused in the other projects. Thus, I've seen so many libraries having different names but just do exactly same thing, | ||
it makes me tired of choosing the library to best fit my needs. That's why **React Awesome Components** was born. | ||
|
||
With **React Awesome Components** you don't have to spend time on finding the next package to use in your project. Just install `@react-awesome/components`. | ||
|
||
One package to solve every problem. | ||
|
||
# Credits | ||
|
||
**React Awesome Components** is powered by these incredible open source projects: | ||
|
||
- https://reactjs.org | ||
- https://nextra.site | ||
- https://tailwindcss.com | ||
- https://www.npmjs.com/package/libphonenumber-js | ||
- https://www.npmjs.com/package/@uidotdev/usehooks | ||
|
||
## License | ||
|
||
The **React Awesome Components** project are licensed under the MIT license. |
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
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
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,90 @@ | ||
--- | ||
title: useClickOutside | ||
--- | ||
|
||
# useClickOutside | ||
|
||
**useClickOutside** triggers callback when user clicks on the outside area of an element. | ||
|
||
## Install | ||
|
||
To start using **useClickOutside**, you can install the `@react-awesome/use-click-outside` library or you can import it directly from `@react-awesome/components` if you have installed it before. In your project directory, run | ||
the following command to install the dependencies: | ||
|
||
```sh npm2yarn | ||
npm i @react-awesome/use-click-outside | ||
``` | ||
|
||
## Usage | ||
|
||
import { useState } from 'react' | ||
import { Container } from '../../components/Container' | ||
import { useClickOutside } from '@react-awesome/components' | ||
|
||
export const Example = () => { | ||
const [ref, setRef] = useState(null) | ||
const [state, setState] = useState(false) | ||
|
||
useClickOutside(ref, () => setState(false)) | ||
|
||
return ( | ||
|
||
<div className="mx-auto flex items-center justify-center"> | ||
<div ref={setRef}> | ||
<button | ||
onClick={() => setState(true)} | ||
className="relative inline-flex items-center justify-center p-0.5 mb-2 me-2 overflow-hidden text-sm font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-purple-600 to-blue-500 group-hover:from-purple-600 group-hover:to-blue-500 hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-blue-300 dark:focus:ring-blue-800" | ||
> | ||
<span className="relative px-5 py-2.5 transition-all ease-in duration-75 bg-white dark:bg-gray-900 rounded-md group-hover:bg-opacity-0"> | ||
Open modal | ||
</span> | ||
</button> | ||
<dialog | ||
open={state} | ||
className="px-6 py-5 bg-purple-400 border border-purple-600 rounded backdrop:bg-gray-50" | ||
> | ||
<p>Hey! click outside to close me.</p> | ||
</dialog> | ||
</div> | ||
</div> | ||
) } | ||
|
||
<Container> | ||
<Example /> | ||
</Container> | ||
|
||
```jsx | ||
import { useClickOutside } from '@react-awesome/use-click-outside' | ||
|
||
const Example = () => { | ||
const ref = useRef(null) | ||
const [state, setState] = useState(false) | ||
|
||
useClickOutside(ref.current, () => { | ||
setState(false) | ||
}) | ||
|
||
return ( | ||
<> | ||
<div ref={ref}> | ||
<button onClick={() => setState(true)}>Open modal</button> | ||
<dialog open={state}> | ||
<p>Hey! click outside to close me.</p> | ||
</dialog> | ||
</div> | ||
</> | ||
) | ||
} | ||
``` | ||
|
||
## Parameters | ||
|
||
The `useClickOutside` takes the following parameters: | ||
|
||
#### `inputEl` | ||
|
||
- Type: `HTMLInputElement` | ||
|
||
#### `callback` | ||
|
||
- Type: `(event: MouseEvent | undefined) => any` |
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
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
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
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
114 changes: 114 additions & 0 deletions
114
packages/phone-input/src/PhoneInput/PhoneInput.spec.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,114 @@ | ||
import { PhoneInput } from './PhoneInput' | ||
import { render } from '@testing-library/react' | ||
import userEvent from '@testing-library/user-event' | ||
import { act } from 'react-dom/test-utils' | ||
import '@testing-library/jest-dom' | ||
|
||
const user = userEvent.setup({ | ||
delay: 300, | ||
}) | ||
|
||
const Comp = () => { | ||
return ( | ||
<div id="container"> | ||
<PhoneInput /> | ||
</div> | ||
) | ||
} | ||
|
||
describe('PhoneInput', () => { | ||
it('should render phone input', async () => { | ||
const { container } = render(<Comp />) | ||
|
||
const input = container.querySelector('input') | ||
|
||
if (!input) { | ||
throw new Error('input is not a valid element.') | ||
} | ||
|
||
await act(async () => { | ||
input.focus() | ||
await user.keyboard('{a},{b},{c},{1},{2},{3}') | ||
}) | ||
|
||
expect(input.getAttribute('value')).toBe('+1 23') | ||
}) | ||
|
||
it('should show country select', async () => { | ||
const { container } = render(<Comp />) | ||
|
||
const input = container.querySelector('input') | ||
const countrySelect = container.querySelector('button') | ||
|
||
if (!input || !countrySelect) { | ||
throw new Error('input is not a valid element.') | ||
} | ||
|
||
await act(async () => { | ||
await user.click(countrySelect) | ||
}) | ||
|
||
expect( | ||
container.querySelector('ul[class*=selectList]')?.parentElement, | ||
).toBeVisible() | ||
}) | ||
|
||
it('should close country select when click outside', async () => { | ||
const { container } = render(<Comp />) | ||
|
||
const input = container.querySelector('input') | ||
const countrySelect = container.querySelector('div[class*=countrySelect]') | ||
|
||
if (!input || !countrySelect) { | ||
throw new Error('input is not a valid element.') | ||
} | ||
|
||
await act(async () => { | ||
await user.click(countrySelect) | ||
}) | ||
|
||
expect( | ||
container.querySelector('ul[class*=selectList]')?.parentElement, | ||
).toBeVisible() | ||
|
||
await act(async () => { | ||
await user.click(input) | ||
}) | ||
|
||
expect( | ||
container | ||
.querySelector('ul[class*=selectList]') | ||
?.parentElement?.classList.value.includes('hidden'), | ||
).toBe(true) | ||
}) | ||
|
||
it('should close the country select when click on country option', async () => { | ||
const { container } = render(<Comp />) | ||
|
||
const input = container.querySelector('input') | ||
const countrySelect = container.querySelector('div[class*=countrySelect]') | ||
const opt = container.querySelector('li') | ||
|
||
if (!input || !countrySelect || !opt) { | ||
throw new Error('input is not a valid element.') | ||
} | ||
|
||
await act(async () => { | ||
await user.click(countrySelect) | ||
}) | ||
|
||
expect( | ||
container.querySelector('ul[class*=selectList]')?.parentElement, | ||
).toBeVisible() | ||
|
||
await act(async () => { | ||
await user.click(opt) | ||
}) | ||
|
||
expect( | ||
container | ||
.querySelector('ul[class*=selectList]') | ||
?.parentElement?.classList.value.includes('hidden'), | ||
).toBe(true) | ||
}) | ||
}) |
Oops, something went wrong.