@nrk/core-toggle
Advanced tools
Comparing version 3.0.6 to 3.0.7
@@ -5,3 +5,3 @@ (function (global, factory) { | ||
(global = global || self, global.CoreToggle = factory(global.React)); | ||
}(this, function (React) { 'use strict'; | ||
}(this, (function (React) { 'use strict'; | ||
@@ -369,8 +369,8 @@ React = React && React.hasOwnProperty('default') ? React['default'] : React; | ||
var version = "3.0.6"; | ||
var version = "3.0.7"; | ||
/** | ||
* closest | ||
* @param {Element} element Element to traverse up from | ||
* @param {String} selector A selector to search for matching parents or element itself | ||
* @param {Element} el Element to traverse up from | ||
* @param {String} css A selector to search for matching parents or element itself | ||
* @return {Element|null} Element which is the closest ancestor matching selector | ||
@@ -396,4 +396,4 @@ */ | ||
* customElementToReact | ||
* @param {Class|Function} elem A custom element definition. | ||
* @param {Array} attr Props and events | ||
* @param {Class|Function} elementClass A custom element definition. | ||
* @param {Array} options Props and custom events | ||
* @return {Object} A React component | ||
@@ -415,4 +415,12 @@ */ | ||
var customEvents = options.customEvents || []; | ||
var skipProps = customProps.concat('forwardRef'); // Keep a copy with forwardRef added | ||
var eventMap = customEvents.reduce(function (map, eventName) { | ||
map[eventName] = "on" + eventName.replace(/(^|\.)./g, function (m) { | ||
return m.slice(-1).toUpperCase(); | ||
}); // input.filter => onInputFilter | ||
return map; | ||
}, {}); | ||
var skipProps = customProps.concat('forwardRef', Object.keys(eventMap).map(function (onEventName) { | ||
return eventMap[onEventName]; | ||
})); | ||
var tagName = (dashCase + "-" + (options.suffix || 'react')).replace(/\W+/g, '-').toLowerCase(); | ||
@@ -424,6 +432,5 @@ return ( | ||
var this$1 = this; | ||
superclass.call(this, props); | ||
superclass.call(this, props); // Register ref prop for accessing custom element https://reactjs.org/docs/refs-and-the-dom.html#callback-refs | ||
this.ref = function (el) { | ||
// Support callback ref https://reactjs.org/docs/refs-and-the-dom.html#callback-refs | ||
if (typeof this$1.props.forwardRef === 'function') { | ||
@@ -436,14 +443,13 @@ this$1.props.forwardRef(el); | ||
return this$1.el = el; | ||
}; | ||
}; // Register event handler on component for each custom event | ||
customEvents.forEach(function (eventName) { | ||
var on = "on" + eventName.replace(/(^|\.)./g, function (m) { | ||
return m.slice(-1).toUpperCase(); | ||
}); // input.filter => onInputFilter | ||
Object.keys(eventMap).forEach(function (eventName) { | ||
var onEventName = eventMap[eventName]; | ||
this$1[eventName] = function (event) { | ||
return this$1.props[on] && closest$1(event.target, this$1.el.nodeName) === this$1.el && this$1.props[on](event); | ||
if (this$1.props[onEventName] && closest$1(event.target, this$1.el.nodeName) === this$1.el) { | ||
this$1.props[onEventName](event); | ||
} | ||
}; | ||
skipProps.push(on); // Skip props that are customEvents | ||
}); | ||
@@ -457,20 +463,27 @@ } | ||
anonymous.prototype.componentDidMount = function componentDidMount() { | ||
var this$1 = this; // Do not run connectedCallback before after React componentDidMount, to allow React hydration to run first | ||
var this$1 = this; // Run connectedCallback() after React componentDidMount() to allow React hydration to run first | ||
if (!window.customElements.get(tagName)) { | ||
window.customElements.define(tagName, elementClass); | ||
} | ||
} // Populate properties on custom element | ||
customProps.forEach(function (key) { | ||
return key in this$1.props && (this$1.el[key] = this$1.props[key]); | ||
customProps.forEach(function (propName) { | ||
if (propName in this$1.props) { | ||
this$1.el[propName] = this$1.props[propName]; | ||
} | ||
}); // Register events on custom element | ||
customEvents.forEach(function (eventName) { | ||
this$1.el.addEventListener(eventName, this$1[eventName]); | ||
}); | ||
customEvents.forEach(function (key) { | ||
return this$1.el.addEventListener(key, this$1[key]); | ||
}); | ||
}; | ||
anonymous.prototype.componentDidUpdate = function componentDidUpdate(prev) { | ||
var this$1 = this; | ||
customProps.forEach(function (key) { | ||
return prev[key] !== this$1.props[key] && (this$1.el[key] = this$1.props[key]); | ||
var this$1 = this; // Sync prop changes to custom element | ||
customProps.forEach(function (propName) { | ||
if (prev[propName] !== this$1.props[propName]) { | ||
this$1.el[propName] = this$1.props[propName]; | ||
} | ||
}); | ||
@@ -480,5 +493,6 @@ }; | ||
anonymous.prototype.componentWillUnmount = function componentWillUnmount() { | ||
var this$1 = this; | ||
var this$1 = this; // Remove event handlers on custom element on unmount | ||
customEvents.forEach(function (eventName) { | ||
return this$1.el.removeEventListener(eventName, this$1[eventName]); | ||
this$1.el.removeEventListener(eventName, this$1[eventName]); | ||
}); | ||
@@ -490,13 +504,13 @@ }; | ||
return React.createElement(tagName, Object.keys(this.props).reduce(function (thisProps, key) { | ||
if (skipProps.indexOf(key) === -1) { | ||
return React.createElement(tagName, Object.keys(this.props).reduce(function (thisProps, propName) { | ||
if (skipProps.indexOf(propName) === -1) { | ||
// Do not render customEvents and custom props as attributes | ||
if (key === 'className') { | ||
thisProps["class"] = this$1.props[key]; | ||
if (propName === 'className') { | ||
thisProps["class"] = this$1.props[propName]; | ||
} // Fixes className for custom elements | ||
else if (this$1.props[key] === true) { | ||
thisProps[key] = ''; | ||
else if (this$1.props[propName] === true) { | ||
thisProps[propName] = ''; | ||
} // Fixes boolean attributes | ||
else if (this$1.props[key] !== false) { | ||
thisProps[key] = this$1.props[key]; | ||
else if (this$1.props[propName] !== false) { | ||
thisProps[propName] = this$1.props[propName]; | ||
} // Pass only truthy, non-function props | ||
@@ -524,3 +538,3 @@ | ||
})); | ||
}))); | ||
//# sourceMappingURL=core-toggle.jsx.js.map |
@@ -1,3 +0,3 @@ | ||
/*! @nrk/core-toggle v3.0.6 - Copyright (c) 2017-2019 NRK */ | ||
/*! @nrk/core-toggle v3.0.7 - Copyright (c) 2017-2019 NRK */ | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).coreToggle=e()}(this,function(){"use strict";function e(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function o(t){return(o=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function r(t,e){return(r=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}function u(t,e,n){return(u=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(t){return!1}}()?Reflect.construct:function(t,e,n){var i=[null];i.push.apply(i,e);var o=new(Function.bind.apply(t,i));return n&&r(o,n.prototype),o}).apply(null,arguments)}function c(t){var n="function"==typeof Map?new Map:void 0;return(c=function(t){if(null===t||!function(t){return-1!==Function.toString.call(t).indexOf("[native code]")}(t))return t;if("function"!=typeof t)throw new TypeError("Super expression must either be null or a function");if(void 0!==n){if(n.has(t))return n.get(t);n.set(t,e)}function e(){return u(t,arguments,o(this).constructor)}return e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),r(e,t)})(t)}function n(t,e){return!e||"object"!=typeof e&&"function"!=typeof e?function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t):e}var t="undefined"!=typeof window,s=t&&/(android)/i.test(navigator.userAgent),a=t&&/iPad|iPhone|iPod/.test(String(navigator.platform));t||global.HTMLElement||(global.HTMLElement=function(){return function t(){e(this,t)}}());var l,f,h=(l="undefined"==typeof window?{}:window.Element.prototype,f=l.matches||l.msMatchesSelector||l.webkitMatchesSelector,l.closest?function(t,e){return t.closest(e)}:function(t,e){for(t.correspondingUseElement&&(t=t.correspondingUseElement);t;t=t.parentElement)if(f.call(t,e))return t;return null});function d(t,e,n){var i,o=2<arguments.length&&void 0!==n?n:{},r="prevent_recursive_dispatch_maximum_callstack".concat(e);if(t[r])return!0;t[r]=!0,"function"==typeof window.CustomEvent?i=new window.CustomEvent(e,{bubbles:!0,cancelable:!0,detail:o}):(i=document.createEvent("CustomEvent")).initCustomEvent(e,!0,!0,o);var u=t.dispatchEvent(i);return t[r]=null,u}function p(){return Date.now().toString(36)+Math.random().toString(36).slice(2,5)}return function(){function t(){return e(this,t),n(this,o(t).apply(this,arguments))}return function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&r(t,e)}(t,c(HTMLElement)),function(t,e,n){e&&i(t.prototype,e),n&&i(t,n)}(t,[{key:"connectedCallback",value:function(){a&&(document.documentElement.style.cursor="pointer"),s||this.setAttribute("aria-labelledby",this.button.id=this.button.id||p()),this.value=this.button.textContent,this.setAttribute("role","group"),this.button.setAttribute("aria-expanded",this._open=!this.hidden),this.button.setAttribute("aria-controls",this.id=this.id||p()),document.addEventListener("keydown",this,!0),document.addEventListener("click",this)}},{key:"disconnectedCallback",value:function(){this._button=null,document.removeEventListener("keydown",this,!0),document.removeEventListener("click",this)}},{key:"attributeChangedCallback",value:function(){if(this._open===this.hidden){this.button.setAttribute("aria-expanded",this._open=!this.hidden);try{this.querySelector("[autofocus]").focus()}catch(t){}d(this,"toggle")}}},{key:"handleEvent",value:function(t){if(!t.defaultPrevented){if("keydown"===t.type&&27===t.keyCode)if(t.target.getAttribute&&"true"===t.target.getAttribute("aria-expanded")?t.target===this.button:h(t.target,this.nodeName)===this)return this.hidden=!0,this.button.focus(),t.preventDefault();if("click"===t.type){var e=h(t.target,"a,button");e&&!e.hasAttribute("aria-expanded")&&h(t.target,this.nodeName)===this?d(this,"toggle.select",e):e&&e.getAttribute("aria-controls")===this.id?this.hidden=!this.hidden:this.popup&&!this.contains(t.target)&&(this.hidden=!0)}}}},{key:"button",get:function(){return this._button&&this._button.getAttribute("for")===this.id?this._button:(this._button=this.id&&document.querySelector('[for="'.concat(this.id,'"]')))||this.previousElementSibling}},{key:"popup",get:function(){return"true"===this.getAttribute("popup")||this.getAttribute("popup")||this.hasAttribute("popup")},set:function(t){this[!1===t?"removeAttribute":"setAttribute"]("popup",t)}},{key:"hidden",get:function(){return this.hasAttribute("hidden")},set:function(t){!function(t,e,n){var i=2<arguments.length&&void 0!==n?n:!this.hasAttribute(e);!i===t.hasAttribute(e)&&t[i?"setAttribute":"removeAttribute"](e,"")}(this,"hidden",t)}},{key:"value",get:function(){return this.button.value||this.button.textContent},set:function(t){var e=0<arguments.length&&void 0!==t&&t;if(this.button&&this.popup.length){var n=this.button,i=(n.getAttribute("aria-label")||",".concat(this.popup)).split(",")[1],o=e.textContent||e||"";i===this.popup&&(n.value=e.value||o,n[e.innerHTML?"innerHTML":"textContent"]=e.innerHTML||o,n.setAttribute("aria-label","".concat(n.textContent,",").concat(this.popup)))}}}],[{key:"observedAttributes",get:function(){return["hidden"]}}]),t}()}),window.customElements.define("core-toggle",coreToggle); | ||
//# sourceMappingURL=core-toggle.min.js.map |
@@ -8,38 +8,2 @@ 'use strict'; | ||
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { | ||
try { | ||
var info = gen[key](arg); | ||
var value = info.value; | ||
} catch (error) { | ||
reject(error); | ||
return; | ||
} | ||
if (info.done) { | ||
resolve(value); | ||
} else { | ||
Promise.resolve(value).then(_next, _throw); | ||
} | ||
} | ||
function _asyncToGenerator(fn) { | ||
return function () { | ||
var self = this, | ||
args = arguments; | ||
return new Promise(function (resolve, reject) { | ||
var gen = fn.apply(self, args); | ||
function _next(value) { | ||
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); | ||
} | ||
function _throw(err) { | ||
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); | ||
} | ||
_next(undefined); | ||
}); | ||
}; | ||
} | ||
function prop(selector, name) { | ||
@@ -59,8 +23,4 @@ return browser.executeScript(function (selector, name) { | ||
describe('core-toggle', function () { | ||
beforeEach( | ||
/*#__PURE__*/ | ||
_asyncToGenerator( | ||
/*#__PURE__*/ | ||
regeneratorRuntime.mark(function _callee() { | ||
return regeneratorRuntime.wrap(function _callee$(_context) { | ||
beforeEach(function _callee() { | ||
return regeneratorRuntime.async(function _callee$(_context) { | ||
while (1) { | ||
@@ -70,11 +30,11 @@ switch (_context.prev = _context.next) { | ||
_context.next = 2; | ||
return browser.refresh(); | ||
return regeneratorRuntime.awrap(browser.refresh()); | ||
case 2: | ||
_context.next = 4; | ||
return browser.executeScript(customElements); | ||
return regeneratorRuntime.awrap(browser.executeScript(customElements)); | ||
case 4: | ||
_context.next = 6; | ||
return browser.executeScript(coreToggle); | ||
return regeneratorRuntime.awrap(browser.executeScript(coreToggle)); | ||
@@ -86,11 +46,7 @@ case 6: | ||
} | ||
}, _callee); | ||
}))); | ||
it('sets up all properties', | ||
/*#__PURE__*/ | ||
_asyncToGenerator( | ||
/*#__PURE__*/ | ||
regeneratorRuntime.mark(function _callee2() { | ||
}); | ||
}); | ||
it('sets up all properties', function _callee2() { | ||
var toggleId, buttonId; | ||
return regeneratorRuntime.wrap(function _callee2$(_context2) { | ||
return regeneratorRuntime.async(function _callee2$(_context2) { | ||
while (1) { | ||
@@ -100,13 +56,13 @@ switch (_context2.prev = _context2.next) { | ||
_context2.next = 2; | ||
return browser.executeScript(function () { | ||
return regeneratorRuntime.awrap(browser.executeScript(function () { | ||
document.body.innerHTML = "\n <button>Toggle</button>\n <core-toggle hidden></core-toggle>\n "; | ||
}); | ||
})); | ||
case 2: | ||
_context2.next = 4; | ||
return expect(attr('button', 'aria-expanded')).toMatch(/null|false/); | ||
return regeneratorRuntime.awrap(expect(attr('button', 'aria-expanded')).toMatch(/null|false/)); | ||
case 4: | ||
_context2.next = 6; | ||
return attr('core-toggle', 'id'); | ||
return regeneratorRuntime.awrap(attr('core-toggle', 'id')); | ||
@@ -116,11 +72,11 @@ case 6: | ||
_context2.next = 9; | ||
return expect(attr('button', 'aria-controls')).toEqual(toggleId); | ||
return regeneratorRuntime.awrap(expect(attr('button', 'aria-controls')).toEqual(toggleId)); | ||
case 9: | ||
_context2.next = 11; | ||
return expect(prop('core-toggle', 'hidden')).toMatch(/true/i); | ||
return regeneratorRuntime.awrap(expect(prop('core-toggle', 'hidden')).toMatch(/true/i)); | ||
case 11: | ||
_context2.next = 13; | ||
return attr('button', 'id'); | ||
return regeneratorRuntime.awrap(attr('button', 'id')); | ||
@@ -130,3 +86,3 @@ case 13: | ||
_context2.next = 16; | ||
return expect(attr('core-toggle', 'aria-labelledby')).toEqual(buttonId); | ||
return regeneratorRuntime.awrap(expect(attr('core-toggle', 'aria-labelledby')).toEqual(buttonId)); | ||
@@ -138,10 +94,6 @@ case 16: | ||
} | ||
}, _callee2); | ||
}))); | ||
it('opens and closes toggle', | ||
/*#__PURE__*/ | ||
_asyncToGenerator( | ||
/*#__PURE__*/ | ||
regeneratorRuntime.mark(function _callee3() { | ||
return regeneratorRuntime.wrap(function _callee3$(_context3) { | ||
}); | ||
}); | ||
it('opens and closes toggle', function _callee3() { | ||
return regeneratorRuntime.async(function _callee3$(_context3) { | ||
while (1) { | ||
@@ -151,29 +103,29 @@ switch (_context3.prev = _context3.next) { | ||
_context3.next = 2; | ||
return browser.executeScript(function () { | ||
return regeneratorRuntime.awrap(browser.executeScript(function () { | ||
document.body.innerHTML = "\n <button>Toggle</button>\n <core-toggle hidden></core-toggle>\n "; | ||
}); | ||
})); | ||
case 2: | ||
_context3.next = 4; | ||
return $('button').click(); | ||
return regeneratorRuntime.awrap($('button').click()); | ||
case 4: | ||
_context3.next = 6; | ||
return expect(attr('button', 'aria-expanded')).toMatch(/true/i); | ||
return regeneratorRuntime.awrap(expect(attr('button', 'aria-expanded')).toMatch(/true/i)); | ||
case 6: | ||
_context3.next = 8; | ||
return expect(prop('core-toggle', 'hidden')).toMatch(/(null|false)/i); | ||
return regeneratorRuntime.awrap(expect(prop('core-toggle', 'hidden')).toMatch(/(null|false)/i)); | ||
case 8: | ||
_context3.next = 10; | ||
return $('button').click(); | ||
return regeneratorRuntime.awrap($('button').click()); | ||
case 10: | ||
_context3.next = 12; | ||
return expect(attr('button', 'aria-expanded')).toEqual('false'); | ||
return regeneratorRuntime.awrap(expect(attr('button', 'aria-expanded')).toEqual('false')); | ||
case 12: | ||
_context3.next = 14; | ||
return expect(prop('core-toggle', 'hidden')).toMatch(/true/i); | ||
return regeneratorRuntime.awrap(expect(prop('core-toggle', 'hidden')).toMatch(/true/i)); | ||
@@ -185,10 +137,6 @@ case 14: | ||
} | ||
}, _callee3); | ||
}))); | ||
it('opens and closes nested toggle', | ||
/*#__PURE__*/ | ||
_asyncToGenerator( | ||
/*#__PURE__*/ | ||
regeneratorRuntime.mark(function _callee4() { | ||
return regeneratorRuntime.wrap(function _callee4$(_context4) { | ||
}); | ||
}); | ||
it('opens and closes nested toggle', function _callee4() { | ||
return regeneratorRuntime.async(function _callee4$(_context4) { | ||
while (1) { | ||
@@ -198,41 +146,41 @@ switch (_context4.prev = _context4.next) { | ||
_context4.next = 2; | ||
return browser.executeScript(function () { | ||
return regeneratorRuntime.awrap(browser.executeScript(function () { | ||
document.body.innerHTML = "\n <button id=\"outer\">Toggle outer</button>\n <core-toggle hidden>\n <button id=\"inner\">Toggle inner</button>\n <core-toggle hidden>\n <div>Inner content</div>\n </core-toggle>\n </core-toggle>\n "; | ||
}); | ||
})); | ||
case 2: | ||
_context4.next = 4; | ||
return $('button#outer').click(); | ||
return regeneratorRuntime.awrap($('button#outer').click()); | ||
case 4: | ||
_context4.next = 6; | ||
return $('button#inner').click(); | ||
return regeneratorRuntime.awrap($('button#inner').click()); | ||
case 6: | ||
_context4.next = 8; | ||
return expect(prop('button#outer + core-toggle', 'hidden')).toMatch(/(null|false)/i); | ||
return regeneratorRuntime.awrap(expect(prop('button#outer + core-toggle', 'hidden')).toMatch(/(null|false)/i)); | ||
case 8: | ||
_context4.next = 10; | ||
return expect(prop('button#outer + core-toggle', 'hidden')).toMatch(/(null|false)/i); | ||
return regeneratorRuntime.awrap(expect(prop('button#outer + core-toggle', 'hidden')).toMatch(/(null|false)/i)); | ||
case 10: | ||
_context4.next = 12; | ||
return $('button#inner').click(); | ||
return regeneratorRuntime.awrap($('button#inner').click()); | ||
case 12: | ||
_context4.next = 14; | ||
return expect(prop('button#inner + core-toggle', 'hidden')).toMatch(/true/i); | ||
return regeneratorRuntime.awrap(expect(prop('button#inner + core-toggle', 'hidden')).toMatch(/true/i)); | ||
case 14: | ||
_context4.next = 16; | ||
return expect(prop('button#outer + core-toggle', 'hidden')).toMatch(/(null|false)/i); | ||
return regeneratorRuntime.awrap(expect(prop('button#outer + core-toggle', 'hidden')).toMatch(/(null|false)/i)); | ||
case 16: | ||
_context4.next = 18; | ||
return $('button#outer').click(); | ||
return regeneratorRuntime.awrap($('button#outer').click()); | ||
case 18: | ||
_context4.next = 20; | ||
return expect(prop('button#outer + core-toggle', 'hidden')).toMatch(/true/i); | ||
return regeneratorRuntime.awrap(expect(prop('button#outer + core-toggle', 'hidden')).toMatch(/true/i)); | ||
@@ -244,10 +192,6 @@ case 20: | ||
} | ||
}, _callee4); | ||
}))); | ||
it('closes nested toggle with esc', | ||
/*#__PURE__*/ | ||
_asyncToGenerator( | ||
/*#__PURE__*/ | ||
regeneratorRuntime.mark(function _callee5() { | ||
return regeneratorRuntime.wrap(function _callee5$(_context5) { | ||
}); | ||
}); | ||
it('closes nested toggle with esc', function _callee5() { | ||
return regeneratorRuntime.async(function _callee5$(_context5) { | ||
while (1) { | ||
@@ -257,41 +201,41 @@ switch (_context5.prev = _context5.next) { | ||
_context5.next = 2; | ||
return browser.executeScript(function () { | ||
return regeneratorRuntime.awrap(browser.executeScript(function () { | ||
document.body.innerHTML = "\n <button id=\"outer\">Toggle outer</button>\n <core-toggle hidden>\n <button id=\"inner\">Toggle inner</button>\n <core-toggle hidden>\n <div>Inner content</div>\n </core-toggle>\n </core-toggle>\n "; | ||
}); | ||
})); | ||
case 2: | ||
_context5.next = 4; | ||
return $('button#outer').click(); | ||
return regeneratorRuntime.awrap($('button#outer').click()); | ||
case 4: | ||
_context5.next = 6; | ||
return $('button#inner').click(); | ||
return regeneratorRuntime.awrap($('button#inner').click()); | ||
case 6: | ||
_context5.next = 8; | ||
return expect(prop('button#outer + core-toggle', 'hidden')).toMatch(/(null|false)/i); | ||
return regeneratorRuntime.awrap(expect(prop('button#outer + core-toggle', 'hidden')).toMatch(/(null|false)/i)); | ||
case 8: | ||
_context5.next = 10; | ||
return expect(prop('button#outer + core-toggle', 'hidden')).toMatch(/(null|false)/i); | ||
return regeneratorRuntime.awrap(expect(prop('button#outer + core-toggle', 'hidden')).toMatch(/(null|false)/i)); | ||
case 10: | ||
_context5.next = 12; | ||
return $('button#inner').sendKeys(protractor.Key.ESCAPE); | ||
return regeneratorRuntime.awrap($('button#inner').sendKeys(protractor.Key.ESCAPE)); | ||
case 12: | ||
_context5.next = 14; | ||
return expect(prop('button#inner + core-toggle', 'hidden')).toMatch(/true/i); | ||
return regeneratorRuntime.awrap(expect(prop('button#inner + core-toggle', 'hidden')).toMatch(/true/i)); | ||
case 14: | ||
_context5.next = 16; | ||
return expect(prop('button#outer + core-toggle', 'hidden')).toMatch(/(null|false)/i); | ||
return regeneratorRuntime.awrap(expect(prop('button#outer + core-toggle', 'hidden')).toMatch(/(null|false)/i)); | ||
case 16: | ||
_context5.next = 18; | ||
return $('button#inner').sendKeys(protractor.Key.ESCAPE); | ||
return regeneratorRuntime.awrap($('button#inner').sendKeys(protractor.Key.ESCAPE)); | ||
case 18: | ||
_context5.next = 20; | ||
return expect(prop('button#outer + core-toggle', 'hidden')).toMatch(/true/i); | ||
return regeneratorRuntime.awrap(expect(prop('button#outer + core-toggle', 'hidden')).toMatch(/true/i)); | ||
@@ -303,10 +247,6 @@ case 20: | ||
} | ||
}, _callee5); | ||
}))); | ||
it('closes popup on click outside', | ||
/*#__PURE__*/ | ||
_asyncToGenerator( | ||
/*#__PURE__*/ | ||
regeneratorRuntime.mark(function _callee6() { | ||
return regeneratorRuntime.wrap(function _callee6$(_context6) { | ||
}); | ||
}); | ||
it('closes popup on click outside', function _callee6() { | ||
return regeneratorRuntime.async(function _callee6$(_context6) { | ||
while (1) { | ||
@@ -316,21 +256,21 @@ switch (_context6.prev = _context6.next) { | ||
_context6.next = 2; | ||
return browser.executeScript(function () { | ||
return regeneratorRuntime.awrap(browser.executeScript(function () { | ||
document.body.innerHTML = "\n <button>Toggle</button>\n <core-toggle popup hidden></core-toggle>\n "; | ||
}); | ||
})); | ||
case 2: | ||
_context6.next = 4; | ||
return $('button').click(); | ||
return regeneratorRuntime.awrap($('button').click()); | ||
case 4: | ||
_context6.next = 6; | ||
return expect(prop('core-toggle', 'hidden')).toMatch(/(null|false)/i); | ||
return regeneratorRuntime.awrap(expect(prop('core-toggle', 'hidden')).toMatch(/(null|false)/i)); | ||
case 6: | ||
_context6.next = 8; | ||
return $('body').click(); | ||
return regeneratorRuntime.awrap($('body').click()); | ||
case 8: | ||
_context6.next = 10; | ||
return expect(prop('core-toggle', 'hidden')).toMatch(/true/i); | ||
return regeneratorRuntime.awrap(expect(prop('core-toggle', 'hidden')).toMatch(/true/i)); | ||
@@ -342,11 +282,7 @@ case 10: | ||
} | ||
}, _callee6); | ||
}))); | ||
it('respects "for" attribute', | ||
/*#__PURE__*/ | ||
_asyncToGenerator( | ||
/*#__PURE__*/ | ||
regeneratorRuntime.mark(function _callee7() { | ||
}); | ||
}); | ||
it('respects "for" attribute', function _callee7() { | ||
var toggleId; | ||
return regeneratorRuntime.wrap(function _callee7$(_context7) { | ||
return regeneratorRuntime.async(function _callee7$(_context7) { | ||
while (1) { | ||
@@ -356,9 +292,9 @@ switch (_context7.prev = _context7.next) { | ||
_context7.next = 2; | ||
return browser.executeScript(function () { | ||
return regeneratorRuntime.awrap(browser.executeScript(function () { | ||
document.body.innerHTML = "\n <div><button for=\"content\">Toggle</button></div>\n <core-toggle id=\"content\" hidden></core-toggle>\n "; | ||
}); | ||
})); | ||
case 2: | ||
_context7.next = 4; | ||
return attr('core-toggle', 'id'); | ||
return regeneratorRuntime.awrap(attr('core-toggle', 'id')); | ||
@@ -368,7 +304,7 @@ case 4: | ||
_context7.next = 7; | ||
return expect(attr('button', 'for')).toEqual(toggleId); | ||
return regeneratorRuntime.awrap(expect(attr('button', 'for')).toEqual(toggleId)); | ||
case 7: | ||
_context7.next = 9; | ||
return expect(attr('button', 'aria-controls')).toEqual(toggleId); | ||
return regeneratorRuntime.awrap(expect(attr('button', 'aria-controls')).toEqual(toggleId)); | ||
@@ -380,11 +316,7 @@ case 9: | ||
} | ||
}, _callee7); | ||
}))); | ||
it('respects exisiting aria-label with popup and value', | ||
/*#__PURE__*/ | ||
_asyncToGenerator( | ||
/*#__PURE__*/ | ||
regeneratorRuntime.mark(function _callee8() { | ||
}); | ||
}); | ||
it('respects exisiting aria-label with popup and value', function _callee8() { | ||
var toggleValue; | ||
return regeneratorRuntime.wrap(function _callee8$(_context8) { | ||
return regeneratorRuntime.async(function _callee8$(_context8) { | ||
while (1) { | ||
@@ -394,15 +326,15 @@ switch (_context8.prev = _context8.next) { | ||
_context8.next = 2; | ||
return browser.executeScript(function () { | ||
return regeneratorRuntime.awrap(browser.executeScript(function () { | ||
document.body.innerHTML = "\n <button aria-label=\"Label\">Toggle</button>\n <core-toggle popup=\"Another label\" hidden></core-toggle>\n "; | ||
}); | ||
})); | ||
case 2: | ||
_context8.next = 4; | ||
return browser.executeScript(function () { | ||
return regeneratorRuntime.awrap(browser.executeScript(function () { | ||
return document.querySelector('core-toggle').value = 'Button text'; | ||
}); | ||
})); | ||
case 4: | ||
_context8.next = 6; | ||
return prop('core-toggle', 'value'); | ||
return regeneratorRuntime.awrap(prop('core-toggle', 'value')); | ||
@@ -412,7 +344,7 @@ case 6: | ||
_context8.next = 9; | ||
return expect(prop('button', 'textContent')).toEqual(toggleValue); | ||
return regeneratorRuntime.awrap(expect(prop('button', 'textContent')).toEqual(toggleValue)); | ||
case 9: | ||
_context8.next = 11; | ||
return expect(attr('button', 'aria-label')).toEqual('Label'); | ||
return regeneratorRuntime.awrap(expect(attr('button', 'aria-label')).toEqual('Label')); | ||
@@ -424,11 +356,7 @@ case 11: | ||
} | ||
}, _callee8); | ||
}))); | ||
it('sets aria-label with popup attr and value', | ||
/*#__PURE__*/ | ||
_asyncToGenerator( | ||
/*#__PURE__*/ | ||
regeneratorRuntime.mark(function _callee9() { | ||
}); | ||
}); | ||
it('sets aria-label with popup attr and value', function _callee9() { | ||
var toggleValue; | ||
return regeneratorRuntime.wrap(function _callee9$(_context9) { | ||
return regeneratorRuntime.async(function _callee9$(_context9) { | ||
while (1) { | ||
@@ -438,15 +366,15 @@ switch (_context9.prev = _context9.next) { | ||
_context9.next = 2; | ||
return browser.executeScript(function () { | ||
return regeneratorRuntime.awrap(browser.executeScript(function () { | ||
document.body.innerHTML = "\n <button>Toggle</button>\n <core-toggle popup=\"Some label\" hidden></core-toggle>\n "; | ||
}); | ||
})); | ||
case 2: | ||
_context9.next = 4; | ||
return browser.executeScript(function () { | ||
return regeneratorRuntime.awrap(browser.executeScript(function () { | ||
return document.querySelector('core-toggle').value = 'Button text'; | ||
}); | ||
})); | ||
case 4: | ||
_context9.next = 6; | ||
return prop('core-toggle', 'value'); | ||
return regeneratorRuntime.awrap(prop('core-toggle', 'value')); | ||
@@ -456,7 +384,7 @@ case 6: | ||
_context9.next = 9; | ||
return expect(prop('button', 'textContent')).toEqual(toggleValue); | ||
return regeneratorRuntime.awrap(expect(prop('button', 'textContent')).toEqual(toggleValue)); | ||
case 9: | ||
_context9.next = 11; | ||
return expect(attr('button', 'aria-label')).toEqual('Button text,Some label'); | ||
return regeneratorRuntime.awrap(expect(attr('button', 'aria-label')).toEqual('Button text,Some label')); | ||
@@ -468,11 +396,7 @@ case 11: | ||
} | ||
}, _callee9); | ||
}))); | ||
it('sets aria-label with popup prop and value', | ||
/*#__PURE__*/ | ||
_asyncToGenerator( | ||
/*#__PURE__*/ | ||
regeneratorRuntime.mark(function _callee10() { | ||
}); | ||
}); | ||
it('sets aria-label with popup prop and value', function _callee10() { | ||
var toggleValue; | ||
return regeneratorRuntime.wrap(function _callee10$(_context10) { | ||
return regeneratorRuntime.async(function _callee10$(_context10) { | ||
while (1) { | ||
@@ -482,21 +406,21 @@ switch (_context10.prev = _context10.next) { | ||
_context10.next = 2; | ||
return browser.executeScript(function () { | ||
return regeneratorRuntime.awrap(browser.executeScript(function () { | ||
document.body.innerHTML = "\n <button>Toggle</button>\n <core-toggle hidden></core-toggle>\n "; | ||
}); | ||
})); | ||
case 2: | ||
_context10.next = 4; | ||
return browser.executeScript(function () { | ||
return regeneratorRuntime.awrap(browser.executeScript(function () { | ||
return document.querySelector('core-toggle').popup = 'Some label'; | ||
}); | ||
})); | ||
case 4: | ||
_context10.next = 6; | ||
return browser.executeScript(function () { | ||
return regeneratorRuntime.awrap(browser.executeScript(function () { | ||
return document.querySelector('core-toggle').value = 'Button text'; | ||
}); | ||
})); | ||
case 6: | ||
_context10.next = 8; | ||
return prop('core-toggle', 'value'); | ||
return regeneratorRuntime.awrap(prop('core-toggle', 'value')); | ||
@@ -506,7 +430,7 @@ case 8: | ||
_context10.next = 11; | ||
return expect(prop('button', 'textContent')).toEqual(toggleValue); | ||
return regeneratorRuntime.awrap(expect(prop('button', 'textContent')).toEqual(toggleValue)); | ||
case 11: | ||
_context10.next = 13; | ||
return expect(attr('button', 'aria-label')).toEqual('Button text,Some label'); | ||
return regeneratorRuntime.awrap(expect(attr('button', 'aria-label')).toEqual('Button text,Some label')); | ||
@@ -518,11 +442,7 @@ case 13: | ||
} | ||
}, _callee10); | ||
}))); | ||
it('triggers toggle event', | ||
/*#__PURE__*/ | ||
_asyncToGenerator( | ||
/*#__PURE__*/ | ||
regeneratorRuntime.mark(function _callee11() { | ||
}); | ||
}); | ||
it('triggers toggle event', function _callee11() { | ||
var triggered; | ||
return regeneratorRuntime.wrap(function _callee11$(_context11) { | ||
return regeneratorRuntime.async(function _callee11$(_context11) { | ||
while (1) { | ||
@@ -532,3 +452,3 @@ switch (_context11.prev = _context11.next) { | ||
_context11.next = 2; | ||
return browser.executeScript(function () { | ||
return regeneratorRuntime.awrap(browser.executeScript(function () { | ||
document.body.innerHTML = "\n <button>Toggle</button>\n <core-toggle hidden></core-toggle>\n "; | ||
@@ -539,9 +459,9 @@ document.addEventListener('toggle', function () { | ||
document.querySelector('core-toggle').hidden = false; | ||
}); | ||
})); | ||
case 2: | ||
_context11.next = 4; | ||
return browser.executeScript(function () { | ||
return regeneratorRuntime.awrap(browser.executeScript(function () { | ||
return window.triggered; | ||
}); | ||
})); | ||
@@ -551,3 +471,3 @@ case 4: | ||
_context11.next = 7; | ||
return expect(triggered).toEqual(true); | ||
return regeneratorRuntime.awrap(expect(triggered).toEqual(true)); | ||
@@ -559,11 +479,7 @@ case 7: | ||
} | ||
}, _callee11); | ||
}))); | ||
it('triggers select event', | ||
/*#__PURE__*/ | ||
_asyncToGenerator( | ||
/*#__PURE__*/ | ||
regeneratorRuntime.mark(function _callee12() { | ||
}); | ||
}); | ||
it('triggers select event', function _callee12() { | ||
var itemId; | ||
return regeneratorRuntime.wrap(function _callee12$(_context12) { | ||
return regeneratorRuntime.async(function _callee12$(_context12) { | ||
while (1) { | ||
@@ -573,9 +489,9 @@ switch (_context12.prev = _context12.next) { | ||
_context12.next = 2; | ||
return browser.executeScript(function () { | ||
return regeneratorRuntime.awrap(browser.executeScript(function () { | ||
document.body.innerHTML = "\n <button>Toggle</button>\n <core-toggle hidden>\n <button id=\"my-item\">Select me</button>\n </core-toggle>\n "; | ||
}); | ||
})); | ||
case 2: | ||
_context12.next = 4; | ||
return browser.executeScript(function () { | ||
return regeneratorRuntime.awrap(browser.executeScript(function () { | ||
document.addEventListener('toggle.select', function (event) { | ||
@@ -587,11 +503,11 @@ return window.itemId = event.detail.id; | ||
toggle.children[0].click(); | ||
}); | ||
})); | ||
case 4: | ||
_context12.next = 6; | ||
return browser.wait(function () { | ||
return regeneratorRuntime.awrap(browser.wait(function () { | ||
return browser.executeScript(function () { | ||
return window.itemId; | ||
}); | ||
}); | ||
})); | ||
@@ -601,3 +517,3 @@ case 6: | ||
_context12.next = 9; | ||
return expect(itemId).toEqual('my-item'); | ||
return regeneratorRuntime.awrap(expect(itemId).toEqual('my-item')); | ||
@@ -609,4 +525,4 @@ case 9: | ||
} | ||
}, _callee12); | ||
}))); | ||
}); | ||
}); | ||
}); |
86
jsx.js
@@ -366,8 +366,8 @@ 'use strict'; | ||
var version = "3.0.6"; | ||
var version = "3.0.7"; | ||
/** | ||
* closest | ||
* @param {Element} element Element to traverse up from | ||
* @param {String} selector A selector to search for matching parents or element itself | ||
* @param {Element} el Element to traverse up from | ||
* @param {String} css A selector to search for matching parents or element itself | ||
* @return {Element|null} Element which is the closest ancestor matching selector | ||
@@ -393,4 +393,4 @@ */ | ||
* customElementToReact | ||
* @param {Class|Function} elem A custom element definition. | ||
* @param {Array} attr Props and events | ||
* @param {Class|Function} elementClass A custom element definition. | ||
* @param {Array} options Props and custom events | ||
* @return {Object} A React component | ||
@@ -412,4 +412,12 @@ */ | ||
var customEvents = options.customEvents || []; | ||
var skipProps = customProps.concat('forwardRef'); // Keep a copy with forwardRef added | ||
var eventMap = customEvents.reduce(function (map, eventName) { | ||
map[eventName] = "on" + eventName.replace(/(^|\.)./g, function (m) { | ||
return m.slice(-1).toUpperCase(); | ||
}); // input.filter => onInputFilter | ||
return map; | ||
}, {}); | ||
var skipProps = customProps.concat('forwardRef', Object.keys(eventMap).map(function (onEventName) { | ||
return eventMap[onEventName]; | ||
})); | ||
var tagName = (dashCase + "-" + (options.suffix || 'react')).replace(/\W+/g, '-').toLowerCase(); | ||
@@ -421,6 +429,5 @@ return ( | ||
var this$1 = this; | ||
superclass.call(this, props); | ||
superclass.call(this, props); // Register ref prop for accessing custom element https://reactjs.org/docs/refs-and-the-dom.html#callback-refs | ||
this.ref = function (el) { | ||
// Support callback ref https://reactjs.org/docs/refs-and-the-dom.html#callback-refs | ||
if (typeof this$1.props.forwardRef === 'function') { | ||
@@ -433,14 +440,13 @@ this$1.props.forwardRef(el); | ||
return this$1.el = el; | ||
}; | ||
}; // Register event handler on component for each custom event | ||
customEvents.forEach(function (eventName) { | ||
var on = "on" + eventName.replace(/(^|\.)./g, function (m) { | ||
return m.slice(-1).toUpperCase(); | ||
}); // input.filter => onInputFilter | ||
Object.keys(eventMap).forEach(function (eventName) { | ||
var onEventName = eventMap[eventName]; | ||
this$1[eventName] = function (event) { | ||
return this$1.props[on] && closest$1(event.target, this$1.el.nodeName) === this$1.el && this$1.props[on](event); | ||
if (this$1.props[onEventName] && closest$1(event.target, this$1.el.nodeName) === this$1.el) { | ||
this$1.props[onEventName](event); | ||
} | ||
}; | ||
skipProps.push(on); // Skip props that are customEvents | ||
}); | ||
@@ -454,20 +460,27 @@ } | ||
anonymous.prototype.componentDidMount = function componentDidMount() { | ||
var this$1 = this; // Do not run connectedCallback before after React componentDidMount, to allow React hydration to run first | ||
var this$1 = this; // Run connectedCallback() after React componentDidMount() to allow React hydration to run first | ||
if (!window.customElements.get(tagName)) { | ||
window.customElements.define(tagName, elementClass); | ||
} | ||
} // Populate properties on custom element | ||
customProps.forEach(function (key) { | ||
return key in this$1.props && (this$1.el[key] = this$1.props[key]); | ||
customProps.forEach(function (propName) { | ||
if (propName in this$1.props) { | ||
this$1.el[propName] = this$1.props[propName]; | ||
} | ||
}); // Register events on custom element | ||
customEvents.forEach(function (eventName) { | ||
this$1.el.addEventListener(eventName, this$1[eventName]); | ||
}); | ||
customEvents.forEach(function (key) { | ||
return this$1.el.addEventListener(key, this$1[key]); | ||
}); | ||
}; | ||
anonymous.prototype.componentDidUpdate = function componentDidUpdate(prev) { | ||
var this$1 = this; | ||
customProps.forEach(function (key) { | ||
return prev[key] !== this$1.props[key] && (this$1.el[key] = this$1.props[key]); | ||
var this$1 = this; // Sync prop changes to custom element | ||
customProps.forEach(function (propName) { | ||
if (prev[propName] !== this$1.props[propName]) { | ||
this$1.el[propName] = this$1.props[propName]; | ||
} | ||
}); | ||
@@ -477,5 +490,6 @@ }; | ||
anonymous.prototype.componentWillUnmount = function componentWillUnmount() { | ||
var this$1 = this; | ||
var this$1 = this; // Remove event handlers on custom element on unmount | ||
customEvents.forEach(function (eventName) { | ||
return this$1.el.removeEventListener(eventName, this$1[eventName]); | ||
this$1.el.removeEventListener(eventName, this$1[eventName]); | ||
}); | ||
@@ -487,13 +501,13 @@ }; | ||
return React.createElement(tagName, Object.keys(this.props).reduce(function (thisProps, key) { | ||
if (skipProps.indexOf(key) === -1) { | ||
return React.createElement(tagName, Object.keys(this.props).reduce(function (thisProps, propName) { | ||
if (skipProps.indexOf(propName) === -1) { | ||
// Do not render customEvents and custom props as attributes | ||
if (key === 'className') { | ||
thisProps["class"] = this$1.props[key]; | ||
if (propName === 'className') { | ||
thisProps["class"] = this$1.props[propName]; | ||
} // Fixes className for custom elements | ||
else if (this$1.props[key] === true) { | ||
thisProps[key] = ''; | ||
else if (this$1.props[propName] === true) { | ||
thisProps[propName] = ''; | ||
} // Fixes boolean attributes | ||
else if (this$1.props[key] !== false) { | ||
thisProps[key] = this$1.props[key]; | ||
else if (this$1.props[propName] !== false) { | ||
thisProps[propName] = this$1.props[propName]; | ||
} // Pass only truthy, non-function props | ||
@@ -500,0 +514,0 @@ |
@@ -5,3 +5,3 @@ { | ||
"author": "NRK <opensource@nrk.no> (https://www.nrk.no/)", | ||
"version": "3.0.6", | ||
"version": "3.0.7", | ||
"license": "MIT", | ||
@@ -8,0 +8,0 @@ "main": "core-toggle.cjs.js", |
@@ -120,2 +120,4 @@ # Core Toggle | ||
popup={Boolean|String} // Optional. Defaults to false. Enable or disable if clicking outside toggle should close it. Provide a string to control the aria-label text on the toggle | ||
ref={(comp) => {}} // Optional. Get reference to React component | ||
forwardRef={(el) => {}} // Optional. Get reference to underlying DOM custom element | ||
onToggle={Function} // Optional. Toggle event listener. See event 'toggle' | ||
@@ -122,0 +124,0 @@ onToggleSelect={Function}> // Optional. Toggle select event listener. See event 'toggle.select' |
Sorry, the diff of this file is not supported yet
136708
281
1867