npm package: @mwid/react-country-picker
Description: <p float="left">   <img src="./assets/search.png" width="44%" align="middle" />   <img src="./assets/demo.gif" width="49%" align="middle" /> </p>
Author: Matthew Widdicombe
Latest version: 0.1.0

# 🌐 React Country Picker

<p float="left">
  <img src="./assets/search.png" width="44%" align="middle" />
  <img src="./assets/demo.gif" width="49%" align="middle" />
</p>

A country picker component with real-time autocomplete, built with React.

## Installation

```sh
# npm
npm install @mwid/react-country-picker

# Yarn
yarn add @mwid/react-country-picker

# pnpm
pnpm add @mwid/react-country-picker
```

## Usage

Import:

```typescript
// TypeScript / ESModules
import { CountryPicker } from "@mwid/react-country-picker";

// CommonJS
const { CountryPicker } = require("@mwid/react-country-picker");
```

Create a callback for when a country is selected:

```typescript
const onSelect = useCallback(() => {
	// Do something
}, []);
```

Add the `CountryPicker` component to your JSX:

```typescript
<CountryPicker onSelect={onSelect} />
```

### Props

| Property   | Type                         | Default | Description                                              |
| ---------- | ---------------------------- | ------- | -------------------------------------------------------- |
| `onSelect` | `(country: Country) => void` |         | Called when a country is selected from the country list. |

Where `Country` is:

```typescript
interface Country {
	officialName: string;
	commonName: string;
	flagSvgUrl: string;
}
```

## Architecture

### Project Structure

| `src/`       | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `api`        | All API requests and their request and response body interfaces.<br><br>Each request should be prefixed with its HTTP method (Eg, `GET /countries/all` -> `getAllCountries`) and their request/responses named similarly (Eg, `getAllCountriesRequest` and `getAllCountriesResponse`).                                                                                                                                                                                                                                                                                                                      |
| `components` | React components.<br><br>Each component resides in its own directory, and sub-components that _only it_ uses are nested under it.<br><br>[Storybook stories](https://storybook.js.org/docs/react/get-started/whats-a-story) are placed in `component.stories.tsx`, unit tests are placed in `component.test.tsx` and [styled-components primitives](https://styled-components.com/) are placed in `component.style.tsx`.                                                                                                                                                                                    |
| `config`     | Configuration-related items (that may be changed via environment variables) and constant values.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `hooks`      | Custom hooks shared across the entire component.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `lib`        | Re-exports of library functions and factories. Eg, create a database connection instance.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `slices`     | [Redux state slices.](https://redux-toolkit.js.org/usage/usage-guide#creating-slices-of-state)<br><br>[Actions](https://redux.js.org/tutorials/fundamentals/part-2-concepts-data-flow#actions) are placed in `slice.actions.ts`, [reducers](https://redux.js.org/tutorials/fundamentals/part-2-concepts-data-flow#reducers) are placed in `slice.reducer.ts`, [selectors](https://redux.js.org/tutorials/fundamentals/part-2-concepts-data-flow#selectors) are placed in `slice.selectors.ts` and [entity adapters](https://redux-toolkit.js.org/api/createEntityAdapter) are placed in `entity.entity.ts`. |
| `test`       | Test-specific configuration and setup.<br><br>Fixtures define unchanging mock data used across multiple tests.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `types`      | TypeScript types used across the component to define a contract on the structure of data.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `utils`      | Reusable utility functions and types.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |

### Technology

#### Tooling

- [Storybook](https://storybook.js.org/) for component prototyping and development.
- [TypeScript](https://www.typescriptlang.org/) for type-checking, type-safety and builds.
- [Prettier](https://prettier.io/) for code formatting.
- [ESLint](https://eslint.org/) for linting and error-checking.
- [Jest](https://jestjs.io/), [React Testing Library](https://testing-library.com/) and [nock](https://github.com/nock/nock) for unit and integration testing.

#### Front-end

- [React](https://reactjs.org/) for user interface, state and components.
- [Redux](https://redux.js.org/) with [Redux Toolkit](https://redux-toolkit.js.org/) for application data management.
- [Styled Components](https://styled-components.com/) for component styling.
- [axios](https://axios-http.com/) for making web requests.
- [react-window](https://react-window.now.sh/) for performant large list rendering.

## Local Development

Install [Node](https://nodejs.org/):

```sh
curl -L https://git.io/n-install | bash
n auto
```

Install dependencies:

```sh
npm i
```

Run unit and integration tests:

```sh
npm t
```

Develop in [Storybook](https://storybook.js.org/):

```sh
npm run storybook
```

Build for production:

```sh
npm run build
```

### npm Scripts

| Script            | Description                                |
| ----------------- | ------------------------------------------ |
| `build`           | Build code for production with TypeScript. |
| `format:check`    | Check all code formatting with Prettier.   |
| `format:write`    | Fix all code formatting with Prettier.     |
| `lint`            | Lint all code with ESLint.                 |
| `test`            | Run all unit and integration tests.        |
| `storybook`       | Start the Storybook development server.    |
| `storybook:build` | Build Storybook for publishing.            |

## License

This project is licensed under the MIT license.