diff --git a/docs/Camera.md b/docs/Camera.md index 073dee4dd..b77a66a82 100644 --- a/docs/Camera.md +++ b/docs/Camera.md @@ -250,7 +250,7 @@ configuration. (Not yet implemented.) func ``` Executes when user tracking mode changes. -@deprecated use Viewport#onStatusChanged instead. +**DEPRECATED** use Viewport#onStatusChanged instead. *signature:*`(event:MapboxGLEvent) => void` diff --git a/docs/Images.md b/docs/Images.md index 1fdff3a4f..4936a8d5a 100644 --- a/docs/Images.md +++ b/docs/Images.md @@ -22,7 +22,7 @@ type Images = { ``` Specifies the external images in key-value pairs required for the shape source. Keys are names - see iconImage expressions, values can be either urls-s objects -with format {uri: 'http://...'}` or `require('image.png')` or `import 'image.png'` +with format `{uri: 'http://...'}` or `require('image.png')` or `import 'image.png'` diff --git a/docs/MapView.md b/docs/MapView.md index 1b9c07694..e05b7aa63 100644 --- a/docs/MapView.md +++ b/docs/MapView.md @@ -270,7 +270,7 @@ when embedded into a scroll view | true ``` [`mapbox` (v10) implementation only] -Set map's label locale, e.g. { "locale": "es" } will localize labels to Spanish, { "locale": "current" } will localize labels to system locale. +Set map's label locale, e.g. `{ "locale": "es" }` will localize labels to Spanish, `{ "locale": "current" }` will localize labels to system locale. [Localize Labels](../examples/Map/LocalizeLabels) @@ -332,7 +332,7 @@ func This event is triggered whenever the currently displayed map region is about to change. -@param {PointFeature} feature - The geojson point feature at the camera center, properties contains zoomLevel, visibleBounds +- `feature`: `PointFeature` - The geojson point feature at the camera center, properties contains zoomLevel, visibleBounds *signature:*`(feature:GeoJSON.Feature) => void` [Show Region Did Change](../examples/Map/ShowRegionDidChange) @@ -344,7 +344,7 @@ func ``` This event is triggered whenever the currently displayed map region is changing. -@param {PointFeature} feature - The geojson point feature at the camera center, properties contains zoomLevel, visibleBounds +- `feature`: `PointFeature` - The geojson point feature at the camera center, properties contains zoomLevel, visibleBounds *signature:*`(feature:GeoJSON.Feature) => void` [Show Region Did Change](../examples/Map/ShowRegionDidChange) @@ -356,7 +356,7 @@ func ``` This event is triggered whenever the currently displayed map region finished changing. -@param {PointFeature} feature - The geojson point feature at the camera center, properties contains zoomLevel, visibleBounds +- `feature`: `PointFeature` - The geojson point feature at the camera center, properties contains zoomLevel, visibleBounds *signature:*`(feature:GeoJSON.Feature) => void` [Show Region Did Change](../examples/Map/ShowRegionDidChange) @@ -407,7 +407,7 @@ This is triggered when the map has successfully loaded a new map style. func ``` This event is triggered when the map has failed to load a new map style. On v10 it's deprecated and replaced by onMapLoadingError -@deprecated use onMapLoadingError +**DEPRECATED** use onMapLoadingError *signature:*`() => void` diff --git a/docs/ShapeSource.md b/docs/ShapeSource.md index 66cd0e13b..426541a9a 100644 --- a/docs/ShapeSource.md +++ b/docs/ShapeSource.md @@ -156,10 +156,10 @@ func Source press listener, gets called when a user presses one of the children layers only if that layer has a higher z-index than another source layers -@param {Object} event -@param {Object[]} event.features - the geojson features that have hit by the press (might be multiple) -@param {Object} event.coordinates - the coordinates of the click -@param {Object} event.point - the point of the click +- `event`: `Object` +- `event.features`: `Object[]` - the geojson features that have hit by the press (might be multiple) +- `event.coordinates`: `Object` - the coordinates of the click +- `event.point`: `Object` - the point of the click @return void *signature:*`(event:OnPressEvent) => void` diff --git a/docs/VectorSource.md b/docs/VectorSource.md index 78ed33364..0f36e17ff 100644 --- a/docs/VectorSource.md +++ b/docs/VectorSource.md @@ -101,10 +101,10 @@ func Source press listener, gets called when a user presses one of the children layers only if that layer has a higher z-index than another source layers -@param {Object} event -@param {Object[]} event.features - the geojson features that have hit by the press (might be multiple) -@param {Object} event.coordinates - the coordinates of the click -@param {Object} event.point - the point of the click +- `event`: `Object` +- `event.features`: `Object[]` - the geojson features that have hit by the press (might be multiple) +- `event.coordinates`: `Object` - the coordinates of the click +- `event.point`: `Object` - the point of the click *signature:*`(event:OnPressEvent) => void` diff --git a/docs/docs.json b/docs/docs.json index b4a6ef9f2..582bfb163 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -900,7 +900,7 @@ "funcSignature": "(event:MapboxGLEvent) => void" }, "default": "none", - "description": "Executes when user tracking mode changes.\n@deprecated use Viewport#onStatusChanged instead.\n*signature:*`(event:MapboxGLEvent) => void`" + "description": "Executes when user tracking mode changes.\n**DEPRECATED** use Viewport#onStatusChanged instead.\n*signature:*`(event:MapboxGLEvent) => void`" } ], "fileNameWithExt": "Camera.tsx", @@ -2477,7 +2477,7 @@ ] }, "default": "none", - "description": "Specifies the external images in key-value pairs required for the shape source.\nKeys are names - see iconImage expressions, values can be either urls-s objects\nwith format {uri: 'http://...'}` or `require('image.png')` or `import 'image.png'`" + "description": "Specifies the external images in key-value pairs required for the shape source.\nKeys are names - see iconImage expressions, values can be either urls-s objects\nwith format `{uri: 'http://...'}` or `require('image.png')` or `import 'image.png'`" }, { "name": "nativeAssetImages", @@ -3920,7 +3920,7 @@ "required": false, "type": "\\| {\n /** locale code like `es` or `current` for the device's current locale */\n locale: string;\n /** layer id to localize. If not specified, all layers will be localized */\n layerIds?: string[];\n }\n\\| true", "default": "none", - "description": "[`mapbox` (v10) implementation only]\nSet map's label locale, e.g. { \"locale\": \"es\" } will localize labels to Spanish, { \"locale\": \"current\" } will localize labels to system locale." + "description": "[`mapbox` (v10) implementation only]\nSet map's label locale, e.g. `{ \"locale\": \"es\" }` will localize labels to Spanish, `{ \"locale\": \"current\" }` will localize labels to system locale." }, { "name": "gestureSettings", @@ -4052,7 +4052,7 @@ "funcSignature": "(feature:GeoJSON.Feature) => void" }, "default": "none", - "description": " void`" + "description": " void`" }, { "name": "onRegionIsChanging", @@ -4062,7 +4062,7 @@ "funcSignature": "(feature:GeoJSON.Feature) => void" }, "default": "none", - "description": "This event is triggered whenever the currently displayed map region is changing.\n\n@param {PointFeature} feature - The geojson point feature at the camera center, properties contains zoomLevel, visibleBounds\n*signature:*`(feature:GeoJSON.Feature) => void`" + "description": "This event is triggered whenever the currently displayed map region is changing.\n\n- `feature`: `PointFeature` - The geojson point feature at the camera center, properties contains zoomLevel, visibleBounds\n*signature:*`(feature:GeoJSON.Feature) => void`" }, { "name": "onRegionDidChange", @@ -4072,7 +4072,7 @@ "funcSignature": "(feature:GeoJSON.Feature) => void" }, "default": "none", - "description": "This event is triggered whenever the currently displayed map region finished changing.\n\n@param {PointFeature} feature - The geojson point feature at the camera center, properties contains zoomLevel, visibleBounds\n*signature:*`(feature:GeoJSON.Feature) => void`" + "description": "This event is triggered whenever the currently displayed map region finished changing.\n\n- `feature`: `PointFeature` - The geojson point feature at the camera center, properties contains zoomLevel, visibleBounds\n*signature:*`(feature:GeoJSON.Feature) => void`" }, { "name": "onCameraChanged", @@ -4122,7 +4122,7 @@ "funcSignature": "() => void" }, "default": "none", - "description": "This event is triggered when the map has failed to load a new map style. On v10 it's deprecated and replaced by onMapLoadingError\n@deprecated use onMapLoadingError\n*signature:*`() => void`" + "description": "This event is triggered when the map has failed to load a new map style. On v10 it's deprecated and replaced by onMapLoadingError\n**DEPRECATED** use onMapLoadingError\n*signature:*`() => void`" }, { "name": "onMapLoadingError", @@ -5264,7 +5264,7 @@ "funcSignature": "(event:OnPressEvent) => void" }, "default": "none", - "description": "Source press listener, gets called when a user presses one of the children layers only\nif that layer has a higher z-index than another source layers\n\n@param {Object} event\n@param {Object[]} event.features - the geojson features that have hit by the press (might be multiple)\n@param {Object} event.coordinates - the coordinates of the click\n@param {Object} event.point - the point of the click\n@return void\n*signature:*`(event:OnPressEvent) => void`" + "description": "Source press listener, gets called when a user presses one of the children layers only\nif that layer has a higher z-index than another source layers\n\n- `event`: `Object` \n- `event.features`: `Object[]` - the geojson features that have hit by the press (might be multiple)\n- `event.coordinates`: `Object` - the coordinates of the click\n- `event.point`: `Object` - the point of the click\n@return void\n*signature:*`(event:OnPressEvent) => void`" }, { "name": "hitbox", @@ -7709,7 +7709,7 @@ "funcSignature": "(event:OnPressEvent) => void" }, "default": "none", - "description": "Source press listener, gets called when a user presses one of the children layers only\nif that layer has a higher z-index than another source layers\n\n@param {Object} event\n@param {Object[]} event.features - the geojson features that have hit by the press (might be multiple)\n@param {Object} event.coordinates - the coordinates of the click\n@param {Object} event.point - the point of the click\n*signature:*`(event:OnPressEvent) => void`" + "description": "Source press listener, gets called when a user presses one of the children layers only\nif that layer has a higher z-index than another source layers\n\n- `event`: `Object` \n- `event.features`: `Object[]` - the geojson features that have hit by the press (might be multiple)\n- `event.coordinates`: `Object` - the coordinates of the click\n- `event.point`: `Object` - the point of the click\n*signature:*`(event:OnPressEvent) => void`" }, { "name": "hitbox", diff --git a/package.json b/package.json index ce175b012..acc6ad271 100644 --- a/package.json +++ b/package.json @@ -115,7 +115,8 @@ "react-native-builder-bob": "^0.23.1", "react-test-renderer": "18.2.0", "ts-node": "10.9.1", - "typescript": "4.8.4" + "typescript": "4.8.4", + "@mdx-js/mdx": "^3.0.0" }, "codegenConfig": { "name": "rnmapbox_maps_specs", diff --git a/scripts/autogenHelpers/DocJSONBuilder.mjs b/scripts/autogenHelpers/DocJSONBuilder.mjs index 2d94d2225..5beec3857 100644 --- a/scripts/autogenHelpers/DocJSONBuilder.mjs +++ b/scripts/autogenHelpers/DocJSONBuilder.mjs @@ -237,6 +237,19 @@ class DocJSONBuilder { } } + /** + * @param {string} jsdoc comment + * @returns string + */ + function formatMethodJSDocToMD(description) { + let result = description + .replaceAll('@deprecated', '**DEPRECATED**') + .replaceAll(/@param\s+\{(.+)\}\s+(\S+)/g, (m, type, name) => { + return `- \`${name}\`: \`${type}\` `; + }); + return result; + } + function mapProp(propMeta, propName, array) { let result = {}; if (!array) { @@ -257,7 +270,8 @@ class DocJSONBuilder { result.type.name === 'func' && result.type.funcSignature ) { - result.description = `${result.description}\n*signature:*\`${result.type.funcSignature}\``; + let description = formatMethodJSDocToMD(result.description); + result.description = `${description}\n*signature:*\`${result.type.funcSignature}\``; } } else { if (propName) { diff --git a/scripts/autogenHelpers/MarkdownBuilder.mjs b/scripts/autogenHelpers/MarkdownBuilder.mjs index 878c235e3..13087d3de 100644 --- a/scripts/autogenHelpers/MarkdownBuilder.mjs +++ b/scripts/autogenHelpers/MarkdownBuilder.mjs @@ -2,6 +2,7 @@ import fs from 'fs'; import path from 'path'; import * as url from 'url'; +import { compile } from '@mdx-js/mdx'; import ejs from 'ejs'; const __dirname = url.fileURLToPath(new URL('.', import.meta.url)); @@ -15,6 +16,21 @@ Object.keys(globalFuncs).forEach((key) => { global[key] = globalFuncs[key]; }); +async function checkMDX(code) { + try { + await compile(code); + } catch (e) { + const lines = code.split('\n'); + const { line, column } = e.place; + + console.error(lines[line-1]); + console.error(' '.repeat(column-1) + '^'); + console.error(e.reason); + throw e; + } + return true; +} + const TMPL_PATH = path.join(__dirname, '..', 'templates'); const TMPL_FILE = fs.readFileSync( path.join(TMPL_PATH, 'component.md.ejs'), @@ -29,7 +45,7 @@ class MarkdownBuilder { * @param {string} componentName * @param {string[]} tagLinks */ - generateComponentFile( + async generateComponentFile( destDirPath, docJSON, componentName, @@ -46,6 +62,10 @@ class MarkdownBuilder { path.join(destDirPath, `${componentName}.md`), fileContents, ); + + if (options.docosaurus) { + await checkMDX(fileContents); + } } parseExampleTagLinks() { @@ -83,14 +103,14 @@ class MarkdownBuilder { * @param {string} docsJsonPath * @param {{docosaurus?: boolean}?} options */ - generate(docsJsonPath, destDirPath, options = {}) { + async generate(docsJsonPath, destDirPath, options = {}) { const docJSONFile = fs.readFileSync(docsJsonPath, 'utf8'); const docJSON = JSON.parse(docJSONFile); const componentPaths = Object.keys(docJSON); const tagLinks = this.parseExampleTagLinks(); for (let componentPath of componentPaths) { - this.generateComponentFile( + await this.generateComponentFile( destDirPath, docJSON, componentPath, diff --git a/scripts/autogenHelpers/globals.mjs b/scripts/autogenHelpers/globals.mjs index 89dd0bb21..654377034 100644 --- a/scripts/autogenHelpers/globals.mjs +++ b/scripts/autogenHelpers/globals.mjs @@ -575,8 +575,12 @@ export function propType(prop) { return `\`\`\`tsx\n${type.replace(/(\\\|)/g, '|')}\n\`\`\``; } -export function propDescription(prop) { - return prop.description.replace('<', '<').replace('>', '>'); +export function propDescription(prop, mdx) { + let result = prop.description.replaceAll('<', '<').replaceAll('>', '>'); + if (mdx && false) { + result = result.replaceAll('{', '{').replaceAll('}', '}'); + } + return result; } export function examplePropLinks(prop, component) { @@ -603,7 +607,7 @@ export function exampleMethodLinks(method, component) { return ''; } -export function getMarkdownMethodSignature(method) { +export function getMarkdownMethodSignature(method, mdx) { const params = method.params .map((param, i) => { const isOptional = param.optional; @@ -615,6 +619,13 @@ export function getMarkdownMethodSignature(method) { } name += param.name; + if (mdx) { + name = name + .replaceAll('<', '<') + .replaceAll('>', '>') + .replaceAll('{', '{') + .replaceAll('}', '}'); + } return isOptional ? `[${name}]` : name; }) .join(''); diff --git a/scripts/templates/component.md.ejs b/scripts/templates/component.md.ejs index 4cde8eb2f..169a5ad4c 100644 --- a/scripts/templates/component.md.ejs +++ b/scripts/templates/component.md.ejs @@ -5,8 +5,9 @@ --- custom_edit_url: https://github.com/rnmapbox/maps/blob/main/<%- component.relPath %> --- -<%_ } _%> +<%_ } else { -%> +<% } -%> <%_ if (component.mbx) { _%> Mapbox spec: [<%- component.mbx.name %>](https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/#<%- component.mbx.name %>) @@ -32,7 +33,7 @@ import { <%- component.name %> } from '@rnmapbox/maps'; <%_ if (prop.required) { _%> _required_ <%_ } _%> -<%- propDescription(prop) %> +<%- propDescription(prop, docosaurus) %> <%_ if (prop.default && (prop.default != 'none')) { _%> _defaults to:_ `<%- prop.default %>` @@ -59,7 +60,7 @@ _required_ <%_ if (component.methods && component.methods.length) { _%> ## methods <%_ for (let method of component.methods) { _%> -### <%- getMarkdownMethodSignature(method) %> +### <%- getMarkdownMethodSignature(method, docosaurus) %> <%- replaceNewLine(method.description) %> diff --git a/src/components/Images.tsx b/src/components/Images.tsx index 352d793c6..595a244ef 100644 --- a/src/components/Images.tsx +++ b/src/components/Images.tsx @@ -82,7 +82,7 @@ interface Props { /** * Specifies the external images in key-value pairs required for the shape source. * Keys are names - see iconImage expressions, values can be either urls-s objects - * with format {uri: 'http://...'}` or `require('image.png')` or `import 'image.png'` + * with format `{uri: 'http://...'}` or `require('image.png')` or `import 'image.png'` */ images?: { [key: string]: ImageEntry }; diff --git a/src/components/MapView.tsx b/src/components/MapView.tsx index b0aa99e31..4d2b59fdf 100644 --- a/src/components/MapView.tsx +++ b/src/components/MapView.tsx @@ -297,7 +297,7 @@ type Props = ViewProps & { /** * [`mapbox` (v10) implementation only] - * Set map's label locale, e.g. { "locale": "es" } will localize labels to Spanish, { "locale": "current" } will localize labels to system locale. + * Set map's label locale, e.g. `{ "locale": "es" }` will localize labels to Spanish, `{ "locale": "current" }` will localize labels to system locale. */ localizeLabels?: LocalizeLabels;