diff --git a/package.json b/package.json
index fcdc7617a..50ebd71a2 100644
--- a/package.json
+++ b/package.json
@@ -48,6 +48,7 @@
"types": "src/types/shepherd.d.ts",
"module": "dist/js/shepherd.esm.js",
"dependencies": {
+ "auto-bind": "^2.1.0",
"body-scroll-lock": "^2.6.3",
"core-js": "^3.1.4",
"element-matches": "^0.1.2",
diff --git a/src/js/step.js b/src/js/step.js
index 9ba051b8e..e9a639831 100644
--- a/src/js/step.js
+++ b/src/js/step.js
@@ -1,6 +1,8 @@
-import { isElement, isFunction, isUndefined } from './utils/type-check';
+import autoBind from 'auto-bind';
+
import { Evented } from './evented.js';
-import { bindAdvance, bindButtonEvents, bindCancelLink, bindMethods } from './utils/bind.js';
+import { isElement, isFunction, isUndefined } from './utils/type-check';
+import { bindAdvance, bindButtonEvents, bindCancelLink } from './utils/bind.js';
import { createFromHTML, setupTooltip, parseAttachTo } from './utils/general.js';
// Polyfills
@@ -106,23 +108,10 @@ export class Step extends Evented {
constructor(tour, options) {
super(tour, options);
this.tour = tour;
- bindMethods.call(this, [
- '_scrollTo',
- '_setupElements',
- '_show',
- 'cancel',
- 'complete',
- 'destroy',
- 'hide',
- 'isOpen',
- 'show'
- ]);
+
+ autoBind(this);
+
this._setOptions(options);
- this.bindAdvance = bindAdvance.bind(this);
- this.bindButtonEvents = bindButtonEvents.bind(this);
- this.bindCancelLink = bindCancelLink.bind(this);
- this.setupTooltip = setupTooltip.bind(this);
- this.parseAttachTo = parseAttachTo.bind(this);
return this;
}
@@ -239,7 +228,7 @@ export class Step extends Evented {
``
);
footer.appendChild(button);
- this.bindButtonEvents(cfg, button);
+ bindButtonEvents(cfg, button, this);
});
content.appendChild(footer);
@@ -258,7 +247,7 @@ export class Step extends Evented {
header.appendChild(link);
element.classList.add('shepherd-has-cancel-link');
- this.bindCancelLink(link);
+ bindCancelLink(link, this);
}
}
@@ -396,7 +385,7 @@ export class Step extends Evented {
* @private
*/
_scrollTo(scrollToOptions) {
- const { element } = this.parseAttachTo();
+ const { element } = parseAttachTo(this);
if (isFunction(this.options.scrollToHandler)) {
this.options.scrollToHandler(element);
@@ -438,10 +427,10 @@ export class Step extends Evented {
this._addKeyDownHandler(this.el);
if (this.options.advanceOn) {
- this.bindAdvance();
+ bindAdvance(this);
}
- this.setupTooltip();
+ setupTooltip(this);
}
/**
diff --git a/src/js/tour.js b/src/js/tour.js
index d0fe437ce..79ed85259 100644
--- a/src/js/tour.js
+++ b/src/js/tour.js
@@ -1,12 +1,12 @@
-import { isFunction, isNumber, isString, isUndefined } from './utils/type-check';
+import autoBind from 'auto-bind';
+import { disableBodyScroll, clearAllBodyScrollLocks } from 'body-scroll-lock/lib/bodyScrollLock.es6.js';
+import tippy from 'tippy.js';
+
import { Evented } from './evented.js';
import { Modal } from './modal.js';
import { Step } from './step.js';
-import { bindMethods } from './utils/bind.js';
-import tippy from 'tippy.js';
-import { disableBodyScroll, clearAllBodyScrollLocks } from 'body-scroll-lock/lib/bodyScrollLock.es6.js';
+import { isFunction, isNumber, isString, isUndefined } from './utils/type-check';
import { defaults as tooltipDefaults } from './utils/tooltip-defaults';
-
import { cleanupSteps, cleanupStepEventListeners } from './utils/cleanup';
import { getElementForStep } from './utils/dom';
import { toggleShepherdModalClass } from './utils/modal';
@@ -47,13 +47,9 @@ export class Tour extends Evented {
*/
constructor(options = {}) {
super(options);
- bindMethods.call(this, [
- 'back',
- 'cancel',
- 'complete',
- 'hide',
- 'next'
- ]);
+
+ autoBind(this);
+
this.options = options;
this.steps = this.options.steps || [];
diff --git a/src/js/utils/bind.js b/src/js/utils/bind.js
index 545563980..00a74c2a9 100644
--- a/src/js/utils/bind.js
+++ b/src/js/utils/bind.js
@@ -2,18 +2,19 @@ import { isString, isUndefined } from './type-check';
/**
* Sets up the handler to determine if we should advance the tour
- * @param selector
+ * @param {string} selector
+ * @param {Step} step The step instance
* @return {Function}
* @private
*/
-function _setupAdvanceOnHandler(selector) {
+function _setupAdvanceOnHandler(selector, step) {
return (event) => {
- if (this.isOpen()) {
- const targetIsEl = this.el && event.target === this.el;
+ if (step.isOpen()) {
+ const targetIsEl = step.el && event.target === step.el;
const targetIsSelector = !isUndefined(selector) && event.target.matches(selector);
if (targetIsSelector || targetIsEl) {
- this.tour.next();
+ step.tour.next();
}
}
};
@@ -21,12 +22,13 @@ function _setupAdvanceOnHandler(selector) {
/**
* Bind the event handler for advanceOn
+ * @param {Step} step The step instance
*/
-export function bindAdvance() {
+export function bindAdvance(step) {
// An empty selector matches the step element
- const { event, selector } = this.options.advanceOn || {};
+ const { event, selector } = step.options.advanceOn || {};
if (event) {
- const handler = _setupAdvanceOnHandler.call(this, selector);
+ const handler = _setupAdvanceOnHandler(selector, step);
// TODO: this should also bind/unbind on show/hide
let el;
@@ -39,12 +41,12 @@ export function bindAdvance() {
return console.error(`No element was found for the selector supplied to advanceOn: ${selector}`);
} else if (el) {
el.addEventListener(event, handler);
- this.on('destroy', () => {
+ step.on('destroy', () => {
return el.removeEventListener(event, handler);
});
} else {
document.body.addEventListener(event, handler, true);
- this.on('destroy', () => {
+ step.on('destroy', () => {
return document.body.removeEventListener(event, handler, true);
});
}
@@ -57,8 +59,9 @@ export function bindAdvance() {
* Bind events to the buttons for next, back, etc
* @param {Object} cfg An object containing the config options for the button
* @param {HTMLElement} el The element for the button
+ * @param {Step} step The step instance
*/
-export function bindButtonEvents(cfg, el) {
+export function bindButtonEvents(cfg, el, step) {
cfg.events = cfg.events || {};
if (!isUndefined(cfg.action)) {
// Including both a click event and an action is not supported
@@ -69,13 +72,13 @@ export function bindButtonEvents(cfg, el) {
Object.entries(cfg.events).forEach(([event, handler]) => {
if (isString(handler)) {
const page = handler;
- handler = () => this.tour.show(page);
+ handler = () => step.tour.show(page);
}
el.dataset.buttonEvent = true;
el.addEventListener(event, handler);
// Cleanup event listeners on destroy
- this.on('destroy', () => {
+ step.on('destroy', () => {
el.removeAttribute('data-button-event');
el.removeEventListener(event, handler);
});
@@ -86,11 +89,12 @@ export function bindButtonEvents(cfg, el) {
/**
* Add a click listener to the cancel link that cancels the tour
* @param {HTMLElement} link The cancel link element
+ * @param {Step} step The step instance
*/
-export function bindCancelLink(link) {
+export function bindCancelLink(link, step) {
link.addEventListener('click', (e) => {
e.preventDefault();
- this.cancel();
+ step.cancel();
});
}
diff --git a/src/js/utils/general.js b/src/js/utils/general.js
index 69ac31179..0ea6ba23c 100644
--- a/src/js/utils/general.js
+++ b/src/js/utils/general.js
@@ -73,34 +73,36 @@ export function debounce(func, wait, immediate) {
/**
* Determines options for the tooltip and initializes
- * `this.tooltip` as a Tippy.js instance.
+ * `step.tooltip` as a Tippy.js instance.
+ * @param {Step} step The step instance
*/
-export function setupTooltip() {
+export function setupTooltip(step) {
if (isUndefined(tippy)) {
throw new Error(missingTippy);
}
- if (this.tooltip) {
- this.tooltip.destroy();
+ if (step.tooltip) {
+ step.tooltip.destroy();
}
- const attachToOpts = this.parseAttachTo();
+ const attachToOpts = parseAttachTo(step);
- this.tooltip = _makeTippyInstance.call(this, attachToOpts);
+ step.tooltip = _makeTippyInstance(attachToOpts, step);
- this.target = attachToOpts.element || document.body;
+ step.target = attachToOpts.element || document.body;
- this.el.classList.add('shepherd-element');
+ step.el.classList.add('shepherd-element');
}
/**
* Checks if options.attachTo.element is a string, and if so, tries to find the element
+ * @param {Step} step The step instance
* @returns {{element, on}}
* `element` is a qualified HTML Element
* `on` is a string position value
*/
-export function parseAttachTo() {
- const options = this.options.attachTo || {};
+export function parseAttachTo(step) {
+ const options = step.options.attachTo || {};
const returnOpts = Object.assign({}, options);
if (isString(options.element)) {
@@ -137,16 +139,17 @@ function _createClassModifier(className) {
/**
* Generates a `Tippy` instance from a set of base `attachTo` options
- *
- * @return {tippy} The final tippy instance
+ * @param attachToOptions
+ * @param {Step} step The step instance
+ * @return {tippy|Instance | Instance[]} The final tippy instance
* @private
*/
-function _makeTippyInstance(attachToOptions) {
+function _makeTippyInstance(attachToOptions, step) {
if (!attachToOptions.element) {
- return _makeCenteredTippy.call(this);
+ return _makeCenteredTippy(step);
}
- const tippyOptions = _makeAttachedTippyOptions.call(this, attachToOptions);
+ const tippyOptions = _makeAttachedTippyOptions(attachToOptions, step);
return tippy(attachToOptions.element, tippyOptions);
}
@@ -156,24 +159,25 @@ function _makeTippyInstance(attachToOptions) {
* target an element in the DOM.
*
* @param {Object} attachToOptions The local `attachTo` options
+ * @param {Step} step The step instance
* @return {Object} The final tippy options object
* @private
*/
-function _makeAttachedTippyOptions(attachToOptions) {
+function _makeAttachedTippyOptions(attachToOptions, step) {
const resultingTippyOptions = {
- content: this.el,
+ content: step.el,
flipOnUpdate: true,
placement: attachToOptions.on || 'right'
};
- Object.assign(resultingTippyOptions, this.options.tippyOptions);
+ Object.assign(resultingTippyOptions, step.options.tippyOptions);
- if (this.options.title) {
+ if (step.options.title) {
Object.assign(defaultPopperOptions.modifiers, { addHasTitleClass });
}
- if (this.options.tippyOptions && this.options.tippyOptions.popperOptions) {
- Object.assign(defaultPopperOptions, this.options.tippyOptions.popperOptions);
+ if (step.options.tippyOptions && step.options.tippyOptions.popperOptions) {
+ Object.assign(defaultPopperOptions, step.options.tippyOptions.popperOptions);
}
resultingTippyOptions.popperOptions = defaultPopperOptions;
@@ -186,20 +190,21 @@ function _makeAttachedTippyOptions(attachToOptions) {
* target element in the DOM -- and thus is positioned in the center
* of the view
*
+ * @param {Step} step The step instance
* @return {tippy} The final tippy instance
* @private
*/
-function _makeCenteredTippy() {
+function _makeCenteredTippy(step) {
const tippyOptions = {
- content: this.el,
+ content: step.el,
placement: 'top',
- ...this.options.tippyOptions
+ ...step.options.tippyOptions
};
tippyOptions.arrow = false;
tippyOptions.popperOptions = tippyOptions.popperOptions || {};
- if (this.options.title) {
+ if (step.options.title) {
Object.assign(defaultPopperOptions.modifiers, { addHasTitleClass });
}
diff --git a/test/unit/step.spec.js b/test/unit/step.spec.js
index ce6473bd8..0e5539e38 100644
--- a/test/unit/step.spec.js
+++ b/test/unit/step.spec.js
@@ -132,164 +132,6 @@ describe('Tour | Step', () => {
});
});
- describe('bindAdvance()', () => {
- let event;
- let link;
- let hasAdvanced = false;
-
- const advanceOnSelector = 'test-selector';
- const advanceOnEventName = 'test-event';
- const tourProto = {
- next() { hasAdvanced = true; }
- };
-
- beforeEach(() => {
- event = new Event(advanceOnEventName);
-
- link = document.createElement('a');
- link.classList.add(advanceOnSelector);
- link.textContent = 'Click Me 👋';
-
- document.body.appendChild(link);
- });
-
- afterEach(() => {
- link.remove();
- });
-
- it('triggers the `advanceOn` option via object', () => {
- const step = new Step(tourProto, {
- advanceOn: { selector: `.${advanceOnSelector}`, event: advanceOnEventName }
- });
-
- step.isOpen = () => true;
-
- step.bindAdvance();
- link.dispatchEvent(event);
-
- expect(link.classList.contains(advanceOnSelector)).toBe(true);
- expect(hasAdvanced, '`next()` triggered for advanceOn').toBe(true);
- });
-
- it('captures events attached to no element', () => {
- const step = new Step(tourProto, {
- advanceOn: { event: advanceOnEventName }
- });
-
- step.isOpen = () => true;
-
- step.bindAdvance();
- document.body.dispatchEvent(event);
-
- expect(hasAdvanced, '`next()` triggered for advanceOn').toBeTruthy();
- });
-
- it('should support bubbling events for nodes that do not exist yet', () => {
- const event = new Event('blur');
-
- const step = new Step(tourProto, {
- text: 'Lorem ipsum dolor: sit amet',
- advanceOn: {
- selector: 'a[href="https://example.com"]',
- event: 'blur'
- }
- });
-
- step.isOpen = () => true;
-
- step.bindAdvance();
- document.body.dispatchEvent(event);
-
- expect(hasAdvanced, '`next()` triggered for advanceOn').toBeTruthy();
- });
-
- it('calls `removeEventListener` when destroyed', function(done) {
- const bodySpy = spy(document.body, 'removeEventListener');
- const step = new Step(tourProto, {
- advanceOn: { event: advanceOnEventName }
- });
-
- step.isOpen = () => true;
-
- step.bindAdvance();
- step.trigger('destroy');
-
- expect(bodySpy.called).toBe(true);
- bodySpy.restore();
-
- done();
- });
- });
-
- describe('bindButtonEvents()', () => {
- const link = document.createElement('a');
- const step = new Step(new Tour(), {});
- it('adds button events', () => {
- const event = new Event('test');
- const hover = new Event('mouseover');
- let eventTriggered = false;
-
- step.bindButtonEvents({
- events: {
- 'mouseover': '1',
- test: () => eventTriggered = true
- },
- text: 'Next',
- action: () => {}
- }, link);
-
- link.dispatchEvent(event);
- link.dispatchEvent(hover);
- expect(eventTriggered, 'custom button event was bound/triggered').toBeTruthy();
- });
-
- it('removes events once destroyed', () => {
- step.destroy();
-
- expect(link.hasAttribute('data-button-event'), 'attribute to confirm event is removed').toBeFalsy();
- });
-
- });
-
- describe('bindCancelLink()', () => {
- it('adds an event handler for the cancel button', () => {
- const event = new MouseEvent('click', {
- view: window,
- bubbles: true,
- cancelable: true
- });
- const link = document.createElement('a');
- const step = new Step();
- let cancelCalled = false;
-
- step.cancel = () => cancelCalled = true;
- step.bindCancelLink(link);
-
- link.dispatchEvent(event);
- expect(cancelCalled, 'cancel method was called from bound click event').toBeTruthy();
- });
- });
-
- describe('bindMethods()', () => {
- it('binds the expected methods', () => {
- const step = new Step();
- const methods = [
- '_scrollTo',
- '_setupElements',
- '_show',
- 'cancel',
- 'complete',
- 'destroy',
- 'hide',
- 'isOpen',
- 'show'
- ];
- methods.forEach((method) => {
- expect(step[method], `${method} has been bound`).toBeTruthy();
- });
- });
- });
-
describe('cancel()', () => {
it('triggers the cancel event and tour method', () => {
let cancelCalled = false;
@@ -358,17 +200,6 @@ describe('Tour | Step', () => {
});
});
- describe('parseAttachTo()', function() {
- it('fails if element does not exist', function() {
- const step = new Step({}, {
- attachTo: { element: '.scroll-test', on: 'center' }
- });
-
- const { element } = step.parseAttachTo();
- expect(element).toBeFalsy();
- });
- });
-
describe('_setupElements()', () => {
it('calls destroy on the step if the content element is already set', () => {
const step = new Step();
@@ -388,18 +219,6 @@ describe('Tour | Step', () => {
step._setupElements();
expect(destroyCalled, '_setupElements method called destroy on the existing tooltip').toBe(true);
});
-
- it('calls bindAdvance() if advanceOn passed', () => {
- const step = new Step({
- next: () => true
- }, {
- advanceOn: { selector: '.click-test', event: 'test' }
- });
- const bindFunction = spy(step, 'bindAdvance');
- step._setupElements();
-
- expect(bindFunction.called).toBeTruthy();
- });
});
describe('_scrollTo()', () => {
@@ -581,13 +400,9 @@ describe('Tour | Step', () => {
const element = document.createElement('div');
const step = new Step(null, { showCancelLink: true });
- const cancelLinkStub = stub(step, 'bindCancelLink');
-
step._addCancelLink(element, header);
- expect(cancelLinkStub.called).toBe(true);
expect(element).toHaveClass('shepherd-has-cancel-link');
- cancelLinkStub.restore();
});
});
diff --git a/test/unit/utils/bind.spec.js b/test/unit/utils/bind.spec.js
new file mode 100644
index 000000000..c72a8528e
--- /dev/null
+++ b/test/unit/utils/bind.spec.js
@@ -0,0 +1,144 @@
+import { bindAdvance, bindButtonEvents, bindCancelLink } from '../../../src/js/utils/bind.js';
+import { Step } from '../../../src/js/step';
+import { spy } from 'sinon';
+import { Tour } from '../../../src/js/tour';
+
+describe('Bind Utils', function() {
+ describe('bindAdvance()', () => {
+ let event;
+ let link;
+ let hasAdvanced = false;
+
+ const advanceOnSelector = 'test-selector';
+ const advanceOnEventName = 'test-event';
+ const tourProto = {
+ next() { hasAdvanced = true; }
+ };
+
+ beforeEach(() => {
+ event = new Event(advanceOnEventName);
+
+ link = document.createElement('a');
+ link.classList.add(advanceOnSelector);
+ link.textContent = 'Click Me 👋';
+
+ document.body.appendChild(link);
+ });
+
+ afterEach(() => {
+ link.remove();
+ });
+
+ it('triggers the `advanceOn` option via object', () => {
+ const step = new Step(tourProto, {
+ advanceOn: { selector: `.${advanceOnSelector}`, event: advanceOnEventName }
+ });
+
+ step.isOpen = () => true;
+
+ bindAdvance(step);
+ link.dispatchEvent(event);
+
+ expect(link.classList.contains(advanceOnSelector)).toBe(true);
+ expect(hasAdvanced, '`next()` triggered for advanceOn').toBe(true);
+ });
+
+ it('captures events attached to no element', () => {
+ const step = new Step(tourProto, {
+ advanceOn: { event: advanceOnEventName }
+ });
+
+ step.isOpen = () => true;
+
+ bindAdvance(step);
+ document.body.dispatchEvent(event);
+
+ expect(hasAdvanced, '`next()` triggered for advanceOn').toBeTruthy();
+ });
+
+ it('should support bubbling events for nodes that do not exist yet', () => {
+ const event = new Event('blur');
+
+ const step = new Step(tourProto, {
+ text: 'Lorem ipsum dolor: sit amet',
+ advanceOn: {
+ selector: 'a[href="https://example.com"]',
+ event: 'blur'
+ }
+ });
+
+ step.isOpen = () => true;
+
+ bindAdvance(step);
+ document.body.dispatchEvent(event);
+
+ expect(hasAdvanced, '`next()` triggered for advanceOn').toBeTruthy();
+ });
+
+ it('calls `removeEventListener` when destroyed', function(done) {
+ const bodySpy = spy(document.body, 'removeEventListener');
+ const step = new Step(tourProto, {
+ advanceOn: { event: advanceOnEventName }
+ });
+
+ step.isOpen = () => true;
+
+ bindAdvance(step);
+ step.trigger('destroy');
+
+ expect(bodySpy.called).toBe(true);
+ bodySpy.restore();
+
+ done();
+ });
+ });
+
+ describe('bindButtonEvents()', () => {
+ const link = document.createElement('a');
+ const step = new Step(new Tour(), {});
+ it('adds button events', () => {
+ const event = new Event('test');
+ const hover = new Event('mouseover');
+ let eventTriggered = false;
+
+ bindButtonEvents({
+ events: {
+ 'mouseover': '1',
+ test: () => eventTriggered = true
+ },
+ text: 'Next',
+ action: () => {}
+ }, link, step);
+
+ link.dispatchEvent(event);
+ link.dispatchEvent(hover);
+ expect(eventTriggered, 'custom button event was bound/triggered').toBeTruthy();
+ });
+
+ it('removes events once destroyed', () => {
+ step.destroy();
+
+ expect(link.hasAttribute('data-button-event'), 'attribute to confirm event is removed').toBeFalsy();
+ });
+
+ });
+
+ describe('bindCancelLink()', () => {
+ it('adds an event handler for the cancel button', () => {
+ const event = new MouseEvent('click', {
+ view: window,
+ bubbles: true,
+ cancelable: true
+ });
+ const link = document.createElement('a');
+ const step = new Step();
+ let cancelCalled = false;
+
+ step.cancel = () => cancelCalled = true;
+ bindCancelLink(link, step);
+
+ link.dispatchEvent(event);
+ expect(cancelCalled, 'cancel method was called from bound click event').toBeTruthy();
+ });
+ });
+});
diff --git a/test/unit/utils/general.spec.js b/test/unit/utils/general.spec.js
new file mode 100644
index 000000000..1faccbc73
--- /dev/null
+++ b/test/unit/utils/general.spec.js
@@ -0,0 +1,16 @@
+import { Step } from '../../../src/js/step';
+import { parseAttachTo } from '../../../src/js/utils/general';
+
+
+describe('General Utils', function() {
+ describe('parseAttachTo()', function() {
+ it('fails if element does not exist', function() {
+ const step = new Step({}, {
+ attachTo: { element: '.scroll-test', on: 'center' }
+ });
+
+ const { element } = parseAttachTo(step);
+ expect(element).toBeFalsy();
+ });
+ });
+});
diff --git a/yarn.lock b/yarn.lock
index da6001b8c..d084182c0 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1062,11 +1062,24 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.2.tgz#a5ccec6abb6060d5f20d256fb03ed743e9774999"
integrity sha512-gojym4tX0FWeV2gsW4Xmzo5wxGjXGm550oVUII7f7G5o4BV6c7DBdiG1RRQd+y1bvqRyYtPfMK85UM95vsapqQ==
+"@types/prop-types@*":
+ version "15.7.1"
+ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.1.tgz#f1a11e7babb0c3cad68100be381d1e064c68f1f6"
+ integrity sha512-CFzn9idOEpHrgdw8JsoTkaDDyRWk1jrzIV8djzcgpq0y9tG4B4lFT+Nxh52DVpDXV+n4+NPNv7M1Dj5uMp6XFg==
+
"@types/q@^1.5.1":
version "1.5.2"
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8"
integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==
+"@types/react@^16.8.12":
+ version "16.8.23"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-16.8.23.tgz#ec6be3ceed6353a20948169b6cb4c97b65b97ad2"
+ integrity sha512-abkEOIeljniUN9qB5onp++g0EY38h7atnDHxwKUFz1r3VH1+yG1OKi2sNPTyObL40goBmfKFpdii2lEzwLX1cA==
+ dependencies:
+ "@types/prop-types" "*"
+ csstype "^2.2.0"
+
"@types/resolve@0.0.8":
version "0.0.8"
resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194"
@@ -1388,6 +1401,13 @@ atob@^2.1.1:
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
+auto-bind@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/auto-bind/-/auto-bind-2.1.0.tgz#254e12d53063d7cab90446ce021accfb3faa1464"
+ integrity sha512-qZuFvkes1eh9lB2mg8/HG18C+5GIO51r+RrCSst/lh+i5B1CtVlkhTE488M805Nr3dKl0sM/pIFKSKUIlg3zUg==
+ dependencies:
+ "@types/react" "^16.8.12"
+
autoprefixer@^9.5.1, autoprefixer@^9.6.1:
version "9.6.1"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.6.1.tgz#51967a02d2d2300bb01866c1611ec8348d355a47"
@@ -2614,6 +2634,11 @@ cssstyle@^1.0.0:
dependencies:
cssom "~0.3.6"
+csstype@^2.2.0:
+ version "2.6.6"
+ resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.6.tgz#c34f8226a94bbb10c32cc0d714afdf942291fc41"
+ integrity sha512-RpFbQGUE74iyPgvr46U9t1xoQBM8T4BL8SxrN66Le2xYAPSaDJJKeztV3awugusb3g3G9iL8StmkBBXhcbbXhg==
+
currently-unhandled@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea"