@placekit/autocomplete-react
Advanced tools
Comparing version 1.4.1 to 1.5.0
@@ -1,2 +0,2 @@ | ||
/*! @placekit/autocomplete-react v1.4.1 | © placekit.io | MIT license | https://github.com/placekit/autocomplete-react#readme */ | ||
/*! @placekit/autocomplete-react v1.5.0 | © placekit.io | MIT license | https://github.com/placekit/autocomplete-react#readme */ | ||
'use strict'; | ||
@@ -25,3 +25,3 @@ | ||
const has = Object.prototype.hasOwnProperty; | ||
const dequal = (foo, bar) => { | ||
function dequal(foo, bar) { | ||
let ctor; | ||
@@ -50,6 +50,6 @@ let len; | ||
return foo !== foo && bar !== bar; | ||
}; | ||
} | ||
// prevent re-renders when options prop is an object literal | ||
const useStableValue = value => { | ||
function useStableValue(value) { | ||
const [stableValue, setStableValue] = React.useState(() => value); | ||
@@ -60,3 +60,3 @@ if (!dequal(stableValue, value)) { | ||
return stableValue; | ||
}; | ||
} | ||
@@ -104,3 +104,6 @@ const usePlaceKit = (apiKey, options = {}) => { | ||
} = stableOptions || {}; | ||
client.on('open', handlers?.onOpen).on('close', handlers?.onClose).on('results', handlers?.onResults).on('pick', handlers?.onPick).on('error', handlers?.onError).on('dirty', handlers?.onDirty).on('empty', handlers?.onEmpty).on('freeForm', handlers?.freeForm).on('geolocation', handlers?.onGeolocation).on('state', newState => { | ||
client.on('open', handlers?.onOpen).on('close', handlers?.onClose).on('results', handlers?.onResults).on('pick', handlers?.onPick).on('error', handlers?.onError).on('dirty', handlers?.onDirty).on('empty', handlers?.onEmpty).on('freeForm', handlers?.freeForm).on('geolocation', handlers?.onGeolocation).on('state', ({ | ||
...newState | ||
}) => { | ||
// spread to remove `client.state` reference | ||
setState(newState); | ||
@@ -112,4 +115,6 @@ if (handlers?.onState) { | ||
// inject initial state from client | ||
setState(client.state); | ||
// inject initial state from client (spread to remove `client.state` reference) | ||
setState({ | ||
...client.state | ||
}); | ||
}, [client, stableOptions]); | ||
@@ -128,2 +133,3 @@ return { | ||
options, | ||
onClient, | ||
onOpen, | ||
@@ -161,2 +167,9 @@ onClose, | ||
// update default value (only if untouched) | ||
React.useEffect(() => { | ||
if (client && !client.state.dirty) { | ||
client.setValue(inputProps.defaultValue); | ||
} | ||
}, [inputProps.defaultValue, client]); | ||
// forward ref from `target` | ||
@@ -172,2 +185,9 @@ React.useEffect(() => { | ||
}, [target.current]); | ||
// pass client to `onClient` when it updates | ||
React.useEffect(() => { | ||
if (onClient?.call) { | ||
onClient(client); | ||
} | ||
}, [client, onClient]); | ||
return /*#__PURE__*/React.createElement("div", { | ||
@@ -227,2 +247,3 @@ className: ['pka-input', className].filter(c => c).join(' ') | ||
// event handlers | ||
onClient: PropTypes.func, | ||
onOpen: PropTypes.func, | ||
@@ -229,0 +250,0 @@ onClose: PropTypes.func, |
@@ -1,2 +0,2 @@ | ||
/*! @placekit/autocomplete-react v1.4.1 | © placekit.io | MIT license | https://github.com/placekit/autocomplete-react#readme */ | ||
/*! @placekit/autocomplete-react v1.5.0 | © placekit.io | MIT license | https://github.com/placekit/autocomplete-react#readme */ | ||
import type { PKAClient, PKAHandlers, PKAOptions, PKAState } from '@placekit/autocomplete-js'; | ||
@@ -22,2 +22,3 @@ | ||
options?: Omit<PKAOptions, 'target'>; | ||
onClient: (client?: PKAClient) => void; | ||
} & Partial<Handlers> & React.HTMLProps<HTMLInputElement>; | ||
@@ -24,0 +25,0 @@ |
{ | ||
"name": "@placekit/autocomplete-react", | ||
"version": "1.4.1", | ||
"version": "1.5.0", | ||
"author": "PlaceKit <support@placekit.io>", | ||
@@ -40,6 +40,6 @@ "description": "PlaceKit Autocomplete React library", | ||
"devDependencies": { | ||
"@babel/core": "^7.22.1", | ||
"@babel/preset-react": "^7.22.3", | ||
"@babel/core": "^7.22.5", | ||
"@babel/preset-react": "^7.22.5", | ||
"@rollup/plugin-babel": "^6.0.3", | ||
"@rollup/plugin-commonjs": "^25.0.0", | ||
"@rollup/plugin-commonjs": "^25.0.1", | ||
"@rollup/plugin-node-resolve": "^15.1.0", | ||
@@ -51,8 +51,8 @@ "eslint": "^8.42.0", | ||
"rimraf": "^5.0.1", | ||
"rollup": "^3.24.0", | ||
"rollup": "^3.25.1", | ||
"rollup-plugin-copy": "^3.4.0" | ||
}, | ||
"dependencies": { | ||
"@placekit/autocomplete-js": "^1.4.1", | ||
"@types/react": "^18.2.9", | ||
"@placekit/autocomplete-js": "^1.5.0", | ||
"@types/react": "^18.2.12", | ||
"prop-types": "^15.8.1" | ||
@@ -59,0 +59,0 @@ }, |
@@ -20,3 +20,3 @@ <h1 align="center"> | ||
<a href="#-custom-hook">Custom hook</a> • | ||
<a href="#-avoid-re-renders">Avoid re-renders</a> • | ||
<a href="#-Troubleshoot">Troubleshoot</a> • | ||
<a href="#%EF%B8%8F-license">License</a> | ||
@@ -94,2 +94,3 @@ </p> | ||
// event handlers (⚠️ use useCallback, see notes) | ||
onClient={(client) => {}} | ||
onOpen={() => {}} | ||
@@ -116,11 +117,10 @@ onClose={() => {}} | ||
Please refer to [PlaceKit Autocomplete JS](https://github.com/placekit/autocomplete-js) documentation for more details about the options. | ||
Please refer to [PlaceKit Autocomplete JS](https://github.com/placekit/autocomplete-js#pkaoptions) documentation for more details about the options. | ||
Some additional notes: | ||
- The `<input>` is using React `ref` attribute. It is therefore an [uncontrolled component](https://reactjs.org/docs/uncontrolled-components.html) and should be treated as such. | ||
- If you want to customize the input style, create your own component using our [custom hook](#-custom-hook). You can reuse our component as a base. | ||
- If you want to customize the suggestions list style, don't import our stylesheet and create your own following [PlaceKit Autocomplete JS](https://github.com/placekit/autocomplete-js#-customize) documentation. | ||
- Handlers are exposed directly as properties for ease of access. | ||
- It's recommended to memoize handler functions with `useCallback`, see [Avoid re-renders](#-avoid-re-renders). | ||
- ⚠️ Passing a non-empty value to `defaultValue` will automatically trigger a first search request when the user focuses the input. | ||
- It's recommended to memoize handler functions with `useCallback`, see [Avoid re-renders](#avoid-re-renders). | ||
- ⚠️ The `<input>` it is an **uncontrolled component**. See [dynamic default value](#dynamic-default-value). | ||
@@ -137,2 +137,3 @@ ## 🪝 Custom hook | ||
countries: ['fr'], | ||
// other options | ||
}); | ||
@@ -146,7 +147,7 @@ | ||
Please refer to [PlaceKit Autocomplete JS](https://github.com/placekit/autocomplete-js) documentation for more details about the options. | ||
Please refer to [PlaceKit Autocomplete JS](https://github.com/placekit/autocomplete-js#pkaoptions) documentation for more details about the options. | ||
Some additional notes: | ||
- `target` is a React `ref` object. | ||
- The handlers can be passed through `options.handlers`, but also be set with `client.on()` (better use a `useState()` in that case). | ||
- The handlers can be passed through `options.handlers`, but also be set with `client.on()` (better use a `useState()` in that case) except for `onClient` which is specific to Autocomplete React. | ||
- `state` exposes stateless client properties (`dirty`, `empty`, `freeForm`, `geolocation`) as stateful ones. | ||
@@ -156,4 +157,42 @@ | ||
## 🔁 Avoid re-renders | ||
## 🚒 Troubleshoot | ||
### Access Autocomplete JS client from parent component | ||
Use the extra `onClient` handler to access the client from the parent component: | ||
```jsx | ||
import { PlaceKit } from '@placekit/autocomplete-react'; | ||
import { useEffect, useState } from 'react'; | ||
const MyComponent = (props) => { | ||
const [client, setClient] = useState(); | ||
useEffect( | ||
() => { | ||
if (client) { | ||
// do something | ||
} | ||
}, | ||
[client] | ||
); | ||
return ( | ||
<PlaceKit | ||
apiKey="<your-api-key>" | ||
onClient={setClient} | ||
options={{ | ||
countries: ['fr'] | ||
}} | ||
/> | ||
); | ||
}; | ||
``` | ||
`onClient` is an exception for handlers: it's **specific to Autocomplete React** and isn't passed in `options.handlers` to Autocomplete JS, so updating it doesn't trigger `pka.configure()`. | ||
Please refer to [PlaceKit Autocomplete JS](https://github.com/placekit/autocomplete-js#-reference) documentation for more details about the client methods. | ||
### Avoid re-renders | ||
Because of the way React works, object/array/function literals are always considered fresh values and may cause unnecessary re-renders. | ||
@@ -197,4 +236,12 @@ | ||
### Dynamic default value | ||
The `<input>` is an [**uncontrolled component**](https://react.dev/learn/sharing-state-between-components#controlled-and-uncontrolled-components) and should be treated as such. Making it controlled may cause typing glitches because React state in controlled components can conflict with Autocomplete JS internal state management. | ||
You can dyamically set a `defaultValue` and it'll update the input value as long as it has not been touched by the user (`state.dirty === false`). | ||
⚠️ Passing a non-empty value to `defaultValue` will automatically trigger a first search request when the user focuses the input. | ||
## ⚖️ License | ||
PlaceKit Autocomplete React Library is an open-sourced software licensed under the [MIT license](./LICENSE). |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
26484
510
241
0
Updated@types/react@^18.2.12