@defra/interactive-map 0.0.48-fmp-1 → 0.0.49-alpha
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/dist/css/index.css +1 -1
- package/dist/esm/im-core.js +1 -1
- package/dist/umd/im-core.js +1 -1
- package/package.json +1 -1
- package/plugins/beta/draw-es/dist/esm/im-draw-es-plugin.js +1 -1
- package/plugins/beta/draw-es/src/graphic.js +1 -0
- package/plugins/datasets/dist/esm/esriLayerAdapter.js +1 -1
- package/plugins/datasets/dist/umd/im-datasets-esri-adapter.js +1 -1
- package/plugins/datasets/src/adapters/esri/esriLayerAdapter.js +60 -9
- package/plugins/datasets/src/adapters/esri/esriLayerAdapter.test.js +90 -4
- package/plugins/datasets/src/adapters/maplibre/registry/mapLibreDataset.test.js +8 -8
- package/plugins/datasets/src/reducers/__data__/demoDatasets.js +3 -3
- package/plugins/map-key/dist/esm/im-map-key-plugin.js +1 -1
- package/plugins/map-key/dist/umd/im-map-key-plugin.js +1 -1
- package/plugins/map-key/dist/umd/index.js +1 -1
- package/plugins/map-key/src/api/addSymbol.js +3 -0
- package/plugins/map-key/src/api/addSymbol.test.js +14 -0
- package/plugins/map-key/src/api/index.js +4 -4
- package/plugins/map-key/src/api/index.test.js +6 -6
- package/plugins/map-key/src/api/removeSymbol.js +3 -0
- package/plugins/map-key/src/api/removeSymbol.test.js +14 -0
- package/plugins/map-key/src/initialise/MapKeyInit.jsx +1 -0
- package/plugins/map-key/src/initialise/MapKeyInit.test.jsx +1 -1
- package/plugins/map-key/src/reducers/pluginState.js +4 -4
- package/plugins/map-key/src/reducers/pluginState.test.js +5 -5
- package/src/App/hooks/useLayoutMeasurements.js +28 -14
- package/src/App/hooks/useLayoutMeasurements.test.js +57 -10
- package/src/App/layout/layout.module.scss +10 -2
- package/plugins/map-key/src/api/addKeyItem.js +0 -3
- package/plugins/map-key/src/api/addKeyItem.test.js +0 -14
- package/plugins/map-key/src/api/removeKeyItem.js +0 -3
- package/plugins/map-key/src/api/removeKeyItem.test.js +0 -14
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! For license information please see index.js.LICENSE.txt */
|
|
2
|
-
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("defra",[],t):"object"==typeof exports?exports.defra=t():(e.defra=e.defra||{},e.defra.mapKeyPlugin=t())}(this,()=>(()=>{"use strict";var e,t,r={738(e){e.exports=preactCompat},287(e){e.exports=preactJsxRuntime}},n={};function o(e){var t=n[e];if(void 0!==t)return t.exports;var i=n[e]={exports:{}};return r[e](i,i.exports,o),i.exports}o.m=r,o.d=(e,t)=>{for(var r in t)o.o(t,r)&&!o.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},o.f={},o.e=e=>Promise.all(Object.keys(o.f).reduce((t,r)=>(o.f[r](e,t),t),[])),o.u=e=>"im-map-key-plugin.js",o.miniCssF=e=>{},o.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),e={},t="defra.mapKeyPlugin:",o.l=(r,n,i,a)=>{if(e[r])e[r].push(n);else{var u,c;if(void 0!==i)for(var f=document.getElementsByTagName("script"),p=0;p<f.length;p++){var l=f[p];if(l.getAttribute("src")==r||l.getAttribute("data-webpack")==t+i){u=l;break}}u||(c=!0,(u=document.createElement("script")).charset="utf-8",o.nc&&u.setAttribute("nonce",o.nc),u.setAttribute("data-webpack",t+i),u.src=r),e[r]=[n];var s=(t,n)=>{u.onerror=u.onload=null,clearTimeout(d);var o=e[r];if(delete e[r],u.parentNode&&u.parentNode.removeChild(u),o&&o.forEach(e=>e(n)),t)return t(n)},d=setTimeout(s.bind(null,void 0,{type:"timeout",target:u}),12e4);u.onerror=s.bind(null,u.onerror),u.onload=s.bind(null,u.onload),c&&document.head.appendChild(u)}},o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{var e;o.g.importScripts&&(e=o.g.location+"");var t=o.g.document;if(!e&&t&&(t.currentScript&&"SCRIPT"===t.currentScript.tagName.toUpperCase()&&(e=t.currentScript.src),!e)){var r=t.getElementsByTagName("script");if(r.length)for(var n=r.length-1;n>-1&&(!e||!/^http(s?):/.test(e));)e=r[n--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),o.p=e})(),(()=>{var e={57:0};o.f.j=(t,r)=>{var n=o.o(e,t)?e[t]:void 0;if(0!==n)if(n)r.push(n[2]);else{var i=new Promise((r,o)=>n=e[t]=[r,o]);r.push(n[2]=i);var a=o.p+o.u(t),u=new Error;o.l(a,r=>{if(o.o(e,t)&&(0!==(n=e[t])&&(e[t]=void 0),n)){var i=r&&("load"===r.type?"missing":r.type),a=r&&r.target&&r.target.src;u.message="Loading chunk "+t+" failed.\n("+i+": "+a+")",u.name="ChunkLoadError",u.type=i,u.request=a,n[1](u)}},"chunk-"+t,t)}};var t=(t,r)=>{var n,i,[a,u,c]=r,f=0;if(a.some(t=>0!==e[t])){for(n in u)o.o(u,n)&&(o.m[n]=u[n]);c&&c(o)}for(t&&t(r);f<a.length;f++)i=a[f],o.o(e,i)&&e[i]&&e[i][0](),e[i]=0},r=this.webpackChunkdefra_DefraMap=this.webpackChunkdefra_DefraMap||[];r.forEach(t.bind(null,0)),r.push=t.bind(null,r.push.bind(r))})();var i={};function a(e){return a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},a(e)}function u(){var e,t,r="function"==typeof Symbol?Symbol:{},n=r.iterator||"@@iterator",o=r.toStringTag||"@@toStringTag";function i(r,n,o,i){var u=n&&n.prototype instanceof f?n:f,p=Object.create(u.prototype);return c(p,"_invoke",function(r,n,o){var i,u,c,f=0,p=o||[],l=!1,s={p:0,n:0,v:e,a:d,f:d.bind(e,4),d:function(t,r){return i=t,u=0,c=e,s.n=r,a}};function d(r,n){for(u=r,c=n,t=0;!l&&f&&!o&&t<p.length;t++){var o,i=p[t],d=s.p,b=i[2];r>3?(o=b===n)&&(c=i[(u=i[4])?5:(u=3,3)],i[4]=i[5]=e):i[0]<=d&&((o=r<2&&d<i[1])?(u=0,s.v=n,s.n=i[1]):d<b&&(o=r<3||i[0]>n||n>b)&&(i[4]=r,i[5]=n,s.n=b,u=0))}if(o||r>1)return a;throw l=!0,n}return function(o,p,b){if(f>1)throw TypeError("Generator is already running");for(l&&1===p&&d(p,b),u=p,c=b;(t=u<2?e:c)||!l;){i||(u?u<3?(u>1&&(s.n=-1),d(u,c)):s.n=c:s.v=c);try{if(f=2,i){if(u||(o="next"),t=i[o]){if(!(t=t.call(i,c)))throw TypeError("iterator result is not an object");if(!t.done)return t;c=t.value,u<2&&(u=0)}else 1===u&&(t=i.return)&&t.call(i),u<2&&(c=TypeError("The iterator does not provide a '"+o+"' method"),u=1);i=e}else if((t=(l=s.n<0)?c:r.call(n,s))!==a)break}catch(t){i=e,u=1,c=t}finally{f=1}}return{value:t,done:l}}}(r,o,i),!0),p}var a={};function f(){}function p(){}function l(){}t=Object.getPrototypeOf;var s=[][n]?t(t([][n]())):(c(t={},n,function(){return this}),t),d=l.prototype=f.prototype=Object.create(s);function b(e){return Object.setPrototypeOf?Object.setPrototypeOf(e,l):(e.__proto__=l,c(e,o,"GeneratorFunction")),e.prototype=Object.create(d),e}return p.prototype=l,c(d,"constructor",l),c(l,"constructor",p),p.displayName="GeneratorFunction",c(l,o,"GeneratorFunction"),c(d),c(d,o,"Generator"),c(d,n,function(){return this}),c(d,"toString",function(){return"[object Generator]"}),(u=function(){return{w:i,m:b}})()}function c(e,t,r,n){var o=Object.defineProperty;try{o({},"",{})}catch(e){o=0}c=function(e,t,r,n){function i(t,r){c(e,t,function(e){return this._invoke(t,r,e)})}t?o?o(e,t,{value:r,enumerable:!n,configurable:!n,writable:!n}):e[t]=r:(i("next",0),i("throw",1),i("return",2))},c(e,t,r,n)}function f(e,t,r,n,o,i,a){try{var u=e[i](a),c=u.value}catch(e){return void r(e)}u.done?t(c):Promise.resolve(c).then(n,o)}function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?p(Object(r),!0).forEach(function(t){s(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):p(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function s(e,t,r){return(t=function(e){var t=function(e){if("object"!=a(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=a(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==a(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function d(){var e,t;return l(l({noKeyItemText:"No features displayed"},arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),{},{id:"mapKey",load:(e=u().m(function e(){var t;return u().w(function(e){for(;;)switch(e.n){case 0:return e.n=1,o.e(414).then(o.bind(o,
|
|
2
|
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("defra",[],t):"object"==typeof exports?exports.defra=t():(e.defra=e.defra||{},e.defra.mapKeyPlugin=t())}(this,()=>(()=>{"use strict";var e,t,r={738(e){e.exports=preactCompat},287(e){e.exports=preactJsxRuntime}},n={};function o(e){var t=n[e];if(void 0!==t)return t.exports;var i=n[e]={exports:{}};return r[e](i,i.exports,o),i.exports}o.m=r,o.d=(e,t)=>{for(var r in t)o.o(t,r)&&!o.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},o.f={},o.e=e=>Promise.all(Object.keys(o.f).reduce((t,r)=>(o.f[r](e,t),t),[])),o.u=e=>"im-map-key-plugin.js",o.miniCssF=e=>{},o.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),e={},t="defra.mapKeyPlugin:",o.l=(r,n,i,a)=>{if(e[r])e[r].push(n);else{var u,c;if(void 0!==i)for(var f=document.getElementsByTagName("script"),p=0;p<f.length;p++){var l=f[p];if(l.getAttribute("src")==r||l.getAttribute("data-webpack")==t+i){u=l;break}}u||(c=!0,(u=document.createElement("script")).charset="utf-8",o.nc&&u.setAttribute("nonce",o.nc),u.setAttribute("data-webpack",t+i),u.src=r),e[r]=[n];var s=(t,n)=>{u.onerror=u.onload=null,clearTimeout(d);var o=e[r];if(delete e[r],u.parentNode&&u.parentNode.removeChild(u),o&&o.forEach(e=>e(n)),t)return t(n)},d=setTimeout(s.bind(null,void 0,{type:"timeout",target:u}),12e4);u.onerror=s.bind(null,u.onerror),u.onload=s.bind(null,u.onload),c&&document.head.appendChild(u)}},o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{var e;o.g.importScripts&&(e=o.g.location+"");var t=o.g.document;if(!e&&t&&(t.currentScript&&"SCRIPT"===t.currentScript.tagName.toUpperCase()&&(e=t.currentScript.src),!e)){var r=t.getElementsByTagName("script");if(r.length)for(var n=r.length-1;n>-1&&(!e||!/^http(s?):/.test(e));)e=r[n--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),o.p=e})(),(()=>{var e={57:0};o.f.j=(t,r)=>{var n=o.o(e,t)?e[t]:void 0;if(0!==n)if(n)r.push(n[2]);else{var i=new Promise((r,o)=>n=e[t]=[r,o]);r.push(n[2]=i);var a=o.p+o.u(t),u=new Error;o.l(a,r=>{if(o.o(e,t)&&(0!==(n=e[t])&&(e[t]=void 0),n)){var i=r&&("load"===r.type?"missing":r.type),a=r&&r.target&&r.target.src;u.message="Loading chunk "+t+" failed.\n("+i+": "+a+")",u.name="ChunkLoadError",u.type=i,u.request=a,n[1](u)}},"chunk-"+t,t)}};var t=(t,r)=>{var n,i,[a,u,c]=r,f=0;if(a.some(t=>0!==e[t])){for(n in u)o.o(u,n)&&(o.m[n]=u[n]);c&&c(o)}for(t&&t(r);f<a.length;f++)i=a[f],o.o(e,i)&&e[i]&&e[i][0](),e[i]=0},r=this.webpackChunkdefra_DefraMap=this.webpackChunkdefra_DefraMap||[];r.forEach(t.bind(null,0)),r.push=t.bind(null,r.push.bind(r))})();var i={};function a(e){return a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},a(e)}function u(){var e,t,r="function"==typeof Symbol?Symbol:{},n=r.iterator||"@@iterator",o=r.toStringTag||"@@toStringTag";function i(r,n,o,i){var u=n&&n.prototype instanceof f?n:f,p=Object.create(u.prototype);return c(p,"_invoke",function(r,n,o){var i,u,c,f=0,p=o||[],l=!1,s={p:0,n:0,v:e,a:d,f:d.bind(e,4),d:function(t,r){return i=t,u=0,c=e,s.n=r,a}};function d(r,n){for(u=r,c=n,t=0;!l&&f&&!o&&t<p.length;t++){var o,i=p[t],d=s.p,b=i[2];r>3?(o=b===n)&&(c=i[(u=i[4])?5:(u=3,3)],i[4]=i[5]=e):i[0]<=d&&((o=r<2&&d<i[1])?(u=0,s.v=n,s.n=i[1]):d<b&&(o=r<3||i[0]>n||n>b)&&(i[4]=r,i[5]=n,s.n=b,u=0))}if(o||r>1)return a;throw l=!0,n}return function(o,p,b){if(f>1)throw TypeError("Generator is already running");for(l&&1===p&&d(p,b),u=p,c=b;(t=u<2?e:c)||!l;){i||(u?u<3?(u>1&&(s.n=-1),d(u,c)):s.n=c:s.v=c);try{if(f=2,i){if(u||(o="next"),t=i[o]){if(!(t=t.call(i,c)))throw TypeError("iterator result is not an object");if(!t.done)return t;c=t.value,u<2&&(u=0)}else 1===u&&(t=i.return)&&t.call(i),u<2&&(c=TypeError("The iterator does not provide a '"+o+"' method"),u=1);i=e}else if((t=(l=s.n<0)?c:r.call(n,s))!==a)break}catch(t){i=e,u=1,c=t}finally{f=1}}return{value:t,done:l}}}(r,o,i),!0),p}var a={};function f(){}function p(){}function l(){}t=Object.getPrototypeOf;var s=[][n]?t(t([][n]())):(c(t={},n,function(){return this}),t),d=l.prototype=f.prototype=Object.create(s);function b(e){return Object.setPrototypeOf?Object.setPrototypeOf(e,l):(e.__proto__=l,c(e,o,"GeneratorFunction")),e.prototype=Object.create(d),e}return p.prototype=l,c(d,"constructor",l),c(l,"constructor",p),p.displayName="GeneratorFunction",c(l,o,"GeneratorFunction"),c(d),c(d,o,"Generator"),c(d,n,function(){return this}),c(d,"toString",function(){return"[object Generator]"}),(u=function(){return{w:i,m:b}})()}function c(e,t,r,n){var o=Object.defineProperty;try{o({},"",{})}catch(e){o=0}c=function(e,t,r,n){function i(t,r){c(e,t,function(e){return this._invoke(t,r,e)})}t?o?o(e,t,{value:r,enumerable:!n,configurable:!n,writable:!n}):e[t]=r:(i("next",0),i("throw",1),i("return",2))},c(e,t,r,n)}function f(e,t,r,n,o,i,a){try{var u=e[i](a),c=u.value}catch(e){return void r(e)}u.done?t(c):Promise.resolve(c).then(n,o)}function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?p(Object(r),!0).forEach(function(t){s(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):p(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function s(e,t,r){return(t=function(e){var t=function(e){if("object"!=a(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=a(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==a(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function d(){var e,t;return l(l({noKeyItemText:"No features displayed"},arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),{},{id:"mapKey",load:(e=u().m(function e(){var t;return u().w(function(e){for(;;)switch(e.n){case 0:return e.n=1,o.e(414).then(o.bind(o,64));case 1:return t=e.v.manifest,e.a(2,t)}},e)}),t=function(){var t=this,r=arguments;return new Promise(function(n,o){var i=e.apply(t,r);function a(e){f(i,n,o,a,u,"next",e)}function u(e){f(i,n,o,a,u,"throw",e)}a(void 0)})},function(){return t.apply(this,arguments)})})}return o.d(i,{default:()=>d}),i.default})());
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { addSymbol } from './addSymbol.js'
|
|
2
|
+
|
|
3
|
+
describe('addSymbol', () => {
|
|
4
|
+
it('dispatches an ADD_KEY_SYMBOL action with the key definition', () => {
|
|
5
|
+
const dispatch = jest.fn()
|
|
6
|
+
|
|
7
|
+
addSymbol({ pluginState: { dispatch } }, { id: 'map-key', groupLabel: 'Map key' })
|
|
8
|
+
|
|
9
|
+
expect(dispatch).toHaveBeenCalledWith({
|
|
10
|
+
type: 'ADD_KEY_SYMBOL',
|
|
11
|
+
payload: { id: 'map-key', groupLabel: 'Map key' }
|
|
12
|
+
})
|
|
13
|
+
})
|
|
14
|
+
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { addSymbol } from './addSymbol.js'
|
|
2
|
+
import { removeSymbol } from './removeSymbol.js'
|
|
3
3
|
|
|
4
4
|
export const api = {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
addSymbol,
|
|
6
|
+
removeSymbol
|
|
7
7
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { api } from './index.js'
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { addSymbol } from './addSymbol.js'
|
|
3
|
+
import { removeSymbol } from './removeSymbol.js'
|
|
4
4
|
|
|
5
5
|
describe('api/index', () => {
|
|
6
|
-
it('exports the
|
|
7
|
-
expect(api.
|
|
6
|
+
it('exports the addSymbol API', () => {
|
|
7
|
+
expect(api.addSymbol).toBe(addSymbol)
|
|
8
8
|
})
|
|
9
9
|
|
|
10
|
-
it('exports the
|
|
11
|
-
expect(api.
|
|
10
|
+
it('exports the removeSymbol API', () => {
|
|
11
|
+
expect(api.removeSymbol).toBe(removeSymbol)
|
|
12
12
|
})
|
|
13
13
|
})
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { removeSymbol } from './removeSymbol.js'
|
|
2
|
+
|
|
3
|
+
describe('removeSymbol', () => {
|
|
4
|
+
it('dispatches a REMOVE_KEY_SYMBOL action with the key definition', () => {
|
|
5
|
+
const dispatch = jest.fn()
|
|
6
|
+
|
|
7
|
+
removeSymbol({ pluginState: { dispatch } }, { id: 'map-key' })
|
|
8
|
+
|
|
9
|
+
expect(dispatch).toHaveBeenCalledWith({
|
|
10
|
+
type: 'REMOVE_KEY_SYMBOL',
|
|
11
|
+
payload: { id: 'map-key' }
|
|
12
|
+
})
|
|
13
|
+
})
|
|
14
|
+
})
|
|
@@ -16,6 +16,7 @@ export function MapKeyInit ({ pluginConfig, pluginState, mapState, services }) {
|
|
|
16
16
|
attachPluginStateRef(pluginStateRef)
|
|
17
17
|
// Request a handle on the datasetsRegistry singleton
|
|
18
18
|
eventBus.requestOnce('datasets:registry', setDatasetRegistry)
|
|
19
|
+
eventBus.emit('map-key:ready')
|
|
19
20
|
}, [mapState.isMapReady])
|
|
20
21
|
|
|
21
22
|
useEffect(() => {
|
|
@@ -6,7 +6,7 @@ jest.mock('../registry/getDatasetRegistry.js', () => ({
|
|
|
6
6
|
setDatasetRegistry: jest.fn()
|
|
7
7
|
}))
|
|
8
8
|
|
|
9
|
-
const eventBus = { requestOnce: jest.fn() }
|
|
9
|
+
const eventBus = { requestOnce: jest.fn(), emit: jest.fn() }
|
|
10
10
|
const pluginState = { dispatch: jest.fn() }
|
|
11
11
|
const pluginConfig = {
|
|
12
12
|
groups: {
|
|
@@ -17,7 +17,7 @@ const findGroup = (state, id, groupId) => {
|
|
|
17
17
|
})
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
const
|
|
20
|
+
const addSymbol = (state, keyDefinition) => {
|
|
21
21
|
const { id, groupLabel } = keyDefinition
|
|
22
22
|
const groupId = keyDefinition.groupId || labelToId(groupLabel)
|
|
23
23
|
// Check for an existingGroup
|
|
@@ -41,7 +41,7 @@ const addKeyItem = (state, keyDefinition) => {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
const
|
|
44
|
+
const removeSymbol = (state, keyDefinition) => {
|
|
45
45
|
const { id } = keyDefinition
|
|
46
46
|
return {
|
|
47
47
|
...state,
|
|
@@ -57,8 +57,8 @@ const addKeyGroups = (state, groups) => {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
const actions = {
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
ADD_KEY_SYMBOL: addSymbol,
|
|
61
|
+
REMOVE_KEY_SYMBOL: removeSymbol,
|
|
62
62
|
ADD_KEY_GROUPS: addKeyGroups
|
|
63
63
|
}
|
|
64
64
|
|
|
@@ -6,7 +6,7 @@ describe('pluginState reducer helpers', () => {
|
|
|
6
6
|
})
|
|
7
7
|
|
|
8
8
|
it('adds a flat key item and creates a flat group when needed', () => {
|
|
9
|
-
const nextState = actions.
|
|
9
|
+
const nextState = actions.ADD_KEY_SYMBOL(initialState, { id: 'flat-key', label: 'Flat key' })
|
|
10
10
|
|
|
11
11
|
expect(nextState).toEqual({
|
|
12
12
|
keyDefinitions: [{ id: 'flat-key', label: 'Flat key', type: 'manual' }],
|
|
@@ -15,7 +15,7 @@ describe('pluginState reducer helpers', () => {
|
|
|
15
15
|
})
|
|
16
16
|
|
|
17
17
|
it('adds a grouped key item when the label can be converted to a group id', () => {
|
|
18
|
-
const nextState = actions.
|
|
18
|
+
const nextState = actions.ADD_KEY_SYMBOL(initialState, { id: 'group-key', groupLabel: 'Group Label', label: 'Group key' })
|
|
19
19
|
|
|
20
20
|
expect(nextState).toEqual({
|
|
21
21
|
keyDefinitions: [{
|
|
@@ -35,7 +35,7 @@ describe('pluginState reducer helpers', () => {
|
|
|
35
35
|
groups: [{ id: 'existing-item', type: 'flat' }]
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
expect(actions.
|
|
38
|
+
expect(actions.ADD_KEY_SYMBOL(state, { id: 'existing-item', label: 'Existing item' })).toEqual({
|
|
39
39
|
keyDefinitions: [
|
|
40
40
|
{ id: 'existing-item' },
|
|
41
41
|
{ id: 'existing-item', label: 'Existing item', type: 'manual' }
|
|
@@ -50,7 +50,7 @@ describe('pluginState reducer helpers', () => {
|
|
|
50
50
|
groups: [{ id: 'group-1', type: 'group', groupLabel: 'Group 1' }]
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
expect(actions.
|
|
53
|
+
expect(actions.ADD_KEY_SYMBOL(state, { id: 'new-item', groupId: 'group-1', groupLabel: 'Group 1', label: 'New item' })).toEqual({
|
|
54
54
|
keyDefinitions: [
|
|
55
55
|
{ id: 'existing-group-item', groupId: 'group-1' },
|
|
56
56
|
{ id: 'new-item', groupId: 'group-1', groupLabel: 'Group 1', label: 'New item', type: 'manual' }
|
|
@@ -65,7 +65,7 @@ describe('pluginState reducer helpers', () => {
|
|
|
65
65
|
groups: [{ id: 'a', type: 'flat' }]
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
expect(actions.
|
|
68
|
+
expect(actions.REMOVE_KEY_SYMBOL(state, { id: 'a' })).toEqual({
|
|
69
69
|
keyDefinitions: [{ id: 'b' }],
|
|
70
70
|
groups: [{ id: 'a', type: 'flat' }]
|
|
71
71
|
})
|
|
@@ -17,8 +17,12 @@ const symmetricWidth = (left, right) => left || right ? Math.max(left, right) :
|
|
|
17
17
|
const subSlotMaxHeight = (columnHeight, siblingButtons, gap) => columnHeight - (siblingButtons ? siblingButtons + gap : 0)
|
|
18
18
|
|
|
19
19
|
// bottomRightHeight is 0 when empty, falling back to the attributions' own height for spacing.
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
// rise is how far attributions has lifted .im-o-app__bottom-right above .im-o-app__bottom's
|
|
21
|
+
// own bottom edge (see attributionsRise below) — without adding it here, .im-o-app__right's
|
|
22
|
+
// computed bottom offset stays at the box's un-lifted position and the floating right column
|
|
23
|
+
// overlaps the now-raised bottom-right buttons.
|
|
24
|
+
const rightOffsetBottom = (containerPad, bottomRightHeight, attributionsHeight, rise, gap) =>
|
|
25
|
+
containerPad + (bottomRightHeight > 0 ? bottomRightHeight + rise + gap : attributionsHeight)
|
|
22
26
|
|
|
23
27
|
// Clears the bottom row's own TOP edge (not just its trailing gap below), so the hint
|
|
24
28
|
// never overlaps the logo/attribution row itself, plus a gap above it. That trivially
|
|
@@ -74,13 +78,22 @@ const attributionsNaturalWidth = (attributionsEl) => {
|
|
|
74
78
|
// longer fits, at its natural width, in the space beside the logo column.
|
|
75
79
|
const isAttributionsStacked = (naturalWidth, availableWidth) => naturalWidth > availableWidth
|
|
76
80
|
|
|
77
|
-
//
|
|
78
|
-
//
|
|
79
|
-
//
|
|
80
|
-
//
|
|
81
|
-
//
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
// How far attributions lifts .im-o-app__bottom-right above .im-o-app__bottom's own bottom
|
|
82
|
+
// edge. The same figure covers both modes, because both bleed primaryGap past that edge and
|
|
83
|
+
// then take attributionsHeight (plus a dividerGap) back up from there:
|
|
84
|
+
// - docked: the box grows upward from the bleed into the row itself, where
|
|
85
|
+
// .im-o-app__bottom-right shares the same horizontal space, so the row needs an explicit
|
|
86
|
+
// margin-bottom (--bottom-right-clearance) to stay clear of it;
|
|
87
|
+
// - stacked: the box is an extra flex line *below* the row, so it lifts the row by exactly
|
|
88
|
+
// that much on its own — no margin needed, hence bottomRightClearance's isStacked branch.
|
|
89
|
+
// Either way .im-o-app__right must clear the lift, so the offsets below use this, not the
|
|
90
|
+
// clearance. Clamped at 0: a box shorter than its own bleed lifts nothing.
|
|
91
|
+
const attributionsRise = (attributionsHeight, dividerGap, primaryGap) =>
|
|
92
|
+
Math.max(0, attributionsHeight + dividerGap - primaryGap)
|
|
93
|
+
|
|
94
|
+
// Stacked gets its lift from the extra flex line itself (see attributionsRise above), so only
|
|
95
|
+
// docked needs the row pushed up by a margin.
|
|
96
|
+
const bottomRightClearance = (isStacked, rise) => isStacked ? 0 : rise
|
|
84
97
|
|
|
85
98
|
// Docks centred between the side columns when there's room, otherwise stacks full-width
|
|
86
99
|
// (mobile always stacks). Sets the banner's own CSS vars and returns what the side-column
|
|
@@ -125,8 +138,9 @@ function applyAttributionsLayout ({ appContainer, bottom, attributions, dividerG
|
|
|
125
138
|
// space-between` gap between the two columns isn't a fixed value (unlike `gap`) to reconstruct.
|
|
126
139
|
const left = attributionsCol ? Math.round(attributionsCol.getBoundingClientRect().left - bottom.getBoundingClientRect().left) : 0
|
|
127
140
|
appContainer.style.setProperty('--attributions-left', `${left}px`)
|
|
128
|
-
const
|
|
129
|
-
appContainer.style.setProperty('--bottom-right-clearance', `${
|
|
141
|
+
const rise = attributionsRise(attributions.offsetHeight, dividerGap, primaryGap)
|
|
142
|
+
appContainer.style.setProperty('--bottom-right-clearance', `${bottomRightClearance(isStacked, rise)}px`)
|
|
143
|
+
return { rise }
|
|
130
144
|
}
|
|
131
145
|
|
|
132
146
|
/**
|
|
@@ -174,7 +188,7 @@ function calculateLayout (layoutRefs, breakpoint) {
|
|
|
174
188
|
? bannerTop + bannerHeight + dividerGap
|
|
175
189
|
: colHeight + top.offsetTop
|
|
176
190
|
|
|
177
|
-
applyAttributionsLayout({ appContainer, bottom, attributions, dividerGap, primaryGap })
|
|
191
|
+
const { rise: attributionsLift } = applyAttributionsLayout({ appContainer, bottom, attributions, dividerGap, primaryGap })
|
|
178
192
|
|
|
179
193
|
// === Left container offsets ===
|
|
180
194
|
const leftOffsetTop = sideOffsetTop(topLeftCol.offsetHeight)
|
|
@@ -187,10 +201,10 @@ function calculateLayout (layoutRefs, breakpoint) {
|
|
|
187
201
|
const bottomRightHeight = buttonHeight(bottomRightRef)
|
|
188
202
|
const bottomContainerPad = main.offsetHeight - bottom.offsetTop - bottom.offsetHeight
|
|
189
203
|
const rightOffsetTop = sideOffsetTop(topRightCol.offsetHeight)
|
|
190
|
-
const rightEffectiveBottom = bottom.offsetTop + bottom.offsetHeight - bottomRightHeight
|
|
204
|
+
const rightEffectiveBottom = bottom.offsetTop + bottom.offsetHeight - bottomRightHeight - attributionsLift
|
|
191
205
|
const rightColumnHeight = rightEffectiveBottom - rightOffsetTop - dividerGap
|
|
192
206
|
appContainer.style.setProperty('--right-offset-top', `${rightOffsetTop}px`)
|
|
193
|
-
appContainer.style.setProperty('--right-offset-bottom', `${rightOffsetBottom(bottomContainerPad, bottomRightHeight, attributions.offsetHeight, dividerGap)}px`)
|
|
207
|
+
appContainer.style.setProperty('--right-offset-bottom', `${rightOffsetBottom(bottomContainerPad, bottomRightHeight, attributions.offsetHeight, attributionsLift, dividerGap)}px`)
|
|
194
208
|
appContainer.style.setProperty('--right-top-max-height', `${rightColumnHeight}px`)
|
|
195
209
|
|
|
196
210
|
// === Keyboard hint bottom offset ===
|
|
@@ -88,9 +88,11 @@ describe('useLayoutMeasurements', () => {
|
|
|
88
88
|
test.each([
|
|
89
89
|
['right-offset-top', { topRightCol: { offsetHeight: 80 }, top: { offsetTop: 15 } }, '95px'],
|
|
90
90
|
['right-offset-bottom', { main: { offsetHeight: 600 }, bottom: { offsetTop: 500 } }, '116px'],
|
|
91
|
-
// leftColumnHeight = 400 - (50+10) - 8 = 332
|
|
91
|
+
// leftColumnHeight = 400 - (50+10) - 8 = 332
|
|
92
|
+
// rightColumnHeight: rightEffectiveBottom = 400 - 0 (bottomRightHeight) - 16 (bottom-right-clearance,
|
|
93
|
+
// since default attributions offsetHeight 16 + dividerGap 8 - primaryGap 8 = 16) = 384; 384 - 50 - 8 = 326
|
|
92
94
|
['left-top-max-height', {}, '332px'],
|
|
93
|
-
['right-top-max-height', {}, '
|
|
95
|
+
['right-top-max-height', {}, '326px']
|
|
94
96
|
])('calculates %s correctly', (name, refOverrides, expected) => {
|
|
95
97
|
const { layoutRefs } = setup({ refs: refOverrides })
|
|
96
98
|
renderHook(() => useLayoutMeasurements())
|
|
@@ -103,10 +105,11 @@ describe('useLayoutMeasurements', () => {
|
|
|
103
105
|
['--left-top-panel-max-height', { leftBottom: { offsetHeight: 50 } }, '274px'], // 332 - 50 - 8
|
|
104
106
|
['--left-bottom-panel-max-height', {}, '332px'],
|
|
105
107
|
['--left-bottom-panel-max-height', { leftTop: { offsetHeight: 40 } }, '284px'], // 332 - 40 - 8
|
|
106
|
-
|
|
107
|
-
['--right-top-panel-max-height', {
|
|
108
|
-
['--right-
|
|
109
|
-
['--right-bottom-panel-max-height', {
|
|
108
|
+
// rightColumnHeight is 326 by default here (see the right-top-max-height case above)
|
|
109
|
+
['--right-top-panel-max-height', {}, '326px'],
|
|
110
|
+
['--right-top-panel-max-height', { rightBottom: { offsetHeight: 60 } }, '258px'], // 326 - 60 - 8
|
|
111
|
+
['--right-bottom-panel-max-height', {}, '326px'],
|
|
112
|
+
['--right-bottom-panel-max-height', { rightTop: { offsetHeight: 30 } }, '288px'] // 326 - 30 - 8
|
|
110
113
|
])('calculates %s with sibling buttons=%o correctly', (varName, refOverrides, expected) => {
|
|
111
114
|
const { layoutRefs } = setup({ refs: refOverrides })
|
|
112
115
|
renderHook(() => useLayoutMeasurements())
|
|
@@ -232,7 +235,7 @@ describe('useLayoutMeasurements', () => {
|
|
|
232
235
|
appendChild(layoutRefs.attributionsRef.current, { scrollWidth: 250 }) // attribution text, too wide to fit
|
|
233
236
|
renderHook(() => useLayoutMeasurements())
|
|
234
237
|
expect(layoutRefs.attributionsRef.current.classList.contains('im-o-app__attributions--stacked')).toBe(true)
|
|
235
|
-
// stacked
|
|
238
|
+
// stacked is lifted by its own extra flex line, not a margin, so no clearance is needed here
|
|
236
239
|
expect(layoutRefs.appContainerRef.current.style.setProperty).toHaveBeenCalledWith('--bottom-right-clearance', '0px')
|
|
237
240
|
})
|
|
238
241
|
|
|
@@ -260,9 +263,53 @@ describe('useLayoutMeasurements', () => {
|
|
|
260
263
|
})
|
|
261
264
|
renderHook(() => useLayoutMeasurements())
|
|
262
265
|
// bottomContainerPad = 500 - 400 - 0 = 100
|
|
263
|
-
//
|
|
266
|
+
// attributions lift = 16 (default attributions offsetHeight 16 + dividerGap 8 - primaryGap 8)
|
|
267
|
+
// expected = 100 + (20 + 16 + 8) = 144
|
|
264
268
|
expect(layoutRefs.appContainerRef.current.style.setProperty)
|
|
265
|
-
.toHaveBeenCalledWith('--right-offset-bottom', '
|
|
269
|
+
.toHaveBeenCalledWith('--right-offset-bottom', '144px')
|
|
270
|
+
})
|
|
271
|
+
|
|
272
|
+
test('adds the attributions lift into right-offset-bottom so .im-o-app__right does not overlap a bottom-right box pushed up by tall docked attributions', () => {
|
|
273
|
+
const { layoutRefs } = setup({
|
|
274
|
+
refs: {
|
|
275
|
+
bottomRight: { offsetHeight: 20 },
|
|
276
|
+
attributions: { offsetHeight: 40 } // lift = 40 + 8 (dividerGap) - 8 (primaryGap) = 40
|
|
277
|
+
}
|
|
278
|
+
})
|
|
279
|
+
renderHook(() => useLayoutMeasurements())
|
|
280
|
+
// bottomContainerPad = 500 - 400 - 0 = 100; expected = 100 + (20 + 40 + 8) = 168
|
|
281
|
+
// Without the lift term this regressed to 128px, letting .im-o-app__right's
|
|
282
|
+
// bottom offset sit below the (margin-bottom-raised) bottom-right box's real top edge.
|
|
283
|
+
expect(layoutRefs.appContainerRef.current.style.setProperty)
|
|
284
|
+
.toHaveBeenCalledWith('--right-offset-bottom', '168px')
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
// Stacked attributions takes a flex line of its own BELOW the bottom-right row, lifting the
|
|
288
|
+
// row by the same amount the docked box's margin-bottom does — but as part of
|
|
289
|
+
// .im-o-app__bottom's own grown height, not as a margin, so --bottom-right-clearance is 0.
|
|
290
|
+
// Reading the clearance here (rather than the mode-independent lift) left the right column's
|
|
291
|
+
// bottom offset at the un-lifted position, so a right-bottom scale bar overlapped a
|
|
292
|
+
// bottom-right draw menu on mobile — the breakpoint where attributions always stacks.
|
|
293
|
+
test('adds the attributions lift into right-offset-bottom when attributions is stacked, not just docked', () => {
|
|
294
|
+
const { layoutRefs } = setup({
|
|
295
|
+
refs: {
|
|
296
|
+
bottom: { rect: { left: 0 } },
|
|
297
|
+
bottomRight: { offsetHeight: 20 },
|
|
298
|
+
attributions: { offsetHeight: 40 } // lift = 40 + 8 (dividerGap) - 8 (primaryGap) = 40
|
|
299
|
+
}
|
|
300
|
+
})
|
|
301
|
+
appendChild(layoutRefs.bottomRef.current, {}) // logo column
|
|
302
|
+
appendChild(layoutRefs.bottomRef.current, { offsetWidth: 192, rect: { left: 115 } }) // bottom-right column
|
|
303
|
+
layoutRefs.bottomRef.current.appendChild(layoutRefs.attributionsRef.current) // sibling of both columns
|
|
304
|
+
appendChild(layoutRefs.attributionsRef.current, { scrollWidth: 250 }) // too wide to fit beside the logo
|
|
305
|
+
renderHook(() => useLayoutMeasurements())
|
|
306
|
+
const spy = layoutRefs.appContainerRef.current.style.setProperty
|
|
307
|
+
expect(layoutRefs.attributionsRef.current.classList.contains('im-o-app__attributions--stacked')).toBe(true)
|
|
308
|
+
expect(spy).toHaveBeenCalledWith('--bottom-right-clearance', '0px')
|
|
309
|
+
// Same 168px as the docked case above, despite the 0px clearance.
|
|
310
|
+
expect(spy).toHaveBeenCalledWith('--right-offset-bottom', '168px')
|
|
311
|
+
// rightEffectiveBottom = 400 + 0 - 20 - 40 = 340; 340 - 50 (rightOffsetTop) - 8 = 282
|
|
312
|
+
expect(spy).toHaveBeenCalledWith('--right-top-max-height', '282px')
|
|
266
313
|
})
|
|
267
314
|
|
|
268
315
|
test('uses 0 when sub-slot refs have null current', () => {
|
|
@@ -274,7 +321,7 @@ describe('useLayoutMeasurements', () => {
|
|
|
274
321
|
renderHook(() => useLayoutMeasurements())
|
|
275
322
|
// With all sub-slot refs null, buttons = 0 ?? 0 = 0, so max-heights equal full column height
|
|
276
323
|
expect(layoutRefs.appContainerRef.current.style.setProperty).toHaveBeenCalledWith('--left-top-panel-max-height', '332px')
|
|
277
|
-
expect(layoutRefs.appContainerRef.current.style.setProperty).toHaveBeenCalledWith('--right-bottom-panel-max-height', '
|
|
324
|
+
expect(layoutRefs.appContainerRef.current.style.setProperty).toHaveBeenCalledWith('--right-bottom-panel-max-height', '326px')
|
|
278
325
|
})
|
|
279
326
|
|
|
280
327
|
test('dispatches safe zone inset on desktop (post-batch RAF read only)', () => {
|
|
@@ -266,6 +266,12 @@
|
|
|
266
266
|
flex-wrap: wrap; // lets a stacked attributions row wrap onto its own line
|
|
267
267
|
justify-content: space-between;
|
|
268
268
|
align-items: flex-end;
|
|
269
|
+
// No effect on a single line (the common case), only between wrapped lines — covers both
|
|
270
|
+
// a too-wide .im-o-app__bottom-right dropping below the logo/bottom-left column, and the
|
|
271
|
+
// stacked attributions row below that (see its own comment further down: this same gap
|
|
272
|
+
// replaces what used to be its one-off margin-top, so a doubly-wrapped bottom stays evenly
|
|
273
|
+
// spaced rather than gapping only at the line the margin happened to be declared on).
|
|
274
|
+
row-gap: var(--divider-gap);
|
|
269
275
|
z-index: -2; // Support masking the viewport
|
|
270
276
|
}
|
|
271
277
|
|
|
@@ -323,7 +329,9 @@
|
|
|
323
329
|
// (being bottom-pinned) pushes the logo and bottom-right buttons up rather than squeezing
|
|
324
330
|
// the text into an ever-narrower column. The oversized flex-basis plus negative
|
|
325
331
|
// right/bottom/left margin bleeds that row flush to the true edges the same way the docked
|
|
326
|
-
// box's absolute offsets do above.
|
|
332
|
+
// box's absolute offsets do above; the gap above it comes from .im-o-app__bottom's own
|
|
333
|
+
// row-gap (not a margin-top here), so it stays exactly one gap even if .im-o-app__bottom-right
|
|
334
|
+
// has also wrapped onto a line of its own above it.
|
|
327
335
|
|
|
328
336
|
.im-o-app__attributions:not(:empty) {
|
|
329
337
|
position: absolute;
|
|
@@ -337,7 +345,7 @@
|
|
|
337
345
|
.im-o-app__attributions--stacked:not(:empty) {
|
|
338
346
|
position: static;
|
|
339
347
|
flex-basis: calc(100% + var(--primary-gap) * 2);
|
|
340
|
-
margin:
|
|
348
|
+
margin: 0 calc(var(--primary-gap) * -1) calc(var(--primary-gap) * -1);
|
|
341
349
|
}
|
|
342
350
|
|
|
343
351
|
// ---------------------------------------------------
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { addKeyItem } from './addKeyItem.js'
|
|
2
|
-
|
|
3
|
-
describe('addKeyItem', () => {
|
|
4
|
-
it('dispatches an ADD_KEY_ITEM action with the key definition', () => {
|
|
5
|
-
const dispatch = jest.fn()
|
|
6
|
-
|
|
7
|
-
addKeyItem({ pluginState: { dispatch } }, { id: 'map-key', groupLabel: 'Map key' })
|
|
8
|
-
|
|
9
|
-
expect(dispatch).toHaveBeenCalledWith({
|
|
10
|
-
type: 'ADD_KEY_ITEM',
|
|
11
|
-
payload: { id: 'map-key', groupLabel: 'Map key' }
|
|
12
|
-
})
|
|
13
|
-
})
|
|
14
|
-
})
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { removeKeyItem } from './removeKeyItem.js'
|
|
2
|
-
|
|
3
|
-
describe('removeKeyItem', () => {
|
|
4
|
-
it('dispatches a REMOVE_KEY_ITEM action with the key definition', () => {
|
|
5
|
-
const dispatch = jest.fn()
|
|
6
|
-
|
|
7
|
-
removeKeyItem({ pluginState: { dispatch } }, { id: 'map-key' })
|
|
8
|
-
|
|
9
|
-
expect(dispatch).toHaveBeenCalledWith({
|
|
10
|
-
type: 'REMOVE_KEY_ITEM',
|
|
11
|
-
payload: { id: 'map-key' }
|
|
12
|
-
})
|
|
13
|
-
})
|
|
14
|
-
})
|