@panneau/fields 5.0.0-alpha.4 → 5.0.0-alpha.6

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.
Files changed (118) hide show
  1. package/README.md +67 -21
  2. package/dist/duration/DurationField.css +11 -0
  3. package/dist/duration/DurationField.d.ts +26 -0
  4. package/dist/duration/DurationField.d.ts.map +1 -0
  5. package/dist/duration/DurationField.js +129 -0
  6. package/dist/duration/DurationField.js.map +1 -0
  7. package/dist/duration/DurationField.module.js +12 -0
  8. package/dist/duration/DurationField.module.js.map +1 -0
  9. package/dist/duration/index.d.ts +2 -0
  10. package/dist/duration/index.d.ts.map +1 -0
  11. package/dist/duration/index.js +1 -0
  12. package/dist/embed/EmbedField.css +60 -0
  13. package/dist/embed/EmbedField.d.ts +20 -0
  14. package/dist/embed/EmbedField.d.ts.map +1 -0
  15. package/dist/embed/EmbedField.js +130 -0
  16. package/dist/embed/EmbedField.js.map +1 -0
  17. package/dist/embed/EmbedField.module.js +22 -0
  18. package/dist/embed/EmbedField.module.js.map +1 -0
  19. package/dist/embed/index.d.ts +3 -0
  20. package/dist/embed/index.d.ts.map +1 -0
  21. package/dist/embed/index.js +3 -0
  22. package/dist/index.d.ts +4 -0
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +4 -1
  25. package/dist/json/JsonField.css +7 -0
  26. package/dist/json/JsonField.d.ts +22 -0
  27. package/dist/json/JsonField.d.ts.map +1 -0
  28. package/dist/json/JsonField.js +125 -0
  29. package/dist/json/JsonField.js.map +1 -0
  30. package/dist/json/JsonField.module.js +8 -0
  31. package/dist/json/JsonField.module.js.map +1 -0
  32. package/dist/json/index.d.ts +2 -0
  33. package/dist/json/index.d.ts.map +1 -0
  34. package/dist/json/index.js +1 -0
  35. package/dist/localized/LocalizedField.d.ts.map +1 -1
  36. package/dist/localized/LocalizedField.js +1 -0
  37. package/dist/localized/LocalizedField.js.map +1 -1
  38. package/dist/location/LocationField.css +54 -0
  39. package/dist/location/LocationField.d.ts +31 -0
  40. package/dist/location/LocationField.d.ts.map +1 -0
  41. package/dist/location/LocationField.js +350 -0
  42. package/dist/location/LocationField.js.map +1 -0
  43. package/dist/location/LocationField.module.js +22 -0
  44. package/dist/location/LocationField.module.js.map +1 -0
  45. package/dist/location/LocationMap.d.ts +25 -0
  46. package/dist/location/LocationMap.d.ts.map +1 -0
  47. package/dist/location/LocationMap.js +115 -0
  48. package/dist/location/LocationMap.js.map +1 -0
  49. package/dist/location/index.d.ts +5 -0
  50. package/dist/location/index.d.ts.map +1 -0
  51. package/dist/location/index.js +4 -0
  52. package/dist/location/leafletCss.d.ts +2 -0
  53. package/dist/location/leafletCss.d.ts.map +1 -0
  54. package/dist/location/leafletCss.js +6 -0
  55. package/dist/location/leafletCss.js.map +1 -0
  56. package/dist/location/nominatim.d.ts +17 -0
  57. package/dist/location/nominatim.d.ts.map +1 -0
  58. package/dist/location/nominatim.js +50 -0
  59. package/dist/location/nominatim.js.map +1 -0
  60. package/dist/location/types.d.ts +40 -0
  61. package/dist/location/types.d.ts.map +1 -0
  62. package/dist/range/RangeField.d.ts +22 -0
  63. package/dist/range/RangeField.d.ts.map +1 -0
  64. package/dist/range/RangeField.js +132 -0
  65. package/dist/range/RangeField.js.map +1 -0
  66. package/dist/range/index.d.ts +2 -0
  67. package/dist/range/index.d.ts.map +1 -0
  68. package/dist/range/index.js +1 -0
  69. package/dist/relation/RelationField.d.ts.map +1 -1
  70. package/dist/relation/RelationField.js +24 -24
  71. package/dist/relation/RelationField.js.map +1 -1
  72. package/dist/shared/DefinitionField.d.ts +3 -1
  73. package/dist/shared/DefinitionField.d.ts.map +1 -1
  74. package/dist/shared/DefinitionField.js +80 -72
  75. package/dist/shared/DefinitionField.js.map +1 -1
  76. package/dist/shared/builtIn.d.ts +1 -0
  77. package/dist/shared/builtIn.d.ts.map +1 -1
  78. package/dist/shared/builtIn.js +16 -1
  79. package/dist/shared/builtIn.js.map +1 -1
  80. package/dist/shared/check.d.ts +27 -0
  81. package/dist/shared/check.d.ts.map +1 -0
  82. package/dist/shared/check.js +18 -0
  83. package/dist/shared/check.js.map +1 -0
  84. package/dist/shared/context.d.ts +18 -3
  85. package/dist/shared/context.d.ts.map +1 -1
  86. package/dist/shared/context.js +31 -19
  87. package/dist/shared/context.js.map +1 -1
  88. package/dist/shared/embed.d.ts +19 -0
  89. package/dist/shared/embed.d.ts.map +1 -0
  90. package/dist/shared/embed.js +14 -0
  91. package/dist/shared/embed.js.map +1 -0
  92. package/dist/shared/types.d.ts +2 -0
  93. package/dist/shared/types.d.ts.map +1 -1
  94. package/dist/slug/SlugField.css +18 -0
  95. package/dist/slug/SlugField.d.ts +31 -3
  96. package/dist/slug/SlugField.d.ts.map +1 -1
  97. package/dist/slug/SlugField.js +231 -159
  98. package/dist/slug/SlugField.js.map +1 -1
  99. package/dist/slug/SlugField.module.js +14 -0
  100. package/dist/slug/SlugField.module.js.map +1 -0
  101. package/dist/slug/index.d.ts +1 -1
  102. package/dist/slug/index.d.ts.map +1 -1
  103. package/dist/slug/index.js +1 -1
  104. package/dist/tags/TagsField.d.ts +17 -0
  105. package/dist/tags/TagsField.d.ts.map +1 -0
  106. package/dist/tags/TagsField.js +120 -0
  107. package/dist/tags/TagsField.js.map +1 -0
  108. package/dist/tags/index.d.ts +2 -0
  109. package/dist/tags/index.d.ts.map +1 -0
  110. package/dist/tags/index.js +1 -0
  111. package/dist/tel/TelField.d.ts +11 -0
  112. package/dist/tel/TelField.d.ts.map +1 -0
  113. package/dist/tel/TelField.js +87 -0
  114. package/dist/tel/TelField.js.map +1 -0
  115. package/dist/tel/index.d.ts +2 -0
  116. package/dist/tel/index.d.ts.map +1 -0
  117. package/dist/tel/index.js +1 -0
  118. package/package.json +41 -4
