@macrostrat/map-interface 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/cjs/container.72611900.js +134 -0
- package/dist/cjs/container.72611900.js.map +1 -0
- package/dist/cjs/context-panel.8c4b009c.js +88 -0
- package/dist/cjs/context-panel.8c4b009c.js.map +1 -0
- package/dist/cjs/controls.7ce3e95c.js +79 -0
- package/dist/cjs/controls.7ce3e95c.js.map +1 -0
- package/dist/cjs/dev.7499151f.js +33 -0
- package/dist/cjs/dev.7499151f.js.map +1 -0
- package/dist/cjs/expansion-panel.08532cee.js +134 -0
- package/dist/cjs/expansion-panel.08532cee.js.map +1 -0
- package/dist/cjs/hash-string.62e84f08.js +67 -0
- package/dist/cjs/hash-string.62e84f08.js.map +1 -0
- package/dist/cjs/header.58c5c012.js +104 -0
- package/dist/cjs/header.58c5c012.js.map +1 -0
- package/dist/cjs/headers.20eae5f7.js +29 -0
- package/dist/cjs/headers.20eae5f7.js.map +1 -0
- package/dist/cjs/helpers.0f72ddaf.js +190 -0
- package/dist/cjs/helpers.0f72ddaf.js.map +1 -0
- package/dist/cjs/index.js +51 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/location-info.92e70042.js +119 -0
- package/dist/cjs/location-info.92e70042.js.map +1 -0
- package/dist/cjs/location-panel.c95f5e96.js +66 -0
- package/dist/cjs/location-panel.c95f5e96.js.map +1 -0
- package/dist/cjs/main.module.02c4de16.css +86 -0
- package/dist/cjs/main.module.02c4de16.css.map +1 -0
- package/dist/cjs/main.module.3f2b7c9f.js +38 -0
- package/dist/cjs/main.module.3f2b7c9f.js.map +1 -0
- package/dist/cjs/main.module.4ecbaaa5.js +62 -0
- package/dist/cjs/main.module.4ecbaaa5.js.map +1 -0
- package/dist/cjs/main.module.62939ea7.js +167 -0
- package/dist/cjs/main.module.62939ea7.js.map +1 -0
- package/dist/cjs/main.module.92978d8b.css +52 -0
- package/dist/cjs/main.module.92978d8b.css.map +1 -0
- package/dist/cjs/main.module.becc2fe7.css +92 -0
- package/dist/cjs/main.module.becc2fe7.css.map +1 -0
- package/dist/cjs/main.module.ccec47df.js +50 -0
- package/dist/cjs/main.module.ccec47df.js.map +1 -0
- package/dist/cjs/main.module.e958948e.js +26 -0
- package/dist/cjs/main.module.e958948e.js.map +1 -0
- package/dist/{index.css → cjs/main.module.f085a193.css} +9 -397
- package/dist/cjs/main.module.f085a193.css.map +1 -0
- package/dist/cjs/main.module.ff1b1aca.css +179 -0
- package/dist/cjs/main.module.ff1b1aca.css.map +1 -0
- package/dist/cjs/map-page.190b6723.js +182 -0
- package/dist/cjs/map-page.190b6723.js.map +1 -0
- package/dist/cjs/map-view.93363b41.js +167 -0
- package/dist/cjs/map-view.93363b41.js.map +1 -0
- package/dist/cjs/terrain.90f76b4e.js +59 -0
- package/dist/cjs/terrain.90f76b4e.js.map +1 -0
- package/dist/cjs/tile-extent.06a4b2ed.js +51 -0
- package/dist/cjs/tile-extent.06a4b2ed.js.map +1 -0
- package/dist/cjs/utils.09cef979.js +36 -0
- package/dist/cjs/utils.09cef979.js.map +1 -0
- package/dist/cjs/utils.26f02633.js +46 -0
- package/dist/cjs/utils.26f02633.js.map +1 -0
- package/dist/cjs/vector-tile-features.456f887b.js +268 -0
- package/dist/cjs/vector-tile-features.456f887b.js.map +1 -0
- package/dist/cjs/xray.a23f8660.js +89 -0
- package/dist/cjs/xray.a23f8660.js.map +1 -0
- package/dist/esm/container.16bde261.js +126 -0
- package/dist/esm/container.16bde261.js.map +1 -0
- package/dist/esm/context-panel.c288c5cd.js +81 -0
- package/dist/esm/context-panel.c288c5cd.js.map +1 -0
- package/dist/esm/controls.f757ce16.js +74 -0
- package/dist/esm/controls.f757ce16.js.map +1 -0
- package/dist/esm/dev.ccb6e774.js +13 -0
- package/dist/esm/dev.ccb6e774.js.map +1 -0
- package/dist/esm/expansion-panel.feff0e62.js +123 -0
- package/dist/esm/expansion-panel.feff0e62.js.map +1 -0
- package/dist/esm/hash-string.836601b2.js +61 -0
- package/dist/esm/hash-string.836601b2.js.map +1 -0
- package/dist/esm/header.0f535ab1.js +99 -0
- package/dist/esm/header.0f535ab1.js.map +1 -0
- package/dist/esm/headers.b25ff414.js +24 -0
- package/dist/esm/headers.b25ff414.js.map +1 -0
- package/dist/esm/helpers.fb1d7227.js +176 -0
- package/dist/esm/helpers.fb1d7227.js.map +1 -0
- package/dist/{types.d.ts → esm/index.d.ts} +102 -51
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +25 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/location-info.5543bb05.js +89 -0
- package/dist/esm/location-info.5543bb05.js.map +1 -0
- package/dist/esm/location-panel.0b1f4ed2.js +58 -0
- package/dist/esm/location-panel.0b1f4ed2.js.map +1 -0
- package/dist/esm/main.module.5eb366de.js +52 -0
- package/dist/esm/main.module.5eb366de.js.map +1 -0
- package/dist/esm/main.module.67a908da.js +40 -0
- package/dist/esm/main.module.67a908da.js.map +1 -0
- package/dist/esm/main.module.89579666.js +64 -0
- package/dist/esm/main.module.89579666.js.map +1 -0
- package/dist/esm/main.module.9c57cc95.js +28 -0
- package/dist/esm/main.module.9c57cc95.js.map +1 -0
- package/dist/esm/main.module.f70e002b.js +169 -0
- package/dist/esm/main.module.f70e002b.js.map +1 -0
- package/dist/esm/map-page.b953c404.js +175 -0
- package/dist/esm/map-page.b953c404.js.map +1 -0
- package/dist/esm/map-view.a3fe6257.js +161 -0
- package/dist/esm/map-view.a3fe6257.js.map +1 -0
- package/dist/esm/terrain.f65cf7c5.js +54 -0
- package/dist/esm/terrain.f65cf7c5.js.map +1 -0
- package/dist/esm/tile-extent.ca526996.js +46 -0
- package/dist/esm/tile-extent.ca526996.js.map +1 -0
- package/dist/esm/utils.122d1f2d.js +28 -0
- package/dist/esm/utils.122d1f2d.js.map +1 -0
- package/dist/esm/utils.d40349f0.js +40 -0
- package/dist/esm/utils.d40349f0.js.map +1 -0
- package/dist/esm/vector-tile-features.e1a24df0.js +258 -0
- package/dist/esm/vector-tile-features.e1a24df0.js.map +1 -0
- package/dist/esm/xray.c0663c25.js +83 -0
- package/dist/esm/xray.c0663c25.js.map +1 -0
- package/package.json +19 -36
- package/src/container.ts +29 -21
- package/src/context-panel/index.ts +4 -4
- package/src/context-panel/main.module.sass +1 -1
- package/src/dev/main.module.sass +16 -0
- package/src/dev/map-page.ts +19 -4
- package/src/dev/vector-tile-features.ts +44 -13
- package/src/location-panel/header.ts +27 -8
- package/src/location-panel/index.ts +4 -2
- package/src/location-panel/main.module.sass +7 -0
- package/src/main.module.sass +4 -1
- package/src/map-view/index.ts +1 -1
- package/dist/index.cjs.css +0 -961
- package/dist/index.cjs.css.map +0 -1
- package/dist/index.cjs.js +0 -1954
- package/dist/index.cjs.js.map +0 -1
- package/dist/index.css.map +0 -1
- package/dist/index.js +0 -1945
- package/dist/index.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":";;;;;;;;;;;;;;;;;;;;;;AAUA,MAAM,0BAAI,CAAA,GAAA,sBAAI,EAAE,MAAM,CAAC,CAAA,GAAA,sEAAK;AAErB,SAAS,0CAAkB,QAAE,IAAI,EAAE,GAAG,MAAM;IACjD,qEAAqE;IACrE,uDAAuD;IACvD,MAAM,CAAC,cAAc,gBAAgB,GAAG,CAAA,GAAA,eAAO,EAAE;IACjD,MAAM,eAAe,CAAA,GAAA,kBAAU,EAAE,IAAM,gBAAgB,OAAO,EAAE;IAChE,MAAM,eAAe,CAAA,GAAA,kBAAU,EAAE,IAAM,gBAAgB,QAAQ,EAAE;IAEjE,OAAO,wBAAE,0BAA0B;sBAAE;sBAAc;IAAa,GAAG;QACjE,wBAAE,EAAE,CAAC,cAAc,gBAAgB,wBAAE,sCAAgB;kBAAE;QAAK;QAC5D,wBAAE,CAAA,GAAA,eAAO,GAAG;kBACV;YACA,UAAU;YACV,GAAG,IAAI;QACT;KACD;AACH;AAEO,SAAS,0CAAc,WAAE,OAAO,EAAE;IACvC,MAAM,QAAQ,QAAQ,UAAU;IAChC,OAAO,wBAAE,sBAAsB;QAC7B,wBAAE,EAAE,CAAC,OAAO,IAAI,CAAC,OAAO,MAAM,GAAG,GAAG,2CAAmB;YAAE,MAAM;QAAM;KACtE;AACH;AAEA,SAAS,qCAAe,QAAE,IAAI,EAAE;IAC9B,MAAM,CAAC,QAAQ,UAAU,GAAG,CAAA,GAAA,eAAO,EAAE;IACrC,OAAO,wBAAE,CAAA,GAAA,aAAK,GAAG;QACf,MAAM,SAAS,SAAS;QACxB,QAAQ,SAAS,CAAA,GAAA,aAAK,EAAE,OAAO,GAAG,CAAA,GAAA,aAAK,EAAE,IAAI;QAC7C,SAAS;QACT,OAAO;QACP;YACE,UAAU,SAAS,CAAC,SAAS,CAAC,KAAK,SAAS,CAAC,MAAM,MAAM;YACzD,UAAU;QACZ;IACF;AACF;AAGO,SAAS,0CAAwB,oBACtC,gBAAgB,eAChB,WAAW,UACX,SAAS,GAKV;IACC,MAAM,SAAS,CAAA,GAAA,gBAAQ;IACvB,MAAM,YAAY,CAAA,GAAA,mBAAW,EAAE,CAAC,IAAM,EAAE,SAAS;IACjD,MAAM,gBAAgB,CAAA,GAAA,mBAAW,EAAE,CAAC,IAAM,EAAE,aAAa;IACzD,MAAM,eAAe,CAAA,GAAA,aAAK,EAAE;IAC5B,MAAM,eAAe,CAAA,GAAA,aAAK,EAAE,EAAE;IAE9B,CAAA,GAAA,gBAAQ,EAAE;QACR,MAAM,MAAM,QAAQ;QACpB,IAAI,OAAO,MAAM;QACjB,IAAI,oBAAoB,MAAM;YAC5B,YAAY;YACZ;QACF;QAEA,IAAI,CAAC,eAAe;QAEpB,MAAM,8BAA8B,aAAa,OAAO,CAAC,MAAM,GAAG;QAElE,MAAM,eAAe,KAAK,SAAS,CAAC;QACpC,IAAI,gBAAgB,aAAa,OAAO,IAAI,6BAC1C;QAEF,aAAa,OAAO,GAAG;QAEvB,8CAA8C;QAC9C,+CAA+C;QAE/C,MAAM,IAAI;QACV,MAAM,KAAK,IAAI,OAAO,CAAC;QAEvB,MAAM,OAAiD;YACrD;gBAAC,GAAG,CAAC,GAAG;gBAAG,GAAG,CAAC,GAAG;aAAE;YACpB;gBAAC,GAAG,CAAC,GAAG;gBAAG,GAAG,CAAC,GAAG;aAAE;SACrB;QACD,MAAM,WAAW,IAAI,qBAAqB,CAAC;QAC3C,aAAa,OAAO,GAAG,YAAY,EAAE;QACrC,YAAY;IACd,GAAG;QAAC;QAAe;QAAkB;KAAU;IAE/C,OAAO;AACT;AAEA,SAAS,oCAAc,WAAE,OAAO,EAAE;IAChC,OAAO,wBAAE,sBAAsB;QAC7B,wBAAE,MAAM;YACN,wBAAE,gCAAU;gBAAE,OAAO;gBAAU,OAAO,QAAQ,MAAM;YAAC;YACrD,wBAAE,gCAAU;gBAAE,OAAO;gBAAgB,OAAO,QAAQ,WAAW;YAAC;SACjE;KACF;AACH;AAEA,SAAS,+BAAS,SAAE,KAAK,SAAE,KAAK,EAAE;IAChC,OAAO,wBAAE,kBAAkB;QAAC,wBAAE,YAAY;QAAQ,wBAAE,cAAc;KAAO;AAC3E;AAEA,SAAS,6CAAuB,YAAE,QAAQ,YAAE,QAAQ,EAAE;IACpD,MAAM,MAAM,CAAA,GAAA,gBAAQ;IACpB,IAAI,KAAK,WAAW,MAAM,OAAO;IACjC,MAAM,CAAC,UAAU,YAAY,GAAG,CAAA,GAAA,eAAO,EAAE;IAEzC,MAAM,iBAAiB,SAAS,MAAM,CAAC,CAAC,IAAM,EAAE,MAAM,IAAI;IAE1D,CAAA,GAAA,gBAAQ,EAAE;QACR,IAAI,eAAe,MAAM,GAAG,GAAG;YAC7B,YAAY;YACZ;QACF;QAEA,MAAM,WAAW,IAAI,OAAO,CAAC,cAAc,CAAC;QAC5C,YAAY;QACZ,IAAI,CAAC,UACH,IAAI,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC;YAC9B,IAAI,EAAE,QAAQ,IAAI,UAChB,YAAY;QAEhB;IAEJ,GAAG;QAAC,IAAI,OAAO;QAAE;QAAU,eAAe,MAAM;KAAC;IAEjD,IAAI,CAAC,UAAU,OAAO,wBAAE,CAAA,GAAA,cAAM;IAC9B,OAAO,wBAAE,2CAAU;QAAE,UAAU;IAAe;AAChD;AAEO,SAAS,yCAAS,WAAE,OAAO,cAAE,UAAU,iBAAE,aAAa,EAAE;IAC7D,IAAI,WAAW,MAAM,OAAO;IAC5B,MAAM,OAAO,QAAQ,kBAAkB,CAAC,IAAI,CAAC,MAAM;IACnD,OAAO,wBAAE,iBAAiB;QACxB,wBAAE,MAAM;QACR,wBAAE,kBAAkB;YAClB,wBAAE,gCAAU;gBAAE,OAAO;gBAAK,OAAO,QAAQ,EAAE;YAAC;YAC5C,wBAAE,gCAAU;gBAAE,OAAO;gBAAK,OAAO,QAAQ,EAAE;YAAC;YAC5C,wBAAE,gCAAU;gBAAE,OAAO;gBAAK,OAAO,QAAQ,EAAE;YAAC;SAC7C;QACD,wBAAE;QACF,wBAAE,gCAAU;YAAE,OAAO;YAAQ,OAAO,iCAAW;QAAM;QACrD,wBAAE,CAAA,GAAA,aAAK,GAAG;YACR,OAAO;YACP,gBAAgB;YAChB,SAAS;YACT;gBACE,cAAc,CAAC;YACjB;QACF;KACD;AACH;AAEA,SAAS,iCAAW,IAAY;IAC9B,IAAI,OAAO,SACT,OAAO,wBAAE,kCAAY;QAAE,OAAO,OAAO;QAAS,MAAM;IAAK;IAC3D,IAAI,OAAO,MAAM,OAAO,wBAAE,kCAAY;QAAE,OAAO,OAAO;QAAM,MAAM;IAAK;IACvE,OAAO,GAAG,KAAK,MAAM,CAAC;AACxB;AAEA,SAAS,iCAAW,SAAE,KAAK,QAAE,IAAI,aAAE,YAAY,GAAG;IAChD,OAAO,wBAAE,oBAAoB;QAC3B,wBAAE,eAAe,MAAM,OAAO,CAAC;QAC/B,wBAAE,aAAa;KAChB;AACH;AAEO,SAAS,0CAAa,YAAE,QAAQ,iBAAE,gBAAgB,MAAM;IAC7D,IAAI,YAAY,MAAM,OAAO;IAE7B,IAAI,qBAAqB;IACzB,IAAI,mBAAmB;IACvB,IAAI,QAAQ;IAEZ,IAAI,iBAAiB,MAAM;QACzB,QAAQ;QACR,qBAAqB,wBACnB,CAAA,GAAA,yCAAa,GACb;YACE,OAAO;YACP,WAAW;YACX,UAAU;QACZ,GACA;YACE,wBAAE,8CAAwB;0BACxB;gBACA,UAAU;YACZ;SACD;QAEH,mBAAmB,SAAS,MAAM,CAAC,CAAC,IAAM,EAAE,MAAM,IAAI;IACxD;IAEA,OAAO,wBAAE,qBAAqB;QAC5B;QACA,wBACE,CAAA,GAAA,yCAAa,GACb;mBAAE;YAAO,WAAW;YAAoB,UAAU,iBAAiB;QAAK,GACxE;YACE,wBAAE,qCAAe;gBACf,UAAU;YACZ;SACD;KAEJ;AACH;AAEA,SAAS,oCAAc,YAAE,QAAQ,EAAE;IACjC,6CAA6C,GAC7C,IAAI,YAAY,MAAM,OAAO;IAE7B,MAAM,SAAS,CAAA,GAAA,YAAI,EAAE,UAAU,CAAC,IAAM,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE;IAEtE,OAAO,wBACL,sBACA,MAAM,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,KAAK,SAAS;QACrC,OAAO,wBAAE,qBAAqB;YAC5B,wBAAE,qCAAe;gBAAE,SAAS,QAAQ,CAAC,EAAE;YAAC;YACxC,wBAAE,2CAAU;0BAAE;YAAS;SACxB;IACH;AAEJ;AAEO,SAAS,0CAAS,YAAE,QAAQ,EAAE;IACnC,OAAO,wBACL,gBACA,SAAS,GAAG,CAAC,CAAC,SAAS,IAAM,wBAAE,2CAAe;YAAE,KAAK;qBAAG;QAAQ;AAEpE","sources":["packages/map-interface/src/dev/vector-tile-features.ts"],"sourcesContent":["import { Spinner, Switch, Button, Intent } from \"@blueprintjs/core\";\nimport { useMapRef, useMapStatus } from \"@macrostrat/mapbox-react\";\nimport mapboxgl from \"mapbox-gl\";\nimport hyper from \"@macrostrat/hyper\";\nimport styles from \"./main.module.sass\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { JSONView } from \"@macrostrat/ui-components\";\nimport { group } from \"d3-array\";\nimport { ExpansionPanel } from \"../expansion-panel\";\n\nconst h = hyper.styled(styles);\n\nexport function FeatureProperties({ data, ...rest }) {\n // Instead of managing hover state with CSS, we use a state variable,\n // so that the button re-renders when the state changes\n const [showControls, setShowControls] = useState(false);\n const onMouseEnter = useCallback(() => setShowControls(true), []);\n const onMouseLeave = useCallback(() => setShowControls(false), []);\n\n return h(\"div.feature-properties\", { onMouseEnter, onMouseLeave }, [\n h.if(showControls)(\"div.controls\", h(CopyJSONButton, { data })),\n h(JSONView, {\n data,\n hideRoot: true,\n ...rest,\n }),\n ]);\n}\n\nexport function FeatureRecord({ feature }) {\n const props = feature.properties;\n return h(\"div.feature-record\", [\n h.if(Object.keys(props).length > 0)(FeatureProperties, { data: props }),\n ]);\n}\n\nfunction CopyJSONButton({ data }) {\n const [copied, setCopied] = useState(false);\n return h(Button, {\n icon: copied ? \"tick\" : \"clipboard\",\n intent: copied ? Intent.SUCCESS : Intent.NONE,\n minimal: true,\n small: true,\n onClick() {\n navigator.clipboard.writeText(JSON.stringify(data, null, 2));\n setCopied(true);\n },\n });\n}\n\n/** This component wraps queryRenderedFeatures to get features at a given location */\nexport function FeatureSelectionHandler({\n selectedLocation,\n setFeatures,\n radius = 2,\n}: {\n selectedLocation: mapboxgl.LngLat;\n setFeatures: (features: mapboxgl.MapboxGeoJSONFeature[]) => void;\n radius?: number;\n}) {\n const mapRef = useMapRef();\n const isLoading = useMapStatus((s) => s.isLoading);\n const isInitialized = useMapStatus((s) => s.isInitialized);\n const prevLocation = useRef(null);\n const prevFeatures = useRef([]);\n\n useEffect(() => {\n const map = mapRef?.current;\n if (map == null) return;\n if (selectedLocation == null) {\n setFeatures(null);\n return;\n }\n\n if (!isInitialized) return;\n\n const hasPreviouslyLoadedFeatures = prevFeatures.current.length > 0;\n\n const locationMemo = JSON.stringify(selectedLocation);\n if (locationMemo == prevLocation.current && hasPreviouslyLoadedFeatures)\n return;\n\n prevLocation.current = locationMemo;\n\n // Don't update if the location hasn't changed\n //if (selectedLocation == prevLocation) return;\n\n const r = radius;\n const pt = map.project(selectedLocation);\n\n const bbox: [mapboxgl.PointLike, mapboxgl.PointLike] = [\n [pt.x - r, pt.y - r],\n [pt.x + r, pt.y + r],\n ];\n const features = map.queryRenderedFeatures(bbox);\n prevFeatures.current = features ?? [];\n setFeatures(features);\n }, [isInitialized, selectedLocation, isLoading]);\n\n return null;\n}\n\nfunction FeatureHeader({ feature }) {\n return h(\"div.feature-header\", [\n h(\"h3\", [\n h(KeyValue, { label: \"Source\", value: feature.source }),\n h(KeyValue, { label: \"Source layer\", value: feature.sourceLayer }),\n ]),\n ]);\n}\n\nfunction KeyValue({ label, value }) {\n return h(\"span.key-value\", [h(\"span.key\", label), h(\"code.value\", value)]);\n}\n\nfunction LoadingAwareFeatureSet({ features, sourceID }) {\n const map = useMapRef();\n if (map?.current == null) return null;\n const [isLoaded, setIsLoaded] = useState(false);\n\n const sourceFeatures = features.filter((d) => d.source == \"burwell\");\n\n useEffect(() => {\n if (sourceFeatures.length > 0) {\n setIsLoaded(true);\n return;\n }\n\n const isLoaded = map.current.isSourceLoaded(sourceID);\n setIsLoaded(isLoaded);\n if (!isLoaded) {\n map.current.once(\"sourcedata\", (e) => {\n if (e.sourceId == sourceID) {\n setIsLoaded(true);\n }\n });\n }\n }, [map.current, sourceID, sourceFeatures.length]);\n\n if (!isLoaded) return h(Spinner);\n return h(Features, { features: sourceFeatures });\n}\n\nexport function TileInfo({ feature, showExtent, setShowExtent }) {\n if (feature == null) return null;\n const size = feature._vectorTileFeature._pbf.length;\n return h(\"div.tile-info\", [\n h(\"h3\", \"Tile\"),\n h(\"div.tile-index\", [\n h(KeyValue, { label: \"x\", value: feature._x }),\n h(KeyValue, { label: \"y\", value: feature._y }),\n h(KeyValue, { label: \"z\", value: feature._z }),\n ]),\n h(\"div.spacer\"),\n h(KeyValue, { label: \"Size\", value: formatSize(size) }),\n h(Switch, {\n label: \"Show extent\",\n alignIndicator: \"right\",\n checked: showExtent,\n onChange() {\n setShowExtent(!showExtent);\n },\n }),\n ]);\n}\n\nfunction formatSize(size: number) {\n if (size > 1000000)\n return h(UnitNumber, { value: size / 1000000, unit: \"Mb\" });\n if (size > 1000) return h(UnitNumber, { value: size / 1000, unit: \"Kb\" });\n return `${size} bytes`;\n}\n\nfunction UnitNumber({ value, unit, precision = 1 }) {\n return h(\"span.unit-number\", [\n h(\"span.number\", value.toFixed(precision)),\n h(\"span.unit\", unit),\n ]);\n}\n\nexport function FeaturePanel({ features, focusedSource = null }) {\n if (features == null) return null;\n\n let focusedSourcePanel = null;\n let filteredFeatures = features;\n let title = \"Features\";\n\n if (focusedSource != null) {\n title = \"Basemap features\";\n focusedSourcePanel = h(\n ExpansionPanel,\n {\n title: \"Macrostrat features\",\n className: \"macrostrat-features\",\n expanded: true,\n },\n [\n h(LoadingAwareFeatureSet, {\n features,\n sourceID: focusedSource,\n }),\n ]\n );\n filteredFeatures = features.filter((d) => d.source != focusedSource);\n }\n\n return h(\"div.feature-panel\", [\n focusedSourcePanel,\n h(\n ExpansionPanel,\n { title, className: \"basemap-features\", expanded: focusedSource == null },\n [\n h(FeatureGroups, {\n features: filteredFeatures,\n }),\n ]\n ),\n ]);\n}\n\nfunction FeatureGroups({ features }) {\n /** Group features by source and sourceLayer */\n if (features == null) return null;\n\n const groups = group(features, (d) => `${d.source} - ${d.sourceLayer}`);\n\n return h(\n \"div.feature-groups\",\n Array.from(groups).map(([key, features]) => {\n return h(\"div.feature-group\", [\n h(FeatureHeader, { feature: features[0] }),\n h(Features, { features }),\n ]);\n })\n );\n}\n\nexport function Features({ features }) {\n return h(\n \"div.features\",\n features.map((feature, i) => h(FeatureRecord, { key: i, feature }))\n );\n}\n"],"names":[],"version":3,"file":"vector-tile-features.e1a24df0.js.map"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import {getMapboxStyle as $gWtFU$getMapboxStyle, mergeStyles as $gWtFU$mergeStyles} from "@macrostrat/mapbox-utils";
|
|
2
|
+
import {asChromaColor as $gWtFU$asChromaColor, toRGBAString as $gWtFU$toRGBAString} from "@macrostrat/color-utils";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
async function $64ee2eed3ed5ffbc$export$eff5fb2e10d05b1d(baseStyle, params = null) {
|
|
7
|
+
const { inDarkMode: inDarkMode = false, color: color = "rgb(74, 242, 161)", mapboxToken: mapboxToken, xRaySources: xRaySources } = params;
|
|
8
|
+
const style = await (0, $gWtFU$getMapboxStyle)(baseStyle, {
|
|
9
|
+
access_token: mapboxToken
|
|
10
|
+
});
|
|
11
|
+
const sources = xRaySources ?? Object.keys(style.sources);
|
|
12
|
+
let layers = [];
|
|
13
|
+
for (let layer of style.layers){
|
|
14
|
+
if (!sources.includes(layer.source)) {
|
|
15
|
+
layers.push(layer);
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
let newLayer = $64ee2eed3ed5ffbc$var$transformMapboxLayer(layer, color, inDarkMode);
|
|
19
|
+
if (newLayer != null) layers.push(newLayer);
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
...style,
|
|
23
|
+
layers: layers
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function $64ee2eed3ed5ffbc$var$transformMapboxLayer(layer, color, inDarkMode) {
|
|
27
|
+
const c = (0, $gWtFU$asChromaColor)(color);
|
|
28
|
+
const xRayColor = (opacity = 1, darken = 0)=>{
|
|
29
|
+
if (!inDarkMode) return (0, $gWtFU$toRGBAString)(c.darken(2 - darken).alpha(opacity));
|
|
30
|
+
return (0, $gWtFU$toRGBAString)(c.alpha(opacity).darken(darken));
|
|
31
|
+
};
|
|
32
|
+
if (layer.type == "background") return null;
|
|
33
|
+
let newLayer = {
|
|
34
|
+
...layer
|
|
35
|
+
};
|
|
36
|
+
console.log(xRayColor(0.5));
|
|
37
|
+
if (layer.type == "fill") newLayer.paint = {
|
|
38
|
+
"fill-color": xRayColor(0.1),
|
|
39
|
+
"fill-outline-color": xRayColor(0.5)
|
|
40
|
+
};
|
|
41
|
+
else if (layer.type == "line") newLayer.paint = {
|
|
42
|
+
"line-color": xRayColor(0.5, 0),
|
|
43
|
+
"line-width": 1.5
|
|
44
|
+
};
|
|
45
|
+
else if (layer.type == "symbol") newLayer.paint = {
|
|
46
|
+
"text-color": xRayColor(1, -0.5),
|
|
47
|
+
"text-halo-color": "#000"
|
|
48
|
+
};
|
|
49
|
+
else if (layer.type == "circle") newLayer.paint = {
|
|
50
|
+
"circle-color": xRayColor(0.5, 0),
|
|
51
|
+
"circle-stroke-color": xRayColor(0.5, 1),
|
|
52
|
+
"circle-radius": 2
|
|
53
|
+
};
|
|
54
|
+
return newLayer;
|
|
55
|
+
}
|
|
56
|
+
async function $64ee2eed3ed5ffbc$export$e739dc8dfc0db9a6(baseStyle, overlayStyle = null, params = {}) {
|
|
57
|
+
const { mapboxToken: mapboxToken, xRay: xRay = false, xRaySources: _xRaySources, ...rest } = params;
|
|
58
|
+
let xRaySources = _xRaySources;
|
|
59
|
+
let style = await (0, $gWtFU$getMapboxStyle)(baseStyle, {
|
|
60
|
+
access_token: mapboxToken
|
|
61
|
+
});
|
|
62
|
+
if (overlayStyle != null) {
|
|
63
|
+
const overlay = await (0, $gWtFU$getMapboxStyle)(overlayStyle, {
|
|
64
|
+
access_token: mapboxToken
|
|
65
|
+
});
|
|
66
|
+
style = (0, $gWtFU$mergeStyles)(style, overlay);
|
|
67
|
+
xRaySources ??= Object.keys(overlay.sources);
|
|
68
|
+
}
|
|
69
|
+
if (xRay) {
|
|
70
|
+
// If we haven't specified sources, then we'll use all of them
|
|
71
|
+
xRaySources ??= Object.keys(style.sources);
|
|
72
|
+
style = await $64ee2eed3ed5ffbc$export$eff5fb2e10d05b1d(style, {
|
|
73
|
+
...rest,
|
|
74
|
+
mapboxToken: mapboxToken,
|
|
75
|
+
xRaySources: xRaySources
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return style;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
export {$64ee2eed3ed5ffbc$export$eff5fb2e10d05b1d as buildXRayStyle, $64ee2eed3ed5ffbc$export$e739dc8dfc0db9a6 as buildInspectorStyle};
|
|
83
|
+
//# sourceMappingURL=xray.c0663c25.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":";;;;;AAWO,eAAe,0CACpB,SAA0B,EAC1B,SAAsB,IAAI;IAE1B,MAAM,cACJ,aAAa,cACb,QAAQ,kCACR,WAAW,eACX,WAAW,EACZ,GAAG;IACJ,MAAM,QAAQ,MAAM,CAAA,GAAA,qBAAa,EAAE,WAAW;QAAE,cAAc;IAAY;IAC1E,MAAM,UAAU,eAAe,OAAO,IAAI,CAAC,MAAM,OAAO;IAExD,IAAI,SAAS,EAAE;IACf,KAAK,IAAI,SAAS,MAAM,MAAM,CAAE;QAC9B,IAAI,CAAC,QAAQ,QAAQ,CAAC,MAAM,MAAM,GAAG;YACnC,OAAO,IAAI,CAAC;YACZ;QACF;QACA,IAAI,WAAW,2CAAqB,OAAO,OAAO;QAClD,IAAI,YAAY,MACd,OAAO,IAAI,CAAC;IAEhB;IAEA,OAAO;QACL,GAAG,KAAK;gBACR;IACF;AACF;AAEA,SAAS,2CAAqB,KAAK,EAAE,KAAK,EAAE,UAAU;IACpD,MAAM,IAAI,CAAA,GAAA,oBAAY,EAAE;IACxB,MAAM,YAAY,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC;QACxC,IAAI,CAAC,YACH,OAAO,CAAA,GAAA,mBAAW,EAAE,EAAE,MAAM,CAAC,IAAI,QAAQ,KAAK,CAAC;QAEjD,OAAO,CAAA,GAAA,mBAAW,EAAE,EAAE,KAAK,CAAC,SAAS,MAAM,CAAC;IAC9C;IAEA,IAAI,MAAM,IAAI,IAAI,cAChB,OAAO;IAGT,IAAI,WAAW;QAAE,GAAG,KAAK;IAAC;IAE1B,QAAQ,GAAG,CAAC,UAAU;IAEtB,IAAI,MAAM,IAAI,IAAI,QAChB,SAAS,KAAK,GAAG;QACf,cAAc,UAAU;QACxB,sBAAsB,UAAU;IAClC;SACK,IAAI,MAAM,IAAI,IAAI,QACvB,SAAS,KAAK,GAAG;QACf,cAAc,UAAU,KAAK;QAC7B,cAAc;IAChB;SACK,IAAI,MAAM,IAAI,IAAI,UACvB,SAAS,KAAK,GAAG;QACf,cAAc,UAAU,GAAG;QAC3B,mBAAmB;IACrB;SACK,IAAI,MAAM,IAAI,IAAI,UACvB,SAAS,KAAK,GAAG;QACf,gBAAgB,UAAU,KAAK;QAC/B,uBAAuB,UAAU,KAAK;QACtC,iBAAiB;IACnB;IAGF,OAAO;AACT;AAMO,eAAe,0CACpB,SAAkC,EAClC,eAA+C,IAAI,EACnD,SAAgC,CAAC,CAAC;IAElC,MAAM,eACJ,WAAW,QACX,OAAO,OACP,aAAa,YAAY,EACzB,GAAG,MACJ,GAAG;IACJ,IAAI,cAAc;IAClB,IAAI,QAAQ,MAAM,CAAA,GAAA,qBAAa,EAAE,WAAW;QAC1C,cAAc;IAChB;IAEA,IAAI,gBAAgB,MAAM;QACxB,MAAM,UAAU,MAAM,CAAA,GAAA,qBAAa,EAAE,cAAc;YACjD,cAAc;QAChB;QACA,QAAQ,CAAA,GAAA,kBAAU,EAAE,OAAO;QAC3B,gBAAgB,OAAO,IAAI,CAAC,QAAQ,OAAO;IAC7C;IAEA,IAAI,MAAM;QACR,8DAA8D;QAC9D,gBAAgB,OAAO,IAAI,CAAC,MAAM,OAAO;QAEzC,QAAQ,MAAM,0CAAe,OAAO;YAAE,GAAG,IAAI;yBAAE;yBAAa;QAAY;IAC1E;IACA,OAAO;AACT","sources":["packages/map-interface/src/dev/xray.ts"],"sourcesContent":["import { getMapboxStyle, mergeStyles } from \"@macrostrat/mapbox-utils\";\nimport { asChromaColor, toRGBAString } from \"@macrostrat/color-utils\";\nimport mapboxgl from \"mapbox-gl\";\n\ninterface XRayOptions {\n color?: string;\n inDarkMode?: boolean;\n mapboxToken?: string;\n xRaySources?: string[];\n}\n\nexport async function buildXRayStyle(\n baseStyle: string | object,\n params: XRayOptions = null\n) {\n const {\n inDarkMode = false,\n color = \"rgb(74, 242, 161)\",\n mapboxToken,\n xRaySources,\n } = params;\n const style = await getMapboxStyle(baseStyle, { access_token: mapboxToken });\n const sources = xRaySources ?? Object.keys(style.sources);\n\n let layers = [];\n for (let layer of style.layers) {\n if (!sources.includes(layer.source)) {\n layers.push(layer);\n continue;\n }\n let newLayer = transformMapboxLayer(layer, color, inDarkMode);\n if (newLayer != null) {\n layers.push(newLayer);\n }\n }\n\n return {\n ...style,\n layers,\n };\n}\n\nfunction transformMapboxLayer(layer, color, inDarkMode) {\n const c = asChromaColor(color);\n const xRayColor = (opacity = 1, darken = 0) => {\n if (!inDarkMode) {\n return toRGBAString(c.darken(2 - darken).alpha(opacity));\n }\n return toRGBAString(c.alpha(opacity).darken(darken));\n };\n\n if (layer.type == \"background\") {\n return null;\n }\n\n let newLayer = { ...layer };\n\n console.log(xRayColor(0.5));\n\n if (layer.type == \"fill\") {\n newLayer.paint = {\n \"fill-color\": xRayColor(0.1),\n \"fill-outline-color\": xRayColor(0.5),\n };\n } else if (layer.type == \"line\") {\n newLayer.paint = {\n \"line-color\": xRayColor(0.5, 0),\n \"line-width\": 1.5,\n };\n } else if (layer.type == \"symbol\") {\n newLayer.paint = {\n \"text-color\": xRayColor(1, -0.5),\n \"text-halo-color\": \"#000\",\n };\n } else if (layer.type == \"circle\") {\n newLayer.paint = {\n \"circle-color\": xRayColor(0.5, 0),\n \"circle-stroke-color\": xRayColor(0.5, 1),\n \"circle-radius\": 2,\n };\n }\n\n return newLayer;\n}\n\ntype InspectorStyleOptions = XRayOptions & {\n xRay?: boolean;\n};\n\nexport async function buildInspectorStyle(\n baseStyle: mapboxgl.Style | string,\n overlayStyle: mapboxgl.Style | string | null = null,\n params: InspectorStyleOptions = {}\n) {\n const {\n mapboxToken,\n xRay = false,\n xRaySources: _xRaySources,\n ...rest\n } = params;\n let xRaySources = _xRaySources;\n let style = await getMapboxStyle(baseStyle, {\n access_token: mapboxToken,\n });\n\n if (overlayStyle != null) {\n const overlay = await getMapboxStyle(overlayStyle, {\n access_token: mapboxToken,\n });\n style = mergeStyles(style, overlay);\n xRaySources ??= Object.keys(overlay.sources);\n }\n\n if (xRay) {\n // If we haven't specified sources, then we'll use all of them\n xRaySources ??= Object.keys(style.sources);\n\n style = await buildXRayStyle(style, { ...rest, mapboxToken, xRaySources });\n }\n return style;\n}\n"],"names":[],"version":3,"file":"xray.c0663c25.js.map"}
|
package/package.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@macrostrat/map-interface",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Map interface for Macrostrat",
|
|
5
|
-
"main": "dist/index.
|
|
6
|
-
"module": "dist/index.js",
|
|
7
|
-
"types": "dist/types.d.ts",
|
|
5
|
+
"main": "dist/cjs/index.js",
|
|
6
|
+
"module": "dist/esm/index.js",
|
|
8
7
|
"source": "src/index.ts",
|
|
9
|
-
"
|
|
8
|
+
"types": "dist/esm/index.d.ts",
|
|
10
9
|
"dependencies": {
|
|
11
|
-
"@
|
|
12
|
-
"@macrostrat/
|
|
13
|
-
"@macrostrat/
|
|
14
|
-
"@macrostrat/mapbox-
|
|
15
|
-
"@macrostrat/
|
|
10
|
+
"@blueprintjs/core": "^5.0.0",
|
|
11
|
+
"@macrostrat/color-utils": "^1.0.1",
|
|
12
|
+
"@macrostrat/hyper": "^3.0.6",
|
|
13
|
+
"@macrostrat/mapbox-react": "^2.5.0",
|
|
14
|
+
"@macrostrat/mapbox-utils": "^1.4.0",
|
|
15
|
+
"@macrostrat/ui-components": "^4.1.0",
|
|
16
16
|
"@mapbox/tilebelt": "^2.0.0",
|
|
17
17
|
"classnames": "^2.5.1",
|
|
18
18
|
"d3-array": "^3.2.4",
|
|
@@ -23,47 +23,30 @@
|
|
|
23
23
|
"underscore": "^1.13.6",
|
|
24
24
|
"use-resize-observer": "^9.1.0"
|
|
25
25
|
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"parcel": "^2.13.3",
|
|
28
|
+
"ui-box": "^5.4.1"
|
|
29
|
+
},
|
|
26
30
|
"peerDependencies": {
|
|
27
|
-
"@blueprintjs/core": "^5.0.0",
|
|
28
31
|
"react": "^16.8.6||^17.0.0||^18.0.0",
|
|
29
32
|
"react-dom": "^16.8.6||^17.0.0||^18.0.0"
|
|
30
33
|
},
|
|
31
34
|
"scripts": {
|
|
32
35
|
"dev": "parcel watch",
|
|
33
|
-
"build": "parcel build"
|
|
36
|
+
"build": "rm -rf dist && parcel build"
|
|
34
37
|
},
|
|
35
38
|
"exports": {
|
|
36
39
|
".": {
|
|
37
|
-
"
|
|
38
|
-
"import":
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
},
|
|
42
|
-
"require": {
|
|
43
|
-
"types": "./dist/types.d.ts",
|
|
44
|
-
"default": "./dist/index.cjs.js"
|
|
45
|
-
},
|
|
46
|
-
"types:": "./dist/types.d.ts",
|
|
47
|
-
"style": "./dist/index.css"
|
|
48
|
-
},
|
|
49
|
-
"./dist/": {
|
|
50
|
-
"import": "./dist/",
|
|
51
|
-
"require": "./dist/"
|
|
52
|
-
},
|
|
53
|
-
"./dist/index.css": {
|
|
54
|
-
"import": "./dist/index.css",
|
|
55
|
-
"require": "./dist/index.css"
|
|
40
|
+
"source": "./src/index.ts",
|
|
41
|
+
"import": "./dist/esm/index.js",
|
|
42
|
+
"require": "./dist/cjs/index.js",
|
|
43
|
+
"types": "./dist/esm/index.d.ts"
|
|
56
44
|
}
|
|
57
45
|
},
|
|
58
46
|
"files": [
|
|
59
47
|
"dist",
|
|
60
48
|
"src"
|
|
61
49
|
],
|
|
62
|
-
"devDependencies": {
|
|
63
|
-
"parcel": "^2.12.0",
|
|
64
|
-
"postcss": "^8.0.0",
|
|
65
|
-
"postcss-modules": "^4.3.0"
|
|
66
|
-
},
|
|
67
50
|
"repository": {
|
|
68
51
|
"type": "git",
|
|
69
52
|
"url": "https://github.com/UW-Macrostrat/web-components.git",
|
package/src/container.ts
CHANGED
|
@@ -35,6 +35,26 @@ export enum DetailPanelStyle {
|
|
|
35
35
|
export const MapAreaContainer = (props) =>
|
|
36
36
|
h(MapProviders, h(_MapAreaContainer, props));
|
|
37
37
|
|
|
38
|
+
interface MapAreaContainerProps {
|
|
39
|
+
navbar: AnyElement;
|
|
40
|
+
children?: AnyElement;
|
|
41
|
+
mapControls?: AnyElement;
|
|
42
|
+
contextPanel?: AnyElement;
|
|
43
|
+
contextStack?: AnyElement;
|
|
44
|
+
mainPanel?: AnyElement;
|
|
45
|
+
detailPanel?: AnyElement;
|
|
46
|
+
bottomPanel?: AnyElement;
|
|
47
|
+
className?: string;
|
|
48
|
+
detailPanelOpen?: boolean;
|
|
49
|
+
contextPanelOpen?: boolean;
|
|
50
|
+
contextStackProps?: ContextStackProps;
|
|
51
|
+
detailStackProps?: HTMLDivProps;
|
|
52
|
+
detailPanelStyle: DetailPanelStyle;
|
|
53
|
+
fitViewport?: boolean;
|
|
54
|
+
showPanelOutlines?: boolean;
|
|
55
|
+
preventMapInteraction?: boolean;
|
|
56
|
+
}
|
|
57
|
+
|
|
38
58
|
function _MapAreaContainer({
|
|
39
59
|
children,
|
|
40
60
|
className,
|
|
@@ -53,24 +73,7 @@ function _MapAreaContainer({
|
|
|
53
73
|
showPanelOutlines = false,
|
|
54
74
|
preventMapInteraction = false,
|
|
55
75
|
...rest
|
|
56
|
-
}: {
|
|
57
|
-
navbar: AnyElement;
|
|
58
|
-
children?: AnyElement;
|
|
59
|
-
mapControls?: AnyElement;
|
|
60
|
-
contextPanel?: AnyElement;
|
|
61
|
-
contextStack?: AnyElement;
|
|
62
|
-
mainPanel?: AnyElement;
|
|
63
|
-
detailPanel?: AnyElement;
|
|
64
|
-
bottomPanel?: AnyElement;
|
|
65
|
-
className?: string;
|
|
66
|
-
detailPanelOpen?: boolean;
|
|
67
|
-
contextPanelOpen?: boolean;
|
|
68
|
-
contextStackProps?: ContextStackProps;
|
|
69
|
-
detailStackProps?: HTMLDivProps;
|
|
70
|
-
detailPanelStyle: DetailPanelStyle;
|
|
71
|
-
fitViewport?: boolean;
|
|
72
|
-
showPanelOutlines?: boolean;
|
|
73
|
-
}) {
|
|
76
|
+
}: MapAreaContainerProps) {
|
|
74
77
|
const _detailPanelOpen = detailPanelOpen ?? detailPanel != null;
|
|
75
78
|
const contextPanelTrans = useTransition(contextPanelOpen, 800);
|
|
76
79
|
const detailPanelTrans = useTransition(_detailPanelOpen, 800);
|
|
@@ -114,12 +117,17 @@ function _MapAreaContainer({
|
|
|
114
117
|
]
|
|
115
118
|
);
|
|
116
119
|
|
|
120
|
+
let contextStack = null;
|
|
121
|
+
if (navbar != null && contextPanel != null) {
|
|
122
|
+
contextStack = h(ContextStack, { navbar, ...contextStackProps }, [
|
|
123
|
+
h.if(contextPanelTrans.shouldMount)([contextPanel]),
|
|
124
|
+
]);
|
|
125
|
+
}
|
|
126
|
+
|
|
117
127
|
return h(MapStyledContainer, { className: mainUIClassNames }, [
|
|
118
128
|
h("div.main-row", [
|
|
119
129
|
h("div.map-ui", { ...rest }, [
|
|
120
|
-
|
|
121
|
-
h.if(contextPanelTrans.shouldMount)([contextPanel]),
|
|
122
|
-
]),
|
|
130
|
+
contextStack,
|
|
123
131
|
//h(MapView),
|
|
124
132
|
children ?? mainPanel,
|
|
125
133
|
h.if(detailPanelStyle == DetailPanelStyle.FLOATING)([detailStackExt]),
|
|
@@ -13,7 +13,7 @@ export function LoadingButton({
|
|
|
13
13
|
isLoading = false,
|
|
14
14
|
onClick,
|
|
15
15
|
active = false,
|
|
16
|
-
large =
|
|
16
|
+
large = true,
|
|
17
17
|
icon = "menu",
|
|
18
18
|
style,
|
|
19
19
|
}) {
|
|
@@ -37,13 +37,13 @@ type AnyChildren = React.ReactNode;
|
|
|
37
37
|
|
|
38
38
|
export interface FloatingNavbarProps {
|
|
39
39
|
className?: string;
|
|
40
|
-
children
|
|
40
|
+
children?: AnyChildren;
|
|
41
41
|
headerElement?: AnyChildren;
|
|
42
42
|
title?: AnyChildren;
|
|
43
43
|
statusElement?: AnyChildren;
|
|
44
44
|
rightElement?: AnyChildren;
|
|
45
|
-
height
|
|
46
|
-
width
|
|
45
|
+
height?: number | string;
|
|
46
|
+
width?: number | string;
|
|
47
47
|
style?: object;
|
|
48
48
|
}
|
|
49
49
|
|
package/src/dev/main.module.sass
CHANGED
|
@@ -5,22 +5,35 @@
|
|
|
5
5
|
.key-value
|
|
6
6
|
display: inline-block
|
|
7
7
|
margin-right: 1em
|
|
8
|
+
|
|
8
9
|
.key
|
|
9
10
|
font-weight: bold
|
|
10
11
|
font-size: 0.9em
|
|
12
|
+
|
|
11
13
|
&:after
|
|
12
14
|
content: ': '
|
|
15
|
+
|
|
13
16
|
.value
|
|
14
17
|
font-size: 0.9em
|
|
15
18
|
|
|
16
19
|
.feature-properties
|
|
17
20
|
position: relative
|
|
21
|
+
|
|
18
22
|
&:before
|
|
19
23
|
content: "–"
|
|
20
24
|
position: absolute
|
|
21
25
|
top: 4px
|
|
22
26
|
left: 0
|
|
23
27
|
|
|
28
|
+
.controls
|
|
29
|
+
display: flex
|
|
30
|
+
flex-direction: row
|
|
31
|
+
align-items: flex-end
|
|
32
|
+
position: absolute
|
|
33
|
+
top: 0
|
|
34
|
+
right: 0
|
|
35
|
+
gap: 0.5em
|
|
36
|
+
|
|
24
37
|
.feature-header h3
|
|
25
38
|
margin-bottom: 0
|
|
26
39
|
margin-top: 0.5em
|
|
@@ -28,6 +41,7 @@
|
|
|
28
41
|
.feature-group
|
|
29
42
|
border-bottom: 1px solid var(--panel-rule-inner)
|
|
30
43
|
margin-bottom: 0.5em
|
|
44
|
+
|
|
31
45
|
&:last-child
|
|
32
46
|
border-bottom: none
|
|
33
47
|
|
|
@@ -35,11 +49,13 @@
|
|
|
35
49
|
display: flex
|
|
36
50
|
flex-direction: row
|
|
37
51
|
align-items: baseline
|
|
52
|
+
|
|
38
53
|
h3
|
|
39
54
|
margin-right: 0.5em
|
|
40
55
|
|
|
41
56
|
.opacity-slider
|
|
42
57
|
margin: 0 1em 0.5em
|
|
58
|
+
|
|
43
59
|
:global
|
|
44
60
|
.bp5-slider-handle .bp5-slider-label
|
|
45
61
|
background-color: var(--secondary-color)
|
package/src/dev/map-page.ts
CHANGED
|
@@ -21,14 +21,15 @@ import { MapPosition } from "@macrostrat/mapbox-utils";
|
|
|
21
21
|
|
|
22
22
|
export const h = hyper.styled(styles);
|
|
23
23
|
|
|
24
|
-
export function
|
|
24
|
+
export function MapInspectorV2({
|
|
25
25
|
title = "Map inspector",
|
|
26
26
|
headerElement = null,
|
|
27
27
|
transformRequest = null,
|
|
28
28
|
mapPosition = null,
|
|
29
29
|
mapboxToken = null,
|
|
30
30
|
overlayStyle = null,
|
|
31
|
-
|
|
31
|
+
controls = null,
|
|
32
|
+
children = null,
|
|
32
33
|
style,
|
|
33
34
|
bounds = null,
|
|
34
35
|
focusedSource = null,
|
|
@@ -40,6 +41,7 @@ export function MapInspector({
|
|
|
40
41
|
transformRequest?: mapboxgl.TransformRequestFunction;
|
|
41
42
|
title?: string;
|
|
42
43
|
style?: mapboxgl.Style | string;
|
|
44
|
+
controls?: React.ReactNode;
|
|
43
45
|
children?: React.ReactNode;
|
|
44
46
|
mapboxToken?: string;
|
|
45
47
|
overlayStyle?: mapboxgl.Style | string;
|
|
@@ -49,7 +51,7 @@ export function MapInspector({
|
|
|
49
51
|
mapPosition?: MapPosition;
|
|
50
52
|
bounds?: [number, number, number, number];
|
|
51
53
|
fitViewport?: boolean;
|
|
52
|
-
styleType
|
|
54
|
+
styleType?: "standard" | "macrostrat";
|
|
53
55
|
}) {
|
|
54
56
|
/* We apply a custom style to the panel container when we are interacting
|
|
55
57
|
with the search bar, so that we can block map interactions until search
|
|
@@ -147,7 +149,7 @@ export function MapInspector({
|
|
|
147
149
|
title,
|
|
148
150
|
}),
|
|
149
151
|
contextPanel: h(PanelCard, [
|
|
150
|
-
|
|
152
|
+
controls,
|
|
151
153
|
h(Switch, {
|
|
152
154
|
checked: xRay,
|
|
153
155
|
label: "X-ray mode",
|
|
@@ -180,10 +182,23 @@ export function MapInspector({
|
|
|
180
182
|
setPosition: onSelectPosition,
|
|
181
183
|
}),
|
|
182
184
|
h(TileExtentLayer, { tile, color: isEnabled ? "white" : "black" }),
|
|
185
|
+
children,
|
|
183
186
|
]
|
|
184
187
|
)
|
|
185
188
|
);
|
|
186
189
|
}
|
|
187
190
|
|
|
191
|
+
function MapInspector(props) {
|
|
192
|
+
const { children, controls, ...rest } = props;
|
|
193
|
+
/** Compatibility wrapper for MapInspectorV2 */
|
|
194
|
+
// React warning about this legacy usage
|
|
195
|
+
console.warn("MapInspector is deprecated. Use MapInspectorV2 instead");
|
|
196
|
+
|
|
197
|
+
return h(MapInspectorV2, {
|
|
198
|
+
...rest,
|
|
199
|
+
controls: [children, controls],
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
|
|
188
203
|
// Legacy export
|
|
189
204
|
export const DevMapPage = MapInspector;
|
|
@@ -1,17 +1,24 @@
|
|
|
1
|
-
import { Spinner, Switch } from "@blueprintjs/core";
|
|
1
|
+
import { Spinner, Switch, Button, Intent } from "@blueprintjs/core";
|
|
2
2
|
import { useMapRef, useMapStatus } from "@macrostrat/mapbox-react";
|
|
3
3
|
import mapboxgl from "mapbox-gl";
|
|
4
4
|
import hyper from "@macrostrat/hyper";
|
|
5
5
|
import styles from "./main.module.sass";
|
|
6
|
-
import { useEffect, useState } from "react";
|
|
7
|
-
import { JSONView
|
|
6
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
7
|
+
import { JSONView } from "@macrostrat/ui-components";
|
|
8
8
|
import { group } from "d3-array";
|
|
9
9
|
import { ExpansionPanel } from "../expansion-panel";
|
|
10
10
|
|
|
11
11
|
const h = hyper.styled(styles);
|
|
12
12
|
|
|
13
13
|
export function FeatureProperties({ data, ...rest }) {
|
|
14
|
-
|
|
14
|
+
// Instead of managing hover state with CSS, we use a state variable,
|
|
15
|
+
// so that the button re-renders when the state changes
|
|
16
|
+
const [showControls, setShowControls] = useState(false);
|
|
17
|
+
const onMouseEnter = useCallback(() => setShowControls(true), []);
|
|
18
|
+
const onMouseLeave = useCallback(() => setShowControls(false), []);
|
|
19
|
+
|
|
20
|
+
return h("div.feature-properties", { onMouseEnter, onMouseLeave }, [
|
|
21
|
+
h.if(showControls)("div.controls", h(CopyJSONButton, { data })),
|
|
15
22
|
h(JSONView, {
|
|
16
23
|
data,
|
|
17
24
|
hideRoot: true,
|
|
@@ -27,6 +34,21 @@ export function FeatureRecord({ feature }) {
|
|
|
27
34
|
]);
|
|
28
35
|
}
|
|
29
36
|
|
|
37
|
+
function CopyJSONButton({ data }) {
|
|
38
|
+
const [copied, setCopied] = useState(false);
|
|
39
|
+
return h(Button, {
|
|
40
|
+
icon: copied ? "tick" : "clipboard",
|
|
41
|
+
intent: copied ? Intent.SUCCESS : Intent.NONE,
|
|
42
|
+
minimal: true,
|
|
43
|
+
small: true,
|
|
44
|
+
onClick() {
|
|
45
|
+
navigator.clipboard.writeText(JSON.stringify(data, null, 2));
|
|
46
|
+
setCopied(true);
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** This component wraps queryRenderedFeatures to get features at a given location */
|
|
30
52
|
export function FeatureSelectionHandler({
|
|
31
53
|
selectedLocation,
|
|
32
54
|
setFeatures,
|
|
@@ -37,8 +59,10 @@ export function FeatureSelectionHandler({
|
|
|
37
59
|
radius?: number;
|
|
38
60
|
}) {
|
|
39
61
|
const mapRef = useMapRef();
|
|
40
|
-
const
|
|
41
|
-
const
|
|
62
|
+
const isLoading = useMapStatus((s) => s.isLoading);
|
|
63
|
+
const isInitialized = useMapStatus((s) => s.isInitialized);
|
|
64
|
+
const prevLocation = useRef(null);
|
|
65
|
+
const prevFeatures = useRef([]);
|
|
42
66
|
|
|
43
67
|
useEffect(() => {
|
|
44
68
|
const map = mapRef?.current;
|
|
@@ -48,8 +72,18 @@ export function FeatureSelectionHandler({
|
|
|
48
72
|
return;
|
|
49
73
|
}
|
|
50
74
|
|
|
75
|
+
if (!isInitialized) return;
|
|
76
|
+
|
|
77
|
+
const hasPreviouslyLoadedFeatures = prevFeatures.current.length > 0;
|
|
78
|
+
|
|
79
|
+
const locationMemo = JSON.stringify(selectedLocation);
|
|
80
|
+
if (locationMemo == prevLocation.current && hasPreviouslyLoadedFeatures)
|
|
81
|
+
return;
|
|
82
|
+
|
|
83
|
+
prevLocation.current = locationMemo;
|
|
84
|
+
|
|
51
85
|
// Don't update if the location hasn't changed
|
|
52
|
-
if (selectedLocation == prevLocation) return;
|
|
86
|
+
//if (selectedLocation == prevLocation) return;
|
|
53
87
|
|
|
54
88
|
const r = radius;
|
|
55
89
|
const pt = map.project(selectedLocation);
|
|
@@ -59,8 +93,9 @@ export function FeatureSelectionHandler({
|
|
|
59
93
|
[pt.x + r, pt.y + r],
|
|
60
94
|
];
|
|
61
95
|
const features = map.queryRenderedFeatures(bbox);
|
|
96
|
+
prevFeatures.current = features ?? [];
|
|
62
97
|
setFeatures(features);
|
|
63
|
-
}, [
|
|
98
|
+
}, [isInitialized, selectedLocation, isLoading]);
|
|
64
99
|
|
|
65
100
|
return null;
|
|
66
101
|
}
|
|
@@ -143,11 +178,7 @@ function UnitNumber({ value, unit, precision = 1 }) {
|
|
|
143
178
|
]);
|
|
144
179
|
}
|
|
145
180
|
|
|
146
|
-
export function FeaturePanel({
|
|
147
|
-
features,
|
|
148
|
-
focusedSource = null,
|
|
149
|
-
focusedSourceTitle = null,
|
|
150
|
-
}) {
|
|
181
|
+
export function FeaturePanel({ features, focusedSource = null }) {
|
|
151
182
|
if (features == null) return null;
|
|
152
183
|
|
|
153
184
|
let focusedSourcePanel = null;
|
|
@@ -11,14 +11,16 @@ import {
|
|
|
11
11
|
|
|
12
12
|
const h = hyper.styled(styles);
|
|
13
13
|
|
|
14
|
-
function PositionButton({ position, showCopyLink = false }) {
|
|
14
|
+
function PositionButton({ position, bounds, showCopyLink = false }) {
|
|
15
15
|
const focusState = useFocusState(position);
|
|
16
16
|
|
|
17
17
|
const copyLinkIsVisible = isCentered(focusState) && showCopyLink;
|
|
18
18
|
|
|
19
19
|
return h("div.position-controls", [
|
|
20
|
-
h(LocationFocusButton, { location: position, focusState }, []),
|
|
21
|
-
h.if(copyLinkIsVisible)(CopyLinkButton, {
|
|
20
|
+
h(LocationFocusButton, { location: position, bounds, focusState }, []),
|
|
21
|
+
h.if(copyLinkIsVisible && position != null)(CopyLinkButton, {
|
|
22
|
+
itemName: "position",
|
|
23
|
+
}),
|
|
22
24
|
]);
|
|
23
25
|
}
|
|
24
26
|
|
|
@@ -66,26 +68,39 @@ function CopyLinkButton({ itemName, children, onClick, ...rest }) {
|
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
export interface InfoDrawerHeaderProps {
|
|
69
|
-
onClose
|
|
70
|
-
position
|
|
71
|
+
onClose?: () => void;
|
|
72
|
+
position?: mapboxgl.LngLat;
|
|
71
73
|
zoom?: number;
|
|
72
74
|
elevation?: number;
|
|
73
75
|
showCopyPositionButton?: boolean;
|
|
76
|
+
bounds?: mapboxgl.LngLatBounds;
|
|
74
77
|
}
|
|
75
78
|
|
|
76
79
|
export function InfoDrawerHeader(props: InfoDrawerHeaderProps) {
|
|
77
80
|
const {
|
|
78
81
|
onClose,
|
|
79
82
|
position,
|
|
83
|
+
bounds,
|
|
80
84
|
zoom = 7,
|
|
81
85
|
elevation,
|
|
82
86
|
showCopyPositionButton,
|
|
87
|
+
children,
|
|
83
88
|
} = props;
|
|
84
89
|
|
|
90
|
+
let leftButton = null;
|
|
91
|
+
if (bounds != null || position != null) {
|
|
92
|
+
leftButton = h(PositionButton, {
|
|
93
|
+
position,
|
|
94
|
+
bounds,
|
|
95
|
+
showCopyLink: showCopyPositionButton,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
85
99
|
return h("header.location-panel-header", [
|
|
86
|
-
|
|
100
|
+
leftButton,
|
|
101
|
+
children,
|
|
87
102
|
h("div.spacer"),
|
|
88
|
-
h(LngLatCoords, {
|
|
103
|
+
h.if(position != null)(LngLatCoords, {
|
|
89
104
|
position,
|
|
90
105
|
zoom,
|
|
91
106
|
className: "infodrawer-header-item",
|
|
@@ -94,6 +109,10 @@ export function InfoDrawerHeader(props: InfoDrawerHeaderProps) {
|
|
|
94
109
|
elevation,
|
|
95
110
|
className: "infodrawer-header-item",
|
|
96
111
|
}),
|
|
97
|
-
h(Button, {
|
|
112
|
+
h.if(onClose != null)(Button, {
|
|
113
|
+
minimal: true,
|
|
114
|
+
icon: "cross",
|
|
115
|
+
onClick: onClose,
|
|
116
|
+
}),
|
|
98
117
|
]);
|
|
99
118
|
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { Card } from "@blueprintjs/core";
|
|
2
1
|
import hyper from "@macrostrat/hyper";
|
|
3
2
|
import { InfoDrawerHeader, InfoDrawerHeaderProps } from "./header";
|
|
4
3
|
import classNames from "classnames";
|
|
5
4
|
import styles from "./main.module.sass";
|
|
6
5
|
import { ErrorBoundary } from "@macrostrat/ui-components";
|
|
6
|
+
import { PanelCard } from "../container";
|
|
7
7
|
|
|
8
8
|
const h = hyper.styled(styles);
|
|
9
9
|
|
|
10
10
|
export function InfoDrawerContainer(props) {
|
|
11
11
|
const className = classNames("infodrawer", props.className);
|
|
12
|
-
return h(
|
|
12
|
+
return h(PanelCard, { ...props, className });
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
interface BaseInfoDrawerProps extends InfoDrawerHeaderProps {
|
|
@@ -42,6 +42,8 @@ export function BaseInfoDrawer(props: BaseInfoDrawerProps) {
|
|
|
42
42
|
]);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
export const DetailsPanel = BaseInfoDrawer;
|
|
46
|
+
|
|
45
47
|
export function LocationPanel(props) {
|
|
46
48
|
const { children, className, loading = false, ...rest } = props;
|
|
47
49
|
const cls = classNames("location-panel", className, { loading });
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
flex-direction: row
|
|
11
11
|
align-items: center
|
|
12
12
|
gap: 1em
|
|
13
|
+
min-height: 40px
|
|
13
14
|
border-bottom: 1px solid var(--panel-rule-color)
|
|
14
15
|
|
|
15
16
|
.spacer
|
|
@@ -21,6 +22,12 @@
|
|
|
21
22
|
.position-controls :global(.bp5-button)
|
|
22
23
|
font-size: 12px !important
|
|
23
24
|
|
|
25
|
+
// Text elements should
|
|
26
|
+
h1, h2, h3, h4, h5, h6, p
|
|
27
|
+
margin: 0
|
|
28
|
+
&:first-child
|
|
29
|
+
margin-left: 10px
|
|
30
|
+
|
|
24
31
|
.infodrawer-header-item
|
|
25
32
|
font-size: 12px
|
|
26
33
|
|