@maplibre/maplibre-react-native 10.0.0-alpha.24 → 10.0.0-alpha.25

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 (62) hide show
  1. package/.husky/pre-commit +1 -1
  2. package/CHANGELOG.md +6 -0
  3. package/CONTRIBUTING.md +1 -1
  4. package/docs/Annotation.md +2 -11
  5. package/docs/BackgroundLayer.md +2 -1
  6. package/docs/Callout.md +2 -1
  7. package/docs/Camera.md +28 -29
  8. package/docs/CircleLayer.md +2 -1
  9. package/docs/FillExtrusionLayer.md +2 -1
  10. package/docs/FillLayer.md +2 -1
  11. package/docs/HeadingIndicator.md +2 -1
  12. package/docs/HeatmapLayer.md +2 -1
  13. package/docs/ImageSource.md +2 -1
  14. package/docs/Images.md +2 -1
  15. package/docs/Light.md +2 -1
  16. package/docs/LineLayer.md +2 -1
  17. package/docs/MapView.md +5 -4
  18. package/docs/MarkerView.md +2 -1
  19. package/docs/NativeUserLocation.md +2 -1
  20. package/docs/PointAnnotation.md +2 -1
  21. package/docs/RasterLayer.md +2 -1
  22. package/docs/RasterSource.md +2 -1
  23. package/docs/ShapeSource.md +2 -1
  24. package/docs/Style.md +2 -1
  25. package/docs/SymbolLayer.md +2 -1
  26. package/docs/UserLocation.md +2 -1
  27. package/docs/VectorSource.md +3 -2
  28. package/docs/coordinates.md +2 -1
  29. package/docs/docs.json +49 -88
  30. package/docs/location.md +2 -1
  31. package/docs/offlineManager.md +3 -2
  32. package/docs/snapshotManager.md +2 -1
  33. package/ios/RCTMLN/RCTMLNCamera.h +0 -3
  34. package/ios/RCTMLN/RCTMLNCamera.m +1 -1
  35. package/ios/RCTMLN/RCTMLNCameraManager.m +0 -3
  36. package/javascript/MLNModule.ts +9 -0
  37. package/javascript/Maplibre.ts +1 -1
  38. package/javascript/components/{annotations/Annotation.tsx → Annotation.tsx} +5 -5
  39. package/javascript/components/Camera.tsx +257 -388
  40. package/javascript/components/UserLocation.tsx +1 -1
  41. package/javascript/hooks/useNativeRef.ts +2 -1
  42. package/javascript/types/CameraMode.ts +6 -0
  43. package/package.json +7 -8
  44. package/scripts/codegen.ts +341 -0
  45. package/scripts/templates/MaplibreStyles.ts.ejs +8 -7
  46. package/scripts/templates/RCTMLNStyle.h.ejs +4 -3
  47. package/scripts/templates/RCTMLNStyle.m.ejs +11 -10
  48. package/scripts/templates/RCTMLNStyleFactory.java.ejs +12 -11
  49. package/scripts/templates/component.md.ejs +14 -12
  50. package/scripts/templates/index.d.ts.ejs +2 -1
  51. package/scripts/templates/styleMap.ts.ejs +2 -1
  52. package/scripts/utils/{DocJSONBuilder.js → DocJSONBuilder.ts} +133 -128
  53. package/scripts/utils/{JSDocNodeTree.js → JSDocNodeTree.ts} +14 -13
  54. package/scripts/utils/MarkdownBuilder.ts +44 -0
  55. package/scripts/utils/{template-globals.js → TemplateHelpers.ts} +65 -94
  56. package/scripts/utils/getNativeVersion.ts +53 -0
  57. package/tsconfig.json +2 -3
  58. package/docs/OfflineManager.md +0 -246
  59. package/scripts/download-style-spec.sh +0 -15
  60. package/scripts/generate-docs.js +0 -396
  61. package/scripts/utils/MarkdownBuilder.js +0 -37
  62. package/style-spec/v8.json +0 -6645
