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