@datum-cloud/datum-ui 0.2.0-alpha.1 → 0.2.0-alpha.3
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 +311 -0
- package/dist/_shadcn/ui/map-leaflet-imports.d.ts +7 -0
- package/dist/_shadcn/ui/map-leaflet-imports.d.ts.map +1 -0
- package/dist/_shadcn/ui/map.d.ts +1 -6
- package/dist/_shadcn/ui/map.d.ts.map +1 -1
- package/dist/components/base/index.d.ts +3 -0
- package/dist/components/base/index.d.ts.map +1 -1
- package/dist/components/base/typography/index.d.ts +2 -0
- package/dist/components/base/typography/index.d.ts.map +1 -0
- package/dist/components/base/typography/typography.d.ts +1182 -0
- package/dist/components/base/typography/typography.d.ts.map +1 -0
- package/dist/components/index.mjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/map-leaflet-imports-OKaoesjZ.mjs +8 -0
- package/dist/style.css +154 -0
- package/dist/{theme-script-CS7JSmQs.mjs → theme-script-DHyLk25i.mjs} +1289 -15
- package/package.json +35 -1
|
@@ -3,9 +3,9 @@ import { n as SpinnerIcon, t as Icon } from "./icon-wrapper-BgPkifId.mjs";
|
|
|
3
3
|
import { t as CloseIcon } from "./close.icon-chkXPAUC.mjs";
|
|
4
4
|
import { n as toast$1, t as useCopyToClipboard } from "./use-copy-to-clipboard-BfrpD6G8.mjs";
|
|
5
5
|
import { cva } from "class-variance-authority";
|
|
6
|
-
import { Ban, Calendar, CalendarIcon, CheckCircle2, CheckIcon, ChevronDown, ChevronDownIcon, ChevronLeftIcon, ChevronRight, ChevronRightIcon, ChevronUp, ChevronUpIcon, CircleAlert, CircleCheck, CircleHelp, CircleIcon, CircleXIcon, CopyIcon, CornerDownRightIcon, Ellipsis, ExternalLinkIcon, FileIcon, Globe, ListTodo, Loader2Icon, MoreHorizontal, PanelLeftCloseIcon, PanelLeftOpenIcon, SearchIcon, UploadIcon, X, XCircle, XIcon } from "lucide-react";
|
|
6
|
+
import { Ban, Calendar, CalendarIcon, CheckCircle2, CheckIcon, ChevronDown, ChevronDownIcon, ChevronLeftIcon, ChevronRight, ChevronRightIcon, ChevronUp, ChevronUpIcon, CircleAlert, CircleCheck, CircleHelp, CircleIcon, CircleXIcon, CopyIcon, CornerDownRightIcon, Ellipsis, ExternalLinkIcon, FileIcon, Globe, LayersIcon, ListTodo, Loader2Icon, LoaderCircleIcon, MapPinIcon, MaximizeIcon, MinimizeIcon, MinusIcon, MoreHorizontal, NavigationIcon, PanelLeftCloseIcon, PanelLeftOpenIcon, PenLineIcon, PentagonIcon, PlusIcon, SearchIcon, SquareIcon, Trash2Icon, Undo2Icon, UploadIcon, WaypointsIcon, X, XCircle, XIcon } from "lucide-react";
|
|
7
7
|
import * as React$1 from "react";
|
|
8
|
-
import React, { Fragment, createContext, use, useCallback, useEffect, useId, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
8
|
+
import React, { Fragment, Suspense, createContext, lazy, use, useCallback, useContext, useEffect, useId, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
9
9
|
import { clsx } from "clsx";
|
|
10
10
|
import { twMerge } from "tailwind-merge";
|
|
11
11
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -19,6 +19,8 @@ import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
|
19
19
|
import { Command } from "cmdk";
|
|
20
20
|
import * as HoverCardPrimitive from "@radix-ui/react-hover-card";
|
|
21
21
|
import * as LabelPrimitive from "@radix-ui/react-label";
|
|
22
|
+
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
23
|
+
import { renderToString } from "react-dom/server.browser";
|
|
22
24
|
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
|
23
25
|
import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
|
|
24
26
|
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
@@ -30,7 +32,6 @@ import { useVirtualizer } from "@tanstack/react-virtual";
|
|
|
30
32
|
import * as AvatarPrimitive from "@radix-ui/react-avatar";
|
|
31
33
|
import { endOfDay, endOfMonth, endOfWeek, endOfYear, format, formatDistanceToNowStrict, isSameDay, isSameYear, parse, startOfDay, startOfMonth, startOfWeek, startOfYear, subDays, subHours, subMinutes } from "date-fns";
|
|
32
34
|
import { formatInTimeZone, fromZonedTime, toDate, toZonedTime } from "date-fns-tz";
|
|
33
|
-
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
34
35
|
import { useDropzone } from "react-dropzone";
|
|
35
36
|
import { FormProvider, getFormProps, getInputProps, getTextareaProps, useForm, useFormMetadata, useInputControl } from "@conform-to/react";
|
|
36
37
|
import { Toaster } from "sonner";
|
|
@@ -1447,6 +1448,1097 @@ function Label({ ref, className, ...props }) {
|
|
|
1447
1448
|
}
|
|
1448
1449
|
Label.displayName = "Label";
|
|
1449
1450
|
|
|
1451
|
+
//#endregion
|
|
1452
|
+
//#region ../shadcn/hooks/use-theme.ts
|
|
1453
|
+
/**
|
|
1454
|
+
* Lightweight theme detection hook for shadcn components.
|
|
1455
|
+
* Detects dark mode via the `dark` class on <html> (Tailwind convention)
|
|
1456
|
+
* or falls back to prefers-color-scheme media query.
|
|
1457
|
+
*/
|
|
1458
|
+
function useTheme() {
|
|
1459
|
+
const [resolvedTheme, setResolvedTheme] = React$1.useState("light");
|
|
1460
|
+
React$1.useEffect(() => {
|
|
1461
|
+
const detect = () => {
|
|
1462
|
+
if (document.documentElement.classList.contains("dark")) return "dark";
|
|
1463
|
+
if (window.matchMedia("(prefers-color-scheme: dark)").matches) return "dark";
|
|
1464
|
+
return "light";
|
|
1465
|
+
};
|
|
1466
|
+
setResolvedTheme(detect());
|
|
1467
|
+
const observer = new MutationObserver(() => setResolvedTheme(detect()));
|
|
1468
|
+
observer.observe(document.documentElement, {
|
|
1469
|
+
attributes: true,
|
|
1470
|
+
attributeFilter: ["class"]
|
|
1471
|
+
});
|
|
1472
|
+
const mql = window.matchMedia("(prefers-color-scheme: dark)");
|
|
1473
|
+
const onChange = () => setResolvedTheme(detect());
|
|
1474
|
+
mql.addEventListener("change", onChange);
|
|
1475
|
+
return () => {
|
|
1476
|
+
observer.disconnect();
|
|
1477
|
+
mql.removeEventListener("change", onChange);
|
|
1478
|
+
};
|
|
1479
|
+
}, []);
|
|
1480
|
+
return { resolvedTheme };
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
//#endregion
|
|
1484
|
+
//#region ../shadcn/ui/dropdown-menu.tsx
|
|
1485
|
+
/**
|
|
1486
|
+
* Vanilla shadcn/ui DropdownMenu Component
|
|
1487
|
+
* Pure shadcn dropdown without Datum customizations
|
|
1488
|
+
* For Datum-specific features (destructive MenuItem), import from @/modules/datum-ui
|
|
1489
|
+
*/
|
|
1490
|
+
const DropdownMenu$1 = DropdownMenuPrimitive.Root;
|
|
1491
|
+
const DropdownMenuTrigger$1 = DropdownMenuPrimitive.Trigger;
|
|
1492
|
+
const DropdownMenuGroup$1 = DropdownMenuPrimitive.Group;
|
|
1493
|
+
const DropdownMenuPortal$1 = DropdownMenuPrimitive.Portal;
|
|
1494
|
+
const DropdownMenuSub$1 = DropdownMenuPrimitive.Sub;
|
|
1495
|
+
const DropdownMenuRadioGroup$1 = DropdownMenuPrimitive.RadioGroup;
|
|
1496
|
+
const DropdownMenuSubTrigger$1 = React$1.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs(DropdownMenuPrimitive.SubTrigger, {
|
|
1497
|
+
ref,
|
|
1498
|
+
className: cn("focus:bg-accent data-[state=open]:bg-accent flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", inset && "pl-8", className),
|
|
1499
|
+
...props,
|
|
1500
|
+
children: [children, /* @__PURE__ */ jsx(ChevronRightIcon, { className: "ml-auto" })]
|
|
1501
|
+
}));
|
|
1502
|
+
DropdownMenuSubTrigger$1.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
|
|
1503
|
+
const DropdownMenuSubContent$1 = React$1.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.SubContent, {
|
|
1504
|
+
ref,
|
|
1505
|
+
className: cn("bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] overflow-hidden rounded-md border p-1 shadow-lg", className),
|
|
1506
|
+
...props
|
|
1507
|
+
}));
|
|
1508
|
+
DropdownMenuSubContent$1.displayName = DropdownMenuPrimitive.SubContent.displayName;
|
|
1509
|
+
const DropdownMenuContent$1 = React$1.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.Content, {
|
|
1510
|
+
ref,
|
|
1511
|
+
sideOffset,
|
|
1512
|
+
className: cn("bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] overflow-hidden rounded-md border p-1 shadow-md", className),
|
|
1513
|
+
...props
|
|
1514
|
+
}) }));
|
|
1515
|
+
DropdownMenuContent$1.displayName = DropdownMenuPrimitive.Content.displayName;
|
|
1516
|
+
const DropdownMenuItem$1 = React$1.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Item, {
|
|
1517
|
+
ref,
|
|
1518
|
+
className: cn("focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm transition-colors outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", inset && "pl-8", className),
|
|
1519
|
+
...props
|
|
1520
|
+
}));
|
|
1521
|
+
DropdownMenuItem$1.displayName = DropdownMenuPrimitive.Item.displayName;
|
|
1522
|
+
const DropdownMenuCheckboxItem$1 = React$1.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs(DropdownMenuPrimitive.CheckboxItem, {
|
|
1523
|
+
ref,
|
|
1524
|
+
className: cn("focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center rounded-sm py-1.5 pr-2 pl-8 text-sm transition-colors outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50", className),
|
|
1525
|
+
checked,
|
|
1526
|
+
...props,
|
|
1527
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
1528
|
+
className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center",
|
|
1529
|
+
children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, { className: "h-4 w-4" }) })
|
|
1530
|
+
}), children]
|
|
1531
|
+
}));
|
|
1532
|
+
DropdownMenuCheckboxItem$1.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
|
|
1533
|
+
const DropdownMenuRadioItem$1 = React$1.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(DropdownMenuPrimitive.RadioItem, {
|
|
1534
|
+
ref,
|
|
1535
|
+
className: cn("focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center rounded-sm py-1.5 pr-2 pl-8 text-sm transition-colors outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50", className),
|
|
1536
|
+
...props,
|
|
1537
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
1538
|
+
className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center",
|
|
1539
|
+
children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CircleIcon, { className: "h-2 w-2 fill-current" }) })
|
|
1540
|
+
}), children]
|
|
1541
|
+
}));
|
|
1542
|
+
DropdownMenuRadioItem$1.displayName = DropdownMenuPrimitive.RadioItem.displayName;
|
|
1543
|
+
const DropdownMenuLabel$1 = React$1.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Label, {
|
|
1544
|
+
ref,
|
|
1545
|
+
className: cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className),
|
|
1546
|
+
...props
|
|
1547
|
+
}));
|
|
1548
|
+
DropdownMenuLabel$1.displayName = DropdownMenuPrimitive.Label.displayName;
|
|
1549
|
+
const DropdownMenuSeparator$1 = React$1.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Separator, {
|
|
1550
|
+
ref,
|
|
1551
|
+
className: cn("bg-muted -mx-1 my-1 h-px", className),
|
|
1552
|
+
...props
|
|
1553
|
+
}));
|
|
1554
|
+
DropdownMenuSeparator$1.displayName = DropdownMenuPrimitive.Separator.displayName;
|
|
1555
|
+
const DropdownMenuShortcut$1 = ({ className, ...props }) => {
|
|
1556
|
+
return /* @__PURE__ */ jsx("span", {
|
|
1557
|
+
className: cn("ml-auto text-xs tracking-widest opacity-60", className),
|
|
1558
|
+
...props
|
|
1559
|
+
});
|
|
1560
|
+
};
|
|
1561
|
+
DropdownMenuShortcut$1.displayName = "DropdownMenuShortcut";
|
|
1562
|
+
|
|
1563
|
+
//#endregion
|
|
1564
|
+
//#region ../shadcn/ui/spinner.tsx
|
|
1565
|
+
function Spinner({ className, ...props }) {
|
|
1566
|
+
return /* @__PURE__ */ jsx(Loader2Icon, {
|
|
1567
|
+
role: "status",
|
|
1568
|
+
"aria-label": "Loading",
|
|
1569
|
+
className: cn("size-4 animate-spin", className),
|
|
1570
|
+
...props
|
|
1571
|
+
});
|
|
1572
|
+
}
|
|
1573
|
+
|
|
1574
|
+
//#endregion
|
|
1575
|
+
//#region ../shadcn/ui/place-autocomplete.tsx
|
|
1576
|
+
function formatAddress(properties) {
|
|
1577
|
+
const parts = [];
|
|
1578
|
+
if (properties.name) parts.push(properties.name);
|
|
1579
|
+
if (properties.housenumber && properties.street) parts.push(`${properties.housenumber} ${properties.street}`);
|
|
1580
|
+
else if (properties.street) parts.push(properties.street);
|
|
1581
|
+
if (properties.city) parts.push(properties.city);
|
|
1582
|
+
else if (properties.locality) parts.push(properties.locality);
|
|
1583
|
+
if (properties.state && properties.state !== properties.city) parts.push(properties.state);
|
|
1584
|
+
if (properties.country) parts.push(properties.country);
|
|
1585
|
+
return [...new Set(parts)].join(", ");
|
|
1586
|
+
}
|
|
1587
|
+
function buildSearchUrl({ query, bbox, lang, lat, limit, locationBiasScale, lon, zoom }) {
|
|
1588
|
+
const url = new URL("https://photon.komoot.io/api");
|
|
1589
|
+
url.searchParams.set("q", query);
|
|
1590
|
+
if (lang) url.searchParams.set("lang", lang);
|
|
1591
|
+
if (limit) url.searchParams.set("limit", String(limit));
|
|
1592
|
+
if (bbox) url.searchParams.set("bbox", bbox.join(","));
|
|
1593
|
+
if (lat !== void 0 && lon !== void 0) {
|
|
1594
|
+
url.searchParams.set("lat", String(lat));
|
|
1595
|
+
url.searchParams.set("lon", String(lon));
|
|
1596
|
+
}
|
|
1597
|
+
if (zoom !== void 0) url.searchParams.set("zoom", String(zoom));
|
|
1598
|
+
if (locationBiasScale !== void 0) url.searchParams.set("location_bias_scale", String(locationBiasScale));
|
|
1599
|
+
return String(url);
|
|
1600
|
+
}
|
|
1601
|
+
function useDebounce(value, delay = 300) {
|
|
1602
|
+
const [debouncedValue, setDebouncedValue] = React$1.useState(value);
|
|
1603
|
+
React$1.useEffect(() => {
|
|
1604
|
+
const timer = setTimeout(() => setDebouncedValue(value), delay);
|
|
1605
|
+
return () => clearTimeout(timer);
|
|
1606
|
+
}, [value, delay]);
|
|
1607
|
+
return debouncedValue;
|
|
1608
|
+
}
|
|
1609
|
+
function usePlaceSearch({ debounceMs, query, ...props }) {
|
|
1610
|
+
const [results, setResults] = React$1.useState([]);
|
|
1611
|
+
const [isLoading, setIsLoading] = React$1.useState(false);
|
|
1612
|
+
const [error, setError] = React$1.useState(null);
|
|
1613
|
+
const [hasSearched, setHasSearched] = React$1.useState(false);
|
|
1614
|
+
const debouncedQuery = useDebounce(query, debounceMs);
|
|
1615
|
+
React$1.useEffect(() => {
|
|
1616
|
+
if (!debouncedQuery.trim()) {
|
|
1617
|
+
setResults([]);
|
|
1618
|
+
setIsLoading(false);
|
|
1619
|
+
setHasSearched(false);
|
|
1620
|
+
return;
|
|
1621
|
+
}
|
|
1622
|
+
const abortController = new AbortController();
|
|
1623
|
+
async function fetchResults() {
|
|
1624
|
+
setIsLoading(true);
|
|
1625
|
+
setError(null);
|
|
1626
|
+
setHasSearched(true);
|
|
1627
|
+
try {
|
|
1628
|
+
const url = buildSearchUrl({
|
|
1629
|
+
query: debouncedQuery,
|
|
1630
|
+
...props
|
|
1631
|
+
});
|
|
1632
|
+
const response = await fetch(url, { signal: abortController.signal });
|
|
1633
|
+
if (!response.ok) throw new Error(`Photon API error: ${response.status} ${response.statusText}`);
|
|
1634
|
+
const data = await response.json();
|
|
1635
|
+
const addressOsmIds = /* @__PURE__ */ new Set();
|
|
1636
|
+
setResults(data.features.filter((feature) => {
|
|
1637
|
+
const id = feature.properties.osm_id;
|
|
1638
|
+
if (addressOsmIds.has(id)) return false;
|
|
1639
|
+
addressOsmIds.add(id);
|
|
1640
|
+
return true;
|
|
1641
|
+
}));
|
|
1642
|
+
} catch (err) {
|
|
1643
|
+
if (err instanceof Error && err.name !== "AbortError") {
|
|
1644
|
+
setError(err);
|
|
1645
|
+
setResults([]);
|
|
1646
|
+
}
|
|
1647
|
+
} finally {
|
|
1648
|
+
setIsLoading(false);
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
fetchResults();
|
|
1652
|
+
return () => abortController.abort();
|
|
1653
|
+
}, [
|
|
1654
|
+
debouncedQuery,
|
|
1655
|
+
props.lang,
|
|
1656
|
+
props.limit,
|
|
1657
|
+
props.bbox,
|
|
1658
|
+
props.lat,
|
|
1659
|
+
props.lon,
|
|
1660
|
+
props.zoom,
|
|
1661
|
+
props.locationBiasScale
|
|
1662
|
+
]);
|
|
1663
|
+
return {
|
|
1664
|
+
results,
|
|
1665
|
+
isLoading,
|
|
1666
|
+
error,
|
|
1667
|
+
hasSearched
|
|
1668
|
+
};
|
|
1669
|
+
}
|
|
1670
|
+
function PlaceAutocomplete({ debounceMs = 300, lang, limit = 5, bbox, lat, lon, zoom, locationBiasScale, className, value: controlledValue, defaultValue = "", onChange: controlledOnChange, onPlaceSelect, onResultsChange, ...props }) {
|
|
1671
|
+
const [internalValue, setInternalValue] = React$1.useState(defaultValue);
|
|
1672
|
+
const [searchQuery, setSearchQuery] = React$1.useState("");
|
|
1673
|
+
const isControlled = controlledValue !== void 0;
|
|
1674
|
+
const displayValue = isControlled ? controlledValue : internalValue;
|
|
1675
|
+
const { results, isLoading, error, hasSearched } = usePlaceSearch({
|
|
1676
|
+
query: searchQuery,
|
|
1677
|
+
debounceMs,
|
|
1678
|
+
lang,
|
|
1679
|
+
limit,
|
|
1680
|
+
bbox,
|
|
1681
|
+
lat,
|
|
1682
|
+
lon,
|
|
1683
|
+
zoom,
|
|
1684
|
+
locationBiasScale
|
|
1685
|
+
});
|
|
1686
|
+
React$1.useEffect(() => {
|
|
1687
|
+
onResultsChange?.(results);
|
|
1688
|
+
}, [results, onResultsChange]);
|
|
1689
|
+
const hasNoResults = hasSearched && !isLoading && !error && results.length === 0;
|
|
1690
|
+
const showCommandList = error || hasNoResults || results.length > 0;
|
|
1691
|
+
return /* @__PURE__ */ jsx(Command$1, {
|
|
1692
|
+
className: cn("h-fit overflow-visible", className),
|
|
1693
|
+
shouldFilter: false,
|
|
1694
|
+
loop: true,
|
|
1695
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
1696
|
+
className: "relative",
|
|
1697
|
+
children: [/* @__PURE__ */ jsxs(InputGroup, {
|
|
1698
|
+
className: cn("border-input! bg-popover! ring-0!", showCommandList && "rounded-b-none"),
|
|
1699
|
+
children: [
|
|
1700
|
+
/* @__PURE__ */ jsx(InputGroupAddon, { children: /* @__PURE__ */ jsx(SearchIcon, {}) }),
|
|
1701
|
+
/* @__PURE__ */ jsx(InputGroupInput, {
|
|
1702
|
+
placeholder: "Search",
|
|
1703
|
+
value: displayValue,
|
|
1704
|
+
onChange: (event) => {
|
|
1705
|
+
const newValue = event.target.value;
|
|
1706
|
+
if (!isControlled) setInternalValue(newValue);
|
|
1707
|
+
setSearchQuery(newValue);
|
|
1708
|
+
controlledOnChange?.(newValue);
|
|
1709
|
+
},
|
|
1710
|
+
...props
|
|
1711
|
+
}),
|
|
1712
|
+
isLoading && /* @__PURE__ */ jsx(InputGroupAddon, {
|
|
1713
|
+
align: "inline-end",
|
|
1714
|
+
children: /* @__PURE__ */ jsx(Spinner, {})
|
|
1715
|
+
})
|
|
1716
|
+
]
|
|
1717
|
+
}), showCommandList && /* @__PURE__ */ jsxs(CommandList, {
|
|
1718
|
+
"data-state": showCommandList ? "open" : "closed",
|
|
1719
|
+
className: cn("bg-popover border-input absolute top-full right-0 left-0 rounded-b-md border border-t-0 shadow-md", "data-[state=open]:animate-in data-[state=closed]:animate-out", "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0", "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95", "data-[state=open]:slide-in-from-top-2 data-[state=closed]:slide-out-to-top-2"),
|
|
1720
|
+
children: [
|
|
1721
|
+
error && /* @__PURE__ */ jsxs(CommandEmpty, { children: ["Error: ", error.message] }),
|
|
1722
|
+
hasNoResults && /* @__PURE__ */ jsxs(CommandEmpty, { children: [
|
|
1723
|
+
"Can't find ",
|
|
1724
|
+
displayValue,
|
|
1725
|
+
"."
|
|
1726
|
+
] }),
|
|
1727
|
+
results.length > 0 && /* @__PURE__ */ jsx(CommandGroup, { children: results.map((feature) => {
|
|
1728
|
+
const formattedAddress = formatAddress(feature.properties);
|
|
1729
|
+
return /* @__PURE__ */ jsxs(CommandItem, {
|
|
1730
|
+
value: String(feature.properties.osm_id),
|
|
1731
|
+
onSelect: () => {
|
|
1732
|
+
const formattedAddress = formatAddress(feature.properties);
|
|
1733
|
+
if (!isControlled) setInternalValue(formattedAddress);
|
|
1734
|
+
setSearchQuery("");
|
|
1735
|
+
controlledOnChange?.(formattedAddress);
|
|
1736
|
+
onPlaceSelect?.(feature);
|
|
1737
|
+
},
|
|
1738
|
+
children: [/* @__PURE__ */ jsx(MapPinIcon, {}), /* @__PURE__ */ jsxs("div", {
|
|
1739
|
+
className: "flex flex-col items-start text-start",
|
|
1740
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
1741
|
+
className: "font-medium",
|
|
1742
|
+
children: feature.properties.name || feature.properties.street || "Unknown"
|
|
1743
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
1744
|
+
className: "text-muted-foreground text-xs",
|
|
1745
|
+
children: formattedAddress
|
|
1746
|
+
})]
|
|
1747
|
+
})]
|
|
1748
|
+
}, feature.properties.osm_id);
|
|
1749
|
+
}) })
|
|
1750
|
+
]
|
|
1751
|
+
})]
|
|
1752
|
+
})
|
|
1753
|
+
});
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1756
|
+
//#endregion
|
|
1757
|
+
//#region ../shadcn/ui/map.tsx
|
|
1758
|
+
let _useMap;
|
|
1759
|
+
let _useMapEvents;
|
|
1760
|
+
if (typeof window !== "undefined") import("./map-leaflet-imports-OKaoesjZ.mjs").then((mod) => {
|
|
1761
|
+
_useMap = mod.useMap;
|
|
1762
|
+
_useMapEvents = mod.useMapEvents;
|
|
1763
|
+
});
|
|
1764
|
+
function createLazyComponent(factory) {
|
|
1765
|
+
const LazyComponent = lazy(factory);
|
|
1766
|
+
return (props) => {
|
|
1767
|
+
const [isMounted, setIsMounted] = useState(false);
|
|
1768
|
+
useEffect(() => {
|
|
1769
|
+
setIsMounted(true);
|
|
1770
|
+
}, []);
|
|
1771
|
+
if (!isMounted) return null;
|
|
1772
|
+
return /* @__PURE__ */ jsx(Suspense, { children: /* @__PURE__ */ jsx(LazyComponent, { ...props }) });
|
|
1773
|
+
};
|
|
1774
|
+
}
|
|
1775
|
+
const LeafletMapContainer = createLazyComponent(() => import("react-leaflet").then((mod) => ({ default: mod.MapContainer })));
|
|
1776
|
+
const LeafletTileLayer = createLazyComponent(() => import("react-leaflet").then((mod) => ({ default: mod.TileLayer })));
|
|
1777
|
+
const LeafletMarker = createLazyComponent(() => import("react-leaflet").then((mod) => ({ default: mod.Marker })));
|
|
1778
|
+
const LeafletPopup = createLazyComponent(() => import("react-leaflet").then((mod) => ({ default: mod.Popup })));
|
|
1779
|
+
const LeafletTooltip = createLazyComponent(() => import("react-leaflet").then((mod) => ({ default: mod.Tooltip })));
|
|
1780
|
+
const LeafletCircle = createLazyComponent(() => import("react-leaflet").then((mod) => ({ default: mod.Circle })));
|
|
1781
|
+
const LeafletCircleMarker = createLazyComponent(() => import("react-leaflet").then((mod) => ({ default: mod.CircleMarker })));
|
|
1782
|
+
const LeafletPolyline = createLazyComponent(() => import("react-leaflet").then((mod) => ({ default: mod.Polyline })));
|
|
1783
|
+
const LeafletPolygon = createLazyComponent(() => import("react-leaflet").then((mod) => ({ default: mod.Polygon })));
|
|
1784
|
+
const LeafletRectangle = createLazyComponent(() => import("react-leaflet").then((mod) => ({ default: mod.Rectangle })));
|
|
1785
|
+
const LeafletLayerGroup = createLazyComponent(() => import("react-leaflet").then((mod) => ({ default: mod.LayerGroup })));
|
|
1786
|
+
const LeafletFeatureGroup = createLazyComponent(() => import("react-leaflet").then((mod) => ({ default: mod.FeatureGroup })));
|
|
1787
|
+
const LeafletMarkerClusterGroup = createLazyComponent(async () => import("react-leaflet-markercluster").then((mod) => ({ default: mod.default })));
|
|
1788
|
+
function Map$1({ zoom = 15, maxZoom = 18, className, ...props }) {
|
|
1789
|
+
return /* @__PURE__ */ jsx(LeafletMapContainer, {
|
|
1790
|
+
zoom,
|
|
1791
|
+
maxZoom,
|
|
1792
|
+
attributionControl: false,
|
|
1793
|
+
zoomControl: false,
|
|
1794
|
+
className: cn("z-50 size-full min-h-96 flex-1 rounded-md", className),
|
|
1795
|
+
...props
|
|
1796
|
+
});
|
|
1797
|
+
}
|
|
1798
|
+
const MapLayersContext = createContext(null);
|
|
1799
|
+
function useMapLayersContext() {
|
|
1800
|
+
return useContext(MapLayersContext);
|
|
1801
|
+
}
|
|
1802
|
+
function MapTileLayer({ name = "Default", url, attribution, darkUrl, darkAttribution, ...props }) {
|
|
1803
|
+
const map = _useMap();
|
|
1804
|
+
if (map.attributionControl) map.attributionControl.setPrefix("");
|
|
1805
|
+
const context = useContext(MapLayersContext);
|
|
1806
|
+
const DEFAULT_URL = "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png";
|
|
1807
|
+
const DEFAULT_DARK_URL = "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png";
|
|
1808
|
+
const { resolvedTheme } = useTheme();
|
|
1809
|
+
const resolvedUrl = resolvedTheme === "dark" ? darkUrl ?? url ?? DEFAULT_DARK_URL : url ?? DEFAULT_URL;
|
|
1810
|
+
const resolvedAttribution = resolvedTheme === "dark" && darkAttribution ? darkAttribution : attribution ?? "© <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a>, © <a href=\"https://carto.com/attributions\">CARTO</a>";
|
|
1811
|
+
useEffect(() => {
|
|
1812
|
+
if (context) context.registerTileLayer({
|
|
1813
|
+
name,
|
|
1814
|
+
url: resolvedUrl,
|
|
1815
|
+
attribution: resolvedAttribution
|
|
1816
|
+
});
|
|
1817
|
+
}, [
|
|
1818
|
+
context,
|
|
1819
|
+
name,
|
|
1820
|
+
url,
|
|
1821
|
+
attribution
|
|
1822
|
+
]);
|
|
1823
|
+
if (context && context.selectedTileLayer !== name) return null;
|
|
1824
|
+
return /* @__PURE__ */ jsx(LeafletTileLayer, {
|
|
1825
|
+
url: resolvedUrl,
|
|
1826
|
+
attribution: resolvedAttribution,
|
|
1827
|
+
...props
|
|
1828
|
+
});
|
|
1829
|
+
}
|
|
1830
|
+
function MapLayerGroup({ name, disabled, ...props }) {
|
|
1831
|
+
const context = useMapLayersContext();
|
|
1832
|
+
useEffect(() => {
|
|
1833
|
+
if (context) context.registerLayerGroup({
|
|
1834
|
+
name,
|
|
1835
|
+
disabled
|
|
1836
|
+
});
|
|
1837
|
+
}, [
|
|
1838
|
+
context,
|
|
1839
|
+
name,
|
|
1840
|
+
disabled
|
|
1841
|
+
]);
|
|
1842
|
+
if (context && !context.activeLayerGroups.includes(name)) return null;
|
|
1843
|
+
return /* @__PURE__ */ jsx(LeafletLayerGroup, { ...props });
|
|
1844
|
+
}
|
|
1845
|
+
function MapFeatureGroup({ name, disabled, ...props }) {
|
|
1846
|
+
const context = useMapLayersContext();
|
|
1847
|
+
useEffect(() => {
|
|
1848
|
+
if (context) context.registerLayerGroup({
|
|
1849
|
+
name,
|
|
1850
|
+
disabled
|
|
1851
|
+
});
|
|
1852
|
+
}, [
|
|
1853
|
+
context,
|
|
1854
|
+
name,
|
|
1855
|
+
disabled
|
|
1856
|
+
]);
|
|
1857
|
+
if (context && !context.activeLayerGroups.includes(name)) return null;
|
|
1858
|
+
return /* @__PURE__ */ jsx(LeafletFeatureGroup, { ...props });
|
|
1859
|
+
}
|
|
1860
|
+
function MapLayers({ defaultTileLayer, defaultLayerGroups = [], ...props }) {
|
|
1861
|
+
const [tileLayers, setTileLayers] = useState([]);
|
|
1862
|
+
const [selectedTileLayer, setSelectedTileLayer] = useState(defaultTileLayer || "");
|
|
1863
|
+
const [layerGroups, setLayerGroups] = useState([]);
|
|
1864
|
+
const [activeLayerGroups, setActiveLayerGroups] = useState(defaultLayerGroups);
|
|
1865
|
+
function registerTileLayer(tileLayer) {
|
|
1866
|
+
setTileLayers((prevTileLayers) => {
|
|
1867
|
+
if (prevTileLayers.some((layer) => layer.name === tileLayer.name)) return prevTileLayers;
|
|
1868
|
+
return [...prevTileLayers, tileLayer];
|
|
1869
|
+
});
|
|
1870
|
+
}
|
|
1871
|
+
function registerLayerGroup(layerGroup) {
|
|
1872
|
+
setLayerGroups((prevLayerGroups) => {
|
|
1873
|
+
if (prevLayerGroups.some((group) => group.name === layerGroup.name)) return prevLayerGroups;
|
|
1874
|
+
return [...prevLayerGroups, layerGroup];
|
|
1875
|
+
});
|
|
1876
|
+
}
|
|
1877
|
+
useEffect(() => {
|
|
1878
|
+
if (defaultTileLayer && tileLayers.length > 0 && !tileLayers.some((tileLayer) => tileLayer.name === defaultTileLayer)) throw new Error(`Invalid defaultTileLayer "${defaultTileLayer}" provided to MapLayers. It must match a MapTileLayer's name prop.`);
|
|
1879
|
+
if (tileLayers.length > 0 && !selectedTileLayer) setSelectedTileLayer(defaultTileLayer && tileLayers.some((layer) => layer.name === defaultTileLayer) ? defaultTileLayer : tileLayers[0].name);
|
|
1880
|
+
if (defaultLayerGroups.length > 0 && layerGroups.length > 0 && defaultLayerGroups.some((name) => !layerGroups.some((group) => group.name === name))) throw new Error(`Invalid defaultLayerGroups value provided to MapLayers. All names must match a MapLayerGroup's name prop.`);
|
|
1881
|
+
}, [
|
|
1882
|
+
tileLayers,
|
|
1883
|
+
defaultTileLayer,
|
|
1884
|
+
selectedTileLayer,
|
|
1885
|
+
layerGroups,
|
|
1886
|
+
defaultLayerGroups
|
|
1887
|
+
]);
|
|
1888
|
+
return /* @__PURE__ */ jsx(MapLayersContext.Provider, {
|
|
1889
|
+
value: {
|
|
1890
|
+
registerTileLayer,
|
|
1891
|
+
tileLayers,
|
|
1892
|
+
selectedTileLayer,
|
|
1893
|
+
setSelectedTileLayer,
|
|
1894
|
+
registerLayerGroup,
|
|
1895
|
+
layerGroups,
|
|
1896
|
+
activeLayerGroups,
|
|
1897
|
+
setActiveLayerGroups
|
|
1898
|
+
},
|
|
1899
|
+
...props
|
|
1900
|
+
});
|
|
1901
|
+
}
|
|
1902
|
+
function MapLayersControl({ tileLayersLabel = "Map Type", layerGroupsLabel = "Layers", position = "top-1 right-1", className, ...props }) {
|
|
1903
|
+
const layersContext = useMapLayersContext();
|
|
1904
|
+
if (!layersContext) throw new Error("MapLayersControl must be used within MapLayers");
|
|
1905
|
+
const { tileLayers, selectedTileLayer, setSelectedTileLayer, layerGroups, activeLayerGroups, setActiveLayerGroups } = layersContext;
|
|
1906
|
+
if (tileLayers.length === 0 && layerGroups.length === 0) return null;
|
|
1907
|
+
function handleLayerGroupToggle(name, checked) {
|
|
1908
|
+
setActiveLayerGroups(checked ? [...activeLayerGroups, name] : activeLayerGroups.filter((groupName) => groupName !== name));
|
|
1909
|
+
}
|
|
1910
|
+
const showTileLayersDropdown = tileLayers.length > 1;
|
|
1911
|
+
const showLayerGroupsDropdown = layerGroups.length > 0;
|
|
1912
|
+
if (!showTileLayersDropdown && !showLayerGroupsDropdown) return null;
|
|
1913
|
+
return /* @__PURE__ */ jsxs(DropdownMenu$1, { children: [/* @__PURE__ */ jsx(DropdownMenuTrigger$1, {
|
|
1914
|
+
asChild: true,
|
|
1915
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
1916
|
+
type: "button",
|
|
1917
|
+
variant: "secondary",
|
|
1918
|
+
size: "sm",
|
|
1919
|
+
"aria-label": "Select layers",
|
|
1920
|
+
title: "Select layers",
|
|
1921
|
+
className: cn("absolute z-1000 border", position, className),
|
|
1922
|
+
...props,
|
|
1923
|
+
children: /* @__PURE__ */ jsx(LayersIcon, {})
|
|
1924
|
+
})
|
|
1925
|
+
}), /* @__PURE__ */ jsxs(DropdownMenuContent$1, {
|
|
1926
|
+
align: "end",
|
|
1927
|
+
className: "z-1000",
|
|
1928
|
+
children: [
|
|
1929
|
+
showTileLayersDropdown && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(DropdownMenuLabel$1, { children: tileLayersLabel }), /* @__PURE__ */ jsx(DropdownMenuRadioGroup$1, {
|
|
1930
|
+
value: selectedTileLayer,
|
|
1931
|
+
onValueChange: setSelectedTileLayer,
|
|
1932
|
+
children: tileLayers.map((tileLayer) => /* @__PURE__ */ jsx(DropdownMenuRadioItem$1, {
|
|
1933
|
+
value: tileLayer.name,
|
|
1934
|
+
children: tileLayer.name
|
|
1935
|
+
}, tileLayer.name))
|
|
1936
|
+
})] }),
|
|
1937
|
+
showTileLayersDropdown && showLayerGroupsDropdown && /* @__PURE__ */ jsx(DropdownMenuSeparator$1, {}),
|
|
1938
|
+
showLayerGroupsDropdown && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(DropdownMenuLabel$1, { children: layerGroupsLabel }), layerGroups.map((layerGroup) => /* @__PURE__ */ jsx(DropdownMenuCheckboxItem$1, {
|
|
1939
|
+
checked: activeLayerGroups.includes(layerGroup.name),
|
|
1940
|
+
disabled: layerGroup.disabled,
|
|
1941
|
+
onCheckedChange: (checked) => handleLayerGroupToggle(layerGroup.name, checked),
|
|
1942
|
+
children: layerGroup.name
|
|
1943
|
+
}, layerGroup.name))] })
|
|
1944
|
+
]
|
|
1945
|
+
})] });
|
|
1946
|
+
}
|
|
1947
|
+
function MapMarker({ icon = /* @__PURE__ */ jsx(MapPinIcon, { className: "size-6" }), iconAnchor = [12, 12], bgPos, popupAnchor, tooltipAnchor, ...props }) {
|
|
1948
|
+
const { L } = useLeaflet();
|
|
1949
|
+
if (!L) return null;
|
|
1950
|
+
return /* @__PURE__ */ jsx(LeafletMarker, {
|
|
1951
|
+
icon: L.divIcon({
|
|
1952
|
+
html: renderToString(icon),
|
|
1953
|
+
iconAnchor,
|
|
1954
|
+
...bgPos ? { bgPos } : {},
|
|
1955
|
+
...popupAnchor ? { popupAnchor } : {},
|
|
1956
|
+
...tooltipAnchor ? { tooltipAnchor } : {}
|
|
1957
|
+
}),
|
|
1958
|
+
riseOnHover: true,
|
|
1959
|
+
...props
|
|
1960
|
+
});
|
|
1961
|
+
}
|
|
1962
|
+
function MapMarkerClusterGroup({ polygonOptions = { className: "fill-foreground stroke-foreground stroke-2" }, spiderLegPolylineOptions = { className: "fill-foreground stroke-foreground stroke-2" }, icon, ...props }) {
|
|
1963
|
+
const { L } = useLeaflet();
|
|
1964
|
+
if (!L) return null;
|
|
1965
|
+
return /* @__PURE__ */ jsx(LeafletMarkerClusterGroup, {
|
|
1966
|
+
polygonOptions,
|
|
1967
|
+
spiderLegPolylineOptions,
|
|
1968
|
+
iconCreateFunction: icon ? (cluster) => {
|
|
1969
|
+
const iconNode = icon(cluster.getChildCount());
|
|
1970
|
+
return L.divIcon({ html: renderToString(iconNode) });
|
|
1971
|
+
} : void 0,
|
|
1972
|
+
...props
|
|
1973
|
+
});
|
|
1974
|
+
}
|
|
1975
|
+
function MapCircle({ className, ...props }) {
|
|
1976
|
+
return /* @__PURE__ */ jsx(LeafletCircle, {
|
|
1977
|
+
className: cn("fill-foreground stroke-foreground stroke-2", className),
|
|
1978
|
+
...props
|
|
1979
|
+
});
|
|
1980
|
+
}
|
|
1981
|
+
function MapCircleMarker({ className, ...props }) {
|
|
1982
|
+
return /* @__PURE__ */ jsx(LeafletCircleMarker, {
|
|
1983
|
+
className: cn("fill-foreground stroke-foreground stroke-2", className),
|
|
1984
|
+
...props
|
|
1985
|
+
});
|
|
1986
|
+
}
|
|
1987
|
+
function MapPolyline({ className, ...props }) {
|
|
1988
|
+
return /* @__PURE__ */ jsx(LeafletPolyline, {
|
|
1989
|
+
className: cn("fill-foreground stroke-foreground stroke-2", className),
|
|
1990
|
+
...props
|
|
1991
|
+
});
|
|
1992
|
+
}
|
|
1993
|
+
function MapPolygon({ className, ...props }) {
|
|
1994
|
+
return /* @__PURE__ */ jsx(LeafletPolygon, {
|
|
1995
|
+
className: cn("fill-foreground stroke-foreground stroke-2", className),
|
|
1996
|
+
...props
|
|
1997
|
+
});
|
|
1998
|
+
}
|
|
1999
|
+
function MapRectangle({ className, ...props }) {
|
|
2000
|
+
return /* @__PURE__ */ jsx(LeafletRectangle, {
|
|
2001
|
+
className: cn("fill-foreground stroke-foreground stroke-2", className),
|
|
2002
|
+
...props
|
|
2003
|
+
});
|
|
2004
|
+
}
|
|
2005
|
+
function MapPopup({ className, ...props }) {
|
|
2006
|
+
return /* @__PURE__ */ jsx(LeafletPopup, {
|
|
2007
|
+
className: cn("bg-popover text-popover-foreground animate-in fade-out-0 fade-in-0 zoom-out-95 zoom-in-95 slide-in-from-bottom-2 z-50 w-72 rounded-md border p-4 font-sans shadow-md outline-hidden", className),
|
|
2008
|
+
...props
|
|
2009
|
+
});
|
|
2010
|
+
}
|
|
2011
|
+
function MapTooltip({ className, children, side = "top", sideOffset = 15, ...props }) {
|
|
2012
|
+
const ARROW_POSITION_CLASSES = {
|
|
2013
|
+
top: "bottom-0.5 left-1/2 -translate-x-1/2 translate-y-1/2",
|
|
2014
|
+
bottom: "top-0.5 left-1/2 -translate-x-1/2 -translate-y-1/2",
|
|
2015
|
+
left: "right-0.5 top-1/2 translate-x-1/2 -translate-y-1/2",
|
|
2016
|
+
right: "left-0.5 top-1/2 -translate-x-1/2 -translate-y-1/2"
|
|
2017
|
+
};
|
|
2018
|
+
const DEFAULT_OFFSET = {
|
|
2019
|
+
top: [0, -sideOffset],
|
|
2020
|
+
bottom: [0, sideOffset],
|
|
2021
|
+
left: [-sideOffset, 0],
|
|
2022
|
+
right: [sideOffset, 0]
|
|
2023
|
+
};
|
|
2024
|
+
return /* @__PURE__ */ jsxs(LeafletTooltip, {
|
|
2025
|
+
className: cn("animate-in fade-in-0 zoom-in-95 fade-out-0 zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 w-fit text-xs text-balance transition-opacity", className),
|
|
2026
|
+
"data-side": side,
|
|
2027
|
+
direction: side,
|
|
2028
|
+
offset: DEFAULT_OFFSET[side],
|
|
2029
|
+
opacity: 1,
|
|
2030
|
+
...props,
|
|
2031
|
+
children: [children, /* @__PURE__ */ jsx("div", { className: cn("bg-foreground fill-foreground absolute z-50 size-2.5 rotate-45 rounded-[2px]", ARROW_POSITION_CLASSES[side]) })]
|
|
2032
|
+
});
|
|
2033
|
+
}
|
|
2034
|
+
function MapZoomControl({ position = "top-1 left-1", className, ...props }) {
|
|
2035
|
+
const map = _useMap();
|
|
2036
|
+
const [zoomLevel, setZoomLevel] = useState(map.getZoom());
|
|
2037
|
+
_useMapEvents({ zoomend: () => {
|
|
2038
|
+
setZoomLevel(map.getZoom());
|
|
2039
|
+
} });
|
|
2040
|
+
return /* @__PURE__ */ jsx(MapControlContainer, {
|
|
2041
|
+
className: cn(position, className),
|
|
2042
|
+
children: /* @__PURE__ */ jsxs(ButtonGroup, {
|
|
2043
|
+
orientation: "vertical",
|
|
2044
|
+
"aria-label": "Zoom controls",
|
|
2045
|
+
...props,
|
|
2046
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
2047
|
+
type: "button",
|
|
2048
|
+
size: "icon",
|
|
2049
|
+
variant: "outline",
|
|
2050
|
+
"aria-label": "Zoom in",
|
|
2051
|
+
title: "Zoom in",
|
|
2052
|
+
className: "border",
|
|
2053
|
+
disabled: zoomLevel >= map.getMaxZoom(),
|
|
2054
|
+
onClick: () => map.zoomIn(),
|
|
2055
|
+
children: /* @__PURE__ */ jsx(PlusIcon, {})
|
|
2056
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
2057
|
+
type: "button",
|
|
2058
|
+
size: "icon",
|
|
2059
|
+
variant: "outline",
|
|
2060
|
+
"aria-label": "Zoom out",
|
|
2061
|
+
title: "Zoom out",
|
|
2062
|
+
className: "border",
|
|
2063
|
+
disabled: zoomLevel <= map.getMinZoom(),
|
|
2064
|
+
onClick: () => map.zoomOut(),
|
|
2065
|
+
children: /* @__PURE__ */ jsx(MinusIcon, {})
|
|
2066
|
+
})]
|
|
2067
|
+
})
|
|
2068
|
+
});
|
|
2069
|
+
}
|
|
2070
|
+
function MapFullscreenControl({ position = "top-1 right-1", className, ...props }) {
|
|
2071
|
+
const map = _useMap();
|
|
2072
|
+
const [isFullscreen, setIsFullscreen] = useState(false);
|
|
2073
|
+
const { L } = useLeaflet();
|
|
2074
|
+
useEffect(() => {
|
|
2075
|
+
if (!L) return;
|
|
2076
|
+
const fullscreenControl = new L.Control.FullScreen();
|
|
2077
|
+
fullscreenControl.addTo(map);
|
|
2078
|
+
const container = fullscreenControl.getContainer();
|
|
2079
|
+
if (container) container.style.display = "none";
|
|
2080
|
+
const handleEnter = () => setIsFullscreen(true);
|
|
2081
|
+
const handleExit = () => setIsFullscreen(false);
|
|
2082
|
+
map.on("enterFullscreen", handleEnter);
|
|
2083
|
+
map.on("exitFullscreen", handleExit);
|
|
2084
|
+
return () => {
|
|
2085
|
+
fullscreenControl.remove();
|
|
2086
|
+
map.off("enterFullscreen", handleEnter);
|
|
2087
|
+
map.off("exitFullscreen", handleExit);
|
|
2088
|
+
};
|
|
2089
|
+
}, [L, map]);
|
|
2090
|
+
return /* @__PURE__ */ jsx(MapControlContainer, {
|
|
2091
|
+
className: cn(position, className),
|
|
2092
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
2093
|
+
type: "button",
|
|
2094
|
+
size: "icon",
|
|
2095
|
+
variant: "outline",
|
|
2096
|
+
onClick: () => map.toggleFullscreen(),
|
|
2097
|
+
"aria-label": isFullscreen ? "Exit fullscreen" : "Enter fullscreen",
|
|
2098
|
+
title: isFullscreen ? "Exit fullscreen" : "Enter fullscreen",
|
|
2099
|
+
className: "border",
|
|
2100
|
+
...props,
|
|
2101
|
+
children: isFullscreen ? /* @__PURE__ */ jsx(MinimizeIcon, {}) : /* @__PURE__ */ jsx(MaximizeIcon, {})
|
|
2102
|
+
})
|
|
2103
|
+
});
|
|
2104
|
+
}
|
|
2105
|
+
function MapLocatePulseIcon() {
|
|
2106
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
2107
|
+
className: "absolute -top-1 -right-1 flex size-3 rounded-full",
|
|
2108
|
+
children: [/* @__PURE__ */ jsx("div", { className: "bg-primary absolute inline-flex size-full animate-ping rounded-full opacity-75" }), /* @__PURE__ */ jsx("div", { className: "bg-primary relative inline-flex size-3 rounded-full" })]
|
|
2109
|
+
});
|
|
2110
|
+
}
|
|
2111
|
+
function MapLocateControl({ watch = false, onLocationFound, onLocationError, position = "right-1 bottom-1", className, ...props }) {
|
|
2112
|
+
const map = _useMap();
|
|
2113
|
+
const [isLocating, setIsLocating] = useDebounceLoadingState(200);
|
|
2114
|
+
const [location, setLocation] = useState(null);
|
|
2115
|
+
function startLocating() {
|
|
2116
|
+
setIsLocating(true);
|
|
2117
|
+
map.locate({
|
|
2118
|
+
setView: true,
|
|
2119
|
+
maxZoom: map.getMaxZoom(),
|
|
2120
|
+
watch
|
|
2121
|
+
});
|
|
2122
|
+
map.on("locationfound", (location) => {
|
|
2123
|
+
setLocation(location.latlng);
|
|
2124
|
+
setIsLocating(false);
|
|
2125
|
+
onLocationFound?.(location);
|
|
2126
|
+
});
|
|
2127
|
+
map.on("locationerror", (error) => {
|
|
2128
|
+
setLocation(null);
|
|
2129
|
+
setIsLocating(false);
|
|
2130
|
+
onLocationError?.(error);
|
|
2131
|
+
});
|
|
2132
|
+
}
|
|
2133
|
+
function stopLocating() {
|
|
2134
|
+
map.stopLocate();
|
|
2135
|
+
map.off("locationfound");
|
|
2136
|
+
map.off("locationerror");
|
|
2137
|
+
setLocation(null);
|
|
2138
|
+
setIsLocating(false);
|
|
2139
|
+
}
|
|
2140
|
+
useEffect(() => () => stopLocating(), []);
|
|
2141
|
+
return /* @__PURE__ */ jsxs(MapControlContainer, {
|
|
2142
|
+
className: cn(position, className),
|
|
2143
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
2144
|
+
type: "button",
|
|
2145
|
+
size: "sm",
|
|
2146
|
+
variant: location ? "default" : "secondary",
|
|
2147
|
+
onClick: location ? stopLocating : startLocating,
|
|
2148
|
+
disabled: isLocating,
|
|
2149
|
+
title: isLocating ? "Locating..." : location ? "Stop tracking" : "Track location",
|
|
2150
|
+
"aria-label": isLocating ? "Locating..." : location ? "Stop location tracking" : "Start location tracking",
|
|
2151
|
+
className: "border",
|
|
2152
|
+
...props,
|
|
2153
|
+
children: isLocating ? /* @__PURE__ */ jsx(LoaderCircleIcon, { className: "animate-spin" }) : /* @__PURE__ */ jsx(NavigationIcon, {})
|
|
2154
|
+
}), location && /* @__PURE__ */ jsx(MapMarker, {
|
|
2155
|
+
position: location,
|
|
2156
|
+
icon: /* @__PURE__ */ jsx(MapLocatePulseIcon, {})
|
|
2157
|
+
})]
|
|
2158
|
+
});
|
|
2159
|
+
}
|
|
2160
|
+
function MapSearchControl({ position = "top-1 left-1", className, ...props }) {
|
|
2161
|
+
return /* @__PURE__ */ jsx(MapControlContainer, {
|
|
2162
|
+
className: cn("z-1001 w-60", position, className),
|
|
2163
|
+
children: /* @__PURE__ */ jsx(PlaceAutocomplete, { ...props })
|
|
2164
|
+
});
|
|
2165
|
+
}
|
|
2166
|
+
const MapDrawContext = createContext(null);
|
|
2167
|
+
function useMapDrawContext() {
|
|
2168
|
+
return useContext(MapDrawContext);
|
|
2169
|
+
}
|
|
2170
|
+
function MapDrawControl({ onLayersChange, position = "bottom-1 left-1", className, ...props }) {
|
|
2171
|
+
const { L, LeafletDraw } = useLeaflet();
|
|
2172
|
+
const map = _useMap();
|
|
2173
|
+
const featureGroupRef = useRef(null);
|
|
2174
|
+
const editControlRef = useRef(null);
|
|
2175
|
+
const deleteControlRef = useRef(null);
|
|
2176
|
+
const [activeMode, setActiveMode] = useState(null);
|
|
2177
|
+
const [layersCount, setLayersCount] = useState(0);
|
|
2178
|
+
function updateLayersCount() {
|
|
2179
|
+
if (featureGroupRef.current) setLayersCount(featureGroupRef.current.getLayers().length);
|
|
2180
|
+
}
|
|
2181
|
+
function handleDrawCreated(event) {
|
|
2182
|
+
if (!featureGroupRef.current) return;
|
|
2183
|
+
const { layer } = event;
|
|
2184
|
+
featureGroupRef.current.addLayer(layer);
|
|
2185
|
+
onLayersChange?.(featureGroupRef.current);
|
|
2186
|
+
updateLayersCount();
|
|
2187
|
+
setActiveMode(null);
|
|
2188
|
+
}
|
|
2189
|
+
function handleDrawEditedOrDeleted() {
|
|
2190
|
+
if (!featureGroupRef.current) return;
|
|
2191
|
+
onLayersChange?.(featureGroupRef.current);
|
|
2192
|
+
updateLayersCount();
|
|
2193
|
+
setActiveMode(null);
|
|
2194
|
+
}
|
|
2195
|
+
useEffect(() => {
|
|
2196
|
+
if (!L || !LeafletDraw || !map) return;
|
|
2197
|
+
map.on(L.Draw.Event.CREATED, handleDrawCreated);
|
|
2198
|
+
map.on(L.Draw.Event.EDITED, handleDrawEditedOrDeleted);
|
|
2199
|
+
map.on(L.Draw.Event.DELETED, handleDrawEditedOrDeleted);
|
|
2200
|
+
return () => {
|
|
2201
|
+
map.off(L.Draw.Event.CREATED, handleDrawCreated);
|
|
2202
|
+
map.off(L.Draw.Event.EDITED, handleDrawEditedOrDeleted);
|
|
2203
|
+
map.off(L.Draw.Event.DELETED, handleDrawEditedOrDeleted);
|
|
2204
|
+
};
|
|
2205
|
+
}, [
|
|
2206
|
+
L,
|
|
2207
|
+
LeafletDraw,
|
|
2208
|
+
map,
|
|
2209
|
+
onLayersChange
|
|
2210
|
+
]);
|
|
2211
|
+
return /* @__PURE__ */ jsxs(MapDrawContext.Provider, {
|
|
2212
|
+
value: {
|
|
2213
|
+
featureGroup: featureGroupRef.current,
|
|
2214
|
+
activeMode,
|
|
2215
|
+
setActiveMode,
|
|
2216
|
+
editControlRef,
|
|
2217
|
+
deleteControlRef,
|
|
2218
|
+
layersCount
|
|
2219
|
+
},
|
|
2220
|
+
children: [/* @__PURE__ */ jsx(LeafletFeatureGroup, { ref: featureGroupRef }), /* @__PURE__ */ jsx(MapControlContainer, {
|
|
2221
|
+
className: cn(position, className),
|
|
2222
|
+
children: /* @__PURE__ */ jsx(ButtonGroup, {
|
|
2223
|
+
orientation: "vertical",
|
|
2224
|
+
...props
|
|
2225
|
+
})
|
|
2226
|
+
})]
|
|
2227
|
+
});
|
|
2228
|
+
}
|
|
2229
|
+
function MapDrawShapeButton({ drawMode, createDrawTool, className, ...props }) {
|
|
2230
|
+
const drawContext = useMapDrawContext();
|
|
2231
|
+
if (!drawContext) throw new Error("MapDrawShapeButton must be used within MapDrawControl");
|
|
2232
|
+
const { L } = useLeaflet();
|
|
2233
|
+
const map = _useMap();
|
|
2234
|
+
const controlRef = useRef(null);
|
|
2235
|
+
const { activeMode, setActiveMode } = drawContext;
|
|
2236
|
+
const isActive = activeMode === drawMode;
|
|
2237
|
+
useEffect(() => {
|
|
2238
|
+
if (!L || !isActive) {
|
|
2239
|
+
controlRef.current?.disable();
|
|
2240
|
+
controlRef.current = null;
|
|
2241
|
+
return;
|
|
2242
|
+
}
|
|
2243
|
+
const control = createDrawTool(L, map);
|
|
2244
|
+
control.enable();
|
|
2245
|
+
controlRef.current = control;
|
|
2246
|
+
return () => {
|
|
2247
|
+
control.disable();
|
|
2248
|
+
controlRef.current = null;
|
|
2249
|
+
};
|
|
2250
|
+
}, [
|
|
2251
|
+
L,
|
|
2252
|
+
map,
|
|
2253
|
+
isActive,
|
|
2254
|
+
createDrawTool
|
|
2255
|
+
]);
|
|
2256
|
+
function handleClick() {
|
|
2257
|
+
setActiveMode(isActive ? null : drawMode);
|
|
2258
|
+
}
|
|
2259
|
+
return /* @__PURE__ */ jsx(Button, {
|
|
2260
|
+
type: "button",
|
|
2261
|
+
size: "sm",
|
|
2262
|
+
"aria-label": `Draw ${drawMode}`,
|
|
2263
|
+
title: `Draw ${drawMode}`,
|
|
2264
|
+
className: cn("border", className),
|
|
2265
|
+
variant: isActive ? "default" : "secondary",
|
|
2266
|
+
disabled: activeMode === "edit" || activeMode === "delete",
|
|
2267
|
+
onClick: handleClick,
|
|
2268
|
+
...props
|
|
2269
|
+
});
|
|
2270
|
+
}
|
|
2271
|
+
function MapDrawMarker({ ...props }) {
|
|
2272
|
+
return /* @__PURE__ */ jsx(MapDrawShapeButton, {
|
|
2273
|
+
drawMode: "marker",
|
|
2274
|
+
createDrawTool: (L, map) => new L.Draw.Marker(map, {
|
|
2275
|
+
icon: L.divIcon({
|
|
2276
|
+
className: "",
|
|
2277
|
+
iconAnchor: [12, 12],
|
|
2278
|
+
html: renderToString(/* @__PURE__ */ jsx(MapPinIcon, { className: "size-6" }))
|
|
2279
|
+
}),
|
|
2280
|
+
...props
|
|
2281
|
+
}),
|
|
2282
|
+
children: /* @__PURE__ */ jsx(MapPinIcon, {})
|
|
2283
|
+
});
|
|
2284
|
+
}
|
|
2285
|
+
function MapDrawPolyline({ showLength = false, drawError = { color: "var(--color-destructive)" }, shapeOptions = {
|
|
2286
|
+
color: "var(--color-primary)",
|
|
2287
|
+
opacity: 1,
|
|
2288
|
+
weight: 2
|
|
2289
|
+
}, ...props }) {
|
|
2290
|
+
const mapDrawHandleIcon = useMapDrawHandleIcon();
|
|
2291
|
+
return /* @__PURE__ */ jsx(MapDrawShapeButton, {
|
|
2292
|
+
drawMode: "polyline",
|
|
2293
|
+
createDrawTool: (L, map) => new L.Draw.Polyline(map, {
|
|
2294
|
+
...mapDrawHandleIcon ? {
|
|
2295
|
+
icon: mapDrawHandleIcon,
|
|
2296
|
+
touchIcon: mapDrawHandleIcon
|
|
2297
|
+
} : {},
|
|
2298
|
+
showLength,
|
|
2299
|
+
drawError,
|
|
2300
|
+
shapeOptions,
|
|
2301
|
+
...props
|
|
2302
|
+
}),
|
|
2303
|
+
children: /* @__PURE__ */ jsx(WaypointsIcon, {})
|
|
2304
|
+
});
|
|
2305
|
+
}
|
|
2306
|
+
function MapDrawCircle({ showRadius = false, shapeOptions = {
|
|
2307
|
+
color: "var(--color-primary)",
|
|
2308
|
+
opacity: 1,
|
|
2309
|
+
weight: 2
|
|
2310
|
+
}, ...props }) {
|
|
2311
|
+
return /* @__PURE__ */ jsx(MapDrawShapeButton, {
|
|
2312
|
+
drawMode: "circle",
|
|
2313
|
+
createDrawTool: (L, map) => new L.Draw.Circle(map, {
|
|
2314
|
+
showRadius,
|
|
2315
|
+
shapeOptions,
|
|
2316
|
+
...props
|
|
2317
|
+
}),
|
|
2318
|
+
children: /* @__PURE__ */ jsx(CircleIcon, {})
|
|
2319
|
+
});
|
|
2320
|
+
}
|
|
2321
|
+
function MapDrawRectangle({ showArea = false, shapeOptions = {
|
|
2322
|
+
color: "var(--color-primary)",
|
|
2323
|
+
opacity: 1,
|
|
2324
|
+
weight: 2
|
|
2325
|
+
}, ...props }) {
|
|
2326
|
+
return /* @__PURE__ */ jsx(MapDrawShapeButton, {
|
|
2327
|
+
drawMode: "rectangle",
|
|
2328
|
+
createDrawTool: (L, map) => new L.Draw.Rectangle(map, {
|
|
2329
|
+
showArea,
|
|
2330
|
+
shapeOptions,
|
|
2331
|
+
...props
|
|
2332
|
+
}),
|
|
2333
|
+
children: /* @__PURE__ */ jsx(SquareIcon, {})
|
|
2334
|
+
});
|
|
2335
|
+
}
|
|
2336
|
+
function MapDrawPolygon({ drawError = { color: "var(--color-destructive)" }, shapeOptions = {
|
|
2337
|
+
color: "var(--color-primary)",
|
|
2338
|
+
opacity: 1,
|
|
2339
|
+
weight: 2
|
|
2340
|
+
}, ...props }) {
|
|
2341
|
+
const mapDrawHandleIcon = useMapDrawHandleIcon();
|
|
2342
|
+
return /* @__PURE__ */ jsx(MapDrawShapeButton, {
|
|
2343
|
+
drawMode: "polygon",
|
|
2344
|
+
createDrawTool: (L, map) => new L.Draw.Polygon(map, {
|
|
2345
|
+
...mapDrawHandleIcon ? {
|
|
2346
|
+
icon: mapDrawHandleIcon,
|
|
2347
|
+
touchIcon: mapDrawHandleIcon
|
|
2348
|
+
} : {},
|
|
2349
|
+
drawError,
|
|
2350
|
+
shapeOptions,
|
|
2351
|
+
...props
|
|
2352
|
+
}),
|
|
2353
|
+
children: /* @__PURE__ */ jsx(PentagonIcon, {})
|
|
2354
|
+
});
|
|
2355
|
+
}
|
|
2356
|
+
function MapDrawActionButton({ drawAction, createDrawTool, controlRef, className, ...props }) {
|
|
2357
|
+
const drawContext = useMapDrawContext();
|
|
2358
|
+
if (!drawContext) throw new Error("MapDrawActionButton must be used within MapDrawControl");
|
|
2359
|
+
const { L } = useLeaflet();
|
|
2360
|
+
const map = _useMap();
|
|
2361
|
+
const { featureGroup, activeMode, setActiveMode, layersCount } = drawContext;
|
|
2362
|
+
const isActive = activeMode === drawAction;
|
|
2363
|
+
const hasFeatures = layersCount > 0;
|
|
2364
|
+
useEffect(() => {
|
|
2365
|
+
if (!L || !featureGroup || !isActive) {
|
|
2366
|
+
controlRef.current?.disable?.();
|
|
2367
|
+
controlRef.current = null;
|
|
2368
|
+
return;
|
|
2369
|
+
}
|
|
2370
|
+
const control = createDrawTool(L, map, featureGroup);
|
|
2371
|
+
control.enable?.();
|
|
2372
|
+
controlRef.current = control;
|
|
2373
|
+
return () => {
|
|
2374
|
+
control.disable?.();
|
|
2375
|
+
controlRef.current = null;
|
|
2376
|
+
};
|
|
2377
|
+
}, [
|
|
2378
|
+
L,
|
|
2379
|
+
map,
|
|
2380
|
+
isActive,
|
|
2381
|
+
featureGroup,
|
|
2382
|
+
createDrawTool
|
|
2383
|
+
]);
|
|
2384
|
+
function handleClick() {
|
|
2385
|
+
controlRef.current?.save();
|
|
2386
|
+
setActiveMode(isActive ? null : drawAction);
|
|
2387
|
+
}
|
|
2388
|
+
return /* @__PURE__ */ jsx(Button, {
|
|
2389
|
+
type: "button",
|
|
2390
|
+
size: "sm",
|
|
2391
|
+
"aria-label": `${drawAction === "edit" ? "Edit" : "Remove"} shapes`,
|
|
2392
|
+
title: `${drawAction === "edit" ? "Edit" : "Remove"} shapes`,
|
|
2393
|
+
variant: isActive ? "default" : "secondary",
|
|
2394
|
+
disabled: !hasFeatures,
|
|
2395
|
+
onClick: handleClick,
|
|
2396
|
+
className: cn("border", className),
|
|
2397
|
+
...props
|
|
2398
|
+
});
|
|
2399
|
+
}
|
|
2400
|
+
function MapDrawEdit({ selectedPathOptions = {
|
|
2401
|
+
color: "var(--color-primary)",
|
|
2402
|
+
fillColor: "var(--color-primary)",
|
|
2403
|
+
weight: 2
|
|
2404
|
+
}, ...props }) {
|
|
2405
|
+
const { L } = useLeaflet();
|
|
2406
|
+
const mapDrawHandleIcon = useMapDrawHandleIcon();
|
|
2407
|
+
const drawContext = useMapDrawContext();
|
|
2408
|
+
if (!drawContext) throw new Error("MapDrawEdit must be used within MapDrawControl");
|
|
2409
|
+
useEffect(() => {
|
|
2410
|
+
if (!L || !mapDrawHandleIcon) return;
|
|
2411
|
+
L.Edit.PolyVerticesEdit.mergeOptions({
|
|
2412
|
+
icon: mapDrawHandleIcon,
|
|
2413
|
+
touchIcon: mapDrawHandleIcon,
|
|
2414
|
+
drawError: { color: "var(--color-destructive)" }
|
|
2415
|
+
});
|
|
2416
|
+
L.Edit.SimpleShape.mergeOptions({
|
|
2417
|
+
moveIcon: mapDrawHandleIcon,
|
|
2418
|
+
resizeIcon: mapDrawHandleIcon,
|
|
2419
|
+
touchMoveIcon: mapDrawHandleIcon,
|
|
2420
|
+
touchResizeIcon: mapDrawHandleIcon
|
|
2421
|
+
});
|
|
2422
|
+
L.drawLocal.edit.handlers.edit.tooltip = {
|
|
2423
|
+
text: "Drag handles or markers to edit.",
|
|
2424
|
+
subtext: ""
|
|
2425
|
+
};
|
|
2426
|
+
L.drawLocal.edit.handlers.remove.tooltip = { text: "Click on a shape to remove." };
|
|
2427
|
+
}, [mapDrawHandleIcon]);
|
|
2428
|
+
return /* @__PURE__ */ jsx(MapDrawActionButton, {
|
|
2429
|
+
drawAction: "edit",
|
|
2430
|
+
controlRef: drawContext.editControlRef,
|
|
2431
|
+
createDrawTool: (L, map, featureGroup) => new L.EditToolbar.Edit(map, {
|
|
2432
|
+
featureGroup,
|
|
2433
|
+
selectedPathOptions,
|
|
2434
|
+
...props
|
|
2435
|
+
}),
|
|
2436
|
+
children: /* @__PURE__ */ jsx(PenLineIcon, {})
|
|
2437
|
+
});
|
|
2438
|
+
}
|
|
2439
|
+
function MapDrawDelete() {
|
|
2440
|
+
const drawContext = useMapDrawContext();
|
|
2441
|
+
if (!drawContext) throw new Error("MapDrawDelete must be used within MapDrawControl");
|
|
2442
|
+
return /* @__PURE__ */ jsx(MapDrawActionButton, {
|
|
2443
|
+
drawAction: "delete",
|
|
2444
|
+
controlRef: drawContext.deleteControlRef,
|
|
2445
|
+
createDrawTool: (L, map, featureGroup) => new L.EditToolbar.Delete(map, { featureGroup }),
|
|
2446
|
+
children: /* @__PURE__ */ jsx(Trash2Icon, {})
|
|
2447
|
+
});
|
|
2448
|
+
}
|
|
2449
|
+
function MapDrawUndo({ className, ...props }) {
|
|
2450
|
+
const drawContext = useMapDrawContext();
|
|
2451
|
+
if (!drawContext) throw new Error("MapDrawUndo must be used within MapDrawControl");
|
|
2452
|
+
const { activeMode, setActiveMode, editControlRef, deleteControlRef, layersCount } = drawContext;
|
|
2453
|
+
const isInEditMode = activeMode === "edit";
|
|
2454
|
+
const isInDeleteMode = activeMode === "delete";
|
|
2455
|
+
const isActive = (isInEditMode || isInDeleteMode) && layersCount > 0;
|
|
2456
|
+
function handleUndo() {
|
|
2457
|
+
if (isInEditMode) editControlRef.current?.revertLayers();
|
|
2458
|
+
else if (isInDeleteMode) deleteControlRef.current?.revertLayers();
|
|
2459
|
+
setActiveMode(null);
|
|
2460
|
+
}
|
|
2461
|
+
return /* @__PURE__ */ jsx(Button, {
|
|
2462
|
+
type: "button",
|
|
2463
|
+
size: "sm",
|
|
2464
|
+
variant: "secondary",
|
|
2465
|
+
"aria-label": `Undo ${activeMode}`,
|
|
2466
|
+
title: `Undo ${activeMode}`,
|
|
2467
|
+
onClick: handleUndo,
|
|
2468
|
+
disabled: !isActive,
|
|
2469
|
+
className: cn("border", className),
|
|
2470
|
+
...props,
|
|
2471
|
+
children: /* @__PURE__ */ jsx(Undo2Icon, {})
|
|
2472
|
+
});
|
|
2473
|
+
}
|
|
2474
|
+
function MapControlContainer({ className, ...props }) {
|
|
2475
|
+
const { L } = useLeaflet();
|
|
2476
|
+
const containerRef = useRef(null);
|
|
2477
|
+
useEffect(() => {
|
|
2478
|
+
if (!L) return;
|
|
2479
|
+
const element = containerRef.current;
|
|
2480
|
+
if (!element) return;
|
|
2481
|
+
L.DomEvent.disableClickPropagation(element);
|
|
2482
|
+
L.DomEvent.disableScrollPropagation(element);
|
|
2483
|
+
}, [L]);
|
|
2484
|
+
return /* @__PURE__ */ jsx("div", {
|
|
2485
|
+
ref: containerRef,
|
|
2486
|
+
className: cn("absolute z-1000 size-fit cursor-default", className),
|
|
2487
|
+
...props
|
|
2488
|
+
});
|
|
2489
|
+
}
|
|
2490
|
+
function useMapDrawHandleIcon() {
|
|
2491
|
+
const { L } = useLeaflet();
|
|
2492
|
+
if (!L) return null;
|
|
2493
|
+
return L.divIcon({
|
|
2494
|
+
iconAnchor: [8, 8],
|
|
2495
|
+
html: renderToString(/* @__PURE__ */ jsx(CircleIcon, { className: "fill-primary stroke-primary size-4 transition-transform hover:scale-110" }))
|
|
2496
|
+
});
|
|
2497
|
+
}
|
|
2498
|
+
function useLeaflet() {
|
|
2499
|
+
const [L, setL] = useState(null);
|
|
2500
|
+
const [LeafletDraw, setLeafletDraw] = useState(null);
|
|
2501
|
+
useEffect(() => {
|
|
2502
|
+
async function loadLeaflet() {
|
|
2503
|
+
const leaflet = await import("leaflet");
|
|
2504
|
+
const leafletFullscreen = await import("leaflet.fullscreen");
|
|
2505
|
+
const leafletDraw = await import("leaflet-draw");
|
|
2506
|
+
const L_object = leaflet.default;
|
|
2507
|
+
if (L_object.Control && !L_object.Control.FullScreen) L_object.Control.FullScreen = leafletFullscreen.default || leafletFullscreen;
|
|
2508
|
+
setLeafletDraw(leafletDraw);
|
|
2509
|
+
setL(L_object);
|
|
2510
|
+
}
|
|
2511
|
+
if (L && LeafletDraw) return;
|
|
2512
|
+
if (typeof window === "undefined") return;
|
|
2513
|
+
loadLeaflet();
|
|
2514
|
+
}, [L, LeafletDraw]);
|
|
2515
|
+
return {
|
|
2516
|
+
L,
|
|
2517
|
+
LeafletDraw
|
|
2518
|
+
};
|
|
2519
|
+
}
|
|
2520
|
+
function useDebounceLoadingState(delay = 200) {
|
|
2521
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
2522
|
+
const [showLoading, setShowLoading] = useState(false);
|
|
2523
|
+
const timeoutRef = useRef(null);
|
|
2524
|
+
useEffect(() => {
|
|
2525
|
+
if (isLoading) timeoutRef.current = setTimeout(() => {
|
|
2526
|
+
setShowLoading(true);
|
|
2527
|
+
}, delay);
|
|
2528
|
+
else {
|
|
2529
|
+
if (timeoutRef.current) {
|
|
2530
|
+
clearTimeout(timeoutRef.current);
|
|
2531
|
+
timeoutRef.current = null;
|
|
2532
|
+
}
|
|
2533
|
+
setShowLoading(false);
|
|
2534
|
+
}
|
|
2535
|
+
return () => {
|
|
2536
|
+
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
2537
|
+
};
|
|
2538
|
+
}, [isLoading, delay]);
|
|
2539
|
+
return [showLoading, setIsLoading];
|
|
2540
|
+
}
|
|
2541
|
+
|
|
1450
2542
|
//#endregion
|
|
1451
2543
|
//#region ../shadcn/ui/popover.tsx
|
|
1452
2544
|
const Popover = ({ ...props }) => {
|
|
@@ -1792,17 +2884,6 @@ function Skeleton({ className, ...props }) {
|
|
|
1792
2884
|
});
|
|
1793
2885
|
}
|
|
1794
2886
|
|
|
1795
|
-
//#endregion
|
|
1796
|
-
//#region ../shadcn/ui/spinner.tsx
|
|
1797
|
-
function Spinner({ className, ...props }) {
|
|
1798
|
-
return /* @__PURE__ */ jsx(Loader2Icon, {
|
|
1799
|
-
role: "status",
|
|
1800
|
-
"aria-label": "Loading",
|
|
1801
|
-
className: cn("size-4 animate-spin", className),
|
|
1802
|
-
...props
|
|
1803
|
-
});
|
|
1804
|
-
}
|
|
1805
|
-
|
|
1806
2887
|
//#endregion
|
|
1807
2888
|
//#region ../shadcn/ui/switch.tsx
|
|
1808
2889
|
function Switch$1({ className, ...props }) {
|
|
@@ -2015,6 +3096,199 @@ function Tooltip({ message, children, delayDuration = 200, side, align, sideOffs
|
|
|
2015
3096
|
});
|
|
2016
3097
|
}
|
|
2017
3098
|
|
|
3099
|
+
//#endregion
|
|
3100
|
+
//#region src/components/base/typography/typography.tsx
|
|
3101
|
+
const titleVariants$1 = cva("font-semibold leading-tight tracking-tight", {
|
|
3102
|
+
variants: {
|
|
3103
|
+
level: {
|
|
3104
|
+
1: "text-2xl md:text-3xl lg:text-4xl",
|
|
3105
|
+
2: "text-xl md:text-2xl lg:text-3xl",
|
|
3106
|
+
3: "text-lg md:text-xl lg:text-2xl",
|
|
3107
|
+
4: "text-base md:text-lg lg:text-xl",
|
|
3108
|
+
5: "text-sm md:text-base lg:text-lg",
|
|
3109
|
+
6: "text-xs md:text-sm lg:text-base"
|
|
3110
|
+
},
|
|
3111
|
+
weight: {
|
|
3112
|
+
normal: "font-normal",
|
|
3113
|
+
medium: "font-medium",
|
|
3114
|
+
semibold: "font-semibold",
|
|
3115
|
+
bold: "font-bold",
|
|
3116
|
+
extrabold: "font-extrabold"
|
|
3117
|
+
},
|
|
3118
|
+
textColor: {
|
|
3119
|
+
default: "text-foreground",
|
|
3120
|
+
muted: "text-muted-foreground",
|
|
3121
|
+
primary: "text-primary",
|
|
3122
|
+
secondary: "text-secondary-foreground",
|
|
3123
|
+
destructive: "text-destructive",
|
|
3124
|
+
success: "text-green-600 dark:text-green-400",
|
|
3125
|
+
warning: "text-yellow-600 dark:text-yellow-400",
|
|
3126
|
+
info: "text-blue-600 dark:text-blue-400"
|
|
3127
|
+
}
|
|
3128
|
+
},
|
|
3129
|
+
defaultVariants: {
|
|
3130
|
+
level: 4,
|
|
3131
|
+
weight: "semibold",
|
|
3132
|
+
textColor: "default"
|
|
3133
|
+
}
|
|
3134
|
+
});
|
|
3135
|
+
const textVariants = cva("leading-relaxed", {
|
|
3136
|
+
variants: {
|
|
3137
|
+
size: {
|
|
3138
|
+
"xs": "text-xs",
|
|
3139
|
+
"sm": "text-sm",
|
|
3140
|
+
"base": "text-sm",
|
|
3141
|
+
"lg": "text-lg",
|
|
3142
|
+
"xl": "text-xl",
|
|
3143
|
+
"2xl": "text-2xl",
|
|
3144
|
+
"3xl": "text-3xl",
|
|
3145
|
+
"4xl": "text-4xl"
|
|
3146
|
+
},
|
|
3147
|
+
weight: {
|
|
3148
|
+
normal: "font-normal",
|
|
3149
|
+
medium: "font-medium",
|
|
3150
|
+
semibold: "font-semibold",
|
|
3151
|
+
bold: "font-bold",
|
|
3152
|
+
extrabold: "font-extrabold"
|
|
3153
|
+
},
|
|
3154
|
+
textColor: {
|
|
3155
|
+
default: "text-foreground",
|
|
3156
|
+
muted: "text-muted-foreground",
|
|
3157
|
+
primary: "text-primary",
|
|
3158
|
+
secondary: "text-secondary-foreground",
|
|
3159
|
+
destructive: "text-destructive",
|
|
3160
|
+
success: "text-green-600 dark:text-green-400",
|
|
3161
|
+
warning: "text-yellow-600 dark:text-yellow-400",
|
|
3162
|
+
info: "text-blue-600 dark:text-blue-400"
|
|
3163
|
+
},
|
|
3164
|
+
type: {
|
|
3165
|
+
default: "",
|
|
3166
|
+
code: "font-mono bg-muted px-1.5 py-0.5 rounded text-sm",
|
|
3167
|
+
mark: "bg-yellow-100 dark:bg-yellow-900/30 px-1.5 py-0.5 rounded",
|
|
3168
|
+
underline: "underline underline-offset-4",
|
|
3169
|
+
delete: "line-through",
|
|
3170
|
+
strong: "font-semibold",
|
|
3171
|
+
italic: "italic"
|
|
3172
|
+
}
|
|
3173
|
+
},
|
|
3174
|
+
defaultVariants: {
|
|
3175
|
+
size: "base",
|
|
3176
|
+
weight: "normal",
|
|
3177
|
+
textColor: "default",
|
|
3178
|
+
type: "default"
|
|
3179
|
+
}
|
|
3180
|
+
});
|
|
3181
|
+
const paragraphVariants = cva("leading-relaxed", {
|
|
3182
|
+
variants: {
|
|
3183
|
+
size: {
|
|
3184
|
+
xs: "text-xs",
|
|
3185
|
+
sm: "text-sm",
|
|
3186
|
+
base: "text-sm",
|
|
3187
|
+
lg: "text-lg",
|
|
3188
|
+
xl: "text-xl"
|
|
3189
|
+
},
|
|
3190
|
+
spacing: {
|
|
3191
|
+
tight: "leading-tight",
|
|
3192
|
+
normal: "leading-relaxed",
|
|
3193
|
+
loose: "leading-loose"
|
|
3194
|
+
}
|
|
3195
|
+
},
|
|
3196
|
+
defaultVariants: {
|
|
3197
|
+
size: "base",
|
|
3198
|
+
spacing: "normal"
|
|
3199
|
+
}
|
|
3200
|
+
});
|
|
3201
|
+
function Title$1({ className, level, weight, textColor, as, children, ...props }) {
|
|
3202
|
+
const Component = as ?? `h${level ?? 4}`;
|
|
3203
|
+
return React$1.createElement(Component, {
|
|
3204
|
+
className: cn$1(titleVariants$1({
|
|
3205
|
+
level,
|
|
3206
|
+
weight,
|
|
3207
|
+
textColor,
|
|
3208
|
+
className
|
|
3209
|
+
})),
|
|
3210
|
+
...props
|
|
3211
|
+
}, children);
|
|
3212
|
+
}
|
|
3213
|
+
function Text({ className, size, weight, textColor, type, as = "span", copyable, ellipsis, mark, underline, delete: deleteProp, strong, italic, code, children, ...props }) {
|
|
3214
|
+
const resolvedType = code ? "code" : italic ? "italic" : strong ? "strong" : deleteProp ? "delete" : underline ? "underline" : mark ? "mark" : type;
|
|
3215
|
+
const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [children, copyable && /* @__PURE__ */ jsx("button", {
|
|
3216
|
+
type: "button",
|
|
3217
|
+
"aria-label": "Copy text",
|
|
3218
|
+
className: "hover:bg-accent hover:text-accent-foreground ml-2 inline-flex size-4 items-center justify-center rounded-md text-sm font-medium transition-colors",
|
|
3219
|
+
onClick: () => {
|
|
3220
|
+
if (typeof children === "string") navigator.clipboard.writeText(children).catch(() => {});
|
|
3221
|
+
},
|
|
3222
|
+
title: "Copy text",
|
|
3223
|
+
children: /* @__PURE__ */ jsx(CopyIcon, {
|
|
3224
|
+
className: "size-3",
|
|
3225
|
+
"aria-hidden": "true"
|
|
3226
|
+
})
|
|
3227
|
+
})] });
|
|
3228
|
+
return React$1.createElement(as, {
|
|
3229
|
+
className: cn$1(textVariants({
|
|
3230
|
+
size,
|
|
3231
|
+
weight,
|
|
3232
|
+
textColor,
|
|
3233
|
+
type: resolvedType
|
|
3234
|
+
}), ellipsis && "truncate", className),
|
|
3235
|
+
...props
|
|
3236
|
+
}, content);
|
|
3237
|
+
}
|
|
3238
|
+
function Paragraph({ className, size, spacing, as = "p", children, ...props }) {
|
|
3239
|
+
return React$1.createElement(as, {
|
|
3240
|
+
className: cn$1(paragraphVariants({
|
|
3241
|
+
size,
|
|
3242
|
+
spacing,
|
|
3243
|
+
className
|
|
3244
|
+
})),
|
|
3245
|
+
...props
|
|
3246
|
+
}, children);
|
|
3247
|
+
}
|
|
3248
|
+
function Link({ className, children, href, target = "_self", rel, ...props }) {
|
|
3249
|
+
return /* @__PURE__ */ jsx("a", {
|
|
3250
|
+
href,
|
|
3251
|
+
target,
|
|
3252
|
+
rel: rel ?? (target === "_blank" ? "noopener noreferrer" : void 0),
|
|
3253
|
+
className: cn$1("text-primary focus-visible:ring-ring underline-offset-4 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none", className),
|
|
3254
|
+
...props,
|
|
3255
|
+
children
|
|
3256
|
+
});
|
|
3257
|
+
}
|
|
3258
|
+
function List({ className, as, listType = "unordered", children, ...props }) {
|
|
3259
|
+
const Component = as ?? (listType === "ordered" ? "ol" : "ul");
|
|
3260
|
+
return React$1.createElement(Component, {
|
|
3261
|
+
className: cn$1("space-y-2", listType === "ordered" ? "list-decimal list-inside" : "list-disc list-inside", className),
|
|
3262
|
+
...props
|
|
3263
|
+
}, children);
|
|
3264
|
+
}
|
|
3265
|
+
function ListItem({ className, children, ...props }) {
|
|
3266
|
+
return /* @__PURE__ */ jsx("li", {
|
|
3267
|
+
className: cn$1("leading-relaxed", className),
|
|
3268
|
+
...props,
|
|
3269
|
+
children
|
|
3270
|
+
});
|
|
3271
|
+
}
|
|
3272
|
+
function Blockquote({ className, children, ...props }) {
|
|
3273
|
+
return /* @__PURE__ */ jsx("blockquote", {
|
|
3274
|
+
className: cn$1("border-primary text-muted-foreground border-l-4 pl-4 italic", className),
|
|
3275
|
+
...props,
|
|
3276
|
+
children
|
|
3277
|
+
});
|
|
3278
|
+
}
|
|
3279
|
+
function Code({ className, as = "code", children, ...props }) {
|
|
3280
|
+
if (as === "pre") return /* @__PURE__ */ jsx("pre", {
|
|
3281
|
+
className: cn$1("bg-muted relative overflow-x-auto rounded p-4 font-mono text-sm", className),
|
|
3282
|
+
...props,
|
|
3283
|
+
children
|
|
3284
|
+
});
|
|
3285
|
+
return /* @__PURE__ */ jsx("code", {
|
|
3286
|
+
className: cn$1("bg-muted relative rounded px-[0.3rem] py-[0.2rem] font-mono text-sm", className),
|
|
3287
|
+
...props,
|
|
3288
|
+
children
|
|
3289
|
+
});
|
|
3290
|
+
}
|
|
3291
|
+
|
|
2018
3292
|
//#endregion
|
|
2019
3293
|
//#region ../shadcn/ui/visuallyhidden.tsx
|
|
2020
3294
|
const VisuallyHidden$1 = { Root: VisuallyHidden };
|
|
@@ -9851,4 +11125,4 @@ const ThemeScript = React$1.memo(({ forcedTheme, storageKey = "theme", attribute
|
|
|
9851
11125
|
});
|
|
9852
11126
|
|
|
9853
11127
|
//#endregion
|
|
9854
|
-
export { SidebarGroupAction as $,
|
|
11128
|
+
export { SidebarGroupAction as $, Card as $i, paragraphVariants as $n, MapDrawPolygon as $r, FormSwitch as $t, TaskPanel as A, HoverCard as Ai, DropdownMenuPortal as An, SelectGroup as Ar, getGutter as At, TaskQueueProvider as B, CommandList as Bi, AvatarStack as Bn, Popover as Br, useFormContext as Bt, localInputStringToUtc as C, badgeVariants as Ca, InputGroup as Ci, DropzoneEmptyState as Cn, SheetDescription as Cr, startProgress as Ct, TaskQueueDropdown as D, InputGroupText as Di, DropdownMenuGroup as Dn, SheetTrigger as Dr, Col as Dt, zonedDateToUtcString as E, AlertTitle as Ea, InputGroupInput as Ei, DropdownMenuContent as En, SheetTitle as Er, InputNumber as Et, getContextLabel as F, CommandDialog as Fi, DropdownMenuSub as Fn, SelectSeparator as Fr, GRID_PREFIX as Ft, createOrgMetadata as G, CollapsibleTrigger as Gi, Blockquote as Gn, MapCircle as Gr, StepperControls as Gt, detectStorage as H, CommandShortcut as Hi, Autocomplete as Hn, PopoverContent as Hr, useField as Ht, matchesCurrentScope as I, CommandEmpty as Ii, DropdownMenuSubContent as In, SelectTrigger as Ir, RESPONSIVE_ARRAY as It, TagsInput as J, ChartLegend as Ji, List as Jn, MapDrawCircle as Jr, defineStepper as Jt, createProjectMetadata as K, Checkbox as Ki, Code as Kn, MapCircleMarker as Kr, FormStep as Kt, useCurrentScope as L, CommandGroup as Li, DropdownMenuSubTrigger as Ln, SelectValue as Lr, RESPONSIVE_MAP as Lt, TaskPanelCounter as M, HoverCardTrigger as Mi, DropdownMenuRadioItem as Mn, SelectLabel as Mr, registerMediaQuery as Mt, TaskPanelActions as N, Dialog as Ni, DropdownMenuSeparator as Nn, SelectScrollDownButton as Nr, GRID_BREAKPOINTS as Nt, TaskSummaryDialog as O, InputGroupTextarea as Oi, DropdownMenuItem as On, Select as Or, Row as Ot, TaskPanelHeader as P, Command$1 as Pi, DropdownMenuShortcut as Pn, SelectScrollUpButton as Pr, GRID_COLUMNS as Pt, SidebarGroup as Q, ChartTooltipContent as Qi, Title$1 as Qn, MapDrawMarker as Qr, FormTextarea as Qt, useTasksWithLabels as R, CommandInput as Ri, DropdownMenuTrigger as Rn, RadioGroup as Rr, Form as Rt, getTimezoneOffset as S, Badge as Sa, Label as Si, DropzoneContent as Sn, SheetOverlay as Sr, configureProgress as St, utcToLocalInputString as T, AlertDescription as Ta, InputGroupButton as Ti, DropdownMenuCheckboxItem as Tn, SheetHeader as Tr, MoreActions as Tt, RedisTaskStorage as U, Collapsible as Ui, LoaderOverlay as Un, PopoverTrigger as Ur, InputWithAddons as Ut, TaskQueue as V, CommandSeparator as Vi, avatarStackVariants as Vn, PopoverAnchor as Vr, useFieldContext as Vt, LocalTaskStorage as W, CollapsibleContent as Wi, VisuallyHidden$1 as Wn, Map$1 as Wr, StepperNavigation as Wt, SidebarContent as X, ChartStyle as Xi, Paragraph as Xn, MapDrawDelete as Xr, useWatch as Xt, Sidebar as Y, ChartLegendContent as Yi, ListItem as Yn, MapDrawControl as Yr, FormWhen as Yt, SidebarFooter as Z, ChartTooltip as Zi, Text as Zn, MapDrawEdit as Zr, useWatchAll as Zt, formatTimezoneLabel as _, BreadcrumbItem as _a, MapTooltip as _i, FormButton as _n, Switch as _r, SidebarTrigger as _t, formatDateForInput as a, Calendar$1 as aa, MapLayerGroup as ai, FormRadioItem as an, TabsContent as ar, SidebarMenu as at, getDefaultTimezoneOptions as b, BreadcrumbPage as ba, PlaceAutocomplete as bi, EmptyContent as bn, SheetClose as br, NavMain as bt, DEFAULT_PRESETS as c, ButtonGroupSeparator as ca, MapLocateControl as ci, FormField as cn, TabsTrigger as cr, SidebarMenuButton as ct, getPresetByShortcut as d, Separator as da, MapPolygon as di, FormDescription as dn, TableCaption as dr, SidebarMenuSub as dt, CardFooter as ea, MapDrawPolyline as ei, FormSubmit as en, textVariants as er, SidebarGroupContent as et, getPresetRange as f, LinkButton as fa, MapPolyline as fi, FormCustom as fn, TableCell as fr, SidebarMenuSubButton as ft, createTimezoneOption as g, BreadcrumbEllipsis as ga, MapTileLayer as gi, FormCheckbox as gn, TableRow as gr, SidebarSeparator as gt, CustomRangePanel as h, Breadcrumb as ha, MapSearchControl as hi, Toaster$1 as hn, TableHeader as hr, SidebarRail as ht, TimeRangePicker as i, CardTitle as ia, MapFullscreenControl as ii, FormRadioGroup as in, Tabs as ir, SidebarInset as it, TaskPanelItem as j, HoverCardContent as ji, DropdownMenuRadioGroup as jn, SelectItem as jr, getResponsiveValue as jt, TaskQueueTrigger as k, Input as ki, DropdownMenuLabel as kn, SelectContent as kr, RowContext as kt, getDefaultPreset as l, ButtonGroupText as la, MapMarker as li, FormError as ln, Table as lr, SidebarMenuItem as lt, QuickRangesPanel as m, buttonVariants$1 as ma, MapRectangle as mi, useToast as mn, TableHead as mr, SidebarProvider as mt, ClientOnly as n, CardContent as na, MapDrawUndo as ni, FormSelectItem as nn, Tooltip as nr, SidebarHeader as nt, formatSingleTimeDisplay as o, CalendarDayButton as oa, MapLayers as oi, FormInput as on, TabsLinkTrigger as or, SidebarMenuAction as ot, TimezoneSelector as p, Button$1 as pa, MapPopup as pi, FormCopyBox as pn, TableFooter as pr, SidebarMenuSubItem as pt, createUserMetadata as q, ChartContainer as qi, Link as qn, MapControlContainer as qr, FormStepper as qt, toApiTimeRange as r, CardDescription as ra, MapFeatureGroup as ri, FormRoot as rn, Textarea as rr, SidebarInput as rt, formatTimeRangeDisplay as s, ButtonGroup as sa, MapLayersControl as si, FormFieldArray as sn, TabsList as sr, SidebarMenuBadge as st, ThemeScript as t, CardHeader as ta, MapDrawRectangle as ti, FormSelect as tn, titleVariants$1 as tr, SidebarGroupLabel as tt, getPresetByKey as u, buttonGroupVariants as ua, MapMarkerClusterGroup as ui, FormDialog as un, TableBody as ur, SidebarMenuSkeleton as ut, formatUtcForDisplay as v, BreadcrumbLink as va, MapZoomControl as vi, FormAutocomplete as vn, Skeleton as vr, useSidebar as vt, utcStringToZonedDate as w, Alert as wa, InputGroupAddon as wi, DropdownMenu as wn, SheetFooter as wr, stopProgress as wt, getShortTimezoneDisplay as x, BreadcrumbSeparator as xa, Spinner as xi, Dropzone as xn, SheetContent as xr, PageTitle as xt, getBrowserTimezone as y, BreadcrumbList as ya, useLeaflet as yi, FileInputButton as yn, Sheet as yr, AppSidebar as yt, useTaskQueue as z, CommandItem as zi, CalendarDatePicker as zn, RadioGroupItem as zr, useStepper as zt };
|