@@ -1,396 +0,0 @@
1
- require("./utils/template-globals");
2
-
3
- const { execSync } = require("child_process");
4
- const ejs = require("ejs");
5
- const prettierrc = require("eslint-config-universe");
6
- const fs = require("fs");
7
- const path = require("path");
8
- const prettier = require("prettier");
9
-
10
- const { camelCase } = require("./utils/template-globals");
11
- const styleSpecJSON = require("../style-spec/v8.json");
12
- const DocJSONBuilder = require("./utils/DocJSONBuilder");
13
- const MarkdownBuilder = require("./utils/MarkdownBuilder");
14
-
15
- function readIosVersion() {
16
- const podspecPath = path.join(
17
- __dirname,
18
- "..",
19
- "maplibre-react-native.podspec",
20
- );
21
- const lines = fs.readFileSync(podspecPath, "utf8").split("\n");
22
- const maplibreLineRegex = /^\s+version:\s*"(\d+\.\d+\.\d+)"$/;
23
- const maplibreLine = lines.filter((i) => maplibreLineRegex.exec(i))[0];
24
- return `${maplibreLineRegex.exec(maplibreLine)[1]}.0`;
25
- }
26
-
27
- function readAndroidVersion() {
28
- const buildGradlePath = path.join(
29
- __dirname,
30
- "..",
31
- "android",
32
- "rctmln",
33
- "build.gradle",
34
- );
35
- const lines = fs.readFileSync(buildGradlePath, "utf8").split("\n");
36
- const maplibreLineRegex =
37
- /^\s+implementation\s+"org.maplibre.gl:android-sdk:(\d+\.\d+\.\d+)"$/;
38
- const maplibreLine = lines.filter((i) => maplibreLineRegex.exec(i))[0];
39
- return maplibreLineRegex.exec(maplibreLine)[1];
40
- }
41
-
42
- if (!styleSpecJSON) {
43
- console.log(
44
- 'Could not find style spec, try running "yarn generate:fetch-style-spec"',
45
- );
46
- process.exit(1);
47
- }
48
-
49
- const layers = [];
50
- const androidVersion = readAndroidVersion();
51
- const iosVersion = readIosVersion();
52
-
53
- const TMPL_PATH = path.join(__dirname, "templates");
54
-
55
- const outputToExample = false;
56
- const OUTPUT_EXAMPLE_PREFIX = [
57
- "..",
58
- "example",
59
- "node_modules",
60
- "@maplibre",
61
- "maplibre-react-native",
62
- ];
63
- const OUTPUT_PREFIX = outputToExample ? OUTPUT_EXAMPLE_PREFIX : [".."];
64
-
65
- const IOS_OUTPUT_PATH = path.join(__dirname, ...OUTPUT_PREFIX, "ios", "RCTMLN");
66
- const ANDROID_OUTPUT_PATH = path.join(
67
- __dirname,
68
- ...OUTPUT_PREFIX,
69
- "android",
70
- "rctmln",
71
- "src",
72
- "main",
73
- "java",
74
- "com",
75
- "maplibre",
76
- "rctmln",
77
- "components",
78
- "styles",
79
- );
80
- const JS_OUTPUT_PATH = path.join(
81
- __dirname,
82
- ...OUTPUT_PREFIX,
83
- "javascript",
84
- "utils",
85
- );
86
-
87
- getSupportedLayers(Object.keys(styleSpecJSON.layer.type.values)).forEach(
88
- (layerName) => {
89
- layers.push({
90
- name: layerName,
91
- properties: getPropertiesForLayer(layerName),
92
- });
93
- },
94
- );
95
-
96
- // add light as a layer
97
- layers.push({ name: "light", properties: getPropertiesForLight() });
98
-
99
- function getPropertiesForLight() {
100
- const lightAttributes = styleSpecJSON.light;
101
-
102
- return getSupportedProperties(lightAttributes).map((attrName) => {
103
- return Object.assign({}, buildProperties(lightAttributes, attrName), {
104
- allowedFunctionTypes: [],
105
- });
106
- });
107
- }
108
-
109
- function getPropertiesForLayer(layerName) {
110
- const paintAttributes = styleSpecJSON[`paint_${layerName}`];
111
- const layoutAttributes = styleSpecJSON[`layout_${layerName}`];
112
-
113
- const paintProps = getSupportedProperties(paintAttributes).map((attrName) => {
114
- const prop = buildProperties(paintAttributes, attrName);
115
-
116
- // overrides
117
- if (["line-width"].includes(attrName)) {
118
- prop.allowedFunctionTypes = ["camera"];
119
- }
120
-
121
- return prop;
122
- });
123
-
124
- const layoutProps = getSupportedProperties(layoutAttributes).map(
125
- (attrName) => {
126
- const prop = buildProperties(layoutAttributes, attrName);
127
-
128
- // overrides
129
- if (
130
- [
131
- "line-join",
132
- "text-max-width",
133
- "text-letter-spacing",
134
- "text-anchor",
135
- "text-justify",
136
- "text-font",
137
- ].includes(attrName)
138
- ) {
139
- prop.allowedFunctionTypes = ["camera"];
140
- }
141
- // Overide type padding
142
- if (prop.type === "padding") {
143
- prop.type = "array";
144
- prop.value = "number";
145
- prop.length = 4;
146
- }
147
- return prop;
148
- },
149
- );
150
-
151
- return layoutProps.concat(paintProps);
152
- }
153
-
154
- function getSupportedLayers(layerNames) {
155
- const layerMap = styleSpecJSON.layer.type.values;
156
-
157
- const supportedLayers = [];
158
- for (const layerName of layerNames) {
159
- const layer = layerMap[layerName];
160
- const support = getAttributeSupport(layer["sdk-support"]);
161
-
162
- if (support.basic.android && support.basic.ios) {
163
- supportedLayers.push(layerName);
164
- }
165
- }
166
-
167
- return supportedLayers;
168
- }
169
-
170
- function getSupportedProperties(attributes) {
171
- return Object.keys(attributes).filter((attrName) =>
172
- isAttrSupported(attributes[attrName]),
173
- );
174
- }
175
-
176
- function buildProperties(attributes, attrName) {
177
- return {
178
- name: camelCase(attrName),
179
- doc: {
180
- default: attributes[attrName].default,
181
- minimum: attributes[attrName].minimum,
182
- maximum: attributes[attrName].maximum,
183
- units: attributes[attrName].units,
184
- description: formatDescription(attributes[attrName].doc),
185
- requires: getRequires(attributes[attrName].requires),
186
- disabledBy: getDisables(attributes[attrName].requires),
187
- values: attributes[attrName].values,
188
- },
189
- type: attributes[attrName].type,
190
- value: attributes[attrName].value,
191
- image: isImage(attrName),
192
- translate: isTranslate(attrName),
193
- transition: attributes[attrName].transition,
194
- expression: attributes[attrName].expression,
195
- expressionSupported:
196
- Object.keys(attributes[attrName].expression || {}).length > 0,
197
- support: getAttributeSupport(attributes[attrName]["sdk-support"]),
198
- allowedFunctionTypes: getAllowedFunctionTypes(attributes[attrName]),
199
- };
200
- }
201
-
202
- function formatDescription(description) {
203
- const words = description.split(" ");
204
-
205
- for (let i = 0; i < words.length; i++) {
206
- const word = words[i];
207
-
208
- if (word.includes("-")) {
209
- words[i] = camelCase(word);
210
- }
211
- }
212
-
213
- return words.join(" ");
214
- }
215
-
216
- function getRequires(requiredItems) {
217
- const items = [];
218
-
219
- if (!requiredItems) {
220
- return items;
221
- }
222
-
223
- for (const item of requiredItems) {
224
- if (typeof item === "string") {
225
- items.push(camelCase(item, "-"));
226
- }
227
- }
228
-
229
- return items;
230
- }
231
-
232
- function getDisables(disabledItems) {
233
- const items = [];
234
-
235
- if (!disabledItems) {
236
- return items;
237
- }
238
-
239
- for (const item of disabledItems) {
240
- if (item["!"]) {
241
- items.push(camelCase(item["!"], "-"));
242
- }
243
- }
244
-
245
- return items;
246
- }
247
-
248
- function isImage(attrName) {
249
- return (
250
- attrName.toLowerCase().indexOf("pattern") !== -1 ||
251
- attrName.toLowerCase().indexOf("image") !== -1
252
- );
253
- }
254
-
255
- function isTranslate(attrName) {
256
- return attrName.toLowerCase().indexOf("translate") !== -1;
257
- }
258
-
259
- function isAttrSupported(attr) {
260
- const support = getAttributeSupport(attr["sdk-support"]);
261
- if (attr.private) {
262
- return false;
263
- }
264
- return support.basic.android && support.basic.ios;
265
- }
266
-
267
- function getAttributeSupport(sdkSupport) {
268
- const support = {
269
- basic: { android: false, ios: false },
270
- data: { android: false, ios: false },
271
- };
272
-
273
- const basicSupport = sdkSupport && sdkSupport["basic functionality"];
274
- if (basicSupport && basicSupport.android) {
275
- support.basic.android = isVersionGTE(androidVersion, basicSupport.android);
276
- }
277
- if (basicSupport && basicSupport.ios) {
278
- support.basic.ios = isVersionGTE(iosVersion, basicSupport.ios);
279
- }
280
-
281
- const dataDrivenSupport = sdkSupport && sdkSupport["data-driven styling"];
282
- if (dataDrivenSupport && dataDrivenSupport.android) {
283
- support.data.android = isVersionGTE(
284
- androidVersion,
285
- dataDrivenSupport.android,
286
- );
287
- }
288
- if (dataDrivenSupport && dataDrivenSupport.ios) {
289
- support.data.ios = isVersionGTE(iosVersion, dataDrivenSupport.ios);
290
- }
291
-
292
- if (support.data.ios !== true || support.data.android !== true) {
293
- support.data.ios = false;
294
- support.data.android = false;
295
- }
296
-
297
- return support;
298
- }
299
-
300
- function isVersionGTE(version, otherVersion) {
301
- const v = +version
302
- .split(".")
303
- .map((i) => String(i).padStart(3, "0"))
304
- .join("");
305
- const ov = +otherVersion
306
- .split(".")
307
- .map((i) => String(i).padStart(3, "0"))
308
- .join("");
309
- return v >= ov;
310
- }
311
-
312
- function getAllowedFunctionTypes(paintAttr) {
313
- const allowedFunctionTypes = [];
314
-
315
- if (paintAttr["zoom-function"]) {
316
- allowedFunctionTypes.push("camera");
317
- }
318
-
319
- if (paintAttr["property-function"]) {
320
- allowedFunctionTypes.push("source");
321
- allowedFunctionTypes.push("composite");
322
- }
323
-
324
- return allowedFunctionTypes;
325
- }
326
-
327
- async function generate() {
328
- const templateMappings = [
329
- {
330
- input: path.join(TMPL_PATH, "RCTMLNStyle.h.ejs"),
331
- output: path.join(IOS_OUTPUT_PATH, "RCTMLNStyle.h"),
332
- },
333
- {
334
- input: path.join(TMPL_PATH, "MaplibreStyles.ts.ejs"),
335
- output: path.join(JS_OUTPUT_PATH, "MaplibreStyles.d.ts"),
336
- },
337
- {
338
- input: path.join(TMPL_PATH, "RCTMLNStyle.m.ejs"),
339
- output: path.join(IOS_OUTPUT_PATH, "RCTMLNStyle.m"),
340
- },
341
- {
342
- input: path.join(TMPL_PATH, "RCTMLNStyleFactory.java.ejs"),
343
- output: path.join(ANDROID_OUTPUT_PATH, "RCTMLNStyleFactory.java"),
344
- },
345
- {
346
- input: path.join(TMPL_PATH, "styleMap.ts.ejs"),
347
- output: path.join(JS_OUTPUT_PATH, "styleMap.ts"),
348
- },
349
- ];
350
- const outputPaths = templateMappings.map((m) => m.output);
351
-
352
- // autogenerate code
353
- await Promise.all(
354
- templateMappings.map(async ({ input, output }) => {
355
- const filename = output.split("/").pop();
356
- console.log(`Generating ${filename}`);
357
- const tmpl = ejs.compile(fs.readFileSync(input, "utf8"), {
358
- strict: true,
359
- });
360
- let results = tmpl({ layers });
361
- if (filename.endsWith("ts")) {
362
- results = await prettier.format(results, {
363
- ...prettierrc,
364
- filepath: filename,
365
- });
366
- // Ensure all enums are exported
367
- results = results.replace(/enum (\w+Enum) \{[^}]+\}\n/g, "export $&");
368
- // Replace Array<any> with any[]
369
- results = results.replace(/Array<any>/g, "any[]");
370
- // Replace padding type with float array
371
- results = results.replace(/padding: string;/g, "padding: number[];");
372
- }
373
- fs.writeFileSync(output, results);
374
- }),
375
- );
376
-
377
- // autogenerate docs
378
- const docBuilder = new DocJSONBuilder(layers);
379
- const markdownBuilder = new MarkdownBuilder();
380
- await docBuilder.generate();
381
- await markdownBuilder.generate();
382
-
383
- // Check if any generated files changed
384
- try {
385
- execSync(`git diff --exit-code docs/ ${outputPaths.join(" ")}`);
386
- } catch (_error) {
387
- console.error(
388
- "\n\nThere are unstaged changes in the generated code. " +
389
- "Please add them to your commit.\n" +
390
- 'If you would really like to exclude them, run "git commit -n" to skip.\n\n',
391
- );
392
- process.exit(1);
393
- }
394
- }
395
-
396
- generate();
@@ -1,37 +0,0 @@
1
- const ejs = require("ejs");
2
- const fs = require("fs");
3
- const path = require("path");
4
-
5
- const TMPL_PATH = path.join(__dirname, "..", "templates");
6
- const TMPL_FILE = fs.readFileSync(
7
- path.join(TMPL_PATH, "component.md.ejs"),
8
- "utf8",
9
- );
10
-
11
- class MarkdownBuilder {
12
- generateComponentFile(docJSON, componentName) {
13
- const tmpl = ejs.compile(TMPL_FILE, { strict: true });
14
- const fileContents = tmpl({ component: docJSON[componentName] });
15
- fs.writeFileSync(
16
- path.join(__dirname, "..", "..", "docs", `${componentName}.md`),
17
- fileContents,
18
- );
19
- }
20
-
21
- generate() {
22
- const docJSONFile = fs.readFileSync(
23
- path.join(__dirname, "..", "..", "docs", "docs.json"),
24
- "utf8",
25
- );
26
- const docJSON = JSON.parse(docJSONFile);
27
- const componentPaths = Object.keys(docJSON);
28
-
29
- for (const componentPath of componentPaths) {
30
- this.generateComponentFile(docJSON, componentPath);
31
- }
32
-
33
- console.log("Markdown is finished generating");
34
- }
35
- }
36
-
37
- module.exports = MarkdownBuilder;