@cfpb/cfpb-atomic-component
Advanced tools
Comparing version 0.20.1 to 0.21.0
{ | ||
"name": "@cfpb/cfpb-atomic-component", | ||
"version": "0.20.1", | ||
"description": "Design System atomic component micro-framework", | ||
"version": "0.21.0", | ||
"description": "Design System atomic component utilities", | ||
"less": "src/cfpb-atomic-component.less", | ||
@@ -16,4 +16,4 @@ "style": "cfpb-atomic-component.css", | ||
], | ||
"gitHead": "32bd5d9b20a025e8bdbb0083106f31eb06f85ea6", | ||
"gitHead": "905c9fa959cdf19f992fabfc0b3f5f64b315d67e", | ||
"type": "module" | ||
} |
# @cfpb/atomic-component [![Build Status](https://img.shields.io/travis/cfpb/design-system.svg)](https://travis-ci.org/cfpb/design-system) [![npm](https://img.shields.io/npm/v/@cfpb/atomic-component.svg?style=flat-square)](https://www.npmjs.com/package/@cfpb/atomic-component) | ||
Design System atomic component micro-framework | ||
Design System atomic component utilities | ||
@@ -5,0 +5,0 @@ This component can be used by itself, but it was made for Design System, |
@@ -74,13 +74,6 @@ /** | ||
/** | ||
* @returns {object} Map of registered events. | ||
*/ | ||
function getRegisteredEvents() { | ||
return _events; | ||
} | ||
this.addEventListener = addEventListener; | ||
this.removeEventListener = removeEventListener; | ||
this.dispatchEvent = dispatchEvent; | ||
this.getRegisteredEvents = getRegisteredEvents; | ||
this.getRegisteredEvents = () => _events; | ||
@@ -87,0 +80,0 @@ return this; |
@@ -5,7 +5,6 @@ /* eslint-disable no-use-before-define */ | ||
JS_HOOK, | ||
noopFunct, | ||
} from '@cfpb/cfpb-atomic-component/src/utilities/standard-type.js'; | ||
import BaseTransition from '@cfpb/cfpb-atomic-component/src/utilities/transition/BaseTransition.js'; | ||
import EventObserver from '@cfpb/cfpb-atomic-component/src/mixins/EventObserver.js'; | ||
import { checkBehaviorDom } from './behavior.js'; | ||
import { checkBehaviorDom } from '@cfpb/cfpb-atomic-component/src/utilities/behavior/behavior.js'; | ||
@@ -43,15 +42,14 @@ const BASE_CLASS = BEHAVIOR_PREFIX + 'flyout-menu'; | ||
let _isExpanded = false; | ||
let _isAnimating = false; | ||
// Flyouts appear in one of four states. | ||
let _state = 0; | ||
const COLLAPSED = 0; | ||
const COLLAPSING = 1; | ||
const EXPANDING = 2; | ||
const EXPANDED = 3; | ||
let _expandTransition; | ||
let _transition; | ||
let _expandTransitionMethod; | ||
let _expandTransitionMethodArgs = []; | ||
let _collapseTransition; | ||
let _collapseTransitionMethod; | ||
let _collapseTransitionMethodArgs = []; | ||
// Binded events. | ||
const _collapseBinded = collapse.bind(this); | ||
// Needed to add and remove events to transitions. | ||
@@ -67,7 +65,2 @@ const _collapseEndBinded = _collapseEnd.bind(this); | ||
/* Set this function to a queued collapse function, | ||
which is called if collapse is called while | ||
expand is animating. */ | ||
let _deferFunct = noopFunct; | ||
// Whether this instance's behaviors are suspended or not. | ||
@@ -128,27 +121,14 @@ let _suspended = true; | ||
function init(isExpanded = false) { | ||
const handleTriggerClickedBinded = _handleTriggerClicked.bind(this); | ||
const handleTriggerOverBinded = _handleTriggerOver.bind(this); | ||
const handleTriggerOutBinded = _handleTriggerOut.bind(this); | ||
_state = isExpanded ? EXPANDED : COLLAPSED; | ||
_triggerDoms.forEach((triggerDom) => { | ||
_setAriaAttr('expanded', triggerDom, isExpanded); | ||
let triggerDom; | ||
for (let i = 0, len = _triggerDoms.length; i < len; i++) { | ||
triggerDom = _triggerDoms[i]; | ||
// Set initial aria attributes to false. | ||
_isExpanded = isExpanded; | ||
if (isExpanded) { | ||
_setAriaAttr('expanded', triggerDom, 'true'); | ||
_setAriaAttr('expanded', _contentDom, 'true'); | ||
} else { | ||
_setAriaAttr('expanded', triggerDom, 'false'); | ||
_setAriaAttr('expanded', _contentDom, 'false'); | ||
} | ||
triggerDom.addEventListener('click', handleTriggerClickedBinded); | ||
triggerDom.addEventListener('click', _handleTriggerClicked.bind(this)); | ||
triggerDom.addEventListener('touchstart', _handleTouchStart, { | ||
passive: true, | ||
}); | ||
triggerDom.addEventListener('mouseover', handleTriggerOverBinded); | ||
triggerDom.addEventListener('mouseout', handleTriggerOutBinded); | ||
} | ||
triggerDom.addEventListener('mouseover', _handleTriggerOver.bind(this)); | ||
triggerDom.addEventListener('mouseout', _handleTriggerOut.bind(this)); | ||
}); | ||
_setAriaAttr('expanded', _contentDom, isExpanded); | ||
@@ -189,9 +169,12 @@ resume(); | ||
function _handleTriggerOver(event) { | ||
if (!_touchTriggered && !_suspended) { | ||
this.dispatchEvent('triggerOver', { | ||
if (_suspended) return; | ||
if (!_touchTriggered) { | ||
this.dispatchEvent('triggerover', { | ||
target: this, | ||
trigger: event.target, | ||
type: 'triggerOver', | ||
type: 'triggerover', | ||
}); | ||
} | ||
_touchTriggered = false; | ||
@@ -206,9 +189,9 @@ } | ||
function _handleTriggerOut(event) { | ||
if (!_suspended) { | ||
this.dispatchEvent('triggerOut', { | ||
target: this, | ||
trigger: event.target, | ||
type: 'triggerOut', | ||
}); | ||
} | ||
if (_suspended) return; | ||
this.dispatchEvent('triggerout', { | ||
target: this, | ||
trigger: event.target, | ||
type: 'triggerout', | ||
}); | ||
} | ||
@@ -223,14 +206,21 @@ | ||
function _handleTriggerClicked(event) { | ||
if (!_suspended) { | ||
this.dispatchEvent('triggerClick', { | ||
target: this, | ||
trigger: event.target, | ||
type: 'triggerClick', | ||
}); | ||
event.preventDefault(); | ||
if (_isExpanded) { | ||
if (_suspended) return; | ||
this.dispatchEvent('triggerclick', { | ||
target: this, | ||
trigger: event.target, | ||
type: 'triggerclick', | ||
}); | ||
event.preventDefault(); | ||
switch (_state) { | ||
case COLLAPSED: | ||
case COLLAPSING: | ||
this.expand(); | ||
break; | ||
case EXPANDING: | ||
case EXPANDED: | ||
this.collapse(); | ||
} else { | ||
this.expand(); | ||
} | ||
break; | ||
} | ||
@@ -245,29 +235,25 @@ } | ||
function expand() { | ||
if (!_isExpanded && !_isAnimating) { | ||
_isAnimating = true; | ||
_deferFunct = noopFunct; | ||
this.dispatchEvent('expandBegin', { target: this, type: 'expandBegin' }); | ||
_transition?.halt(); | ||
if (_state === EXPANDING || _state === EXPANDED) return this; | ||
// Only use transitions if both expand and collapse are set. | ||
if (_expandTransitionMethod && _collapseTransitionMethod) { | ||
const hasTransition = | ||
_expandTransition && _expandTransition.isAnimated(); | ||
if (hasTransition) { | ||
_expandTransition.addEventListener( | ||
BaseTransition.END_EVENT, | ||
_expandEndBinded | ||
); | ||
} | ||
_expandTransitionMethod.apply( | ||
_expandTransition, | ||
_expandTransitionMethodArgs | ||
); | ||
if (!hasTransition) { | ||
_expandEndBinded(); | ||
} | ||
} else { | ||
_expandEndBinded(); | ||
} | ||
_state = EXPANDING; | ||
this.dispatchEvent('expandbegin', { target: this, type: 'expandbegin' }); | ||
// Only use transitions if both expand and collapse are set. | ||
if (!_expandTransitionMethod || !_collapseTransitionMethod) { | ||
_expandEndBinded(); | ||
return this; | ||
} | ||
const hasTransition = _transition?.isAnimated(); | ||
if (hasTransition) { | ||
_transition.addEventListener(BaseTransition.END_EVENT, _expandEndBinded); | ||
} | ||
_expandTransitionMethod(); | ||
if (!hasTransition) { | ||
_expandEndBinded(); | ||
} | ||
return this; | ||
@@ -285,41 +271,37 @@ } | ||
function collapse() { | ||
if (_isExpanded && !_isAnimating) { | ||
_deferFunct = noopFunct; | ||
_isAnimating = true; | ||
_isExpanded = false; | ||
this.dispatchEvent('collapseBegin', { | ||
target: this, | ||
type: 'collapseBegin', | ||
}); | ||
_transition?.halt(); | ||
if (_state === COLLAPSING || _state === COLLAPSED) return this; | ||
// Only use transitions if both expand and collapse are set. | ||
if (_collapseTransitionMethod && _expandTransitionMethod) { | ||
const hasTransition = | ||
_collapseTransition && _collapseTransition.isAnimated(); | ||
if (hasTransition) { | ||
_collapseTransition.addEventListener( | ||
BaseTransition.END_EVENT, | ||
_collapseEndBinded | ||
); | ||
} | ||
_collapseTransitionMethod.apply( | ||
_collapseTransition, | ||
_collapseTransitionMethodArgs | ||
); | ||
if (!hasTransition) { | ||
_collapseEndBinded(); | ||
} | ||
} else { | ||
_collapseEndBinded(); | ||
} | ||
for (let i = 0, len = _triggerDoms.length; i < len; i++) { | ||
_setAriaAttr('expanded', _triggerDoms[i], false); | ||
} | ||
for (let i = 0, len = _triggerDoms.length; i < len; i++) { | ||
_setAriaAttr('expanded', _triggerDoms[i], false); | ||
} | ||
_setAriaAttr('expanded', _contentDom, false); | ||
_setAriaAttr('expanded', _contentDom, false); | ||
} else { | ||
_deferFunct = _collapseBinded; | ||
_state = COLLAPSING; | ||
this.dispatchEvent('collapsebegin', { | ||
target: this, | ||
type: 'collapsebegin', | ||
}); | ||
// Only use transitions if both expand and collapse are set. | ||
if (!_collapseTransitionMethod || !_expandTransitionMethod) { | ||
_collapseEndBinded(); | ||
return this; | ||
} | ||
const hasTransition = _transition?.isAnimated(); | ||
if (hasTransition) { | ||
_transition.addEventListener( | ||
BaseTransition.END_EVENT, | ||
_collapseEndBinded | ||
); | ||
} | ||
_collapseTransitionMethod(); | ||
if (!hasTransition) { | ||
_collapseEndBinded(); | ||
} | ||
return this; | ||
@@ -334,6 +316,5 @@ } | ||
function _expandEnd() { | ||
_isAnimating = false; | ||
_isExpanded = true; | ||
if (_expandTransition) { | ||
_expandTransition.removeEventListener( | ||
_state = EXPANDED; | ||
if (_transition) { | ||
_transition.removeEventListener( | ||
BaseTransition.END_EVENT, | ||
@@ -343,3 +324,3 @@ _expandEndBinded | ||
} | ||
this.dispatchEvent('expandEnd', { target: this, type: 'expandEnd' }); | ||
this.dispatchEvent('expandend', { target: this, type: 'expandend' }); | ||
@@ -351,4 +332,2 @@ for (let i = 0, len = _triggerDoms.length; i < len; i++) { | ||
_setAriaAttr('expanded', _contentDom, true); | ||
// Call collapse, if it was called while expand was animating. | ||
_deferFunct(); | ||
} | ||
@@ -360,5 +339,5 @@ | ||
function _collapseEnd() { | ||
_isAnimating = false; | ||
if (_collapseTransition) { | ||
_collapseTransition.removeEventListener( | ||
_state = COLLAPSED; | ||
if (_transition) { | ||
_transition.removeEventListener( | ||
BaseTransition.END_EVENT, | ||
@@ -368,46 +347,15 @@ _collapseEndBinded | ||
} | ||
this.dispatchEvent('collapseEnd', { target: this, type: 'collapseEnd' }); | ||
} | ||
/** | ||
* @param {BaseTransition} transition - A transition instance | ||
* to watch for events on. | ||
* @param {Function} method - The transition method to call on expand. | ||
* @param {Array} [args] - List of arguments to apply to expand method. | ||
*/ | ||
function setExpandTransition(transition, method, args) { | ||
_expandTransition = transition; | ||
_expandTransitionMethod = method; | ||
_expandTransitionMethodArgs = args; | ||
_initTransitions(); | ||
this.dispatchEvent('collapseend', { target: this, type: 'collapseend' }); | ||
} | ||
/** | ||
* @param {BaseTransition} transition - A transition instance | ||
* to watch for events on. | ||
* @param {Function} method - The transition method to call on collapse. | ||
* @param {Array} [args] - List of arguments to apply to collapse method. | ||
*/ | ||
function setCollapseTransition(transition, method, args) { | ||
_collapseTransition = transition; | ||
_collapseTransitionMethod = method; | ||
_collapseTransitionMethodArgs = args; | ||
function setTransition(transition, collapseMethod, expandMethod) { | ||
_transition = transition; | ||
_initTransitions(); | ||
} | ||
if (collapseMethod && collapseMethod !== _collapseTransitionMethod) { | ||
_collapseTransitionMethod = collapseMethod; | ||
} | ||
/** | ||
* Make initial call to transition expand or collapse methods. | ||
* Called after the transitions are set on the FlyoutMenu. | ||
*/ | ||
function _initTransitions() { | ||
if (_isExpanded && _expandTransition) { | ||
_expandTransition.animateOff(); | ||
_expandTransitionMethod(); | ||
_expandTransition.animateOn(); | ||
} else if (_collapseTransition) { | ||
_collapseTransition.animateOff(); | ||
_collapseTransitionMethod(); | ||
_collapseTransition.animateOn(); | ||
if (expandMethod && expandMethod !== _expandTransitionMethod) { | ||
_expandTransitionMethod = expandMethod; | ||
} | ||
@@ -419,41 +367,16 @@ } | ||
*/ | ||
function clearTransitions() { | ||
let transition = getTransition(FlyoutMenu.EXPAND_TYPE); | ||
if (transition) { | ||
transition.remove(); | ||
function clearTransition() { | ||
if (_transition) { | ||
_transition.remove(); | ||
} | ||
transition = getTransition(FlyoutMenu.COLLAPSE_TYPE); | ||
if (transition) { | ||
transition.remove(); | ||
} | ||
let UNDEFINED; | ||
_expandTransition = UNDEFINED; | ||
_transition = UNDEFINED; | ||
_expandTransitionMethod = UNDEFINED; | ||
_expandTransitionMethodArgs = []; | ||
_collapseTransition = UNDEFINED; | ||
_collapseTransitionMethod = UNDEFINED; | ||
_collapseTransitionMethodArgs = []; | ||
} | ||
/** | ||
* @param {string} [type] - The type of transition to return. | ||
* Accepts 'expand' or 'collapse'. | ||
* `FlyoutMenu.EXPAND_TYPE` and `FlyoutMenu.COLLAPSE_TYPE` can be used | ||
* as type-safe constants passed into this method. | ||
* If neither or something else is supplied, expand type is returned. | ||
* @returns {BaseTransition|undefined} A transition instance | ||
* set on this instance, or undefined if none is set. | ||
*/ | ||
function getTransition(type) { | ||
if (type === FlyoutMenu.COLLAPSE_TYPE) { | ||
return _collapseTransition; | ||
} | ||
return _expandTransition; | ||
} | ||
/** | ||
* @returns {object} | ||
@@ -476,5 +399,3 @@ * Hash of container, content DOM references, and a list of trigger DOMs. | ||
function resume() { | ||
if (_suspended) { | ||
_suspended = false; | ||
} | ||
if (_suspended) _suspended = false; | ||
@@ -490,5 +411,3 @@ return !_suspended; | ||
function suspend() { | ||
if (!_suspended) { | ||
_suspended = true; | ||
} | ||
if (!_suspended) _suspended = true; | ||
@@ -499,10 +418,2 @@ return _suspended; | ||
/** | ||
* @returns {number | string | object} A data identifier | ||
* such as an Array index, Hash key, or Tree node. | ||
*/ | ||
function getData() { | ||
return _data; | ||
} | ||
/** | ||
* @param {number | string | object} data - A data identifier | ||
@@ -518,16 +429,2 @@ * such as an Array index, Hash key, or Tree node. | ||
/** | ||
* @returns {boolean} True if menu is animating, false otherwise. | ||
*/ | ||
function isAnimating() { | ||
return _isAnimating; | ||
} | ||
/** | ||
* @returns {boolean} True if menu is expanded, false otherwise. | ||
*/ | ||
function isExpanded() { | ||
return _isExpanded; | ||
} | ||
// Attach public events. | ||
@@ -542,10 +439,9 @@ const eventObserver = new EventObserver(); | ||
this.collapse = collapse; | ||
this.setExpandTransition = setExpandTransition; | ||
this.setCollapseTransition = setCollapseTransition; | ||
this.clearTransitions = clearTransitions; | ||
this.getData = getData; | ||
this.getTransition = getTransition; | ||
this.setTransition = setTransition; | ||
this.clearTransition = clearTransition; | ||
this.getData = () => _data; | ||
this.getTransition = () => _transition; | ||
this.getDom = getDom; | ||
this.isAnimating = isAnimating; | ||
this.isExpanded = isExpanded; | ||
this.isAnimating = () => _state === EXPANDING || _state === COLLAPSING; | ||
this.isExpanded = () => _state === EXPANDED; | ||
this.resume = resume; | ||
@@ -556,4 +452,2 @@ this.setData = setData; | ||
// Public static properties. | ||
FlyoutMenu.EXPAND_TYPE = 'expand'; | ||
FlyoutMenu.COLLAPSE_TYPE = 'collapse'; | ||
FlyoutMenu.BASE_CLASS = BASE_CLASS; | ||
@@ -560,0 +454,0 @@ |
@@ -55,10 +55,2 @@ /** | ||
// Bit values intended to be used for bit inversion. | ||
const DIRECTIONS = { | ||
UP: 0, | ||
RIGHT: 1, | ||
DOWN: -1, | ||
LEFT: -2, | ||
}; | ||
export { BEHAVIOR_PREFIX, JS_HOOK, noopFunct, STATE_PREFIX, DIRECTIONS }; | ||
export { BEHAVIOR_PREFIX, JS_HOOK, noopFunct, STATE_PREFIX }; |
@@ -21,17 +21,11 @@ import BaseTransition from './BaseTransition.js'; | ||
function AlphaTransition(element) { | ||
const _baseTransition = new BaseTransition(element, CLASSES); | ||
const eventObserver = new EventObserver(); | ||
const _baseTransition = new BaseTransition(element, CLASSES, this); | ||
/** | ||
* Handle the end of a transition. | ||
*/ | ||
function _transitionComplete() { | ||
this.dispatchEvent(BaseTransition.END_EVENT, { target: this }); | ||
} | ||
/** | ||
* @param {Function} initialClass - The initial state for this transition. | ||
* @returns {AlphaTransition} An instance. | ||
*/ | ||
function init() { | ||
_baseTransition.init(); | ||
_baseTransition.proxyEvents(this, _transitionComplete.bind(this)); | ||
function init(initialClass) { | ||
_baseTransition.init(initialClass); | ||
@@ -64,3 +58,2 @@ return this; | ||
// Attach public events. | ||
const eventObserver = new EventObserver(); | ||
this.addEventListener = eventObserver.addEventListener; | ||
@@ -67,0 +60,0 @@ this.dispatchEvent = eventObserver.dispatchEvent; |
@@ -1,3 +0,1 @@ | ||
import EventObserver from '@cfpb/cfpb-atomic-component/src/mixins/EventObserver.js'; | ||
/** | ||
@@ -12,7 +10,10 @@ * BaseTransition | ||
* @param {object} classes - The classes to apply to this transition. | ||
* @param {Object} child - The child transition using this as a base. | ||
* @returns {BaseTransition} An instance. | ||
*/ | ||
function BaseTransition(element, classes) { | ||
function BaseTransition(element, classes, child) { | ||
const _classes = classes; | ||
let _dom; | ||
let _dom = element; | ||
if (!child) throw new Error('Child transition argument must be defined!'); | ||
let _child = child; | ||
@@ -22,3 +23,4 @@ let _lastClass; | ||
let _transitionCompleteBinded; | ||
let _addEventListenerBinded; | ||
let _isAnimated = false; | ||
let _isAnimating = false; | ||
@@ -40,27 +42,28 @@ let _isFlushed = false; | ||
* Add an event listener to the transition, or call the transition | ||
* complete handler immediately if transition not supported. | ||
* complete handler immediately if the transition is not supported. | ||
*/ | ||
function _addEventListener() { | ||
_dom.classList.add(BaseTransition.ANIMATING_CLASS); | ||
_isAnimating = true; | ||
/* | ||
If transition is not supported, call handler directly (IE9/OperaMini). | ||
Also, if "transition-duration: 0s" is set, transitionEnd event will not | ||
If transition is supported and the animation is animated, | ||
listen for transition end event, otherwise call the handler directly. | ||
Some browsers (e.g. IE9/OperaMini) do not support transitionend event. | ||
If "transition-duration: 0s" is set, transitionEnd event will not | ||
fire, so we need to call the handler straight away. | ||
*/ | ||
if ( | ||
_transitionEndEvent && | ||
!_dom.classList.contains(BaseTransition.NO_ANIMATION_CLASS) | ||
) { | ||
if (_transitionEndEvent && _isAnimated) { | ||
_dom.addEventListener(_transitionEndEvent, _transitionCompleteBinded); | ||
this.dispatchEvent(BaseTransition.BEGIN_EVENT, { | ||
target: this, | ||
_child.dispatchEvent(BaseTransition.BEGIN_EVENT, { | ||
target: _child, | ||
type: BaseTransition.BEGIN_EVENT, | ||
}); | ||
} else { | ||
this.dispatchEvent(BaseTransition.BEGIN_EVENT, { | ||
target: this, | ||
_child.dispatchEvent(BaseTransition.BEGIN_EVENT, { | ||
target: _child, | ||
type: BaseTransition.BEGIN_EVENT, | ||
}); | ||
_transitionCompleteBinded(); | ||
} | ||
_dom.classList.add(BaseTransition.ANIMATING_CLASS); | ||
_isAnimating = true; | ||
} | ||
@@ -89,4 +92,5 @@ | ||
_dom.classList.remove(BaseTransition.ANIMATING_CLASS); | ||
this.dispatchEvent(BaseTransition.END_EVENT, { | ||
target: this, | ||
_child.dispatchEvent(BaseTransition.END_EVENT, { | ||
target: _child, | ||
type: BaseTransition.END_EVENT, | ||
}); | ||
@@ -135,15 +139,7 @@ _isAnimating = false; | ||
* Remove all transition classes, if transition is initialized. | ||
* | ||
* @returns {boolean} | ||
* True, if the element's CSS classes were touched, false otherwise. | ||
*/ | ||
function remove() { | ||
if (_dom) { | ||
halt(); | ||
_dom.classList.remove(_classes.BASE_CLASS); | ||
_flush(); | ||
return true; | ||
} | ||
return false; | ||
halt(); | ||
_flush(); | ||
_dom.classList.remove(_classes.BASE_CLASS); | ||
} | ||
@@ -153,12 +149,6 @@ | ||
* Add a "transition-duration: 0s" utility CSS class. | ||
* | ||
* @returns {BaseTransition} An instance. | ||
*/ | ||
function animateOn() { | ||
if (!_dom) { | ||
return this; | ||
} | ||
_dom.classList.remove(BaseTransition.NO_ANIMATION_CLASS); | ||
return this; | ||
_isAnimated = true; | ||
} | ||
@@ -168,12 +158,6 @@ | ||
* Remove a "transition-duration: 0s" utility CSS class. | ||
* | ||
* @returns {BaseTransition} An instance. | ||
*/ | ||
function animateOff() { | ||
if (!_dom) { | ||
return this; | ||
} | ||
_dom.classList.add(BaseTransition.NO_ANIMATION_CLASS); | ||
return this; | ||
_isAnimated = false; | ||
} | ||
@@ -219,10 +203,6 @@ | ||
function setElement(targetElement) { | ||
/* | ||
If the element has already been set, | ||
clear the transition classes from the old element. | ||
*/ | ||
if (_dom) { | ||
remove(); | ||
animateOn(); | ||
} | ||
// Clear the transition classes from the old element. | ||
remove(); | ||
animateOn(); | ||
_dom = targetElement; | ||
@@ -234,8 +214,15 @@ _dom.classList.add(_classes.BASE_CLASS); | ||
/** | ||
* @param {Function} initialClass - The initial state for this transition. | ||
* @returns {BaseTransition} An instance. | ||
*/ | ||
function init() { | ||
function init(initialClass) { | ||
_isAnimated = !_dom.classList.contains(BaseTransition.NO_ANIMATION_CLASS); | ||
_transitionCompleteBinded = _transitionComplete.bind(this); | ||
_addEventListenerBinded = _addEventListener.bind(this); | ||
setElement(element); | ||
setElement(_dom); | ||
if (!initialClass) { | ||
throw new Error( | ||
'Transition needs to be passed an initial CSS class on initialization!' | ||
); | ||
} | ||
_dom.classList.add(initialClass); | ||
@@ -246,22 +233,7 @@ return this; | ||
/** | ||
* @returns {boolean} Whether the transition has a duration or not. | ||
* Returns false if this transition has not been initialized. | ||
*/ | ||
function isAnimated() { | ||
if (!_dom) { | ||
return false; | ||
} | ||
return !_dom.classList.contains(BaseTransition.NO_ANIMATION_CLASS); | ||
} | ||
/** | ||
* @param {string} className - A CSS class. | ||
* @returns {boolean} False if the class is already applied | ||
* or the transition is not initialized, | ||
* @returns {boolean} False if the class is already applied, | ||
* otherwise true if the class was applied. | ||
*/ | ||
function applyClass(className) { | ||
if (!_dom) { | ||
return false; | ||
} | ||
if (!_isFlushed) { | ||
@@ -279,3 +251,3 @@ _flush(); | ||
_lastClass = className; | ||
_addEventListenerBinded(); | ||
_addEventListener(); | ||
_dom.classList.add(_lastClass); | ||
@@ -286,26 +258,3 @@ | ||
/** | ||
* Passes events fired on BaseTransition to the passed event target. | ||
* | ||
* @param {object} eventTarget - A child transition to proxy events to. | ||
* @param {Function} transitionComplete - what to call when transition ends. | ||
* @returns {BaseTransition} An instance. | ||
*/ | ||
function proxyEvents(eventTarget, transitionComplete) { | ||
this.addEventListener(BaseTransition.BEGIN_EVENT, () => { | ||
eventTarget.dispatchEvent(BaseTransition.BEGIN_EVENT, { | ||
target: eventTarget, | ||
}); | ||
}); | ||
this.addEventListener(BaseTransition.END_EVENT, transitionComplete); | ||
return this; | ||
} | ||
// Attach public events. | ||
const eventObserver = new EventObserver(); | ||
this.addEventListener = eventObserver.addEventListener; | ||
this.dispatchEvent = eventObserver.dispatchEvent; | ||
this.removeEventListener = eventObserver.removeEventListener; | ||
this.animateOff = animateOff; | ||
@@ -316,6 +265,5 @@ this.animateOn = animateOn; | ||
this.init = init; | ||
this.isAnimated = isAnimated; | ||
this.isAnimated = () => _isAnimated; | ||
this.remove = remove; | ||
this.setElement = setElement; | ||
this.proxyEvents = proxyEvents; | ||
@@ -326,4 +274,4 @@ return this; | ||
// Public static constants. | ||
BaseTransition.BEGIN_EVENT = 'transitionBegin'; | ||
BaseTransition.END_EVENT = 'transitionEnd'; | ||
BaseTransition.BEGIN_EVENT = 'transitionbegin'; | ||
BaseTransition.END_EVENT = 'transitionend'; | ||
BaseTransition.NO_ANIMATION_CLASS = 'u-no-animation'; | ||
@@ -330,0 +278,0 @@ BaseTransition.ANIMATING_CLASS = 'u-is-animating'; |
@@ -22,4 +22,5 @@ import BaseTransition from '@cfpb/cfpb-atomic-component/src/utilities/transition/BaseTransition.js'; | ||
function MaxHeightTransition(element) { | ||
const _baseTransition = new BaseTransition(element, CLASSES); | ||
let previousHeight; | ||
const eventObserver = new EventObserver(); | ||
const _baseTransition = new BaseTransition(element, CLASSES, this); | ||
let _previousHeight = 0; | ||
@@ -31,17 +32,8 @@ /** | ||
function refresh() { | ||
element.style.maxHeight = element.scrollHeight + 'px'; | ||
const elmHeight = element.scrollHeight; | ||
const newHeight = elmHeight + 'px'; | ||
element.style.maxHeight = newHeight; | ||
} | ||
/** | ||
* Handle the end of a transition. | ||
*/ | ||
function _transitionComplete() { | ||
this.dispatchEvent(BaseTransition.END_EVENT, { target: this }); | ||
if (element.scrollHeight > previousHeight) { | ||
element.style.maxHeight = element.scrollHeight + 'px'; | ||
} | ||
} | ||
/** | ||
* The whole page has loaded, | ||
@@ -56,13 +48,21 @@ * including all dependent resources such as stylesheets and images. | ||
/** | ||
* @param {Function} initialClass - The initial state for this transition. | ||
* @returns {MaxHeightTransition} An instance. | ||
*/ | ||
function init() { | ||
_baseTransition.init(); | ||
function init(initialClass) { | ||
_baseTransition.init(initialClass); | ||
/* The scrollHeight of an element may be incorrect if the page hasn't | ||
fully loaded yet, so we listen for that to happen before calculating | ||
the element max-height. */ | ||
/* | ||
The scrollHeight of an element may be incorrect if the page hasn't | ||
fully loaded yet, so we listen for that to happen before calculating | ||
the element max-height. | ||
*/ | ||
window.addEventListener('load', _pageLoaded); | ||
_baseTransition.proxyEvents(this, _transitionComplete.bind(this)); | ||
/* | ||
The scrollHeight of an element may change on page load. | ||
*/ | ||
window.addEventListener('resize', () => { | ||
refresh(); | ||
}); | ||
@@ -78,6 +78,7 @@ return this; | ||
function maxHeightDefault() { | ||
refresh(); | ||
_baseTransition.applyClass(CLASSES.MH_DEFAULT); | ||
if (!previousHeight || element.scrollHeight > previousHeight) { | ||
previousHeight = element.scrollHeight; | ||
if (!_previousHeight || element.scrollHeight > _previousHeight) { | ||
_previousHeight = element.scrollHeight; | ||
} | ||
@@ -96,3 +97,3 @@ | ||
previousHeight = element.scrollHeight; | ||
_previousHeight = element.scrollHeight; | ||
@@ -110,3 +111,3 @@ return this; | ||
previousHeight = element.scrollHeight; | ||
_previousHeight = element.scrollHeight; | ||
@@ -129,3 +130,2 @@ return this; | ||
// Attach public events. | ||
const eventObserver = new EventObserver(); | ||
this.addEventListener = eventObserver.addEventListener; | ||
@@ -132,0 +132,0 @@ this.dispatchEvent = eventObserver.dispatchEvent; |
@@ -25,17 +25,11 @@ import BaseTransition from './BaseTransition.js'; | ||
function MoveTransition(element) { | ||
const _baseTransition = new BaseTransition(element, CLASSES); | ||
const eventObserver = new EventObserver(); | ||
const _baseTransition = new BaseTransition(element, CLASSES, this); | ||
/** | ||
* Handle the end of a transition. | ||
*/ | ||
function _transitionComplete() { | ||
this.dispatchEvent(BaseTransition.END_EVENT, { target: this }); | ||
} | ||
/** | ||
* @param {Function} initialClass - The initial state for this transition. | ||
* @returns {MoveTransition} An instance. | ||
*/ | ||
function init() { | ||
_baseTransition.init(); | ||
_baseTransition.proxyEvents(this, _transitionComplete.bind(this)); | ||
function init(initialClass) { | ||
_baseTransition.init(initialClass); | ||
@@ -63,3 +57,3 @@ return this; | ||
*/ | ||
function moveLeft(count) { | ||
function _moveLeft(count) { | ||
count = count || 1; | ||
@@ -72,6 +66,2 @@ const moveClasses = [ | ||
if (count < 1 || count > moveClasses.length) { | ||
throw new Error('MoveTransition: moveLeft count is out of range!'); | ||
} | ||
_baseTransition.applyClass(moveClasses[count - 1]); | ||
@@ -105,3 +95,2 @@ | ||
// Attach public events. | ||
const eventObserver = new EventObserver(); | ||
this.addEventListener = eventObserver.addEventListener; | ||
@@ -119,3 +108,5 @@ this.dispatchEvent = eventObserver.dispatchEvent; | ||
this.init = init; | ||
this.moveLeft = moveLeft; | ||
this.moveLeft = () => _moveLeft(1); | ||
this.moveLeft2 = () => _moveLeft(2); | ||
this.moveLeft3 = () => _moveLeft(3); | ||
this.moveRight = moveRight; | ||
@@ -122,0 +113,0 @@ this.moveToOrigin = moveToOrigin; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
71657
1742