@wherabouts/react-ui 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -5
- package/dist/index.cjs +249 -257
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +97 -45
- package/dist/index.d.ts +97 -45
- package/dist/index.js +249 -257
- package/dist/index.js.map +1 -1
- package/dist/styles.css +23 -26
- package/docs/README.md +16 -0
- package/docs/address-autocomplete.md +208 -0
- package/docs/address-field-group.md +152 -0
- package/docs/address-form-field.md +198 -0
- package/docs/forward-geocode-input.md +115 -0
- package/docs/reverse-geocode-input.md +124 -0
- package/package.json +9 -2
package/dist/index.js
CHANGED
|
@@ -3,22 +3,42 @@ import { useMemo, useRef, useState, useEffect } from 'react';
|
|
|
3
3
|
import { createPortal } from 'react-dom';
|
|
4
4
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
5
|
|
|
6
|
-
// src/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
6
|
+
// src/components/address-autocomplete.tsx
|
|
7
|
+
function useAddressGeolocation(enabled) {
|
|
8
|
+
const [lat, setLat] = useState(void 0);
|
|
9
|
+
const [lng, setLng] = useState(void 0);
|
|
10
|
+
const [loading, setLoading] = useState(false);
|
|
11
|
+
const [error, setError] = useState(null);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
if (!enabled) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (typeof navigator === "undefined" || !("geolocation" in navigator)) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
setLoading(true);
|
|
20
|
+
const controller = new AbortController();
|
|
21
|
+
navigator.geolocation.getCurrentPosition(
|
|
22
|
+
(position) => {
|
|
23
|
+
if (!controller.signal.aborted) {
|
|
24
|
+
setLat(position.coords.latitude);
|
|
25
|
+
setLng(position.coords.longitude);
|
|
26
|
+
setError(null);
|
|
27
|
+
setLoading(false);
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
(err) => {
|
|
31
|
+
if (!controller.signal.aborted) {
|
|
32
|
+
setError(err);
|
|
33
|
+
setLoading(false);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
return () => {
|
|
38
|
+
controller.abort();
|
|
39
|
+
};
|
|
40
|
+
}, [enabled]);
|
|
41
|
+
return { lat, lng, loading, error };
|
|
22
42
|
}
|
|
23
43
|
|
|
24
44
|
// ../../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
|
|
@@ -2500,41 +2520,23 @@ var twMerge = /* @__PURE__ */ createTailwindMerge(getDefaultConfig);
|
|
|
2500
2520
|
function cn(...inputs) {
|
|
2501
2521
|
return twMerge(clsx(inputs));
|
|
2502
2522
|
}
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
setLat(position.coords.latitude);
|
|
2521
|
-
setLng(position.coords.longitude);
|
|
2522
|
-
setError(null);
|
|
2523
|
-
setLoading(false);
|
|
2524
|
-
}
|
|
2525
|
-
},
|
|
2526
|
-
(err) => {
|
|
2527
|
-
if (!controller.signal.aborted) {
|
|
2528
|
-
setError(err);
|
|
2529
|
-
setLoading(false);
|
|
2530
|
-
}
|
|
2531
|
-
}
|
|
2532
|
-
);
|
|
2533
|
-
return () => {
|
|
2534
|
-
controller.abort();
|
|
2535
|
-
};
|
|
2536
|
-
}, [enabled]);
|
|
2537
|
-
return { lat, lng, loading, error };
|
|
2523
|
+
|
|
2524
|
+
// src/utils/parse-address.ts
|
|
2525
|
+
var COUNTRY_NAMES = {
|
|
2526
|
+
AU: "Australia"
|
|
2527
|
+
};
|
|
2528
|
+
function toAddressWithParsed(suggestion) {
|
|
2529
|
+
return {
|
|
2530
|
+
id: suggestion.id,
|
|
2531
|
+
formattedAddress: suggestion.formattedAddress,
|
|
2532
|
+
latitude: suggestion.latitude,
|
|
2533
|
+
longitude: suggestion.longitude,
|
|
2534
|
+
streetAddress: suggestion.streetAddress,
|
|
2535
|
+
suburb: suggestion.locality,
|
|
2536
|
+
state: suggestion.state,
|
|
2537
|
+
postcode: suggestion.postcode,
|
|
2538
|
+
country: COUNTRY_NAMES[suggestion.country] ?? suggestion.country
|
|
2539
|
+
};
|
|
2538
2540
|
}
|
|
2539
2541
|
var DEFAULT_I18N = {
|
|
2540
2542
|
noResults: "No addresses found",
|
|
@@ -2778,186 +2780,6 @@ function AddressAutocomplete({
|
|
|
2778
2780
|
}
|
|
2779
2781
|
);
|
|
2780
2782
|
}
|
|
2781
|
-
function AddressFormField({
|
|
2782
|
-
label,
|
|
2783
|
-
labelClassName,
|
|
2784
|
-
errorClassName,
|
|
2785
|
-
error,
|
|
2786
|
-
required,
|
|
2787
|
-
disabled,
|
|
2788
|
-
id: customId,
|
|
2789
|
-
className,
|
|
2790
|
-
...autocompleteProps
|
|
2791
|
-
}) {
|
|
2792
|
-
const id = customId ?? "wherabouts-field";
|
|
2793
|
-
return /* @__PURE__ */ jsxs(
|
|
2794
|
-
"div",
|
|
2795
|
-
{
|
|
2796
|
-
"data-slot": "address-form-field",
|
|
2797
|
-
className: "flex flex-col gap-2",
|
|
2798
|
-
children: [
|
|
2799
|
-
/* @__PURE__ */ jsxs(
|
|
2800
|
-
"label",
|
|
2801
|
-
{
|
|
2802
|
-
htmlFor: id,
|
|
2803
|
-
className: cn(
|
|
2804
|
-
"block text-sm font-medium text-gray-900",
|
|
2805
|
-
labelClassName
|
|
2806
|
-
),
|
|
2807
|
-
children: [
|
|
2808
|
-
label,
|
|
2809
|
-
required && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "ml-1 text-red-600", children: "*" })
|
|
2810
|
-
]
|
|
2811
|
-
}
|
|
2812
|
-
),
|
|
2813
|
-
/* @__PURE__ */ jsx(
|
|
2814
|
-
AddressAutocomplete,
|
|
2815
|
-
{
|
|
2816
|
-
...autocompleteProps,
|
|
2817
|
-
id,
|
|
2818
|
-
required,
|
|
2819
|
-
disabled,
|
|
2820
|
-
error,
|
|
2821
|
-
className
|
|
2822
|
-
}
|
|
2823
|
-
),
|
|
2824
|
-
error && /* @__PURE__ */ jsx(
|
|
2825
|
-
"p",
|
|
2826
|
-
{
|
|
2827
|
-
role: "alert",
|
|
2828
|
-
"aria-live": "polite",
|
|
2829
|
-
className: cn(
|
|
2830
|
-
"text-sm text-red-600",
|
|
2831
|
-
errorClassName
|
|
2832
|
-
),
|
|
2833
|
-
children: error
|
|
2834
|
-
}
|
|
2835
|
-
)
|
|
2836
|
-
]
|
|
2837
|
-
}
|
|
2838
|
-
);
|
|
2839
|
-
}
|
|
2840
|
-
function ReverseGeocodeInput({
|
|
2841
|
-
client,
|
|
2842
|
-
latitude,
|
|
2843
|
-
longitude,
|
|
2844
|
-
onResult,
|
|
2845
|
-
className,
|
|
2846
|
-
disabled,
|
|
2847
|
-
placeholder = "Address will appear here",
|
|
2848
|
-
id
|
|
2849
|
-
}) {
|
|
2850
|
-
const { address, distance } = useReverseGeocode(
|
|
2851
|
-
client,
|
|
2852
|
-
latitude != null && longitude != null ? { lat: latitude, lng: longitude } : null
|
|
2853
|
-
);
|
|
2854
|
-
useEffect(() => {
|
|
2855
|
-
onResult?.({
|
|
2856
|
-
address: address?.formattedAddress ?? null,
|
|
2857
|
-
distance: distance ?? null
|
|
2858
|
-
});
|
|
2859
|
-
}, [address, distance, onResult]);
|
|
2860
|
-
const displayText = address?.formattedAddress ?? "";
|
|
2861
|
-
return /* @__PURE__ */ jsx(
|
|
2862
|
-
"input",
|
|
2863
|
-
{
|
|
2864
|
-
id,
|
|
2865
|
-
"data-slot": "geocode-input",
|
|
2866
|
-
type: "text",
|
|
2867
|
-
readOnly: true,
|
|
2868
|
-
disabled,
|
|
2869
|
-
value: displayText,
|
|
2870
|
-
placeholder,
|
|
2871
|
-
className: cn(
|
|
2872
|
-
"block h-8 w-full cursor-default rounded-none border border-input bg-muted/40 px-2.5 py-1 text-foreground text-xs",
|
|
2873
|
-
className
|
|
2874
|
-
)
|
|
2875
|
-
}
|
|
2876
|
-
);
|
|
2877
|
-
}
|
|
2878
|
-
var toGeocodeAddress = (address) => address ? {
|
|
2879
|
-
id: address.id,
|
|
2880
|
-
formattedAddress: address.formattedAddress,
|
|
2881
|
-
latitude: address.latitude,
|
|
2882
|
-
longitude: address.longitude
|
|
2883
|
-
} : null;
|
|
2884
|
-
function useForwardGeocode(client, query) {
|
|
2885
|
-
const [data, setData] = useState(null);
|
|
2886
|
-
const [loading, setLoading] = useState(false);
|
|
2887
|
-
const [error, setError] = useState(null);
|
|
2888
|
-
useEffect(() => {
|
|
2889
|
-
if (!query) {
|
|
2890
|
-
setData(null);
|
|
2891
|
-
setError(null);
|
|
2892
|
-
return;
|
|
2893
|
-
}
|
|
2894
|
-
const controller = new AbortController();
|
|
2895
|
-
async function fetch() {
|
|
2896
|
-
setLoading(true);
|
|
2897
|
-
setError(null);
|
|
2898
|
-
try {
|
|
2899
|
-
const response = await client.geocode.forward(
|
|
2900
|
-
{ q: query },
|
|
2901
|
-
{ signal: controller.signal }
|
|
2902
|
-
);
|
|
2903
|
-
if (controller.signal.aborted) {
|
|
2904
|
-
return;
|
|
2905
|
-
}
|
|
2906
|
-
setData(toGeocodeAddress(response.address));
|
|
2907
|
-
} catch (err) {
|
|
2908
|
-
if (controller.signal.aborted) {
|
|
2909
|
-
return;
|
|
2910
|
-
}
|
|
2911
|
-
setError(err instanceof Error ? err : new Error(String(err)));
|
|
2912
|
-
setData(null);
|
|
2913
|
-
} finally {
|
|
2914
|
-
if (!controller.signal.aborted) {
|
|
2915
|
-
setLoading(false);
|
|
2916
|
-
}
|
|
2917
|
-
}
|
|
2918
|
-
}
|
|
2919
|
-
fetch();
|
|
2920
|
-
return () => {
|
|
2921
|
-
controller.abort();
|
|
2922
|
-
};
|
|
2923
|
-
}, [client, query]);
|
|
2924
|
-
return { data, loading, error };
|
|
2925
|
-
}
|
|
2926
|
-
function ForwardGeocodeInput({
|
|
2927
|
-
client,
|
|
2928
|
-
query,
|
|
2929
|
-
onResult,
|
|
2930
|
-
className,
|
|
2931
|
-
disabled,
|
|
2932
|
-
placeholder = "Coordinates will appear here",
|
|
2933
|
-
id
|
|
2934
|
-
}) {
|
|
2935
|
-
const { data } = useForwardGeocode(client, query);
|
|
2936
|
-
useEffect(() => {
|
|
2937
|
-
onResult?.({
|
|
2938
|
-
latitude: data?.latitude ?? null,
|
|
2939
|
-
longitude: data?.longitude ?? null,
|
|
2940
|
-
formattedAddress: data?.formattedAddress ?? null
|
|
2941
|
-
});
|
|
2942
|
-
}, [data, onResult]);
|
|
2943
|
-
const displayText = data ? `${data.latitude.toFixed(4)}, ${data.longitude.toFixed(4)}` : "";
|
|
2944
|
-
return /* @__PURE__ */ jsx(
|
|
2945
|
-
"input",
|
|
2946
|
-
{
|
|
2947
|
-
id,
|
|
2948
|
-
"data-slot": "geocode-input",
|
|
2949
|
-
type: "text",
|
|
2950
|
-
readOnly: true,
|
|
2951
|
-
disabled,
|
|
2952
|
-
value: displayText,
|
|
2953
|
-
placeholder,
|
|
2954
|
-
className: cn(
|
|
2955
|
-
"block h-8 w-full cursor-default rounded-none border border-input bg-muted/40 px-2.5 py-1 text-foreground text-xs",
|
|
2956
|
-
className
|
|
2957
|
-
)
|
|
2958
|
-
}
|
|
2959
|
-
);
|
|
2960
|
-
}
|
|
2961
2783
|
function AddressFieldGroup({
|
|
2962
2784
|
client,
|
|
2963
2785
|
value,
|
|
@@ -2986,8 +2808,8 @@ function AddressFieldGroup({
|
|
|
2986
2808
|
return /* @__PURE__ */ jsxs(
|
|
2987
2809
|
"div",
|
|
2988
2810
|
{
|
|
2989
|
-
"data-slot": "address-field-group",
|
|
2990
2811
|
className: cn("flex flex-col gap-4", className),
|
|
2812
|
+
"data-slot": "address-field-group",
|
|
2991
2813
|
children: [
|
|
2992
2814
|
/* @__PURE__ */ jsx(
|
|
2993
2815
|
AddressAutocomplete,
|
|
@@ -3001,28 +2823,28 @@ function AddressFieldGroup({
|
|
|
3001
2823
|
/* @__PURE__ */ jsxs(
|
|
3002
2824
|
"div",
|
|
3003
2825
|
{
|
|
3004
|
-
"data-slot": "address-field-group-inputs",
|
|
3005
2826
|
className: "grid grid-cols-2 gap-4",
|
|
2827
|
+
"data-slot": "address-field-group-inputs",
|
|
3006
2828
|
children: [
|
|
3007
2829
|
/* @__PURE__ */ jsxs("div", { className: "col-span-2", children: [
|
|
3008
2830
|
/* @__PURE__ */ jsx(
|
|
3009
2831
|
"label",
|
|
3010
2832
|
{
|
|
3011
|
-
htmlFor: "field-street",
|
|
3012
2833
|
className: "mb-1 block font-medium text-foreground text-sm",
|
|
2834
|
+
htmlFor: "field-street",
|
|
3013
2835
|
children: streetLabel
|
|
3014
2836
|
}
|
|
3015
2837
|
),
|
|
3016
2838
|
/* @__PURE__ */ jsx(
|
|
3017
2839
|
"input",
|
|
3018
2840
|
{
|
|
3019
|
-
|
|
3020
|
-
type: "text",
|
|
2841
|
+
className: "block h-8 w-full rounded-none border border-input bg-transparent px-2.5 py-1 text-foreground text-xs outline-none transition-colors placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-1 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-input/30",
|
|
3021
2842
|
disabled,
|
|
3022
|
-
|
|
2843
|
+
id: "field-street",
|
|
3023
2844
|
onChange: (e) => handleFieldChange("street", e.target.value),
|
|
3024
|
-
|
|
3025
|
-
|
|
2845
|
+
placeholder: "Street address",
|
|
2846
|
+
type: "text",
|
|
2847
|
+
value: value.street
|
|
3026
2848
|
}
|
|
3027
2849
|
)
|
|
3028
2850
|
] }),
|
|
@@ -3030,21 +2852,21 @@ function AddressFieldGroup({
|
|
|
3030
2852
|
/* @__PURE__ */ jsx(
|
|
3031
2853
|
"label",
|
|
3032
2854
|
{
|
|
3033
|
-
htmlFor: "field-suburb",
|
|
3034
2855
|
className: "mb-1 block font-medium text-foreground text-sm",
|
|
2856
|
+
htmlFor: "field-suburb",
|
|
3035
2857
|
children: suburbLabel
|
|
3036
2858
|
}
|
|
3037
2859
|
),
|
|
3038
2860
|
/* @__PURE__ */ jsx(
|
|
3039
2861
|
"input",
|
|
3040
2862
|
{
|
|
3041
|
-
|
|
3042
|
-
type: "text",
|
|
2863
|
+
className: "block h-8 w-full rounded-none border border-input bg-transparent px-2.5 py-1 text-foreground text-xs outline-none transition-colors placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-1 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-input/30",
|
|
3043
2864
|
disabled,
|
|
3044
|
-
|
|
2865
|
+
id: "field-suburb",
|
|
3045
2866
|
onChange: (e) => handleFieldChange("suburb", e.target.value),
|
|
3046
|
-
|
|
3047
|
-
|
|
2867
|
+
placeholder: "Suburb",
|
|
2868
|
+
type: "text",
|
|
2869
|
+
value: value.suburb
|
|
3048
2870
|
}
|
|
3049
2871
|
)
|
|
3050
2872
|
] }),
|
|
@@ -3052,21 +2874,21 @@ function AddressFieldGroup({
|
|
|
3052
2874
|
/* @__PURE__ */ jsx(
|
|
3053
2875
|
"label",
|
|
3054
2876
|
{
|
|
3055
|
-
htmlFor: "field-state",
|
|
3056
2877
|
className: "mb-1 block font-medium text-foreground text-sm",
|
|
2878
|
+
htmlFor: "field-state",
|
|
3057
2879
|
children: stateLabel
|
|
3058
2880
|
}
|
|
3059
2881
|
),
|
|
3060
2882
|
/* @__PURE__ */ jsx(
|
|
3061
2883
|
"input",
|
|
3062
2884
|
{
|
|
3063
|
-
|
|
3064
|
-
type: "text",
|
|
2885
|
+
className: "block h-8 w-full rounded-none border border-input bg-transparent px-2.5 py-1 text-foreground text-xs outline-none transition-colors placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-1 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-input/30",
|
|
3065
2886
|
disabled,
|
|
3066
|
-
|
|
2887
|
+
id: "field-state",
|
|
3067
2888
|
onChange: (e) => handleFieldChange("state", e.target.value),
|
|
3068
|
-
|
|
3069
|
-
|
|
2889
|
+
placeholder: "State",
|
|
2890
|
+
type: "text",
|
|
2891
|
+
value: value.state
|
|
3070
2892
|
}
|
|
3071
2893
|
)
|
|
3072
2894
|
] }),
|
|
@@ -3074,21 +2896,21 @@ function AddressFieldGroup({
|
|
|
3074
2896
|
/* @__PURE__ */ jsx(
|
|
3075
2897
|
"label",
|
|
3076
2898
|
{
|
|
3077
|
-
htmlFor: "field-postcode",
|
|
3078
2899
|
className: "mb-1 block font-medium text-foreground text-sm",
|
|
2900
|
+
htmlFor: "field-postcode",
|
|
3079
2901
|
children: postcodeLabel
|
|
3080
2902
|
}
|
|
3081
2903
|
),
|
|
3082
2904
|
/* @__PURE__ */ jsx(
|
|
3083
2905
|
"input",
|
|
3084
2906
|
{
|
|
3085
|
-
|
|
3086
|
-
type: "text",
|
|
2907
|
+
className: "block h-8 w-full rounded-none border border-input bg-transparent px-2.5 py-1 text-foreground text-xs outline-none transition-colors placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-1 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-input/30",
|
|
3087
2908
|
disabled,
|
|
3088
|
-
|
|
2909
|
+
id: "field-postcode",
|
|
3089
2910
|
onChange: (e) => handleFieldChange("postcode", e.target.value),
|
|
3090
|
-
|
|
3091
|
-
|
|
2911
|
+
placeholder: "Postcode",
|
|
2912
|
+
type: "text",
|
|
2913
|
+
value: value.postcode
|
|
3092
2914
|
}
|
|
3093
2915
|
)
|
|
3094
2916
|
] })
|
|
@@ -3099,6 +2921,176 @@ function AddressFieldGroup({
|
|
|
3099
2921
|
}
|
|
3100
2922
|
);
|
|
3101
2923
|
}
|
|
2924
|
+
function AddressFormField({
|
|
2925
|
+
label,
|
|
2926
|
+
labelClassName,
|
|
2927
|
+
errorClassName,
|
|
2928
|
+
error,
|
|
2929
|
+
required,
|
|
2930
|
+
disabled,
|
|
2931
|
+
id: customId,
|
|
2932
|
+
className,
|
|
2933
|
+
...autocompleteProps
|
|
2934
|
+
}) {
|
|
2935
|
+
const id = customId ?? "wherabouts-field";
|
|
2936
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", "data-slot": "address-form-field", children: [
|
|
2937
|
+
/* @__PURE__ */ jsxs(
|
|
2938
|
+
"label",
|
|
2939
|
+
{
|
|
2940
|
+
className: cn(
|
|
2941
|
+
"block font-medium text-gray-900 text-sm",
|
|
2942
|
+
labelClassName
|
|
2943
|
+
),
|
|
2944
|
+
htmlFor: id,
|
|
2945
|
+
children: [
|
|
2946
|
+
label,
|
|
2947
|
+
required && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "ml-1 text-red-600", children: "*" })
|
|
2948
|
+
]
|
|
2949
|
+
}
|
|
2950
|
+
),
|
|
2951
|
+
/* @__PURE__ */ jsx(
|
|
2952
|
+
AddressAutocomplete,
|
|
2953
|
+
{
|
|
2954
|
+
...autocompleteProps,
|
|
2955
|
+
className,
|
|
2956
|
+
disabled,
|
|
2957
|
+
error,
|
|
2958
|
+
id,
|
|
2959
|
+
required
|
|
2960
|
+
}
|
|
2961
|
+
),
|
|
2962
|
+
error && /* @__PURE__ */ jsx(
|
|
2963
|
+
"p",
|
|
2964
|
+
{
|
|
2965
|
+
"aria-live": "polite",
|
|
2966
|
+
className: cn("text-red-600 text-sm", errorClassName),
|
|
2967
|
+
role: "alert",
|
|
2968
|
+
children: error
|
|
2969
|
+
}
|
|
2970
|
+
)
|
|
2971
|
+
] });
|
|
2972
|
+
}
|
|
2973
|
+
var toGeocodeAddress = (address) => address ? {
|
|
2974
|
+
id: address.id,
|
|
2975
|
+
formattedAddress: address.formattedAddress,
|
|
2976
|
+
latitude: address.latitude,
|
|
2977
|
+
longitude: address.longitude
|
|
2978
|
+
} : null;
|
|
2979
|
+
function useForwardGeocode(client, query) {
|
|
2980
|
+
const [data, setData] = useState(null);
|
|
2981
|
+
const [loading, setLoading] = useState(false);
|
|
2982
|
+
const [error, setError] = useState(null);
|
|
2983
|
+
useEffect(() => {
|
|
2984
|
+
if (!query) {
|
|
2985
|
+
setData(null);
|
|
2986
|
+
setError(null);
|
|
2987
|
+
return;
|
|
2988
|
+
}
|
|
2989
|
+
const controller = new AbortController();
|
|
2990
|
+
async function fetch() {
|
|
2991
|
+
setLoading(true);
|
|
2992
|
+
setError(null);
|
|
2993
|
+
try {
|
|
2994
|
+
const response = await client.geocode.forward(
|
|
2995
|
+
{ q: query },
|
|
2996
|
+
{ signal: controller.signal }
|
|
2997
|
+
);
|
|
2998
|
+
if (controller.signal.aborted) {
|
|
2999
|
+
return;
|
|
3000
|
+
}
|
|
3001
|
+
setData(toGeocodeAddress(response.address));
|
|
3002
|
+
} catch (err) {
|
|
3003
|
+
if (controller.signal.aborted) {
|
|
3004
|
+
return;
|
|
3005
|
+
}
|
|
3006
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
3007
|
+
setData(null);
|
|
3008
|
+
} finally {
|
|
3009
|
+
if (!controller.signal.aborted) {
|
|
3010
|
+
setLoading(false);
|
|
3011
|
+
}
|
|
3012
|
+
}
|
|
3013
|
+
}
|
|
3014
|
+
fetch();
|
|
3015
|
+
return () => {
|
|
3016
|
+
controller.abort();
|
|
3017
|
+
};
|
|
3018
|
+
}, [client, query]);
|
|
3019
|
+
return { data, loading, error };
|
|
3020
|
+
}
|
|
3021
|
+
function ForwardGeocodeInput({
|
|
3022
|
+
client,
|
|
3023
|
+
query,
|
|
3024
|
+
onResult,
|
|
3025
|
+
className,
|
|
3026
|
+
disabled,
|
|
3027
|
+
placeholder = "Coordinates will appear here",
|
|
3028
|
+
id
|
|
3029
|
+
}) {
|
|
3030
|
+
const { data } = useForwardGeocode(client, query);
|
|
3031
|
+
useEffect(() => {
|
|
3032
|
+
onResult?.({
|
|
3033
|
+
latitude: data?.latitude ?? null,
|
|
3034
|
+
longitude: data?.longitude ?? null,
|
|
3035
|
+
formattedAddress: data?.formattedAddress ?? null
|
|
3036
|
+
});
|
|
3037
|
+
}, [data, onResult]);
|
|
3038
|
+
const displayText = data ? `${data.latitude.toFixed(4)}, ${data.longitude.toFixed(4)}` : "";
|
|
3039
|
+
return /* @__PURE__ */ jsx(
|
|
3040
|
+
"input",
|
|
3041
|
+
{
|
|
3042
|
+
className: cn(
|
|
3043
|
+
"block h-8 w-full cursor-default rounded-none border border-input bg-muted/40 px-2.5 py-1 text-foreground text-xs",
|
|
3044
|
+
className
|
|
3045
|
+
),
|
|
3046
|
+
"data-slot": "geocode-input",
|
|
3047
|
+
disabled,
|
|
3048
|
+
id,
|
|
3049
|
+
placeholder,
|
|
3050
|
+
readOnly: true,
|
|
3051
|
+
type: "text",
|
|
3052
|
+
value: displayText
|
|
3053
|
+
}
|
|
3054
|
+
);
|
|
3055
|
+
}
|
|
3056
|
+
function ReverseGeocodeInput({
|
|
3057
|
+
client,
|
|
3058
|
+
latitude,
|
|
3059
|
+
longitude,
|
|
3060
|
+
onResult,
|
|
3061
|
+
className,
|
|
3062
|
+
disabled,
|
|
3063
|
+
placeholder = "Address will appear here",
|
|
3064
|
+
id
|
|
3065
|
+
}) {
|
|
3066
|
+
const { address, distance } = useReverseGeocode(
|
|
3067
|
+
client,
|
|
3068
|
+
latitude != null && longitude != null ? { lat: latitude, lng: longitude } : null
|
|
3069
|
+
);
|
|
3070
|
+
useEffect(() => {
|
|
3071
|
+
onResult?.({
|
|
3072
|
+
address: address?.formattedAddress ?? null,
|
|
3073
|
+
distance: distance ?? null
|
|
3074
|
+
});
|
|
3075
|
+
}, [address, distance, onResult]);
|
|
3076
|
+
const displayText = address?.formattedAddress ?? "";
|
|
3077
|
+
return /* @__PURE__ */ jsx(
|
|
3078
|
+
"input",
|
|
3079
|
+
{
|
|
3080
|
+
className: cn(
|
|
3081
|
+
"block h-8 w-full cursor-default rounded-none border border-input bg-muted/40 px-2.5 py-1 text-foreground text-xs",
|
|
3082
|
+
className
|
|
3083
|
+
),
|
|
3084
|
+
"data-slot": "geocode-input",
|
|
3085
|
+
disabled,
|
|
3086
|
+
id,
|
|
3087
|
+
placeholder,
|
|
3088
|
+
readOnly: true,
|
|
3089
|
+
type: "text",
|
|
3090
|
+
value: displayText
|
|
3091
|
+
}
|
|
3092
|
+
);
|
|
3093
|
+
}
|
|
3102
3094
|
|
|
3103
3095
|
export { AddressAutocomplete, AddressFieldGroup, AddressFormField, ForwardGeocodeInput, ReverseGeocodeInput, cn, toAddressWithParsed };
|
|
3104
3096
|
//# sourceMappingURL=index.js.map
|