Skip to content

Commit

Permalink
th-108: Google autocomplete (BinaryStudioAcademy#113)
Browse files Browse the repository at this point in the history
* th-48: + portal

* th-48: + modal

* th-48: + react google autocomplete

* th-48: + location input

* th-48: * fix

---------

Co-authored-by: Pavel Sukhinin <[email protected]>
  • Loading branch information
DmytroVoronkov and PavloSukhinin committed Sep 4, 2023
1 parent 66ffe45 commit 3017d50
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 2 deletions.
5 changes: 3 additions & 2 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@
"modern-normalize": "2.0.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-google-autocomplete": "2.7.3",
"react-hook-form": "7.43.5",
"react-redux": "8.1.2",
"react-router-dom": "6.8.2",
"react-select": "5.7.4",
"react-toastify": "9.1.3",
"socket.io-client": "4.7.2",
"react-select": "5.7.4"
"socket.io-client": "4.7.2"
},
"devDependencies": {
"@types/google.maps": "3.54.0",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/libs/components/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export { Icon } from './icon/icon.js';
export { Image } from './image/image.js';
export { Input } from './input/input.js';
export { Link } from './link/link.js';
export { LocationInput } from './location-input/location-input.js';
export { Modal } from './modal/modal.js';
export { Notification } from './notification/notification.js';
export { Pagination } from './pagination/pagination.js';
Expand Down
71 changes: 71 additions & 0 deletions frontend/src/libs/components/location-input/location-input.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import GooglePlacesAutocomplete from 'react-google-autocomplete';
import {
type Control,
type FieldErrors,
type FieldPath,
type FieldValues,
} from 'react-hook-form';

import { getValidClassNames } from '~/libs/helpers/helpers.js';
import { useFormController } from '~/libs/hooks/hooks.js';
import { config } from '~/libs/packages/config/config.js';

import styles from './styles.module.scss';

type Properties<T extends FieldValues> = {
control: Control<T, null>;
errors: FieldErrors<T>;
label?: string;
name: FieldPath<T>;
placeholder?: string;
isDisabled?: boolean;
};

const LocationInput = <T extends FieldValues>({
control,
errors,
label = '',
name,
placeholder = '',
isDisabled,
}: Properties<T>): JSX.Element => {
const { field } = useFormController({ name, control });

const error = errors[name]?.message;
const hasError = Boolean(error);
const hasValue = Boolean(field.value);
const hasLabel = Boolean(label);
const inputStyles = [
styles.input,
hasValue && styles.filled,
isDisabled && styles.disabled,
hasError && styles.error,
];

return (
<label className={styles.inputComponentWrapper}>
{hasLabel && <span className={styles.label}>{label}</span>}
<span className={styles.inputWrapper}>
<GooglePlacesAutocomplete
{...field}
type="text"
placeholder={placeholder}
className={getValidClassNames(...inputStyles)}
disabled={isDisabled}
apiKey={config.ENV.API.GOOGLE_MAPS_API_KEY}
/>
</span>

<span
className={getValidClassNames(
styles.errorMessage,
hasError && styles.visible,
)}
>
{error as string}
</span>
</label>
);
};

export { LocationInput };
90 changes: 90 additions & 0 deletions frontend/src/libs/components/location-input/styles.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
@import "src/assets/css/vars.scss";

$error-font-size: 12px;
$line-height-coefficient: 1.54;
$error-message-height: calc($error-font-size * $line-height-coefficient);

.inputComponentWrapper {
display: flex;
flex-direction: column;
max-width: 327px;
color: $grey-dark;
font-weight: $font-weight-semibold;
font-size: 16px;
font-family: $font-family;
font-style: normal;
line-height: 140.5%;
}

.input {
width: 100%;
padding: 8px;
color: $grey-dark;
font-weight: $font-weight-regular;
font-size: 14px;
font-family: $font-family;
font-style: normal;
line-height: normal;
background: $white;
border: 2px solid $grey-light;
border-radius: 4px;
outline: none;
}

.input.filled {
color: $black;
}

.input:focus {
border-color: $blue;
box-shadow:
0 2px 4px -2px rgb(0 44 132 / 6%),
0 4px 8px -2px rgb(0 85 255 / 16%);
}

.input.disabled {
color: $grey-light;
}

.input.error {
border-color: $red;
}

.errorMessage {
display: block;
flex-grow: 1;
width: 100%;
height: $error-message-height;
margin-top: 5px;
overflow: hidden;
color: $red-dark;
font-weight: $font-weight-regular;
font-size: $error-font-size;
font-family: $font-family;
line-height: normal;
white-space: nowrap;
text-align: end;
text-overflow: ellipsis;
visibility: hidden;
}

.visible {
visibility: visible;
}

.label {
width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}

.disabled .label {
color: $grey-light;
}

.inputWrapper {
position: relative;
display: block;
width: 100%;
}
18 changes: 18 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 3017d50

Please sign in to comment.