najm-kit 2.11.22 → 2.12.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/CHANGELOG.md +22 -7
- package/README.md +28 -1
- package/dist/NIcon-D73-C51g.d.ts +21 -0
- package/dist/{NNotFoundState-BmGDW2Bx.d.ts → NNotFoundState-Z2n2gbhS.d.ts} +1 -16
- package/dist/{NajmUIProvider-BwL5HFIV.d.ts → NajmUIProvider-C9IJW1ya.d.ts} +2 -19
- package/dist/adapters/app.d.ts +6 -4
- package/dist/adapters/app.mjs +9 -6
- package/dist/adapters/next.d.ts +2 -1
- package/dist/adapters/next.mjs +5 -3
- package/dist/chunk-5UY7U2ED.mjs +9 -0
- package/dist/chunk-A34LRQYI.mjs +7 -0
- package/dist/chunk-BFFTC7LD.mjs +66 -0
- package/dist/{chunk-5ZTOCWRA.mjs → chunk-F32O3WRX.mjs} +7 -197
- package/dist/chunk-FZX3DONZ.mjs +200 -0
- package/dist/chunk-GYPQLOQ5.mjs +2202 -0
- package/dist/{chunk-BDQK6ECA.mjs → chunk-LMW4DM5L.mjs} +43 -101
- package/dist/{chunk-DKHIQFXX.mjs → chunk-QDFLHSWO.mjs} +1 -1
- package/dist/{chunk-5JVFMOLI.mjs → chunk-QJ22WAQY.mjs} +2 -28
- package/dist/{chunk-LK3SMYUP.mjs → chunk-TZRTOQCC.mjs} +1 -6
- package/dist/chunk-VZXMMC72.mjs +31 -0
- package/dist/{chunk-M5VGBZ7R.mjs → chunk-WHGRN7PP.mjs} +2 -1
- package/dist/formFill-CQkTA0JS.d.ts +17 -0
- package/dist/index.d.ts +20 -436
- package/dist/index.mjs +338 -1950
- package/dist/json.mjs +5 -3
- package/dist/location/google.d.ts +14 -0
- package/dist/location/google.mjs +184 -0
- package/dist/location/index.d.ts +33 -0
- package/dist/location/index.mjs +9 -0
- package/dist/location/leaflet.d.ts +13 -0
- package/dist/location/leaflet.mjs +168 -0
- package/dist/theme.css +23 -2
- package/dist/types-BQBx0RZd.d.ts +578 -0
- package/package.json +29 -2
package/dist/json.mjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
export { NTableJson } from './chunk-
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
1
|
+
export { NTableJson } from './chunk-VZXMMC72.mjs';
|
|
2
|
+
import './chunk-QJ22WAQY.mjs';
|
|
3
|
+
import { Button } from './chunk-WHGRN7PP.mjs';
|
|
4
|
+
import './chunk-TZRTOQCC.mjs';
|
|
5
|
+
import { cn } from './chunk-5UY7U2ED.mjs';
|
|
4
6
|
import './chunk-TFHWLE7N.mjs';
|
|
5
7
|
import { useMemo, useRef, useCallback } from 'react';
|
|
6
8
|
import CodeMirror from '@uiw/react-codemirror';
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { G as GoogleLocationAdapterOptions, N as NLocationMapAdapter, a as NLocationGeocoderAdapter } from '../types-BQBx0RZd.js';
|
|
2
|
+
import 'react';
|
|
3
|
+
import 'react-hook-form';
|
|
4
|
+
import 'zod';
|
|
5
|
+
import 'culori';
|
|
6
|
+
import '../NIcon-D73-C51g.js';
|
|
7
|
+
import '../formFill-CQkTA0JS.js';
|
|
8
|
+
import 'class-variance-authority/types';
|
|
9
|
+
import '@radix-ui/react-slider';
|
|
10
|
+
|
|
11
|
+
declare function createGoogleLocationAdapter(options: GoogleLocationAdapterOptions): NLocationMapAdapter;
|
|
12
|
+
declare function createGooglePlacesGeocoder(options: GoogleLocationAdapterOptions): NLocationGeocoderAdapter;
|
|
13
|
+
|
|
14
|
+
export { createGoogleLocationAdapter, createGooglePlacesGeocoder };
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { locationMarkerUrl } from '../chunk-A34LRQYI.mjs';
|
|
3
|
+
import { cn } from '../chunk-5UY7U2ED.mjs';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import { importLibrary, setOptions } from '@googlemaps/js-api-loader';
|
|
6
|
+
import { jsx } from 'react/jsx-runtime';
|
|
7
|
+
|
|
8
|
+
var configuredKey = null;
|
|
9
|
+
function configure(options) {
|
|
10
|
+
if (configuredKey && configuredKey !== options.apiKey) throw new Error("Google Maps is already configured");
|
|
11
|
+
if (!configuredKey) {
|
|
12
|
+
setOptions({
|
|
13
|
+
key: options.apiKey,
|
|
14
|
+
v: "weekly",
|
|
15
|
+
language: options.language,
|
|
16
|
+
region: options.region,
|
|
17
|
+
authReferrerPolicy: "origin",
|
|
18
|
+
mapIds: options.mapId ? [options.mapId] : void 0
|
|
19
|
+
});
|
|
20
|
+
configuredKey = options.apiKey;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function createMarkerContent() {
|
|
24
|
+
const image = document.createElement("img");
|
|
25
|
+
image.src = locationMarkerUrl;
|
|
26
|
+
image.alt = "";
|
|
27
|
+
image.width = 40;
|
|
28
|
+
image.height = 50;
|
|
29
|
+
image.draggable = false;
|
|
30
|
+
image.setAttribute("aria-hidden", "true");
|
|
31
|
+
return image;
|
|
32
|
+
}
|
|
33
|
+
function createMapComponent(options) {
|
|
34
|
+
return function GoogleLocationMap({ value, initialCenter, initialZoom, onChange, onReady, onLoadingChange, onError, onControlsReady, reducedMotion, className }) {
|
|
35
|
+
const elementRef = React.useRef(null);
|
|
36
|
+
const mapRef = React.useRef(null);
|
|
37
|
+
const markerRef = React.useRef(null);
|
|
38
|
+
const setMarkerRef = React.useRef(null);
|
|
39
|
+
const onChangeRef = React.useRef(onChange);
|
|
40
|
+
const valueRef = React.useRef(value);
|
|
41
|
+
onChangeRef.current = onChange;
|
|
42
|
+
valueRef.current = value;
|
|
43
|
+
React.useEffect(() => {
|
|
44
|
+
let active = true;
|
|
45
|
+
let listeners = [];
|
|
46
|
+
onLoadingChange?.(true);
|
|
47
|
+
void (async () => {
|
|
48
|
+
try {
|
|
49
|
+
configure(options);
|
|
50
|
+
const [{ Map: Map2 }, { AdvancedMarkerElement }] = await Promise.all([importLibrary("maps"), importLibrary("marker")]);
|
|
51
|
+
if (!active || !elementRef.current) return;
|
|
52
|
+
const currentValue = valueRef.current;
|
|
53
|
+
const center = currentValue ?? initialCenter;
|
|
54
|
+
const map = new Map2(elementRef.current, {
|
|
55
|
+
center: { lat: center.latitude, lng: center.longitude },
|
|
56
|
+
zoom: initialZoom,
|
|
57
|
+
mapId: options.mapId ?? "DEMO_MAP_ID",
|
|
58
|
+
disableDefaultUI: true,
|
|
59
|
+
clickableIcons: false,
|
|
60
|
+
gestureHandling: "greedy"
|
|
61
|
+
});
|
|
62
|
+
const setMarker = (latitude, longitude) => {
|
|
63
|
+
if (!markerRef.current) {
|
|
64
|
+
const marker = new AdvancedMarkerElement({ map, position: { lat: latitude, lng: longitude }, content: createMarkerContent(), gmpDraggable: true, title: "Selected location" });
|
|
65
|
+
listeners.push(marker.addListener("dragend", () => {
|
|
66
|
+
const position = marker.position;
|
|
67
|
+
const lat = typeof position?.lat === "function" ? position.lat() : position?.lat;
|
|
68
|
+
const lng = typeof position?.lng === "function" ? position.lng() : position?.lng;
|
|
69
|
+
if (typeof lat === "number" && typeof lng === "number") onChangeRef.current({ latitude: lat, longitude: lng });
|
|
70
|
+
}));
|
|
71
|
+
markerRef.current = marker;
|
|
72
|
+
} else markerRef.current.position = { lat: latitude, lng: longitude };
|
|
73
|
+
};
|
|
74
|
+
setMarkerRef.current = setMarker;
|
|
75
|
+
if (currentValue) setMarker(currentValue.latitude, currentValue.longitude);
|
|
76
|
+
listeners.push(map.addListener("click", (event) => {
|
|
77
|
+
const point = event.latLng;
|
|
78
|
+
if (!point) return;
|
|
79
|
+
setMarker(point.lat(), point.lng());
|
|
80
|
+
onChangeRef.current({ latitude: point.lat(), longitude: point.lng() });
|
|
81
|
+
}));
|
|
82
|
+
mapRef.current = map;
|
|
83
|
+
onControlsReady?.({
|
|
84
|
+
zoomIn: () => map.setZoom((map.getZoom() ?? initialZoom) + 1),
|
|
85
|
+
zoomOut: () => map.setZoom((map.getZoom() ?? initialZoom) - 1),
|
|
86
|
+
recenter: (point) => map.panTo({ lat: point.latitude, lng: point.longitude })
|
|
87
|
+
});
|
|
88
|
+
onLoadingChange?.(false);
|
|
89
|
+
onReady?.();
|
|
90
|
+
} catch {
|
|
91
|
+
if (!active) return;
|
|
92
|
+
onLoadingChange?.(false);
|
|
93
|
+
onError?.(new Error("Google map unavailable"));
|
|
94
|
+
}
|
|
95
|
+
})();
|
|
96
|
+
return () => {
|
|
97
|
+
active = false;
|
|
98
|
+
listeners.forEach((listener) => listener.remove());
|
|
99
|
+
listeners = [];
|
|
100
|
+
if (markerRef.current) markerRef.current.map = null;
|
|
101
|
+
markerRef.current = null;
|
|
102
|
+
setMarkerRef.current = null;
|
|
103
|
+
mapRef.current = null;
|
|
104
|
+
onControlsReady?.(null);
|
|
105
|
+
};
|
|
106
|
+
}, []);
|
|
107
|
+
React.useEffect(() => {
|
|
108
|
+
if (!value && markerRef.current) {
|
|
109
|
+
markerRef.current.map = null;
|
|
110
|
+
markerRef.current = null;
|
|
111
|
+
} else if (value && mapRef.current) {
|
|
112
|
+
setMarkerRef.current?.(value.latitude, value.longitude);
|
|
113
|
+
mapRef.current.panTo({ lat: value.latitude, lng: value.longitude });
|
|
114
|
+
}
|
|
115
|
+
}, [value]);
|
|
116
|
+
return /* @__PURE__ */ jsx("div", { ref: elementRef, "data-location-map": "google", className: cn("absolute inset-0 z-0 h-full min-h-72 w-full", reducedMotion && "[&_*]:!transition-none", className) });
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function createGoogleLocationAdapter(options) {
|
|
120
|
+
return { id: "google", Map: createMapComponent(options) };
|
|
121
|
+
}
|
|
122
|
+
function createGooglePlacesGeocoder(options) {
|
|
123
|
+
let token = null;
|
|
124
|
+
const predictions = /* @__PURE__ */ new Map();
|
|
125
|
+
return {
|
|
126
|
+
id: "google-places",
|
|
127
|
+
async search(query, context) {
|
|
128
|
+
if (context.signal.aborted) return [];
|
|
129
|
+
configure(options);
|
|
130
|
+
const { AutocompleteSessionToken, AutocompleteSuggestion } = await importLibrary("places");
|
|
131
|
+
token ??= new AutocompleteSessionToken();
|
|
132
|
+
const response = await AutocompleteSuggestion.fetchAutocompleteSuggestions({
|
|
133
|
+
input: query,
|
|
134
|
+
sessionToken: token,
|
|
135
|
+
language: context.language,
|
|
136
|
+
locationBias: { lat: context.center.latitude, lng: context.center.longitude }
|
|
137
|
+
});
|
|
138
|
+
if (context.signal.aborted) return [];
|
|
139
|
+
predictions.clear();
|
|
140
|
+
return response.suggestions.flatMap((suggestion) => {
|
|
141
|
+
const prediction = suggestion.placePrediction;
|
|
142
|
+
if (!prediction) return [];
|
|
143
|
+
predictions.set(prediction.placeId, prediction);
|
|
144
|
+
return [{ id: prediction.placeId, providerId: prediction.placeId, label: prediction.mainText?.toString() ?? prediction.text.toString(), description: prediction.secondaryText?.toString() }];
|
|
145
|
+
});
|
|
146
|
+
},
|
|
147
|
+
async resolve(candidate, signal) {
|
|
148
|
+
const prediction = predictions.get(candidate.providerId ?? candidate.id);
|
|
149
|
+
if (!prediction) throw new Error("Place prediction expired");
|
|
150
|
+
const place = prediction.toPlace();
|
|
151
|
+
await place.fetchFields({ fields: ["formattedAddress", "location", "displayName"] });
|
|
152
|
+
token = null;
|
|
153
|
+
predictions.clear();
|
|
154
|
+
if (signal.aborted || !place.location) throw new DOMException("Aborted", "AbortError");
|
|
155
|
+
return {
|
|
156
|
+
...candidate,
|
|
157
|
+
label: place.formattedAddress || place.displayName || candidate.label,
|
|
158
|
+
coordinates: { latitude: place.location.lat(), longitude: place.location.lng() }
|
|
159
|
+
};
|
|
160
|
+
},
|
|
161
|
+
async reverse(coordinates, signal) {
|
|
162
|
+
configure(options);
|
|
163
|
+
const { Geocoder } = await importLibrary("geocoding");
|
|
164
|
+
if (signal.aborted) return null;
|
|
165
|
+
const response = await new Geocoder().geocode({
|
|
166
|
+
location: { lat: coordinates.latitude, lng: coordinates.longitude }
|
|
167
|
+
});
|
|
168
|
+
if (signal.aborted || !response.results[0]) return null;
|
|
169
|
+
const result = response.results[0];
|
|
170
|
+
return {
|
|
171
|
+
id: result.place_id,
|
|
172
|
+
providerId: result.place_id,
|
|
173
|
+
label: result.formatted_address,
|
|
174
|
+
coordinates
|
|
175
|
+
};
|
|
176
|
+
},
|
|
177
|
+
resetSession() {
|
|
178
|
+
token = null;
|
|
179
|
+
predictions.clear();
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export { createGoogleLocationAdapter, createGooglePlacesGeocoder };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { K as NLocationInputProps, J as NLocationDialogProps, V as NLocationProviderProps, z as NCoordinates, Q as NLocationLabels, u as FormLocationInputProps, W as NLocationValue } from '../types-BQBx0RZd.js';
|
|
3
|
+
export { G as GoogleLocationAdapterOptions, L as LeafletLocationAdapterOptions, B as NLocationCandidate, H as NLocationClassNames, a as NLocationGeocoderAdapter, N as NLocationMapAdapter, ad as NLocationMapControls, U as NLocationMapProps, ae as NLocationSearchContext } from '../types-BQBx0RZd.js';
|
|
4
|
+
import 'react-hook-form';
|
|
5
|
+
import 'zod';
|
|
6
|
+
import 'culori';
|
|
7
|
+
import '../NIcon-D73-C51g.js';
|
|
8
|
+
import '../formFill-CQkTA0JS.js';
|
|
9
|
+
import 'class-variance-authority/types';
|
|
10
|
+
import '@radix-ui/react-slider';
|
|
11
|
+
|
|
12
|
+
declare const NLocationInput: React__default.ForwardRefExoticComponent<NLocationInputProps & React__default.RefAttributes<HTMLInputElement>>;
|
|
13
|
+
|
|
14
|
+
declare function NLocationDialog({ open, value, onOpenChange, onConfirm, labels: labelOverrides, classNames }: NLocationDialogProps): React__default.JSX.Element;
|
|
15
|
+
|
|
16
|
+
interface NLocationContextValue {
|
|
17
|
+
adapter: NLocationProviderProps["adapter"];
|
|
18
|
+
geocoder: NLocationProviderProps["geocoder"];
|
|
19
|
+
defaultCenter: NCoordinates;
|
|
20
|
+
defaultZoom: number;
|
|
21
|
+
labels: NLocationLabels;
|
|
22
|
+
searchMode: "submit" | "autocomplete";
|
|
23
|
+
unavailableReason?: string;
|
|
24
|
+
}
|
|
25
|
+
declare function NLocationProvider({ children, adapter, geocoder, defaultCenter, defaultZoom, labels, searchMode, unavailableReason, }: NLocationProviderProps): React__default.JSX.Element;
|
|
26
|
+
declare function useNLocationProvider(): NLocationContextValue;
|
|
27
|
+
|
|
28
|
+
declare function FormLocationInput({ name, formLabel, formDescription, required, disabled, readOnly, hidden, background, classNames, onChange: consumerOnChange, ...props }: FormLocationInputProps): React__default.JSX.Element;
|
|
29
|
+
|
|
30
|
+
declare function isCompleteCoordinatePair(value: Pick<NLocationValue, "latitude" | "longitude">): boolean;
|
|
31
|
+
declare function normalizeLocationValue(value?: Partial<NLocationValue> | null): NLocationValue;
|
|
32
|
+
|
|
33
|
+
export { FormLocationInput, FormLocationInputProps, NCoordinates, NLocationDialog, NLocationDialogProps, NLocationInput, NLocationInputProps, NLocationLabels, NLocationProvider, NLocationProviderProps, NLocationValue, isCompleteCoordinatePair, normalizeLocationValue, useNLocationProvider };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
export { FormLocationInput, NLocationDialog, NLocationInput, NLocationProvider, isCompleteCoordinatePair, normalizeLocationValue, useNLocationProvider } from '../chunk-GYPQLOQ5.mjs';
|
|
3
|
+
import '../chunk-FZX3DONZ.mjs';
|
|
4
|
+
import '../chunk-BFFTC7LD.mjs';
|
|
5
|
+
import '../chunk-QJ22WAQY.mjs';
|
|
6
|
+
import '../chunk-WHGRN7PP.mjs';
|
|
7
|
+
import '../chunk-TZRTOQCC.mjs';
|
|
8
|
+
import '../chunk-5UY7U2ED.mjs';
|
|
9
|
+
import '../chunk-TFHWLE7N.mjs';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { L as LeafletLocationAdapterOptions, N as NLocationMapAdapter } from '../types-BQBx0RZd.js';
|
|
2
|
+
import 'react';
|
|
3
|
+
import 'react-hook-form';
|
|
4
|
+
import 'zod';
|
|
5
|
+
import 'culori';
|
|
6
|
+
import '../NIcon-D73-C51g.js';
|
|
7
|
+
import '../formFill-CQkTA0JS.js';
|
|
8
|
+
import 'class-variance-authority/types';
|
|
9
|
+
import '@radix-ui/react-slider';
|
|
10
|
+
|
|
11
|
+
declare function createLeafletLocationAdapter(options: LeafletLocationAdapterOptions): NLocationMapAdapter;
|
|
12
|
+
|
|
13
|
+
export { createLeafletLocationAdapter };
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { locationMarkerUrl } from '../chunk-A34LRQYI.mjs';
|
|
3
|
+
import { cn } from '../chunk-5UY7U2ED.mjs';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import 'leaflet/dist/leaflet.css';
|
|
6
|
+
import { jsx } from 'react/jsx-runtime';
|
|
7
|
+
|
|
8
|
+
var leafletPromise = null;
|
|
9
|
+
function loadLeaflet() {
|
|
10
|
+
leafletPromise ??= import('leaflet');
|
|
11
|
+
return leafletPromise;
|
|
12
|
+
}
|
|
13
|
+
function createMapComponent(options) {
|
|
14
|
+
return function LeafletLocationMap({ value, initialCenter, initialZoom, onChange, onReady, onLoadingChange, onError, onControlsReady, reducedMotion, className }) {
|
|
15
|
+
const elementRef = React.useRef(null);
|
|
16
|
+
const mapRef = React.useRef(null);
|
|
17
|
+
const markerRef = React.useRef(null);
|
|
18
|
+
const setMarkerRef = React.useRef(null);
|
|
19
|
+
const onChangeRef = React.useRef(onChange);
|
|
20
|
+
const valueRef = React.useRef(value);
|
|
21
|
+
onChangeRef.current = onChange;
|
|
22
|
+
valueRef.current = value;
|
|
23
|
+
React.useEffect(() => {
|
|
24
|
+
const element = elementRef.current;
|
|
25
|
+
if (!element || mapRef.current) return;
|
|
26
|
+
let active = true;
|
|
27
|
+
let map = null;
|
|
28
|
+
let resizeFrame = null;
|
|
29
|
+
let resizeObserver = null;
|
|
30
|
+
const settleTimers = [];
|
|
31
|
+
const scheduleResize = () => {
|
|
32
|
+
if (!active || !map) return;
|
|
33
|
+
if (resizeFrame !== null) cancelAnimationFrame(resizeFrame);
|
|
34
|
+
resizeFrame = requestAnimationFrame(() => {
|
|
35
|
+
resizeFrame = null;
|
|
36
|
+
if (!active || !map || mapRef.current !== map || !element.isConnected) return;
|
|
37
|
+
map.invalidateSize({ animate: false, pan: false });
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
onLoadingChange?.(true);
|
|
41
|
+
void (async () => {
|
|
42
|
+
try {
|
|
43
|
+
const L = await loadLeaflet();
|
|
44
|
+
if (!active || !element.isConnected) return;
|
|
45
|
+
const currentValue = valueRef.current;
|
|
46
|
+
const center = currentValue ?? initialCenter;
|
|
47
|
+
const markerIcon = L.icon({
|
|
48
|
+
iconUrl: locationMarkerUrl,
|
|
49
|
+
iconSize: [40, 50],
|
|
50
|
+
iconAnchor: [20, 46]
|
|
51
|
+
});
|
|
52
|
+
map = L.map(element, {
|
|
53
|
+
center: [center.latitude, center.longitude],
|
|
54
|
+
zoom: initialZoom,
|
|
55
|
+
zoomControl: false,
|
|
56
|
+
attributionControl: true,
|
|
57
|
+
keyboard: false,
|
|
58
|
+
fadeAnimation: !reducedMotion,
|
|
59
|
+
zoomAnimation: !reducedMotion,
|
|
60
|
+
markerZoomAnimation: !reducedMotion
|
|
61
|
+
});
|
|
62
|
+
mapRef.current = map;
|
|
63
|
+
map.attributionControl.setPrefix(false);
|
|
64
|
+
map.attributionControl.setPosition("topright");
|
|
65
|
+
L.tileLayer(options.tileUrl, {
|
|
66
|
+
attribution: options.attribution,
|
|
67
|
+
maxZoom: options.tileOptions?.maxZoom ?? 19,
|
|
68
|
+
minZoom: options.tileOptions?.minZoom ?? 1
|
|
69
|
+
}).addTo(map);
|
|
70
|
+
const setMarker = (latitude, longitude) => {
|
|
71
|
+
if (!map) return;
|
|
72
|
+
if (!markerRef.current) {
|
|
73
|
+
const marker = L.marker([latitude, longitude], { draggable: true, icon: markerIcon }).addTo(map);
|
|
74
|
+
marker.on("dragend", () => {
|
|
75
|
+
const point = marker.getLatLng();
|
|
76
|
+
onChangeRef.current({ latitude: point.lat, longitude: point.lng });
|
|
77
|
+
});
|
|
78
|
+
markerRef.current = marker;
|
|
79
|
+
} else {
|
|
80
|
+
markerRef.current.setLatLng([latitude, longitude]);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
setMarkerRef.current = setMarker;
|
|
84
|
+
if (currentValue) setMarker(currentValue.latitude, currentValue.longitude);
|
|
85
|
+
map.on("click", (event) => {
|
|
86
|
+
setMarker(event.latlng.lat, event.latlng.lng);
|
|
87
|
+
onChangeRef.current({ latitude: event.latlng.lat, longitude: event.latlng.lng });
|
|
88
|
+
});
|
|
89
|
+
onControlsReady?.({
|
|
90
|
+
zoomIn: () => active && mapRef.current === map && map?.zoomIn(),
|
|
91
|
+
zoomOut: () => active && mapRef.current === map && map?.zoomOut(),
|
|
92
|
+
recenter: (point) => {
|
|
93
|
+
if (active && mapRef.current === map) {
|
|
94
|
+
map?.setView([point.latitude, point.longitude], map.getZoom(), { animate: !reducedMotion });
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
99
|
+
resizeObserver = new ResizeObserver(scheduleResize);
|
|
100
|
+
resizeObserver.observe(element);
|
|
101
|
+
}
|
|
102
|
+
window.addEventListener("resize", scheduleResize);
|
|
103
|
+
scheduleResize();
|
|
104
|
+
for (const delay of [80, 200, 400]) {
|
|
105
|
+
settleTimers.push(window.setTimeout(scheduleResize, delay));
|
|
106
|
+
}
|
|
107
|
+
onLoadingChange?.(false);
|
|
108
|
+
onReady?.();
|
|
109
|
+
} catch {
|
|
110
|
+
if (!active) return;
|
|
111
|
+
active = false;
|
|
112
|
+
if (resizeFrame !== null) cancelAnimationFrame(resizeFrame);
|
|
113
|
+
settleTimers.forEach((timer) => window.clearTimeout(timer));
|
|
114
|
+
resizeObserver?.disconnect();
|
|
115
|
+
window.removeEventListener("resize", scheduleResize);
|
|
116
|
+
map?.off();
|
|
117
|
+
map?.remove();
|
|
118
|
+
map = null;
|
|
119
|
+
mapRef.current = null;
|
|
120
|
+
setMarkerRef.current = null;
|
|
121
|
+
onLoadingChange?.(false);
|
|
122
|
+
onError?.(new Error("Leaflet map unavailable"));
|
|
123
|
+
}
|
|
124
|
+
})();
|
|
125
|
+
return () => {
|
|
126
|
+
active = false;
|
|
127
|
+
if (resizeFrame !== null) cancelAnimationFrame(resizeFrame);
|
|
128
|
+
settleTimers.forEach((timer) => window.clearTimeout(timer));
|
|
129
|
+
resizeObserver?.disconnect();
|
|
130
|
+
window.removeEventListener("resize", scheduleResize);
|
|
131
|
+
onControlsReady?.(null);
|
|
132
|
+
markerRef.current?.off();
|
|
133
|
+
markerRef.current = null;
|
|
134
|
+
setMarkerRef.current = null;
|
|
135
|
+
map?.off();
|
|
136
|
+
map?.remove();
|
|
137
|
+
mapRef.current = null;
|
|
138
|
+
};
|
|
139
|
+
}, []);
|
|
140
|
+
React.useEffect(() => {
|
|
141
|
+
const map = mapRef.current;
|
|
142
|
+
if (!map) return;
|
|
143
|
+
if (!value) {
|
|
144
|
+
if (markerRef.current) {
|
|
145
|
+
markerRef.current.off();
|
|
146
|
+
markerRef.current.removeFrom(map);
|
|
147
|
+
markerRef.current = null;
|
|
148
|
+
}
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
setMarkerRef.current?.(value.latitude, value.longitude);
|
|
152
|
+
map.setView([value.latitude, value.longitude], map.getZoom(), { animate: !reducedMotion });
|
|
153
|
+
}, [reducedMotion, value]);
|
|
154
|
+
return /* @__PURE__ */ jsx(
|
|
155
|
+
"div",
|
|
156
|
+
{
|
|
157
|
+
ref: elementRef,
|
|
158
|
+
"data-location-map": "leaflet",
|
|
159
|
+
className: cn("nlocation-leaflet absolute inset-0 z-0 h-full w-full", className)
|
|
160
|
+
}
|
|
161
|
+
);
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
function createLeafletLocationAdapter(options) {
|
|
165
|
+
return { id: "leaflet", Map: createMapComponent(options) };
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export { createLeafletLocationAdapter };
|
package/dist/theme.css
CHANGED
|
@@ -405,11 +405,32 @@ input:autofill {
|
|
|
405
405
|
}
|
|
406
406
|
|
|
407
407
|
/* Darker, more subtle handle in dark mode */
|
|
408
|
-
.dark .os-scrollbar.os-theme-najm {
|
|
408
|
+
.dark .os-scrollbar.os-theme-najm {
|
|
409
409
|
--os-handle-bg: rgba(113, 113, 122, 0.36);
|
|
410
410
|
--os-handle-bg-hover: rgba(161, 161, 170, 0.62);
|
|
411
411
|
--os-handle-bg-active: rgba(212, 212, 216, 0.72);
|
|
412
|
-
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/* Leaflet's structural CSS is imported by the optional adapter entrypoint.
|
|
415
|
+
These rules only connect its visual treatment to Najm theme tokens. */
|
|
416
|
+
.nlocation-leaflet.leaflet-container {
|
|
417
|
+
background: var(--muted);
|
|
418
|
+
font: inherit;
|
|
419
|
+
}
|
|
420
|
+
.nlocation-leaflet .leaflet-control-attribution {
|
|
421
|
+
margin: 0;
|
|
422
|
+
padding: 2px 5px;
|
|
423
|
+
background: color-mix(in oklab, var(--card) 88%, transparent);
|
|
424
|
+
color: var(--muted-foreground);
|
|
425
|
+
font-size: 10px;
|
|
426
|
+
line-height: 1.3;
|
|
427
|
+
}
|
|
428
|
+
.nlocation-leaflet .leaflet-control-attribution a { color: var(--foreground); text-decoration: underline; }
|
|
429
|
+
|
|
430
|
+
@media (prefers-reduced-motion: reduce) {
|
|
431
|
+
.nlocation-dialog *,
|
|
432
|
+
.nlocation-leaflet * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
|
|
433
|
+
}
|
|
413
434
|
|
|
414
435
|
|
|
415
436
|
/* overlayscrollbars */
|