@@ -0,0 +1,350 @@
1
+ import { useFieldsContext } from "../shared/context.js";
2
+ import { getFieldProps, getSetting, isNumber, isString } from "../shared/entry.js";
3
+ import { messages } from "../shared/messages.js";
4
+ import LocationField_module_default from "./LocationField.module.js";
5
+ import { LocationMap } from "./LocationMap.js";
6
+ import { c } from "react/compiler-runtime";
7
+ import { ComboBox, Fieldset, IconButton, NumberInput, TextInput, usePanneauIntl } from "@panneau/ui";
8
+ import { useEffect, useRef, useState } from "react";
9
+ import { jsx, jsxs } from "react/jsx-runtime";
10
+ import { X } from "lucide-react";
11
+ //#region src/location/LocationField.tsx
12
+ /** OpenStreetMap's standard tiles: fine for an admin panel, with their credit. */
13
+ var OPEN_STREET_MAP_TILES = {
14
+ url: "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
15
+ attribution: "&copy; <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors",
16
+ maxZoom: 19
17
+ };
18
+ var SEARCH_DELAY = 400;
19
+ var SEARCH_MIN_LENGTH = 3;
20
+ /** Whether a value is a point. */
21
+ function isLocation(value) {
22
+ return value !== null && typeof value === "object" && isNumber(value.lat) && isNumber(value.lng);
23
+ }
24
+ /** The search of addresses: results of the text typed, after a pause. */
25
+ function useAddressSearch(geocoding, query, locale) {
26
+ const $ = c(9);
27
+ let t0;
28
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
29
+ t0 = {
30
+ query: "",
31
+ results: [],
32
+ loading: false
33
+ };
34
+ $[0] = t0;
35
+ } else t0 = $[0];
36
+ const [state, setState] = useState(t0);
37
+ let t1;
38
+ let t2;
39
+ if ($[1] !== geocoding || $[2] !== locale || $[3] !== query) {
40
+ t1 = () => {
41
+ const text = query.trim();
42
+ if (geocoding === null || text.length < SEARCH_MIN_LENGTH) return;
43
+ const controller = new AbortController();
44
+ const timeout = window.setTimeout(() => {
45
+ setState(_temp);
46
+ geocoding.search(text, {
47
+ signal: controller.signal,
48
+ locale
49
+ }).then((results) => setState({
50
+ query: text,
51
+ results,
52
+ loading: false
53
+ })).catch(() => {
54
+ if (!controller.signal.aborted) setState({
55
+ query: text,
56
+ results: [],
57
+ loading: false
58
+ });
59
+ });
60
+ }, SEARCH_DELAY);
61
+ return () => {
62
+ window.clearTimeout(timeout);
63
+ controller.abort();
64
+ };
65
+ };
66
+ t2 = [
67
+ geocoding,
68
+ query,
69
+ locale
70
+ ];
71
+ $[1] = geocoding;
72
+ $[2] = locale;
73
+ $[3] = query;
74
+ $[4] = t1;
75
+ $[5] = t2;
76
+ } else {
77
+ t1 = $[4];
78
+ t2 = $[5];
79
+ }
80
+ useEffect(t1, t2);
81
+ let t3;
82
+ if ($[6] !== query || $[7] !== state) {
83
+ t3 = query.trim().length >= SEARCH_MIN_LENGTH ? state : {
84
+ ...state,
85
+ results: []
86
+ };
87
+ $[6] = query;
88
+ $[7] = state;
89
+ $[8] = t3;
90
+ } else t3 = $[8];
91
+ return t3;
92
+ }
93
+ /**
94
+ * A point on a map, and its address. Clicking the map or dragging the marker places the point,
95
+ * and its latitude and longitude can be typed. With an address search, a place found sets the
96
+ * point and the address; with a reverse search, placing a point fills an empty address.
97
+ */
98
+ function _temp(current) {
99
+ return {
100
+ ...current,
101
+ loading: true
102
+ };
103
+ }
104
+ function LocationField({ value, onChange, onBlur, geocoding: geocodingProp, tiles: tilesProp, center = {
105
+ lat: 20,
106
+ lng: 0
107
+ }, zoom = 15, label, description, errors, disabled, readOnly, required, className }) {
108
+ const intl = usePanneauIntl();
109
+ const { maps } = useFieldsContext();
110
+ const geocoding = geocodingProp === void 0 ? maps?.geocoding ?? null : geocodingProp;
111
+ const tiles = tilesProp ?? maps?.tiles ?? OPEN_STREET_MAP_TILES;
112
+ const editable = disabled !== true && readOnly !== true;
113
+ const [query, setQuery] = useState("");
114
+ const [chosen, setChosen] = useState(null);
115
+ const search = useAddressSearch(editable && query !== chosen?.label ? geocoding : null, query, intl.locale);
116
+ const places = chosen !== null && query === chosen.label ? [chosen] : search.results;
117
+ const addressRef = useRef(null);
118
+ const focusAddress = () => window.requestAnimationFrame(() => addressRef.current?.querySelector("input")?.focus());
119
+ const [draft, setDraft] = useState({
120
+ source: value,
121
+ lat: value?.lat ?? null,
122
+ lng: value?.lng ?? null
123
+ });
124
+ if (draft.source !== value) setDraft({
125
+ source: value,
126
+ lat: value?.lat ?? null,
127
+ lng: value?.lng ?? null
128
+ });
129
+ const setPoint = (point, address = value?.address) => {
130
+ const next = {
131
+ lat: Number(point.lat.toFixed(6)),
132
+ lng: Number(point.lng.toFixed(6)),
133
+ ...address !== void 0 && address !== "" ? { address } : {}
134
+ };
135
+ onChange?.(next);
136
+ if ((address === void 0 || address === "") && geocoding?.reverse !== void 0) {
137
+ const controller = new AbortController();
138
+ geocoding.reverse(point, {
139
+ signal: controller.signal,
140
+ locale: intl.locale
141
+ }).then((place) => {
142
+ if (place !== null) onChange?.({
143
+ ...next,
144
+ address: place.label
145
+ });
146
+ }).catch(() => void 0);
147
+ }
148
+ };
149
+ const setCoordinate = (key, number) => {
150
+ const next_0 = {
151
+ ...draft,
152
+ [key]: number
153
+ };
154
+ setDraft(next_0);
155
+ if (next_0.lat !== null && next_0.lng !== null) setPoint({
156
+ lat: next_0.lat,
157
+ lng: next_0.lng
158
+ });
159
+ else if (next_0.lat === null && next_0.lng === null) onChange?.(null);
160
+ };
161
+ const point_0 = isLocation(value) ? {
162
+ lat: value.lat,
163
+ lng: value.lng
164
+ } : null;
165
+ return /* @__PURE__ */ jsx(Fieldset, {
166
+ legend: label,
167
+ description,
168
+ errors,
169
+ isRequired: required,
170
+ isDisabled: disabled,
171
+ className,
172
+ children: /* @__PURE__ */ jsxs("div", {
173
+ className: LocationField_module_default.location,
174
+ children: [
175
+ editable && geocoding !== null ? /* @__PURE__ */ jsx(ComboBox, {
176
+ "aria-label": intl.formatMessage(messages.searchAddress),
177
+ placeholder: intl.formatMessage(messages.searchAddress),
178
+ onInputChange: setQuery,
179
+ items: places.map((result, index) => ({
180
+ id: String(index),
181
+ label: result.label
182
+ })),
183
+ isLoading: search.loading,
184
+ menuTrigger: "input",
185
+ emptyMessage: query.trim().length < SEARCH_MIN_LENGTH ? intl.formatMessage(messages.searchAddressHint, { count: SEARCH_MIN_LENGTH }) : intl.formatMessage(messages.noPlaces),
186
+ value: chosen !== null && query === chosen.label ? "0" : null,
187
+ onChange: (id) => {
188
+ const result_0 = id !== null ? places[Number(id)] : void 0;
189
+ if (result_0 !== void 0) {
190
+ setChosen(result_0);
191
+ setPoint(result_0, result_0.label);
192
+ focusAddress();
193
+ }
194
+ }
195
+ }) : null,
196
+ /* @__PURE__ */ jsx(LocationMap, {
197
+ point: point_0,
198
+ onChange: (next_1) => setPoint(next_1),
199
+ tiles,
200
+ center,
201
+ zoom,
202
+ readOnly: !editable,
203
+ label: intl.formatMessage(messages.map, { label: typeof label === "string" ? label : "" })
204
+ }),
205
+ /* @__PURE__ */ jsxs("div", {
206
+ className: LocationField_module_default.coordinates,
207
+ children: [
208
+ /* @__PURE__ */ jsx(NumberInput, {
209
+ label: intl.formatMessage(messages.latitude),
210
+ value: draft.lat,
211
+ onChange: (next_2) => setCoordinate("lat", next_2),
212
+ onBlur: () => onBlur?.(),
213
+ minValue: -90,
214
+ maxValue: 90,
215
+ step: 1e-6,
216
+ formatOptions: { maximumFractionDigits: 6 },
217
+ isDisabled: disabled,
218
+ isReadOnly: readOnly,
219
+ className: LocationField_module_default.coordinate
220
+ }),
221
+ /* @__PURE__ */ jsx(NumberInput, {
222
+ label: intl.formatMessage(messages.longitude),
223
+ value: draft.lng,
224
+ onChange: (next_3) => setCoordinate("lng", next_3),
225
+ onBlur: () => onBlur?.(),
226
+ minValue: -180,
227
+ maxValue: 180,
228
+ step: 1e-6,
229
+ formatOptions: { maximumFractionDigits: 6 },
230
+ isDisabled: disabled,
231
+ isReadOnly: readOnly,
232
+ className: LocationField_module_default.coordinate
233
+ }),
234
+ editable && point_0 !== null ? /* @__PURE__ */ jsx(IconButton, {
235
+ icon: X,
236
+ label: intl.formatMessage(messages.removePoint),
237
+ className: LocationField_module_default.remove,
238
+ onPress: () => onChange?.(null)
239
+ }) : null
240
+ ]
241
+ }),
242
+ point_0 !== null ? /* @__PURE__ */ jsx("div", {
243
+ ref: addressRef,
244
+ children: /* @__PURE__ */ jsx(TextInput, {
245
+ label: intl.formatMessage(messages.address),
246
+ value: value?.address ?? "",
247
+ onChange: (address_0) => onChange?.({
248
+ lat: point_0.lat,
249
+ lng: point_0.lng,
250
+ ...address_0 !== "" ? { address: address_0 } : {}
251
+ }),
252
+ onBlur: () => onBlur?.(),
253
+ isDisabled: disabled,
254
+ isReadOnly: readOnly
255
+ })
256
+ }) : null
257
+ ]
258
+ })
259
+ });
260
+ }
261
+ function isPoint(value) {
262
+ return isLocation(value);
263
+ }
264
+ /**
265
+ * The `location` type: settings `zoom`, `center` (`{ "lat", "lng" }`, where the map opens without
266
+ * a point) and `tiles` (`{ "url", "attribution" }`), over the maps of the `FieldsProvider`.
267
+ */
268
+ function LocationFieldEntry(props) {
269
+ const $ = c(23);
270
+ const { field } = props;
271
+ let t0;
272
+ if ($[0] !== field) {
273
+ t0 = getSetting(field, "zoom", isNumber);
274
+ $[0] = field;
275
+ $[1] = t0;
276
+ } else t0 = $[1];
277
+ const zoom = t0;
278
+ let t1;
279
+ if ($[2] !== field) {
280
+ t1 = getSetting(field, "center", isPoint);
281
+ $[2] = field;
282
+ $[3] = t1;
283
+ } else t1 = $[3];
284
+ const center = t1;
285
+ let t2;
286
+ if ($[4] !== field) {
287
+ t2 = getSetting(field, "tiles", _temp2);
288
+ $[4] = field;
289
+ $[5] = t2;
290
+ } else t2 = $[5];
291
+ const tiles = t2;
292
+ let t3;
293
+ if ($[6] !== props) {
294
+ t3 = getFieldProps(props);
295
+ $[6] = props;
296
+ $[7] = t3;
297
+ } else t3 = $[7];
298
+ let fieldProps;
299
+ if ($[8] !== t3) {
300
+ const { placeholder: _placeholder, ...t4 } = t3;
301
+ fieldProps = t4;
302
+ $[8] = t3;
303
+ $[9] = fieldProps;
304
+ } else fieldProps = $[9];
305
+ const t4 = isLocation(props.value) ? props.value : null;
306
+ let t5;
307
+ if ($[10] !== zoom) {
308
+ t5 = zoom !== void 0 ? { zoom } : {};
309
+ $[10] = zoom;
310
+ $[11] = t5;
311
+ } else t5 = $[11];
312
+ let t6;
313
+ if ($[12] !== center) {
314
+ t6 = center !== void 0 ? { center } : {};
315
+ $[12] = center;
316
+ $[13] = t6;
317
+ } else t6 = $[13];
318
+ let t7;
319
+ if ($[14] !== tiles) {
320
+ t7 = tiles !== void 0 ? { tiles } : {};
321
+ $[14] = tiles;
322
+ $[15] = t7;
323
+ } else t7 = $[15];
324
+ let t8;
325
+ if ($[16] !== fieldProps || $[17] !== props.onChange || $[18] !== t4 || $[19] !== t5 || $[20] !== t6 || $[21] !== t7) {
326
+ t8 = /* @__PURE__ */ jsx(LocationField, {
327
+ ...fieldProps,
328
+ value: t4,
329
+ onChange: props.onChange,
330
+ ...t5,
331
+ ...t6,
332
+ ...t7
333
+ });
334
+ $[16] = fieldProps;
335
+ $[17] = props.onChange;
336
+ $[18] = t4;
337
+ $[19] = t5;
338
+ $[20] = t6;
339
+ $[21] = t7;
340
+ $[22] = t8;
341
+ } else t8 = $[22];
342
+ return t8;
343
+ }
344
+ function _temp2(value) {
345
+ return value !== null && typeof value === "object" && isString(value.url) && isString(value.attribution);
346
+ }
347
+ //#endregion
348
+ export { LocationField, LocationFieldEntry, OPEN_STREET_MAP_TILES, isLocation };
349
+
350
+ //# sourceMappingURL=LocationField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocationField.js","names":["next","point","result","address","_c","styles"],"sources":["../../src/location/LocationField.tsx"],"sourcesContent":["import { X } from 'lucide-react';\nimport { useEffect, useRef, useState } from 'react';\n\nimport type { LocationValue } from '@panneau/protocol';\nimport {\n ComboBox,\n Fieldset,\n IconButton,\n NumberInput,\n TextInput,\n usePanneauIntl,\n} from '@panneau/ui';\n\nimport { useFieldsContext } from '../shared/context';\nimport { getFieldProps, getSetting, isNumber, isString } from '../shared/entry';\nimport { messages } from '../shared/messages';\nimport type { FieldEntryProps, FieldProps } from '../shared/types';\nimport styles from './LocationField.module.css';\nimport { LocationMap, type Point } from './LocationMap';\nimport type { GeocodingResult, GeocodingSource, MapTiles } from './types';\n\nexport type { LocationValue };\n\n/** OpenStreetMap's standard tiles: fine for an admin panel, with their credit. */\nexport const OPEN_STREET_MAP_TILES: MapTiles = {\n url: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',\n attribution:\n '&copy; <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors',\n maxZoom: 19,\n};\n\nconst SEARCH_DELAY = 400;\nconst SEARCH_MIN_LENGTH = 3;\n\nexport interface LocationFieldProps extends FieldProps<LocationValue> {\n /** The address search. Defaults to that of the `FieldsProvider`; without one, there is none. */\n geocoding?: GeocodingSource | null;\n /** The tiles of the map. Defaults to those of the `FieldsProvider`, or OpenStreetMap's. */\n tiles?: MapTiles;\n /** Where the map opens without a point. Defaults to the whole world. */\n center?: Point;\n /** Zoom of the map on a point. Defaults to 15. */\n zoom?: number;\n}\n\n/** Whether a value is a point. */\nexport function isLocation(value: unknown): value is LocationValue {\n return (\n value !== null &&\n typeof value === 'object' &&\n isNumber((value as Record<string, unknown>).lat) &&\n isNumber((value as Record<string, unknown>).lng)\n );\n}\n\n/** The search of addresses: results of the text typed, after a pause. */\nfunction useAddressSearch(geocoding: GeocodingSource | null, query: string, locale: string) {\n const [state, setState] = useState<{\n query: string;\n results: GeocodingResult[];\n loading: boolean;\n }>({ query: '', results: [], loading: false });\n useEffect(() => {\n const text = query.trim();\n if (geocoding === null || text.length < SEARCH_MIN_LENGTH) {\n return undefined;\n }\n const controller = new AbortController();\n const timeout = window.setTimeout(() => {\n setState((current) => ({ ...current, loading: true }));\n geocoding\n .search(text, { signal: controller.signal, locale })\n .then((results) => setState({ query: text, results, loading: false }))\n .catch(() => {\n if (!controller.signal.aborted) {\n setState({ query: text, results: [], loading: false });\n }\n });\n }, SEARCH_DELAY);\n return () => {\n window.clearTimeout(timeout);\n controller.abort();\n };\n }, [geocoding, query, locale]);\n return query.trim().length >= SEARCH_MIN_LENGTH ? state : { ...state, results: [] };\n}\n\n/**\n * A point on a map, and its address. Clicking the map or dragging the marker places the point,\n * and its latitude and longitude can be typed. With an address search, a place found sets the\n * point and the address; with a reverse search, placing a point fills an empty address.\n */\nexport function LocationField({\n value,\n onChange,\n onBlur,\n geocoding: geocodingProp,\n tiles: tilesProp,\n center = { lat: 20, lng: 0 },\n zoom = 15,\n label,\n description,\n errors,\n disabled,\n readOnly,\n required,\n className,\n}: LocationFieldProps) {\n const intl = usePanneauIntl();\n const { maps } = useFieldsContext();\n const geocoding = geocodingProp === undefined ? (maps?.geocoding ?? null) : geocodingProp;\n const tiles = tilesProp ?? maps?.tiles ?? OPEN_STREET_MAP_TILES;\n const editable = disabled !== true && readOnly !== true;\n const [query, setQuery] = useState('');\n // The place chosen: the search shows its label until something else is typed\n const [chosen, setChosen] = useState<GeocodingResult | null>(null);\n const search = useAddressSearch(\n editable && query !== chosen?.label ? geocoding : null,\n query,\n intl.locale,\n );\n const places = chosen !== null && query === chosen.label ? [chosen] : search.results;\n // A place chosen moves focus to its address, which closes the results\n const addressRef = useRef<HTMLDivElement>(null);\n const focusAddress = () =>\n window.requestAnimationFrame(() =>\n addressRef.current?.querySelector<HTMLInputElement>('input')?.focus(),\n );\n\n // The coordinates as typed: a value needs both\n const [draft, setDraft] = useState<{ source: unknown; lat: number | null; lng: number | null }>(\n { source: value, lat: value?.lat ?? null, lng: value?.lng ?? null },\n );\n if (draft.source !== value) {\n setDraft({ source: value, lat: value?.lat ?? null, lng: value?.lng ?? null });\n }\n\n const setPoint = (point: Point, address = value?.address) => {\n const next: LocationValue = {\n lat: Number(point.lat.toFixed(6)),\n lng: Number(point.lng.toFixed(6)),\n ...(address !== undefined && address !== '' ? { address } : {}),\n };\n onChange?.(next);\n // Fills an empty address from the point\n if ((address === undefined || address === '') && geocoding?.reverse !== undefined) {\n const controller = new AbortController();\n void geocoding\n .reverse(point, { signal: controller.signal, locale: intl.locale })\n .then((place) => {\n if (place !== null) {\n onChange?.({ ...next, address: place.label });\n }\n })\n .catch(() => undefined);\n }\n };\n\n const setCoordinate = (key: 'lat' | 'lng', number: number | null) => {\n const next = { ...draft, [key]: number };\n setDraft(next);\n if (next.lat !== null && next.lng !== null) {\n setPoint({ lat: next.lat, lng: next.lng });\n } else if (next.lat === null && next.lng === null) {\n onChange?.(null);\n }\n };\n\n const point = isLocation(value) ? { lat: value.lat, lng: value.lng } : null;\n return (\n <Fieldset\n legend={label}\n description={description}\n errors={errors}\n isRequired={required}\n isDisabled={disabled}\n className={className}\n >\n <div className={styles.location}>\n {editable && geocoding !== null ? (\n <ComboBox\n aria-label={intl.formatMessage(messages.searchAddress)}\n placeholder={intl.formatMessage(messages.searchAddress)}\n onInputChange={setQuery}\n items={places.map((result, index) => ({\n id: String(index),\n label: result.label,\n }))}\n isLoading={search.loading}\n menuTrigger=\"input\"\n emptyMessage={\n query.trim().length < SEARCH_MIN_LENGTH\n ? intl.formatMessage(messages.searchAddressHint, {\n count: SEARCH_MIN_LENGTH,\n })\n : intl.formatMessage(messages.noPlaces)\n }\n value={chosen !== null && query === chosen.label ? '0' : null}\n onChange={(id) => {\n const result = id !== null ? places[Number(id)] : undefined;\n if (result !== undefined) {\n setChosen(result);\n setPoint(result, result.label);\n focusAddress();\n }\n }}\n />\n ) : null}\n <LocationMap\n point={point}\n onChange={(next) => setPoint(next)}\n tiles={tiles}\n center={center}\n zoom={zoom}\n readOnly={!editable}\n label={intl.formatMessage(messages.map, {\n label: typeof label === 'string' ? label : '',\n })}\n />\n <div className={styles.coordinates}>\n <NumberInput\n label={intl.formatMessage(messages.latitude)}\n value={draft.lat}\n onChange={(next) => setCoordinate('lat', next)}\n onBlur={() => onBlur?.()}\n minValue={-90}\n maxValue={90}\n step={0.000001}\n formatOptions={{ maximumFractionDigits: 6 }}\n isDisabled={disabled}\n isReadOnly={readOnly}\n className={styles.coordinate}\n />\n <NumberInput\n label={intl.formatMessage(messages.longitude)}\n value={draft.lng}\n onChange={(next) => setCoordinate('lng', next)}\n onBlur={() => onBlur?.()}\n minValue={-180}\n maxValue={180}\n step={0.000001}\n formatOptions={{ maximumFractionDigits: 6 }}\n isDisabled={disabled}\n isReadOnly={readOnly}\n className={styles.coordinate}\n />\n {editable && point !== null ? (\n <IconButton\n icon={X}\n label={intl.formatMessage(messages.removePoint)}\n className={styles.remove}\n onPress={() => onChange?.(null)}\n />\n ) : null}\n </div>\n {point !== null ? (\n <div ref={addressRef}>\n <TextInput\n label={intl.formatMessage(messages.address)}\n value={value?.address ?? ''}\n onChange={(address) =>\n onChange?.({\n lat: point.lat,\n lng: point.lng,\n ...(address !== '' ? { address } : {}),\n })\n }\n onBlur={() => onBlur?.()}\n isDisabled={disabled}\n isReadOnly={readOnly}\n />\n </div>\n ) : null}\n </div>\n </Fieldset>\n );\n}\n\nfunction isPoint(value: unknown): value is Point {\n return isLocation(value);\n}\n\n/**\n * The `location` type: settings `zoom`, `center` (`{ \"lat\", \"lng\" }`, where the map opens without\n * a point) and `tiles` (`{ \"url\", \"attribution\" }`), over the maps of the `FieldsProvider`.\n */\nexport function LocationFieldEntry(props: FieldEntryProps) {\n const { field } = props;\n const zoom = getSetting(field, 'zoom', isNumber);\n const center = getSetting(field, 'center', isPoint);\n const tiles = getSetting(\n field,\n 'tiles',\n (value): value is MapTiles =>\n value !== null &&\n typeof value === 'object' &&\n isString((value as Record<string, unknown>).url) &&\n isString((value as Record<string, unknown>).attribution),\n );\n const { placeholder: _placeholder, ...fieldProps } = getFieldProps(props);\n return (\n <LocationField\n {...fieldProps}\n value={isLocation(props.value) ? props.value : null}\n onChange={props.onChange}\n {...(zoom !== undefined ? { zoom } : {})}\n {...(center !== undefined ? { center } : {})}\n {...(tiles !== undefined ? { tiles } : {})}\n />\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import "./LocationField.css";
2
+ //#region src/location/LocationField.module.css
3
+ var location = "panneau-location-field-location";
4
+ var map = "panneau-location-field-map";
5
+ var marker = "panneau-location-field-marker";
6
+ var pin = "panneau-location-field-pin";
7
+ var coordinates = "panneau-location-field-coordinates";
8
+ var coordinate = "panneau-location-field-coordinate";
9
+ var remove = "panneau-location-field-remove";
10
+ var LocationField_module_default = {
11
+ location,
12
+ map,
13
+ marker,
14
+ pin,
15
+ coordinates,
16
+ coordinate,
17
+ remove
18
+ };
19
+ //#endregion
20
+ export { coordinate, coordinates, LocationField_module_default as default, location, map, marker, pin, remove };
21
+
22
+ //# sourceMappingURL=LocationField.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocationField.module.js","names":[],"sources":["../../src/location/LocationField.module.css"],"sourcesContent":["/* The search, the map, then the coordinates and the address. */\n.location {\n display: flex;\n flex-direction: column;\n gap: var(--panneau-space-2);\n}\n\n.map {\n position: relative;\n z-index: 0;\n height: 16rem;\n overflow: hidden;\n background-color: var(--panneau-color-surface-sunken);\n border: var(--panneau-border-width) solid var(--panneau-color-border-control);\n border-radius: var(--panneau-radius-md);\n}\n\n.map:focus-visible {\n outline: var(--panneau-focus-width) solid var(--panneau-color-focus);\n outline-offset: 1px;\n}\n\n/* A pin: a round head pointing down at the point. */\n.marker {\n background: none;\n border: 0;\n}\n\n.pin {\n display: block;\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n background-color: var(--panneau-color-accent);\n border: 2px solid var(--panneau-color-surface);\n border-radius: 50% 50% 50% 0;\n box-shadow: var(--panneau-shadow-sm);\n rotate: -45deg;\n}\n\n.coordinates {\n display: flex;\n flex-wrap: wrap;\n align-items: flex-end;\n gap: var(--panneau-space-2);\n}\n\n.coordinate {\n flex: 1 1 8rem;\n}\n\n.remove {\n flex: none;\n}\n"],"mappings":""}
@@ -0,0 +1,25 @@
1
+ import type { MapTiles } from './types';
2
+ export interface Point {
3
+ lat: number;
4
+ lng: number;
5
+ }
6
+ export interface LocationMapProps {
7
+ point: Point | null;
8
+ /** Called with the point clicked, or where the marker was dropped. */
9
+ onChange?: (point: Point) => void;
10
+ tiles: MapTiles;
11
+ /** Where the map opens without a point. */
12
+ center: Point;
13
+ /** Zoom of the map on a point; the map opens wider without one. */
14
+ zoom: number;
15
+ readOnly?: boolean;
16
+ /** Accessible name of the map. */
17
+ label: string;
18
+ className?: string;
19
+ }
20
+ /**
21
+ * A Leaflet map with a marker on the point. Clicking the map or dragging the marker moves the
22
+ * point. Leaflet and its stylesheet load when the map first shows.
23
+ */
24
+ export declare function LocationMap({ point, onChange, tiles, center, zoom, readOnly, label, className, }: LocationMapProps): import("react").JSX.Element;
25
+ //# sourceMappingURL=LocationMap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocationMap.d.ts","sourceRoot":"","sources":["../../src/location/LocationMap.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAkBxC,MAAM,WAAW,KAAK;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC7B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAClC,KAAK,EAAE,QAAQ,CAAC;IAChB,2CAA2C;IAC3C,MAAM,EAAE,KAAK,CAAC;IACd,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EACxB,KAAK,EACL,QAAQ,EACR,KAAK,EACL,MAAM,EACN,IAAI,EACJ,QAAgB,EAChB,KAAK,EACL,SAAS,GACZ,EAAE,gBAAgB,+BAsGlB"}
@@ -0,0 +1,115 @@
1
+ import LocationField_module_default from "./LocationField.module.js";
2
+ import { LEAFLET_CSS } from "./leafletCss.js";
3
+ import { useEffect, useRef } from "react";
4
+ import { jsx } from "react/jsx-runtime";
5
+ //#region src/location/LocationMap.tsx
6
+ var STYLE_ID = "panneau-leaflet-css";
7
+ /** Adds Leaflet's stylesheet to the document of the map, once. */
8
+ function injectStyles(document) {
9
+ if (document.getElementById(STYLE_ID) === null) {
10
+ const style = document.createElement("style");
11
+ style.id = STYLE_ID;
12
+ style.textContent = LEAFLET_CSS;
13
+ document.head.append(style);
14
+ }
15
+ }
16
+ /**
17
+ * A Leaflet map with a marker on the point. Clicking the map or dragging the marker moves the
18
+ * point. Leaflet and its stylesheet load when the map first shows.
19
+ */
20
+ function LocationMap({ point, onChange, tiles, center, zoom, readOnly = false, label, className }) {
21
+ const container = useRef(null);
22
+ const map = useRef(null);
23
+ const latest = useRef({
24
+ onChange,
25
+ readOnly
26
+ });
27
+ useEffect(() => {
28
+ latest.current = {
29
+ onChange,
30
+ readOnly
31
+ };
32
+ });
33
+ useEffect(() => {
34
+ const element = container.current;
35
+ if (element === null) return;
36
+ let cancelled = false;
37
+ import("leaflet").then((module) => {
38
+ if (cancelled) return;
39
+ const leaflet = module.default ?? module;
40
+ injectStyles(element.ownerDocument);
41
+ const instance = leaflet.map(element, { attributionControl: true });
42
+ leaflet.tileLayer(tiles.url, {
43
+ attribution: tiles.attribution,
44
+ maxZoom: tiles.maxZoom ?? 19
45
+ }).addTo(instance);
46
+ instance.on("click", (event) => {
47
+ if (!latest.current.readOnly) latest.current.onChange?.({
48
+ lat: event.latlng.lat,
49
+ lng: event.latlng.lng
50
+ });
51
+ });
52
+ map.current = {
53
+ leaflet,
54
+ map: instance,
55
+ marker: null
56
+ };
57
+ instance.setView(point ?? center, point !== null ? zoom : 2);
58
+ sync(point, false);
59
+ });
60
+ return () => {
61
+ cancelled = true;
62
+ map.current?.map.remove();
63
+ map.current = null;
64
+ };
65
+ }, [tiles.url]);
66
+ /** Puts the marker on the point, and the point in view. */
67
+ function sync(next, pan) {
68
+ const current = map.current;
69
+ if (current === null) return;
70
+ if (next === null) {
71
+ current.marker?.remove();
72
+ current.marker = null;
73
+ return;
74
+ }
75
+ if (current.marker === null) {
76
+ const marker = current.leaflet.marker(next, {
77
+ draggable: !latest.current.readOnly,
78
+ keyboard: false,
79
+ icon: current.leaflet.divIcon({
80
+ className: LocationField_module_default.marker,
81
+ html: `<span class="${LocationField_module_default.pin}"></span>`,
82
+ iconSize: [24, 24],
83
+ iconAnchor: [12, 29]
84
+ })
85
+ }).addTo(current.map);
86
+ marker.on("dragend", () => {
87
+ const position = marker.getLatLng();
88
+ latest.current.onChange?.({
89
+ lat: position.lat,
90
+ lng: position.lng
91
+ });
92
+ });
93
+ current.marker = marker;
94
+ } else current.marker.setLatLng(next);
95
+ if (pan && !current.map.getBounds().contains(next)) current.map.setView(next, Math.max(current.map.getZoom(), zoom));
96
+ }
97
+ const lat = point?.lat;
98
+ const lng = point?.lng;
99
+ useEffect(() => {
100
+ sync(lat !== void 0 && lng !== void 0 ? {
101
+ lat,
102
+ lng
103
+ } : null, true);
104
+ }, [lat, lng]);
105
+ return /* @__PURE__ */ jsx("div", {
106
+ ref: container,
107
+ className: [LocationField_module_default.map, className].filter(Boolean).join(" "),
108
+ role: "application",
109
+ "aria-label": label
110
+ });
111
+ }
112
+ //#endregion
113
+ export { LocationMap };
114
+
115
+ //# sourceMappingURL=LocationMap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocationMap.js","names":["styles"],"sources":["../../src/location/LocationMap.tsx"],"sourcesContent":["import type * as LeafletModule from 'leaflet';\nimport { useEffect, useRef } from 'react';\n\nimport styles from './LocationField.module.css';\nimport { LEAFLET_CSS } from './leafletCss';\nimport type { MapTiles } from './types';\n\ntype Leaflet = typeof LeafletModule;\ntype LeafletMap = LeafletModule.Map;\ntype LeafletMarker = LeafletModule.Marker;\n\nconst STYLE_ID = 'panneau-leaflet-css';\n\n/** Adds Leaflet's stylesheet to the document of the map, once. */\nfunction injectStyles(document: Document) {\n if (document.getElementById(STYLE_ID) === null) {\n const style = document.createElement('style');\n style.id = STYLE_ID;\n style.textContent = LEAFLET_CSS;\n document.head.append(style);\n }\n}\n\nexport interface Point {\n lat: number;\n lng: number;\n}\n\nexport interface LocationMapProps {\n point: Point | null;\n /** Called with the point clicked, or where the marker was dropped. */\n onChange?: (point: Point) => void;\n tiles: MapTiles;\n /** Where the map opens without a point. */\n center: Point;\n /** Zoom of the map on a point; the map opens wider without one. */\n zoom: number;\n readOnly?: boolean;\n /** Accessible name of the map. */\n label: string;\n className?: string;\n}\n\n/**\n * A Leaflet map with a marker on the point. Clicking the map or dragging the marker moves the\n * point. Leaflet and its stylesheet load when the map first shows.\n */\nexport function LocationMap({\n point,\n onChange,\n tiles,\n center,\n zoom,\n readOnly = false,\n label,\n className,\n}: LocationMapProps) {\n const container = useRef<HTMLDivElement>(null);\n const map = useRef<{ leaflet: Leaflet; map: LeafletMap; marker: LeafletMarker | null } | null>(\n null,\n );\n // The latest values, for the handlers of the map\n const latest = useRef({ onChange, readOnly });\n useEffect(() => {\n latest.current = { onChange, readOnly };\n });\n\n // Creates the map once Leaflet is loaded\n useEffect(() => {\n const element = container.current;\n if (element === null) {\n return undefined;\n }\n let cancelled = false;\n void import('leaflet').then((module) => {\n if (cancelled) {\n return;\n }\n const leaflet = ((module as { default?: Leaflet }).default ?? module) as Leaflet;\n injectStyles(element.ownerDocument);\n const instance = leaflet.map(element, { attributionControl: true });\n leaflet\n .tileLayer(tiles.url, {\n attribution: tiles.attribution,\n maxZoom: tiles.maxZoom ?? 19,\n })\n .addTo(instance);\n instance.on('click', (event) => {\n if (!latest.current.readOnly) {\n latest.current.onChange?.({ lat: event.latlng.lat, lng: event.latlng.lng });\n }\n });\n map.current = { leaflet, map: instance, marker: null };\n instance.setView(point ?? center, point !== null ? zoom : 2);\n sync(point, false);\n });\n return () => {\n cancelled = true;\n map.current?.map.remove();\n map.current = null;\n };\n // The map is made once; later changes go through the effect below\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [tiles.url]);\n\n /** Puts the marker on the point, and the point in view. */\n function sync(next: Point | null, pan: boolean) {\n const current = map.current;\n if (current === null) {\n return;\n }\n if (next === null) {\n current.marker?.remove();\n current.marker = null;\n return;\n }\n if (current.marker === null) {\n const marker = current.leaflet\n .marker(next, {\n draggable: !latest.current.readOnly,\n keyboard: false,\n icon: current.leaflet.divIcon({\n className: styles.marker,\n // Leaflet places the icon with `transform`: the pin turns inside it\n html: `<span class=\"${styles.pin}\"></span>`,\n iconSize: [24, 24],\n iconAnchor: [12, 29],\n }),\n })\n .addTo(current.map);\n marker.on('dragend', () => {\n const position = marker.getLatLng();\n latest.current.onChange?.({ lat: position.lat, lng: position.lng });\n });\n current.marker = marker;\n } else {\n current.marker.setLatLng(next);\n }\n if (pan && !current.map.getBounds().contains(next)) {\n current.map.setView(next, Math.max(current.map.getZoom(), zoom));\n }\n }\n\n const lat = point?.lat;\n const lng = point?.lng;\n useEffect(() => {\n sync(lat !== undefined && lng !== undefined ? { lat, lng } : null, true);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [lat, lng]);\n\n return (\n <div\n ref={container}\n className={[styles.map, className].filter(Boolean).join(' ')}\n role=\"application\"\n aria-label={label}\n />\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { LocationField, LocationFieldEntry, type LocationFieldProps, type LocationValue, OPEN_STREET_MAP_TILES, isLocation, } from './LocationField';
2
+ export { LocationMap, type LocationMapProps, type Point } from './LocationMap';
3
+ export { createNominatimSource, type NominatimSourceOptions } from './nominatim';
4
+ export type { GeocodingResult, GeocodingSource, MapTiles, MapsConfig } from './types';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/location/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,aAAa,EACb,kBAAkB,EAClB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,qBAAqB,EACrB,UAAU,GACb,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,KAAK,KAAK,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,EAAE,qBAAqB,EAAE,KAAK,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACjF,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { LocationMap } from "./LocationMap.js";
2
+ import { LocationField, LocationFieldEntry, OPEN_STREET_MAP_TILES, isLocation } from "./LocationField.js";
3
+ import { createNominatimSource } from "./nominatim.js";
4
+ export { LocationField, LocationFieldEntry, LocationMap, OPEN_STREET_MAP_TILES, createNominatimSource, isLocation };
@@ -0,0 +1,2 @@
1
+ export declare const LEAFLET_CSS = ".leaflet-pane,\r\n.leaflet-tile,\r\n.leaflet-marker-icon,\r\n.leaflet-marker-shadow,\r\n.leaflet-tile-container,\r\n.leaflet-pane > svg,\r\n.leaflet-pane > canvas,\r\n.leaflet-zoom-box,\r\n.leaflet-image-layer,\r\n.leaflet-layer {\r\n\tposition: absolute;\r\n\tleft: 0;\r\n\ttop: 0;\r\n\t}\r\n.leaflet-container {\r\n\toverflow: hidden;\r\n\t}\r\n.leaflet-tile,\r\n.leaflet-marker-icon,\r\n.leaflet-marker-shadow {\r\n\t-webkit-user-select: none;\r\n\t -moz-user-select: none;\r\n\t user-select: none;\r\n\t -webkit-user-drag: none;\r\n\t}\r\n.leaflet-tile::selection {\r\n\tbackground: transparent;\r\n}\r\n.leaflet-safari .leaflet-tile {\r\n\timage-rendering: -webkit-optimize-contrast;\r\n\t}\r\n.leaflet-safari .leaflet-tile-container {\r\n\twidth: 1600px;\r\n\theight: 1600px;\r\n\t-webkit-transform-origin: 0 0;\r\n\t}\r\n.leaflet-marker-icon,\r\n.leaflet-marker-shadow {\r\n\tdisplay: block;\r\n\t}\r\n.leaflet-container .leaflet-overlay-pane svg {\r\n\tmax-width: none !important;\r\n\tmax-height: none !important;\r\n\t}\r\n.leaflet-container .leaflet-marker-pane img,\r\n.leaflet-container .leaflet-shadow-pane img,\r\n.leaflet-container .leaflet-tile-pane img,\r\n.leaflet-container img.leaflet-image-layer,\r\n.leaflet-container .leaflet-tile {\r\n\tmax-width: none !important;\r\n\tmax-height: none !important;\r\n\twidth: auto;\r\n\tpadding: 0;\r\n\t}\r\n.leaflet-container img.leaflet-tile {\r\n\tmix-blend-mode: plus-lighter;\r\n}\r\n.leaflet-container.leaflet-touch-zoom {\r\n\t-ms-touch-action: pan-x pan-y;\r\n\ttouch-action: pan-x pan-y;\r\n\t}\r\n.leaflet-container.leaflet-touch-drag {\r\n\t-ms-touch-action: pinch-zoom;\r\n\ttouch-action: none;\r\n\ttouch-action: pinch-zoom;\r\n}\r\n.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom {\r\n\t-ms-touch-action: none;\r\n\ttouch-action: none;\r\n}\r\n.leaflet-container {\r\n\t-webkit-tap-highlight-color: transparent;\r\n}\r\n.leaflet-container a {\r\n\t-webkit-tap-highlight-color: rgba(51, 181, 229, 0.4);\r\n}\r\n.leaflet-tile {\r\n\tfilter: inherit;\r\n\tvisibility: hidden;\r\n\t}\r\n.leaflet-tile-loaded {\r\n\tvisibility: inherit;\r\n\t}\r\n.leaflet-zoom-box {\r\n\twidth: 0;\r\n\theight: 0;\r\n\t-moz-box-sizing: border-box;\r\n\t box-sizing: border-box;\r\n\tz-index: 800;\r\n\t}\r\n.leaflet-overlay-pane svg {\r\n\t-moz-user-select: none;\r\n\t}\r\n.leaflet-pane { z-index: 400; }\r\n.leaflet-tile-pane { z-index: 200; }\r\n.leaflet-overlay-pane { z-index: 400; }\r\n.leaflet-shadow-pane { z-index: 500; }\r\n.leaflet-marker-pane { z-index: 600; }\r\n.leaflet-tooltip-pane { z-index: 650; }\r\n.leaflet-popup-pane { z-index: 700; }\r\n.leaflet-map-pane canvas { z-index: 100; }\r\n.leaflet-map-pane svg { z-index: 200; }\r\n.leaflet-vml-shape {\r\n\twidth: 1px;\r\n\theight: 1px;\r\n\t}\r\n.lvml {\r\n\tbehavior: url(#default#VML);\r\n\tdisplay: inline-block;\r\n\tposition: absolute;\r\n\t}\r\n.leaflet-control {\r\n\tposition: relative;\r\n\tz-index: 800;\r\n\tpointer-events: visiblePainted; \r\n\tpointer-events: auto;\r\n\t}\r\n.leaflet-top,\r\n.leaflet-bottom {\r\n\tposition: absolute;\r\n\tz-index: 1000;\r\n\tpointer-events: none;\r\n\t}\r\n.leaflet-top {\r\n\ttop: 0;\r\n\t}\r\n.leaflet-right {\r\n\tright: 0;\r\n\t}\r\n.leaflet-bottom {\r\n\tbottom: 0;\r\n\t}\r\n.leaflet-left {\r\n\tleft: 0;\r\n\t}\r\n.leaflet-control {\r\n\tfloat: left;\r\n\tclear: both;\r\n\t}\r\n.leaflet-right .leaflet-control {\r\n\tfloat: right;\r\n\t}\r\n.leaflet-top .leaflet-control {\r\n\tmargin-top: 10px;\r\n\t}\r\n.leaflet-bottom .leaflet-control {\r\n\tmargin-bottom: 10px;\r\n\t}\r\n.leaflet-left .leaflet-control {\r\n\tmargin-left: 10px;\r\n\t}\r\n.leaflet-right .leaflet-control {\r\n\tmargin-right: 10px;\r\n\t}\r\n.leaflet-fade-anim .leaflet-popup {\r\n\topacity: 0;\r\n\t-webkit-transition: opacity 0.2s linear;\r\n\t -moz-transition: opacity 0.2s linear;\r\n\t transition: opacity 0.2s linear;\r\n\t}\r\n.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {\r\n\topacity: 1;\r\n\t}\r\n.leaflet-zoom-animated {\r\n\t-webkit-transform-origin: 0 0;\r\n\t -ms-transform-origin: 0 0;\r\n\t transform-origin: 0 0;\r\n\t}\r\nsvg.leaflet-zoom-animated {\r\n\twill-change: transform;\r\n}\r\n.leaflet-zoom-anim .leaflet-zoom-animated {\r\n\t-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);\r\n\t -moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);\r\n\t transition: transform 0.25s cubic-bezier(0,0,0.25,1);\r\n\t}\r\n.leaflet-zoom-anim .leaflet-tile,\r\n.leaflet-pan-anim .leaflet-tile {\r\n\t-webkit-transition: none;\r\n\t -moz-transition: none;\r\n\t transition: none;\r\n\t}\r\n.leaflet-zoom-anim .leaflet-zoom-hide {\r\n\tvisibility: hidden;\r\n\t}\r\n.leaflet-interactive {\r\n\tcursor: pointer;\r\n\t}\r\n.leaflet-grab {\r\n\tcursor: -webkit-grab;\r\n\tcursor: -moz-grab;\r\n\tcursor: grab;\r\n\t}\r\n.leaflet-crosshair,\r\n.leaflet-crosshair .leaflet-interactive {\r\n\tcursor: crosshair;\r\n\t}\r\n.leaflet-popup-pane,\r\n.leaflet-control {\r\n\tcursor: auto;\r\n\t}\r\n.leaflet-dragging .leaflet-grab,\r\n.leaflet-dragging .leaflet-grab .leaflet-interactive,\r\n.leaflet-dragging .leaflet-marker-draggable {\r\n\tcursor: move;\r\n\tcursor: -webkit-grabbing;\r\n\tcursor: -moz-grabbing;\r\n\tcursor: grabbing;\r\n\t}\r\n.leaflet-marker-icon,\r\n.leaflet-marker-shadow,\r\n.leaflet-image-layer,\r\n.leaflet-pane > svg path,\r\n.leaflet-tile-container {\r\n\tpointer-events: none;\r\n\t}\r\n.leaflet-marker-icon.leaflet-interactive,\r\n.leaflet-image-layer.leaflet-interactive,\r\n.leaflet-pane > svg path.leaflet-interactive,\r\nsvg.leaflet-image-layer.leaflet-interactive path {\r\n\tpointer-events: visiblePainted; \r\n\tpointer-events: auto;\r\n\t}\r\n.leaflet-container {\r\n\tbackground: #ddd;\r\n\toutline-offset: 1px;\r\n\t}\r\n.leaflet-container a {\r\n\tcolor: #0078A8;\r\n\t}\r\n.leaflet-zoom-box {\r\n\tborder: 2px dotted #38f;\r\n\tbackground: rgba(255,255,255,0.5);\r\n\t}\r\n.leaflet-container {\r\n\tfont-family: \"Helvetica Neue\", Arial, Helvetica, sans-serif;\r\n\tfont-size: 12px;\r\n\tfont-size: 0.75rem;\r\n\tline-height: 1.5;\r\n\t}\r\n.leaflet-bar {\r\n\tbox-shadow: 0 1px 5px rgba(0,0,0,0.65);\r\n\tborder-radius: 4px;\r\n\t}\r\n.leaflet-bar a {\r\n\tbackground-color: #fff;\r\n\tborder-bottom: 1px solid #ccc;\r\n\twidth: 26px;\r\n\theight: 26px;\r\n\tline-height: 26px;\r\n\tdisplay: block;\r\n\ttext-align: center;\r\n\ttext-decoration: none;\r\n\tcolor: black;\r\n\t}\r\n.leaflet-bar a,\r\n.leaflet-control-layers-toggle {\r\n\tbackground-position: 50% 50%;\r\n\tbackground-repeat: no-repeat;\r\n\tdisplay: block;\r\n\t}\r\n.leaflet-bar a:hover,\r\n.leaflet-bar a:focus {\r\n\tbackground-color: #f4f4f4;\r\n\t}\r\n.leaflet-bar a:first-child {\r\n\tborder-top-left-radius: 4px;\r\n\tborder-top-right-radius: 4px;\r\n\t}\r\n.leaflet-bar a:last-child {\r\n\tborder-bottom-left-radius: 4px;\r\n\tborder-bottom-right-radius: 4px;\r\n\tborder-bottom: none;\r\n\t}\r\n.leaflet-bar a.leaflet-disabled {\r\n\tcursor: default;\r\n\tbackground-color: #f4f4f4;\r\n\tcolor: #bbb;\r\n\t}\r\n.leaflet-touch .leaflet-bar a {\r\n\twidth: 30px;\r\n\theight: 30px;\r\n\tline-height: 30px;\r\n\t}\r\n.leaflet-touch .leaflet-bar a:first-child {\r\n\tborder-top-left-radius: 2px;\r\n\tborder-top-right-radius: 2px;\r\n\t}\r\n.leaflet-touch .leaflet-bar a:last-child {\r\n\tborder-bottom-left-radius: 2px;\r\n\tborder-bottom-right-radius: 2px;\r\n\t}\r\n.leaflet-control-zoom-in,\r\n.leaflet-control-zoom-out {\r\n\tfont: bold 18px 'Lucida Console', Monaco, monospace;\r\n\ttext-indent: 1px;\r\n\t}\r\n.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out {\r\n\tfont-size: 22px;\r\n\t}\r\n.leaflet-control-layers {\r\n\tbox-shadow: 0 1px 5px rgba(0,0,0,0.4);\r\n\tbackground: #fff;\r\n\tborder-radius: 5px;\r\n\t}\r\n.leaflet-control-layers-toggle {\r\n\tbackground-image: url(images/layers.png);\r\n\twidth: 36px;\r\n\theight: 36px;\r\n\t}\r\n.leaflet-retina .leaflet-control-layers-toggle {\r\n\tbackground-image: url(images/layers-2x.png);\r\n\tbackground-size: 26px 26px;\r\n\t}\r\n.leaflet-touch .leaflet-control-layers-toggle {\r\n\twidth: 44px;\r\n\theight: 44px;\r\n\t}\r\n.leaflet-control-layers .leaflet-control-layers-list,\r\n.leaflet-control-layers-expanded .leaflet-control-layers-toggle {\r\n\tdisplay: none;\r\n\t}\r\n.leaflet-control-layers-expanded .leaflet-control-layers-list {\r\n\tdisplay: block;\r\n\tposition: relative;\r\n\t}\r\n.leaflet-control-layers-expanded {\r\n\tpadding: 6px 10px 6px 6px;\r\n\tcolor: #333;\r\n\tbackground: #fff;\r\n\t}\r\n.leaflet-control-layers-scrollbar {\r\n\toverflow-y: scroll;\r\n\toverflow-x: hidden;\r\n\tpadding-right: 5px;\r\n\t}\r\n.leaflet-control-layers-selector {\r\n\tmargin-top: 2px;\r\n\tposition: relative;\r\n\ttop: 1px;\r\n\t}\r\n.leaflet-control-layers label {\r\n\tdisplay: block;\r\n\tfont-size: 13px;\r\n\tfont-size: 1.08333em;\r\n\t}\r\n.leaflet-control-layers-separator {\r\n\theight: 0;\r\n\tborder-top: 1px solid #ddd;\r\n\tmargin: 5px -10px 5px -6px;\r\n\t}\r\n.leaflet-default-icon-path { \r\n\tbackground-image: url(images/marker-icon.png);\r\n\t}\r\n.leaflet-container .leaflet-control-attribution {\r\n\tbackground: #fff;\r\n\tbackground: rgba(255, 255, 255, 0.8);\r\n\tmargin: 0;\r\n\t}\r\n.leaflet-control-attribution,\r\n.leaflet-control-scale-line {\r\n\tpadding: 0 5px;\r\n\tcolor: #333;\r\n\tline-height: 1.4;\r\n\t}\r\n.leaflet-control-attribution a {\r\n\ttext-decoration: none;\r\n\t}\r\n.leaflet-control-attribution a:hover,\r\n.leaflet-control-attribution a:focus {\r\n\ttext-decoration: underline;\r\n\t}\r\n.leaflet-attribution-flag {\r\n\tdisplay: inline !important;\r\n\tvertical-align: baseline !important;\r\n\twidth: 1em;\r\n\theight: 0.6669em;\r\n\t}\r\n.leaflet-left .leaflet-control-scale {\r\n\tmargin-left: 5px;\r\n\t}\r\n.leaflet-bottom .leaflet-control-scale {\r\n\tmargin-bottom: 5px;\r\n\t}\r\n.leaflet-control-scale-line {\r\n\tborder: 2px solid #777;\r\n\tborder-top: none;\r\n\tline-height: 1.1;\r\n\tpadding: 2px 5px 1px;\r\n\twhite-space: nowrap;\r\n\t-moz-box-sizing: border-box;\r\n\t box-sizing: border-box;\r\n\tbackground: rgba(255, 255, 255, 0.8);\r\n\ttext-shadow: 1px 1px #fff;\r\n\t}\r\n.leaflet-control-scale-line:not(:first-child) {\r\n\tborder-top: 2px solid #777;\r\n\tborder-bottom: none;\r\n\tmargin-top: -2px;\r\n\t}\r\n.leaflet-control-scale-line:not(:first-child):not(:last-child) {\r\n\tborder-bottom: 2px solid #777;\r\n\t}\r\n.leaflet-touch .leaflet-control-attribution,\r\n.leaflet-touch .leaflet-control-layers,\r\n.leaflet-touch .leaflet-bar {\r\n\tbox-shadow: none;\r\n\t}\r\n.leaflet-touch .leaflet-control-layers,\r\n.leaflet-touch .leaflet-bar {\r\n\tborder: 2px solid rgba(0,0,0,0.2);\r\n\tbackground-clip: padding-box;\r\n\t}\r\n.leaflet-popup {\r\n\tposition: absolute;\r\n\ttext-align: center;\r\n\tmargin-bottom: 20px;\r\n\t}\r\n.leaflet-popup-content-wrapper {\r\n\tpadding: 1px;\r\n\ttext-align: left;\r\n\tborder-radius: 12px;\r\n\t}\r\n.leaflet-popup-content {\r\n\tmargin: 13px 24px 13px 20px;\r\n\tline-height: 1.3;\r\n\tfont-size: 13px;\r\n\tfont-size: 1.08333em;\r\n\tmin-height: 1px;\r\n\t}\r\n.leaflet-popup-content p {\r\n\tmargin: 17px 0;\r\n\tmargin: 1.3em 0;\r\n\t}\r\n.leaflet-popup-tip-container {\r\n\twidth: 40px;\r\n\theight: 20px;\r\n\tposition: absolute;\r\n\tleft: 50%;\r\n\tmargin-top: -1px;\r\n\tmargin-left: -20px;\r\n\toverflow: hidden;\r\n\tpointer-events: none;\r\n\t}\r\n.leaflet-popup-tip {\r\n\twidth: 17px;\r\n\theight: 17px;\r\n\tpadding: 1px;\r\n\tmargin: -10px auto 0;\r\n\tpointer-events: auto;\r\n\t-webkit-transform: rotate(45deg);\r\n\t -moz-transform: rotate(45deg);\r\n\t -ms-transform: rotate(45deg);\r\n\t transform: rotate(45deg);\r\n\t}\r\n.leaflet-popup-content-wrapper,\r\n.leaflet-popup-tip {\r\n\tbackground: white;\r\n\tcolor: #333;\r\n\tbox-shadow: 0 3px 14px rgba(0,0,0,0.4);\r\n\t}\r\n.leaflet-container a.leaflet-popup-close-button {\r\n\tposition: absolute;\r\n\ttop: 0;\r\n\tright: 0;\r\n\tborder: none;\r\n\ttext-align: center;\r\n\twidth: 24px;\r\n\theight: 24px;\r\n\tfont: 16px/24px Tahoma, Verdana, sans-serif;\r\n\tcolor: #757575;\r\n\ttext-decoration: none;\r\n\tbackground: transparent;\r\n\t}\r\n.leaflet-container a.leaflet-popup-close-button:hover,\r\n.leaflet-container a.leaflet-popup-close-button:focus {\r\n\tcolor: #585858;\r\n\t}\r\n.leaflet-popup-scrolled {\r\n\toverflow: auto;\r\n\t}\r\n.leaflet-oldie .leaflet-popup-content-wrapper {\r\n\t-ms-zoom: 1;\r\n\t}\r\n.leaflet-oldie .leaflet-popup-tip {\r\n\twidth: 24px;\r\n\tmargin: 0 auto;\r\n\t-ms-filter: \"progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)\";\r\n\tfilter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);\r\n\t}\r\n.leaflet-oldie .leaflet-control-zoom,\r\n.leaflet-oldie .leaflet-control-layers,\r\n.leaflet-oldie .leaflet-popup-content-wrapper,\r\n.leaflet-oldie .leaflet-popup-tip {\r\n\tborder: 1px solid #999;\r\n\t}\r\n.leaflet-div-icon {\r\n\tbackground: #fff;\r\n\tborder: 1px solid #666;\r\n\t}\r\n.leaflet-tooltip {\r\n\tposition: absolute;\r\n\tpadding: 6px;\r\n\tbackground-color: #fff;\r\n\tborder: 1px solid #fff;\r\n\tborder-radius: 3px;\r\n\tcolor: #222;\r\n\twhite-space: nowrap;\r\n\t-webkit-user-select: none;\r\n\t-moz-user-select: none;\r\n\t-ms-user-select: none;\r\n\tuser-select: none;\r\n\tpointer-events: none;\r\n\tbox-shadow: 0 1px 3px rgba(0,0,0,0.4);\r\n\t}\r\n.leaflet-tooltip.leaflet-interactive {\r\n\tcursor: pointer;\r\n\tpointer-events: auto;\r\n\t}\r\n.leaflet-tooltip-top:before,\r\n.leaflet-tooltip-bottom:before,\r\n.leaflet-tooltip-left:before,\r\n.leaflet-tooltip-right:before {\r\n\tposition: absolute;\r\n\tpointer-events: none;\r\n\tborder: 6px solid transparent;\r\n\tbackground: transparent;\r\n\tcontent: \"\";\r\n\t}\r\n.leaflet-tooltip-bottom {\r\n\tmargin-top: 6px;\r\n}\r\n.leaflet-tooltip-top {\r\n\tmargin-top: -6px;\r\n}\r\n.leaflet-tooltip-bottom:before,\r\n.leaflet-tooltip-top:before {\r\n\tleft: 50%;\r\n\tmargin-left: -6px;\r\n\t}\r\n.leaflet-tooltip-top:before {\r\n\tbottom: 0;\r\n\tmargin-bottom: -12px;\r\n\tborder-top-color: #fff;\r\n\t}\r\n.leaflet-tooltip-bottom:before {\r\n\ttop: 0;\r\n\tmargin-top: -12px;\r\n\tmargin-left: -6px;\r\n\tborder-bottom-color: #fff;\r\n\t}\r\n.leaflet-tooltip-left {\r\n\tmargin-left: -6px;\r\n}\r\n.leaflet-tooltip-right {\r\n\tmargin-left: 6px;\r\n}\r\n.leaflet-tooltip-left:before,\r\n.leaflet-tooltip-right:before {\r\n\ttop: 50%;\r\n\tmargin-top: -6px;\r\n\t}\r\n.leaflet-tooltip-left:before {\r\n\tright: 0;\r\n\tmargin-right: -12px;\r\n\tborder-left-color: #fff;\r\n\t}\r\n.leaflet-tooltip-right:before {\r\n\tleft: 0;\r\n\tmargin-left: -12px;\r\n\tborder-right-color: #fff;\r\n\t}\r\n@media print {\r\n\t.leaflet-control {\r\n\t\t-webkit-print-color-adjust: exact;\r\n\t\tprint-color-adjust: exact;\r\n\t\t}\r\n\t}";
2
+ //# sourceMappingURL=leafletCss.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"leafletCss.d.ts","sourceRoot":"","sources":["../../src/location/leafletCss.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,WAAW,gqdACqod,CAAC"}