@lebonplan/shared-address-selector
v1.3.3
Published
React address selector component with GPS geolocation and Google Places autocomplete using Places API (New)
Maintainers
Readme
@lebonplan/shared-address-selector
Package React réutilisable pour la sélection d'adresse avec géolocalisation GPS et recherche Google Places.
Utilise Places API (New) pour l'autocomplete et Geocoding API v3 (version standard) pour le reverse geocoding.
Installation
pnpm add @lebonplan/shared-address-selectorDépendances requises
- React 19.x
- React DOM 19.x
- Google Maps API Key (à configurer dans votre application)
Utilisation
Composant principal : AddressSelectorModal
import { AddressSelectorModal, AddressSelectionData } from '@lebonplan/shared-address-selector';
function MyComponent() {
const [isOpen, setIsOpen] = useState(false);
const [selectedAddress, setSelectedAddress] = useState<AddressSelectionData | null>(null);
const handleComplete = (address: AddressSelectionData) => {
setSelectedAddress(address);
// Transformer en CreateAddressDto pour l'API
const dto = {
placeId: address.googlePlaceId,
latitude: address.latitude, // Toujours présent
longitude: address.longitude, // Toujours présent
accuracy: address.accuracy, // Toujours présent (GPS réel ou 50m)
displayAddress: address.displayAddress,
isCustomDisplayAddress: address.isCustomDisplayAddress,
};
// Envoyer à POST /addresses
};
return (
<>
<button onClick={() => setIsOpen(true)}>Sélectionner une adresse</button>
<AddressSelectorModal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
onComplete={handleComplete}
apiKey={process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY || ''}
maxAccuracy={50} // Optionnel, 50m par défaut
/>
</>
);
}Flux utilisateur
Le composant suit un flux privilégiant la géolocalisation GPS :
- Ouverture automatique GPS : À l'ouverture du modal, une tentative de géolocalisation GPS est lancée automatiquement
- Vérification de précision : Si la précision est supérieure à
maxAccuracy(50m par défaut), l'utilisateur est invité à réessayer ou rechercher manuellement - En cas d'échec GPS : Si la géolocalisation échoue (permission, timeout, etc.), l'utilisateur peut :
- Réessayer la géolocalisation GPS
- Rechercher manuellement via autocomplete Google Places
- Confirmation : Une fois l'adresse obtenue (GPS ou recherche), l'utilisateur peut modifier l'adresse d'affichage avant de confirmer
Composant d'affichage : AddressDisplay
import { AddressDisplay, AddressSelectionData } from '@lebonplan/shared-address-selector';
function MyComponent() {
const [address, setAddress] = useState<AddressSelectionData | null>(null);
const [isModalOpen, setIsModalOpen] = useState(false);
return (
<AddressDisplay
address={address}
onEdit={() => setIsModalOpen(true)}
showFormattedAddress={true} // Afficher l'adresse Google formatée si personnalisée (défaut: true)
/>
);
}Props disponibles :
address: L'adresse à afficher (ounull)onEdit: Callback appelé lors du clic sur le bouton d'éditionclassName: Classes CSS supplémentaires (optionnel)showFormattedAddress: Afficher l'adresse Google formatée quand l'adresse est personnalisée (défaut:true)
Hook : useAddressSelector
import { useAddressSelector, AddressSelectionData } from '@lebonplan/shared-address-selector';
function MyComponent() {
const { isOpen, open, close, handleComplete } = useAddressSelector(address => {
console.log('Address selected:', address);
});
return <button onClick={open}>Sélectionner une adresse</button>;
}Types
AddressSelectionData
Type unifié représentant une adresse sélectionnée (GPS ou Google Places) :
interface AddressSelectionData {
type: 'google_place' | 'gps';
googlePlaceId: string;
latitude: number;
longitude: number;
accuracy: number; // Précision GPS réelle ou 50m pour Google Places
formattedAddress: string;
displayAddress: string;
isCustomDisplayAddress: boolean;
city: string; // Ville extraite depuis Google Places (depuis v1.2.0)
}type: 'gps': Adresse obtenue via géolocalisation GPS (accuracy = précision réelle de l'appareil)type: 'google_place': Adresse sélectionnée via recherche Google Places (accuracy = 50m par défaut)city: Ville extraite automatiquement depuis lesaddressComponentsde Google Places (locality ou administrative_area_level_1)
Intégration avec le backend
Le composant retourne AddressSelectionData qui doit être transformé en CreateAddressDto avant l'envoi à POST /addresses :
const dto: CreateAddressDto = {
placeId: addressData.googlePlaceId,
latitude: addressData.latitude, // Toujours présent (GPS réel ou Google Places)
longitude: addressData.longitude, // Toujours présent (GPS réel ou Google Places)
accuracy: addressData.accuracy, // Toujours présent (GPS réel ou 50m pour Google Places)
displayAddress: addressData.displayAddress,
isCustomDisplayAddress: addressData.isCustomDisplayAddress,
city: addressData.city, // Disponible depuis v1.2.0 (extrait automatiquement)
// label et isDefault peuvent être ajoutés par l'app
};Note : Le champ city est maintenant automatiquement extrait depuis les addressComponents de Google Places lors de la sélection d'une adresse (via GPS ou recherche manuelle).
Configuration
Props du composant AddressSelectorModal
isOpen: État d'ouverture du modal (requis)onClose: Callback appelé lors de la fermeture (requis)onComplete: Callback appelé avecAddressSelectionDatalors de la confirmation (requis)apiKey: Clé API Google Maps (requis)maxAccuracy(optionnel, défaut: 50) : Précision maximale acceptée en mètres pour la géolocalisation GPS. Si la précision est supérieure, l'utilisateur devra réessayer ou rechercher manuellement.
Améliorations UX (v1.2.0+)
- Modal responsive : Le modal s'adapte à différentes tailles d'écran avec un layout flex et scrollable
- Gestion améliorée du displayAddress : L'adresse d'affichage peut être modifiée indépendamment de l'adresse formatée
- Meilleure lisibilité : Amélioration des styles et de la hiérarchie visuelle dans tous les composants
- Extraction automatique de la ville : Le champ
cityest maintenant automatiquement extrait depuis Google Places
Variables d'environnement
NEXT_PUBLIC_GOOGLE_MAPS_API_KEY: Clé API Google Maps (requise)
Permissions navigateur
Pour la géolocalisation GPS, l'utilisateur doit autoriser l'accès à sa position. Le composant gère automatiquement les cas d'erreur (permission refusée, timeout, etc.).
Structure
packages/shared-address-selector/
├── src/
│ ├── types/
│ │ └── address-selection.types.ts (contient AddressSelectionData avec champ city)
│ ├── hooks/
│ │ ├── useGeolocation.ts
│ │ ├── useGooglePlaces.ts (utilise Places API New - REST, optimisé avec gestion d'erreurs)
│ │ └── useAddressSelector.ts
│ ├── components/
│ │ ├── AddressSelectorModal.tsx (utilise Geocoding API New - REST, UX améliorée)
│ │ ├── AddressConfirmationScreen.tsx (UX améliorée avec meilleure gestion du displayAddress)
│ │ └── AddressDisplay.tsx (lisibilité améliorée, option showFormattedAddress)
│ └── index.tsChangelog
v1.3.0 (publié)
- Publication sur npm
v1.2.0
- ✨ Nouveau champ
city: Extraction automatique de la ville depuis Google Places - 🎨 Amélioration UX des composants :
- Modal responsive avec layout flex et scrollable
- Meilleure gestion du
displayAddressdansAddressConfirmationScreen - Amélioration de la lisibilité dans
AddressDisplayavec optionshowFormattedAddress - Styles améliorés et hiérarchie visuelle optimisée
- ⚡ Optimisation
useGooglePlaces:- Gestion améliorée des erreurs avec AbortController
- Optimisation des appels API avec annulation des requêtes précédentes
- Meilleure gestion des timeouts et erreurs réseau
v1.1.0
- Version initiale avec fonctionnalités de base
Développement
# Build
pnpm build
# Watch mode
pnpm dev
# Clean
pnpm clean
# Type check
pnpm type-checkPublication sur npm
Prérequis
- Être connecté à npm :
npm login - Avoir les droits de publication sur le scope
@lebonplan
Scripts de publication
# Bump de version patch (1.0.0 -> 1.0.1)
pnpm publish:patch
# Bump de version minor (1.0.0 -> 1.1.0)
pnpm publish:minor
# Bump de version major (1.0.0 -> 2.0.0)
pnpm publish:major
# Test de publication (dry-run)
pnpm publish:dry-runLes scripts de publication effectuent automatiquement :
- Bump de version dans
package.json - Build du package
- Publication sur npm avec
--access public(nécessaire pour les scoped packages publics)
Bump de version manuel
Si vous voulez juste bump la version sans publier :
# Patch
pnpm version:patch
# Minor
pnpm version:minor
# Major
pnpm version:major