diff --git a/cfgov/teachers_digital_platform/jinja2/teachers_digital_platform/activity_search_facets_and_results.html b/cfgov/teachers_digital_platform/jinja2/teachers_digital_platform/activity_search_facets_and_results.html index 90a51b35362..03962bded6f 100644 --- a/cfgov/teachers_digital_platform/jinja2/teachers_digital_platform/activity_search_facets_and_results.html +++ b/cfgov/teachers_digital_platform/jinja2/teachers_digital_platform/activity_search_facets_and_results.html @@ -1,20 +1,12 @@ {% import 'v1/includes/atoms/tag.html' as tag %} {% import 'v1/includes/molecules/pagination.html' as pagination with context %} -{% from 'teachers_digital_platform/tdp_expandable.html' import expandable with context %} {% macro build_filter_section(name) %}
{% set label = name | capitalize | replace('_', ' ') %} {% set items = facets[name] %} - {% set expandable_settings = { - 'label': label, - 'is_expanded': true, - 'is_collapsed_for_mobile': true, - 'is_midtone': true - } %} - {% call() expandable(expandable_settings) %} - {{build_form_group(name, items)}} - {% endcall %} +

{{label}}

+ {{build_form_group(name, items)}}
{% endmacro %} @@ -78,22 +70,15 @@

Filter results by

{% if facets.grade_level %}{{build_filter_section('grade_level')}}{% endif %} {% if facets.activity_duration %}{{build_filter_section('activity_duration')}}{% endif %} {% if facets.topic %} - {% set topic_dict = {'Earn': 'Earning', 'Save and invest': 'Saving and investing', 'Protect': 'Protecting', 'Spend': 'Spending', 'Borrow': 'Borrowing'} %} + {% set topic_dict = {'Earn': 'Earning', 'Save and invest': 'Saving and investing', 'Protect': 'Protecting', 'Spend': 'Spending', 'Borrow': 'Borrowing'} %}
+

Topic

{% set items = facets.topic %} - {% set expandable_settings = { - 'label': 'Topic', - 'is_expanded': true, - 'is_collapsed_for_mobile': true, - 'is_midtone': true - } %} - {% call() expandable(expandable_settings) %} - {% for topic in items %} -
{{topic_dict[topic.title]}}
- {{build_form_group('topic', topic.children)}} -
- {% endfor %} - {% endcall %} + {% for topic in items %} +
{{topic_dict[topic.title]}}
+ {{build_form_group('topic', topic.children)}} +
+ {% endfor %}
{% endif %} diff --git a/cfgov/teachers_digital_platform/jinja2/teachers_digital_platform/tdp_expandable.html b/cfgov/teachers_digital_platform/jinja2/teachers_digital_platform/tdp_expandable.html deleted file mode 100644 index 20693e99187..00000000000 --- a/cfgov/teachers_digital_platform/jinja2/teachers_digital_platform/tdp_expandable.html +++ /dev/null @@ -1,80 +0,0 @@ -{# -TODO: Note that this is a copy of our standard expandable for TDP, - in order to isolate TDP customizations. -#} -{# ========================================================================== - - Expandable - - ========================================================================== - - Description: - - Create an Expandable molecule when given: - - value: Object defined from a StreamField block. - - value.label: Label you want on the Expandable. - Default is an empty string. - - value.content: Main content of the expandable. - - value.is_bordered: Whether the Expandable has a bottom border or not. - Default is false. - - value.is_collapsed_for_mobile: - Whether the Expandable is always initially - collapsed below 800px. - Default is false. - - value.is_midtone: Whether the Expandable is gray or not. - Default is false. - - value.is_expanded: Whether the Expandable is expanded or not. - Default is false. - - ========================================================================== #} - -{% macro expandable(value) %} -
- - -
- {% if caller is defined %} - {{ caller() }} - {% else %} - {% for block in value.content %} - {% if 'paragraph' in block.block_type %} - {{ block.value | safe }} - {% else %} - {{ render_stream_child(block) }} - {% endif %} - {% endfor %} - {% endif %} -
- -
-{% endmacro %} - -{% if value %} - {{ expandable(value) }} -{% endif %} diff --git a/cfgov/teachers_digital_platform/models/activity_index_page.py b/cfgov/teachers_digital_platform/models/activity_index_page.py index 0c51ef6cb16..a8cd6e08857 100644 --- a/cfgov/teachers_digital_platform/models/activity_index_page.py +++ b/cfgov/teachers_digital_platform/models/activity_index_page.py @@ -51,7 +51,6 @@ FACET_DICT["aggs"].update( {"{}_terms".format(facet): {"terms": {"field": facet}}} ) -ALWAYS_EXPANDED = {"topic", "school_subject"} SEARCH_FIELDS = [ "text", "related_text", @@ -132,7 +131,6 @@ def dsl_search(self, request, *args, **kwargs): "total_activities": total_activities, "selected_facets": selected_facets, "all_facets": all_facets, - "expanded_facets": ALWAYS_EXPANDED, } self.results = payload results_per_page = validate_results_per_page(request) @@ -195,18 +193,6 @@ def dsl_search(self, request, *args, **kwargs): "selected_facets": selected_facets, "all_facets": all_facets, } - # List all facet blocks that need to be expanded - conditionally_expanded = { - facet_name - for facet_name, facet_items in all_facets.items() - if any(facet["selected"] is True for facet in facet_items) - } - expanded_facets = ALWAYS_EXPANDED.union(set(conditionally_expanded)) - payload.update( - { - "expanded_facets": expanded_facets, - } - ) self.results = payload results_per_page = validate_results_per_page(request) paginator = Paginator(payload["results"], results_per_page) diff --git a/cfgov/unprocessed/apps/teachers-digital-platform/css/main.less b/cfgov/unprocessed/apps/teachers-digital-platform/css/main.less index 4b004a522bd..2404140a0fc 100755 --- a/cfgov/unprocessed/apps/teachers-digital-platform/css/main.less +++ b/cfgov/unprocessed/apps/teachers-digital-platform/css/main.less @@ -14,14 +14,11 @@ @import (reference) 'cfpb-typography.less'; @import (reference) 'cfpb-notifications.less'; @import (reference) 'cfpb-pagination.less'; -@import (reference) 'cfpb-expandables.less'; @import (reference) 'cfpb-tables.less'; // Project specific Less goes here or you can break it up into discrete files. @import url('atoms/icon.less'); @import url('molecules/form-fields.less'); @import url('molecules/search-hero.less'); -@import url('organisms/expandable.less'); -@import url('organisms/expandable-facets.less'); @import url('pages/activity-search.less'); @import url('utilities/hide-on.less'); diff --git a/cfgov/unprocessed/apps/teachers-digital-platform/css/organisms/expandable-facets.less b/cfgov/unprocessed/apps/teachers-digital-platform/css/organisms/expandable-facets.less deleted file mode 100644 index 29f84f2fbe2..00000000000 --- a/cfgov/unprocessed/apps/teachers-digital-platform/css/organisms/expandable-facets.less +++ /dev/null @@ -1,37 +0,0 @@ -// Expandable facets. - -.o-expandable-facets { - &.is-open > div .o-expandable-facets_cue-close { - display: inline-block; - } - - &.is-closed { - > div .o-expandable-facets_cue-open { - display: inline-block; - } - - > .o-expandable-facets_content { - display: none; - } - } -} - -.o-expandable-facets_target { - &.is-closed > .o-expandable-facets_cue-open { - display: inline-block; - } - - &.is-open > .o-expandable-facets_cue-close { - display: inline-block; - } -} - -.o-expandable-facets_cue { - display: none; -} - -.o-expandable-facets_content { - &.o-expandable-facets_content__collapsed { - display: none; - } -} diff --git a/cfgov/unprocessed/apps/teachers-digital-platform/css/organisms/expandable.less b/cfgov/unprocessed/apps/teachers-digital-platform/css/organisms/expandable.less deleted file mode 100644 index 5fda495b1e1..00000000000 --- a/cfgov/unprocessed/apps/teachers-digital-platform/css/organisms/expandable.less +++ /dev/null @@ -1,211 +0,0 @@ -// Import external dependencies -@import (reference) '@cfpb/cfpb-core/src/cfpb-core.less'; -@import (reference) '@cfpb/cfpb-buttons/src/cfpb-buttons.less'; -@import (reference) '@cfpb/cfpb-icons/src/cfpb-icons.less'; - -/* ========================================================================== - Design System - Expandable Styling - ========================================================================== */ - -// -// Theme variables -// - -// .o-expandable -@expandable-focus: @black; - -// .o-expandable_label -@expandable_label-text: @black; - -// .o-expandable_cues -@expandable_cues-text: @pacific; - -// .o-expandable modifiers -@expandable__background: @gray-5; -@expandable__border: @gray-40; - -// Sizing variables - -// .o-expandable_cues -@expandable_cues-font-size: @btn-font-size; - -// Timing variables - -// .o-expandable_content__transition -@expandable__transition-speed: 0.25s; - -// -// Recommended expandable pattern -// - -.o-expandable { - position: relative; - - &_target { - padding: 0; - border: 0; - background-color: transparent; - cursor: pointer; - - &:focus { - outline: 1px dotted @expandable-focus; - outline-offset: 1px; - } - - .o-expandable_cue-close, - .o-expandable_cue-open { - display: none; - } - - &__expanded .o-expandable_cue-close { - display: block; - } - - &__collapsed .o-expandable_cue-open { - display: block; - } - } - - &_content { - // A clearfix prevents twitchy animations from occurring when margins - // collapse and extend past the bounds of the expandable. - .u-clearfix(); - - &__transition { - transition: max-height @expandable__transition-speed ease-in-out; - } - - &__collapsed { - max-height: 0; - } - - &__expanded { - max-height: 1000px; - } - - &.u-is-animating { - overflow: hidden; - } - } - - // - // Expandable text elements - // - - &_label { - // Remove default h4 margin style - margin-bottom: 0; - color: @expandable_label-text; - font-weight: 500; - } - - &_cues { - min-width: 60px; - text-align: right; - color: @expandable_cues-text; - font-size: unit((@expandable_cues-font-size / @base-font-size-px), em); - line-height: unit((@base-line-height-px / @expandable_cues-font-size)); - } - - // - // Header - // - - &_header { - display: flex; - justify-content: space-between; - - // Using the button element with .o-expandable_header requires setting - // an explicit width. - button& { - width: 100%; - text-align: left; - } - - .o-expandable_label { - // Grow to available width. - flex-grow: 1; - } - } - - // - // Padded expandable modifier - // - - &__padded { - .o-expandable_header { - padding: unit((10px / @base-font-size-px), em) - unit((15px / @base-font-size-px), em); - } - - .o-expandable_content { - padding: 0 unit((15px / @base-font-size-px), em); - - // The divider between _header and _content. - &::before { - content: ''; - display: block; - border-top: 1px solid @expandable__border; - padding-top: unit((15px / @base-font-size-px), em); - } - - &::after { - padding-bottom: unit((15px / @base-font-size-px), em); - width: 100%; - } - } - } - - // - // Expandable with a background color modifier - // - - &__background { - background: @expandable__background; - } - - // - // Expandable with a border modifier - // - - &__border { - border: 1px solid @expandable__border; - } - - // - // Expandable groups - // - - &-group { - .o-expandable__padded { - border-bottom: 1px solid @expandable__border; - - &:first-child { - border-top: 1px solid @expandable__border; - } - } - } - - .respond-to-print( { - // Hide the interactive expandable cues when printing - &_target__expanded &_cue-close, - &_target__collapsed &_cue-open { - display: none; - } - - // Ensure all expandables are expanded when printing. - // To accommodate print stylesheets that display the raw URL after links, - // set an enormous max height to accommodate expandables that have a lot of links. - &_content__collapsed { - display: block; - max-height: 99999px !important; - } - } ); -} - -// Used when the set language reads right-to-left -div[dir='rtl'] .o-expandable_header { - width: 100%; - text-align: right; -} diff --git a/cfgov/unprocessed/apps/teachers-digital-platform/css/pages/activity-search.less b/cfgov/unprocessed/apps/teachers-digital-platform/css/pages/activity-search.less index b5617b864bb..bbe87ba9b80 100644 --- a/cfgov/unprocessed/apps/teachers-digital-platform/css/pages/activity-search.less +++ b/cfgov/unprocessed/apps/teachers-digital-platform/css/pages/activity-search.less @@ -35,38 +35,30 @@ .skip-filters__hidden { display: none; } + .breadcrumbs { + .respond-to-max( @bp-sm-max, { + display: none; + } ); + } .content_sidebar { - padding: unit(15px / @base-font-size-px, em) + padding: unit(30px / @base-font-size-px, em) unit(15px / @base-font-size-px, em) 0; border: 1px solid @gray-40; background-color: @gray-5; - margin-bottom: unit(30px / @base-font-size-px, em); + margin-bottom: 0; - .respond-to-min( @bp-med-min, { - margin-bottom: 0; - padding-top: unit( 30px / @base-font-size-px, em ); + .respond-to-max( @bp-sm-max, { + display: none; } ); - .o-expandable_header, - .o-expandable_content { - border: 0; - padding: 0; - overflow: hidden; - - &::before, - &::after { - border: 0; - } - - &::before { - padding: 0; - } + h4 { + padding: unit(13px / @base-font-size-px, em) 0; + margin-bottom: 0; } - .o-expandable_header { - padding: unit(13px / @base-font-size-px, em) 0; - margin-bottom: 2px; + h4 + h5 { + margin-top: 0; } .m-list__unstyled .m-list__unstyled { @@ -75,12 +67,7 @@ .filter-section { border-top: 1px solid @gray-40; - } - - .filter-section:first-of-type { - .respond-to-max( @bp-sm-max, { - border-top: 0; - } ); + padding-bottom: unit(16px / @base-font-size-px, em); } .o-form_group { diff --git a/cfgov/unprocessed/apps/teachers-digital-platform/js/AtomicComponent.js b/cfgov/unprocessed/apps/teachers-digital-platform/js/AtomicComponent.js deleted file mode 100644 index eb28c41e303..00000000000 --- a/cfgov/unprocessed/apps/teachers-digital-platform/js/AtomicComponent.js +++ /dev/null @@ -1,301 +0,0 @@ -// TODO: Note that this is an older copy of AtomicComponent from the -// design-system to isolate TDP expandable customizations. - -/* ========================================================================== - AtomicComponent - Base Atomic Component - Contains code copied from the following with major modifications : - - Backbone.js ( http://backbonejs.org/docs/backbone.html ). - - Marionette ( http://marionettejs.com ). - ========================================================================== */ - -import { - isFunction, - EventObserver, - instantiateAll, - setInitFlag, -} from '@cfpb/cfpb-atomic-component'; -import Delegate from 'ftdomdelegate'; - -const TAG_NAME = 'div'; - -/** - * Function as the constrcutor for the AtomicComponent. - * Sets up initial instance properties and calls - * necessary methods to properly instantiatie component. - * @param {HTMLElement} element - The element to set as the base element. - * @param {object} attributes - Hash of attributes to set on base element. - */ -function AtomicComponent(element, attributes) { - this.element = element; - this.initializers = []; - this.uId = this.uniqueId('ac'); - Object.assign(this, attributes); - this.processModifiers(); - this.ensureElement(); - this.setCachedElements(); - this.initializers.push(this.initialize); -} - -// Public instance Methods and properties. -Object.assign(AtomicComponent.prototype, new EventObserver(), { - /** - * Run through and call the component's initializers. - * @returns {AtomicComponent} An instance. - */ - init: function () { - this.initializers.forEach(function (func) { - if (isFunction(func)) { - func.apply(this, arguments); - } - }, this); - this.dispatchEvent('component:initialized'); - - return this; - }, - - /** - * Function used to process class modifiers. These should - * correspond with BEM modifiers. - */ - processModifiers: function () { - if (!this.modifiers) { - return; - } - - this.modifiers.forEach(function (modifier) { - const modifierClass = modifier.ui.base.substring(1); - if (this.element.classList.contains(modifierClass)) { - if (modifier.initialize) { - this.initializers.push(modifier.initialize); - } - Object.assign(this, modifier); - } - }, this); - }, - - /** - * Function used to render a template in Single Page Applications. - * @returns {AtomicComponent} An instance. - */ - render: function () { - return this; - }, - - /** - * Function used to ensure and set / create the base DOM element. - */ - ensureElement: function () { - if (!this.element) { - // eslint-disable-line no-negated-condition - const attrs = Object.assign({}, this.attributes); - attrs.id = this.id || this.u_id; - if (this.className) attrs.class = this.className; - this.setElement(document.createElement(TAG_NAME)); - this.setElementAttributes(attrs); - } else { - this.setElement(this.element); - } - setInitFlag(this.element); - }, - - /** - * Function used to set the base DOM element. - * @param {HTMLElement} element - The element to set as the base element. - * @returns {AtomicComponent} An instance. - */ - setElement: function (element) { - if (this.element) { - this.undelegateEvents(); - } - this.element = element; - this.delegateEvents(); - - return this; - }, - - // TODO Fix complexity issue - /* eslint-disable complexity */ - /** - * Function used to set the cached DOM elements. - * @returns {object} Hash of event names and cached elements. - */ - setCachedElements: function () { - const ui = Object.assign({}, this.ui); - let key; - let element; - - for (key in ui) { - if ({}.hasOwnProperty.call(ui, key)) { - element = this.element.querySelectorAll(ui[key]); - if (element.length === 1) { - ui[key] = element[0]; - } else if (element.length > 1) { - ui[key] = element; - } else { - ui[key] = null; - } - } - } - this.ui = ui; - - return ui; - }, - /* eslint-enable complexity */ - - /** - * Function used to remove the base element from the DOM - * and unbind events. - * @returns {boolean} True if successful in tearing down component. - */ - destroy: function () { - if (this.element) { - this.element.parentNode.removeChild(this.element); - if (this.element.view) delete this.element.view; - delete this.element; - } - this.undelegateEvents(); - this.dispatchEvent('component:destroyed'); - - return true; - }, - - /** - * Function used to set the attributes on an element. - * @param {object} attributes - Hash of attributes to set on base element. - */ - setElementAttributes: function (attributes) { - let property; - - for (property in attributes) { - if ({}.hasOwnProperty.call(attributes, property)) { - this.element.setAttribute(property, attributes[property]); - } - } - }, - - // TODO Fix complexity issue - /* eslint-disable complexity */ - /** - * Function used to up event delegation on the base element. - * Using Dom-delegate library to enable this functionality. - * @param {object} events - Hash of events to bind to the dom element. - * @returns {AtomicComponent} An instance. - */ - delegateEvents: function (events) { - const delegateEventSplitter = /^(\S+)\s*(.*)$/; - let key; - let method; - let match; - - events = events || (events = this.events); - if (!events) { - return this; - } - - this.undelegateEvents(); - this._delegate = new Delegate(this.element); - for (key in events) { - if ({}.hasOwnProperty.call(events, key)) { - method = events[key]; - if (isFunction(this[method])) { - method = this[method]; - } - if (method) { - match = key.match(delegateEventSplitter); - this.delegate(match[1], match[2], method.bind(this)); - } - } - } - this.dispatchEvent('component:bound'); - - return this; - }, - /* eslint-enable complexity */ - - /** - * Function used to set the attributes on an element. - * @param {string} eventName - Event in which to listen for. - * @param {string} selector - CSS selector. - * @param {Function} listener - Callback for event. - * @returns {AtomicComponent} An instance. - */ - delegate: function (eventName, selector, listener) { - this._delegate.on(eventName, selector, listener); - - return this; - }, - - /** - * Function used to remove events from the base element. - * @returns {AtomicComponent} An instance. - */ - undelegateEvents: function () { - if (this._delegate) { - this._delegate.destroy(); - } - this.element.removeAttribute('data-js-hook'); - - return this; - }, - - /** - * Function used to set the attributes on an element. - * @param {string} prefix - String to use a prefix. - * @returns {string} Prefixed unique id string. - */ - uniqueId: function (prefix) { - return prefix + '_' + Math.random().toString(36).substr(2, 9); - }, -}); - -// Static Methods - -/** - * Function used to set the attributes on an element. - * and unbind events. - * @param {object} attributes - Hash of attributes to set on base element. - * @returns {Function} Extended child constructor function. - */ -function extend(attributes) { - /** - * Function used as constructor in order to establish inheritance chain. - * @returns {AtomicComponent} An instance. - */ - function child() { - this._super = AtomicComponent.prototype; - return AtomicComponent.apply(this, arguments); - } - - child.prototype = Object.create(AtomicComponent.prototype); - Object.assign(child.prototype, attributes); - Object.assign(child, AtomicComponent); - - if ( - {}.hasOwnProperty.call(attributes, 'ui') && - {}.hasOwnProperty.call(attributes.ui, 'base') - ) { - child.selector = attributes.ui.base; - } - - child.constants = {}; - - return child; -} - -/** - * Function used to instantiate all instances of the particular - * atomic component on a page. - * @param {HTMLElement} scope - Where to search for components within. - * @returns {Array} List of AtomicComponent instances. - */ -function init(scope) { - const components = instantiateAll(this.selector, this, scope); - return components; -} - -// Set public static methods. -AtomicComponent.init = init; -AtomicComponent.extend = extend; - -export default AtomicComponent; diff --git a/cfgov/unprocessed/apps/teachers-digital-platform/js/BaseTransition.js b/cfgov/unprocessed/apps/teachers-digital-platform/js/BaseTransition.js deleted file mode 100644 index 8e060196952..00000000000 --- a/cfgov/unprocessed/apps/teachers-digital-platform/js/BaseTransition.js +++ /dev/null @@ -1,292 +0,0 @@ -// TODO: Note that this is an older copy of BaseTransition from the -// design-system to isolate TDP expandable customizations. - -// Required modules. -import { EventObserver } from '@cfpb/cfpb-atomic-component'; - -// eslint-disable-next-line max-statements -/** - * BaseTransition - * @class - * @classdesc Initializes new BaseTransition behavior. - * This shouldn't be used directly, but instead should be - * the base class used through composition by a specific transition. - * @param {HTMLElement} element - DOM element to apply transition to. - * @param {object} classes - The classes to apply to this transition. - * @returns {BaseTransition} An instance. - */ -function BaseTransition(element, classes) { - const _classes = classes; - let _dom; - - let _lastClass; - let _transitionEndEvent; - let _transitionCompleteBinded; - let _addEventListenerBinded; - let _isAnimating = false; - let _isFlushed = false; - - // Make sure required attributes are passed in. - if ( - typeof _classes.CSS_PROPERTY === 'undefined' || - typeof _classes.BASE_CLASS === 'undefined' - ) { - throw new Error( - 'Transitions require CSS_PROPERTY and BASE_CLASS ' + - 'to be passed into BaseTransition.', - ); - } - - /** - * Add an event listener to the transition, or call the transition - * complete handler immediately if transition 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 - fire, so we need to call the handler straight away. - */ - if ( - _transitionEndEvent && - !_dom.classList.contains(BaseTransition.NO_ANIMATION_CLASS) - ) { - _dom.addEventListener(_transitionEndEvent, _transitionCompleteBinded); - this.dispatchEvent(BaseTransition.BEGIN_EVENT, { target: this }); - } else { - this.dispatchEvent(BaseTransition.BEGIN_EVENT, { target: this }); - _transitionCompleteBinded(); - } - } - - /** - * Remove an event listener to the transition. - */ - function _removeEventListener() { - _dom.removeEventListener(_transitionEndEvent, _transitionCompleteBinded); - } - - /** - * Handle the end of a transition. - * @param {TransitionEvent} evt - Transition event object. - * @returns {boolean} True if transition was cleaned up, - * false if an outside transitioning property triggered this event handler. - */ - function _transitionComplete(evt) { - if (evt && evt.propertyName !== _classes.CSS_PROPERTY) { - return false; - } - - _removeEventListener(); - _dom.classList.remove(BaseTransition.ANIMATING_CLASS); - this.dispatchEvent(BaseTransition.END_EVENT, { target: this }); - _isAnimating = false; - return true; - } - - /** - * Search for and remove initial BaseTransition classes that have - * already been applied to this BaseTransition's target element. - */ - function _flush() { - let prop; - for (prop in _classes) { - if ( - {}.hasOwnProperty.call(_classes, prop) && - _classes[prop] !== _classes.BASE_CLASS && - _dom.classList.contains(_classes[prop]) - ) { - _dom.classList.remove(_classes[prop]); - } - } - } - - /** - * Halt an in-progress animation and call the complete event immediately. - */ - function halt() { - if (!_isAnimating) { - return; - } - _dom.style.webkitTransitionDuration = '0'; - _dom.style.mozTransitionDuration = '0'; - _dom.style.oTransitionDuration = '0'; - _dom.style.transitionDuration = '0'; - _dom.removeEventListener(_transitionEndEvent, _transitionCompleteBinded); - _transitionCompleteBinded(); - _dom.style.webkitTransitionDuration = ''; - _dom.style.mozTransitionDuration = ''; - _dom.style.oTransitionDuration = ''; - _dom.style.transitionDuration = ''; - } - - /** - * 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; - } - - /** - * 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; - } - - /** - * 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; - } - - /** - * @param {HTMLElement} elem - The element to check - * for support of transition end event. - * @returns {string} The browser-prefixed transition end event. - */ - function _getTransitionEndEvent(elem) { - if (!elem) { - const msg = 'Element does not have TransitionEnd event. It may be null!'; - throw new Error(msg); - } - - let transition; - const transitions = { - WebkitTransition: 'webkitTransitionEnd', - MozTransition: 'transitionend', - OTransition: 'oTransitionEnd otransitionend', - transition: 'transitionend', - }; - - let transitionEvent; - for (transitionEvent in transitions) { - if ( - {}.hasOwnProperty.call(transitions, transitionEvent) && - typeof elem.style[transitionEvent] !== 'undefined' - ) { - transition = transitions[transitionEvent]; - break; - } - } - return transition; - } - - /** - * Set the HTML element target of this transition. - * @param {HTMLElement} targetElement - The target of the transition. - */ - function setElement(targetElement) { - /* - If the element has already been set, - clear the transition classes from the old element. - */ - if (_dom) { - remove(); - animateOn(); - } - _dom = targetElement; - _dom.classList.add(_classes.BASE_CLASS); - _transitionEndEvent = _getTransitionEndEvent(_dom); - } - - /** - * @returns {BaseTransition} An instance. - */ - function init() { - _transitionCompleteBinded = _transitionComplete.bind(this); - _addEventListenerBinded = _addEventListener.bind(this); - setElement(element); - - 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, - * otherwise true if the class was applied. - */ - function applyClass(className) { - if (!_dom) { - return false; - } - if (!_isFlushed) { - _flush(); - _isFlushed = true; - } - - if (_dom.classList.contains(className)) { - return false; - } - - _removeEventListener(); - _dom.classList.remove(_lastClass); - _lastClass = className; - _addEventListenerBinded(); - _dom.classList.add(_lastClass); - - return true; - } - - // Attach public events. - const eventObserver = new EventObserver(); - this.addEventListener = eventObserver.addEventListener; - this.dispatchEvent = eventObserver.dispatchEvent; - this.removeEventListener = eventObserver.removeEventListener; - - this.animateOff = animateOff; - this.animateOn = animateOn; - this.applyClass = applyClass; - this.halt = halt; - this.init = init; - this.isAnimated = isAnimated; - this.remove = remove; - this.setElement = setElement; - - return this; -} - -// Public static constants. -BaseTransition.BEGIN_EVENT = 'transitionBegin'; -BaseTransition.END_EVENT = 'transitionEnd'; -BaseTransition.NO_ANIMATION_CLASS = 'u-no-animation'; -BaseTransition.ANIMATING_CLASS = 'u-is-animating'; - -export default BaseTransition; diff --git a/cfgov/unprocessed/apps/teachers-digital-platform/js/Expandable.js b/cfgov/unprocessed/apps/teachers-digital-platform/js/Expandable.js deleted file mode 100644 index 65645331563..00000000000 --- a/cfgov/unprocessed/apps/teachers-digital-platform/js/Expandable.js +++ /dev/null @@ -1,146 +0,0 @@ -// TODO: Note that this is an older copy of Expandable from the -// design-system to isolate TDP expandable customizations. - -/* ========================================================================== - Expandable Organism - ========================================================================== */ - -import AtomicComponent from './AtomicComponent.js'; -import { EventObserver } from '@cfpb/cfpb-atomic-component'; -import ExpandableTransition from './ExpandableTransition.js'; - -const eventObserver = new EventObserver(); - -/** - * Event handler for when an expandable begins expanding. - */ -function expandBeginHandler() { - this.ui.content.classList.remove('u-hidden'); -} - -/** - * Event handler for when an expandable is finished collapsing. - */ -function collapseEndHandler() { - this.ui.content.classList.add('u-hidden'); -} - -/** - * Event handler for when an accordion is activated - */ -function _accordionActivatedHandler() { - if (this.activeAccordion) { - this.transition.toggleExpandable(); - this.toggleTargetState(this.ui.target); - this.activeAccordion = false; - } -} - -/** - * Initialize a new expandable. - */ -function initialize() { - const transition = new ExpandableTransition(this.ui.content); - this.transition = transition.init(); - this.transition.addEventListener( - 'expandBegin', - expandBeginHandler.bind(this), - ); - this.transition.addEventListener( - 'collapseEnd', - collapseEndHandler.bind(this), - ); - - if ( - this.ui.content.classList.contains(ExpandableTransition.CLASSES.EXPANDED) - ) { - this.ui.target.classList.add(this.classes.targetExpanded); - } else { - this.ui.target.classList.add(this.classes.targetCollapsed); - this.ui.content.classList.add('u-hidden'); - } - - const expandableGroup = this.ui.target.closest('.' + this.classes.group); - - this.isAccordionGroup = - expandableGroup !== null && - expandableGroup.classList.contains(this.classes.groupAccordion); - - if (this.isAccordionGroup) { - eventObserver.addEventListener( - 'accordionActivated', - _accordionActivatedHandler.bind(this), - ); - } -} - -/** - * Event handler for when an expandable is clicked. - */ -function expandableClickHandler() { - this.transition.toggleExpandable(); - this.toggleTargetState(this.ui.target); - - if (this.isAccordionGroup) { - if (this.activeAccordion) { - this.activeAccordion = false; - } else { - eventObserver.dispatchEvent('accordionActivated', { target: this }); - this.activeAccordion = true; - } - } -} - -/** - * Toggle an expandable to open or closed. - * @param {HTMLElement} element - The expandable target HTML DOM element. - */ -function toggleTargetState(element) { - if (element.classList.contains(this.classes.targetExpanded)) { - this.ui.target.classList.add(this.classes.targetCollapsed); - this.ui.target.classList.remove(this.classes.targetExpanded); - } else { - this.ui.target.classList.add(this.classes.targetExpanded); - this.ui.target.classList.remove(this.classes.targetCollapsed); - } -} - -/** - * Retrieve the label text of the expandable header. - * @returns {string} The text of the expandable's label. - */ -function getLabelText() { - return this.ui.label.textContent.trim(); -} - -const Expandable = AtomicComponent.extend({ - ui: { - base: '.o-expandable', - target: '.o-expandable_header', - content: '.o-expandable_content', - header: '.o-expandable_header', - label: '.o-expandable_label', - }, - - classes: { - targetExpanded: 'o-expandable_target__expanded', - targetCollapsed: 'o-expandable_target__collapsed', - group: 'o-expandable-group', - groupAccordion: 'o-expandable-group__accordion', - }, - - events: { - 'click .o-expandable_header': 'expandableClickHandler', - }, - - transition: null, - isAccordionGroup: false, - activeAccordion: false, - - initialize: initialize, - expandableClickHandler: expandableClickHandler, - toggleTargetState: toggleTargetState, - getLabelText: getLabelText, -}); - -export default Expandable; diff --git a/cfgov/unprocessed/apps/teachers-digital-platform/js/ExpandableFacetTransition.js b/cfgov/unprocessed/apps/teachers-digital-platform/js/ExpandableFacetTransition.js deleted file mode 100644 index c5f1453cf68..00000000000 --- a/cfgov/unprocessed/apps/teachers-digital-platform/js/ExpandableFacetTransition.js +++ /dev/null @@ -1,129 +0,0 @@ -import BaseTransition from './BaseTransition.js'; -import { EventObserver } from '@cfpb/cfpb-atomic-component'; - -// Exported constants. -const CLASSES = { - CSS_PROPERTY: 'max-height', - BASE_CLASS: 'o-expandable-facets_content__transition', - EXPANDED: 'o-expandable-facets_content__expanded', - COLLAPSED: 'o-expandable-facets_content__collapsed', - OPEN_DEFAULT: 'o-expandable-facets_content__onload-open', -}; - -/** - * ExpandableFacetTransition - * @class - * @classdesc Initializes new ExpandableFacetTransition behavior. - * @param {HTMLElement} element - DOM element to apply move transition to. - * @returns {ExpandableFacetTransition} An instance. - */ -function ExpandableFacetTransition(element) { - const _baseTransition = new BaseTransition(element, CLASSES, this); - let previousHeight; - - /** - * @param {Function} initialClass - The initial state for this transition. - * @returns {ExpandableFacetTransition} An instance. - */ - function init(initialClass) { - _baseTransition.init(initialClass); - this.addEventListener( - BaseTransition.END_EVENT, - _transitionComplete.bind(this), - ); - - if (element.classList.contains(CLASSES.OPEN_DEFAULT)) { - this.expand(); - } else { - this.collapse(); - } - - return this; - } - - /** - * Handle the end of a transition. - */ - function _transitionComplete() { - if (element.classList.contains(CLASSES.EXPANDED)) { - this.dispatchEvent('expandend', { target: this }); - - if (element.scrollHeight > previousHeight) { - element.style.maxHeight = element.scrollHeight + 'px'; - } - } else if (element.classList.contains(CLASSES.COLLAPSED)) { - this.dispatchEvent('collapseend', { target: this }); - } - } - - /** - * Toggle the expandable - * @returns {ExpandableFacetTransition} An instance. - */ - function toggleExpandable() { - if (element.classList.contains(CLASSES.COLLAPSED)) { - this.expand(); - } else { - this.collapse(); - } - - return this; - } - - /** - * Collapses the expandable content - * @returns {ExpandableFacetTransition} An instance. - */ - function collapse() { - this.dispatchEvent('collapsebegin', { target: this }); - - previousHeight = element.scrollHeight; - element.style.maxHeight = '0'; - _baseTransition.applyClass(CLASSES.COLLAPSED); - - return this; - } - - /** - * Expands the expandable content - * @returns {ExpandableFacetTransition} An instance. - */ - function expand() { - this.dispatchEvent('expandbegin', { target: this }); - - if (!previousHeight || element.scrollHeight > previousHeight) { - previousHeight = element.scrollHeight; - } - - element.style.maxHeight = previousHeight + 'px'; - _baseTransition.applyClass(CLASSES.EXPANDED); - - return this; - } - - // Attach public events. - const eventObserver = new EventObserver(); - this.addEventListener = eventObserver.addEventListener; - this.removeEventListener = eventObserver.removeEventListener; - this.dispatchEvent = eventObserver.dispatchEvent; - - this.animateOff = _baseTransition.animateOff; - this.animateOn = _baseTransition.animateOn; - this.halt = _baseTransition.halt; - this.isAnimated = _baseTransition.isAnimated; - this.setElement = _baseTransition.setElement; - this.remove = _baseTransition.remove; - - this.init = init; - this.toggleExpandable = toggleExpandable; - this.collapse = collapse; - this.expand = expand; - - return this; -} -/* eslint-enable max-lines-per-function */ - -// Public static properties. -ExpandableFacetTransition.CLASSES = CLASSES; - -export default ExpandableFacetTransition; diff --git a/cfgov/unprocessed/apps/teachers-digital-platform/js/ExpandableTransition.js b/cfgov/unprocessed/apps/teachers-digital-platform/js/ExpandableTransition.js deleted file mode 100644 index 79de875ac11..00000000000 --- a/cfgov/unprocessed/apps/teachers-digital-platform/js/ExpandableTransition.js +++ /dev/null @@ -1,130 +0,0 @@ -// Required modules. -import BaseTransition from './BaseTransition.js'; -import { EventObserver } from '@cfpb/cfpb-atomic-component'; - -// Exported constants. -const CLASSES = { - CSS_PROPERTY: 'max-height', - BASE_CLASS: 'o-expandable_content__transition', - EXPANDED: 'o-expandable_content__expanded', - COLLAPSED: 'o-expandable_content__collapsed', - OPEN_DEFAULT: 'o-expandable_content__onload-open', -}; - -/* eslint-disable max-lines-per-function */ -/** - * ExpandableTransition - * @class - * @classdesc Initializes new ExpandableTransition behavior. - * @param {HTMLElement} element - DOM element to apply move transition to. - * @returns {ExpandableTransition} An instance. - */ -function ExpandableTransition(element) { - const _baseTransition = new BaseTransition(element, CLASSES); - let previousHeight; - - /** - * Handle the end of a transition. - */ - function _transitionComplete() { - if (element.classList.contains(CLASSES.EXPANDED)) { - this.dispatchEvent('expandEnd', { target: this }); - - if (element.scrollHeight > previousHeight) { - element.style.maxHeight = element.scrollHeight + 'px'; - } - } else if (element.classList.contains(CLASSES.COLLAPSED)) { - this.dispatchEvent('collapseEnd', { target: this }); - } - } - - /** - * @returns {ExpandableTransition} An instance. - */ - function init() { - _baseTransition.init(); - _baseTransition.addEventListener( - BaseTransition.END_EVENT, - _transitionComplete.bind(this), - ); - - if (element.classList.contains(CLASSES.OPEN_DEFAULT)) { - this.expand(); - } else { - this.collapse(); - } - - return this; - } - - /** - * Toggle the expandable - * @returns {ExpandableTransition} An instance. - */ - function toggleExpandable() { - if (element.classList.contains(CLASSES.COLLAPSED)) { - this.expand(); - } else { - this.collapse(); - } - - return this; - } - - /** - * Collapses the expandable content - * @returns {ExpandableTransition} An instance. - */ - function collapse() { - this.dispatchEvent('collapseBegin', { target: this }); - - previousHeight = element.scrollHeight; - element.style.maxHeight = '0'; - _baseTransition.applyClass(CLASSES.COLLAPSED); - - return this; - } - - /** - * Expands the expandable content - * @returns {ExpandableTransition} An instance. - */ - function expand() { - this.dispatchEvent('expandBegin', { target: this }); - - if (!previousHeight || element.scrollHeight > previousHeight) { - previousHeight = element.scrollHeight; - } - - element.style.maxHeight = previousHeight + 'px'; - _baseTransition.applyClass(CLASSES.EXPANDED); - - return this; - } - - // Attach public events. - const eventObserver = new EventObserver(); - this.addEventListener = eventObserver.addEventListener; - this.dispatchEvent = eventObserver.dispatchEvent; - this.removeEventListener = eventObserver.removeEventListener; - - this.animateOff = _baseTransition.animateOff; - this.animateOn = _baseTransition.animateOn; - this.halt = _baseTransition.halt; - this.isAnimated = _baseTransition.isAnimated; - this.setElement = _baseTransition.setElement; - this.remove = _baseTransition.remove; - - this.init = init; - this.toggleExpandable = toggleExpandable; - this.collapse = collapse; - this.expand = expand; - - return this; -} -/* eslint-enable max-lines-per-function */ - -// Public static properties. -ExpandableTransition.CLASSES = CLASSES; - -export default ExpandableTransition; diff --git a/cfgov/unprocessed/apps/teachers-digital-platform/js/expandable-facets.js b/cfgov/unprocessed/apps/teachers-digital-platform/js/expandable-facets.js deleted file mode 100644 index abebe2a1573..00000000000 --- a/cfgov/unprocessed/apps/teachers-digital-platform/js/expandable-facets.js +++ /dev/null @@ -1,96 +0,0 @@ -/* ========================================================================== - Expandable Facets Organism - ========================================================================== */ - -import AtomicComponent from './AtomicComponent.js'; -import ExpandableFacetTransition from './ExpandableFacetTransition.js'; - -const ExpandableFacets = AtomicComponent.extend({ - ui: { - base: '.o-expandable-facets', - target: '.o-expandable-facets_target', - content: '.o-expandable-facets_content', - header: '.o-expandable_header', - facetCheckbox: '.o-expandable-facets_checkbox', - facetLabel: '.o-expandable-facets_checkbox ~ .a-label', - }, - - classes: { - targetExpanded: 'is-open', - targetCollapsed: 'is-closed', - group: 'o-expandable-group', - }, - - events: { - 'click .o-expandable-facets_target': 'expandableClickHandler', - }, - - transition: null, - - initialize: initialize, - expandableClickHandler: expandableClickHandler, - toggleTargetState: toggleTargetState, -}); - -/** - * Initialize a new expandable. - */ -function initialize() { - const customClasses = { - BASE_CLASS: 'o-expandable-facets_content__transition', - EXPANDED: 'o-expandable-facets_content__expanded', - COLLAPSED: 'o-expandable-facets_content__collapsed', - OPEN_DEFAULT: 'o-expandable-facets_content__onload-open', - }; - - const transition = new ExpandableFacetTransition( - this.ui.content, - customClasses, - ); - this.transition = transition.init( - ExpandableFacetTransition.CLASSES.COLLAPSED, - ); - - if (this.ui.content.classList.contains(customClasses.OPEN_DEFAULT)) { - this.ui.target.classList.add(this.classes.targetExpanded); - } else { - this.ui.target.classList.add(this.classes.targetCollapsed); - } - - if ( - this.ui.facetCheckbox.hasAttribute('checked') || - this.ui.facetLabel.classList.contains('indeterminate') - ) { - this.transition.toggleExpandable(); - this.toggleTargetState(this.ui.target); - } -} - -/** - * Event handler for when an expandable is clicked. - */ -function expandableClickHandler() { - this.transition.toggleExpandable(); - this.toggleTargetState(this.ui.target); -} - -/** - * Toggle an expandable to open or closed. - * @param {HTMLElement} element - The expandable target HTML DOM element. - */ -function toggleTargetState(element) { - if (element.classList.contains(this.classes.targetExpanded)) { - this.ui.target.classList.add(this.classes.targetCollapsed); - this.ui.target.classList.remove(this.classes.targetExpanded); - } else { - this.ui.target.classList.add(this.classes.targetExpanded); - this.ui.target.classList.remove(this.classes.targetCollapsed); - } -} - -export default ExpandableFacets; - -/** - * Find .o-expandable-facets, add `is-open` class. - * Find .o-expandable-facets_target and add a click handler to toggle classes on .o-expandable-facets between `is-open` and `is-closed`. - */ diff --git a/cfgov/unprocessed/apps/teachers-digital-platform/js/expandable-mobile.js b/cfgov/unprocessed/apps/teachers-digital-platform/js/expandable-mobile.js deleted file mode 100644 index d53290f3a48..00000000000 --- a/cfgov/unprocessed/apps/teachers-digital-platform/js/expandable-mobile.js +++ /dev/null @@ -1,43 +0,0 @@ -const OPEN_DEFAULT = 'o-expandable_content__onload-open'; -const MOBILE_COLLAPSED_CLASS = 'o-expandable__mobile-collapsed'; -const MOBILE_WIDTH = 900; - -let innerWidth; - -/** - * Get the viewport width - * @returns {number} The viewport width - */ -function getInnerWidth() { - return innerWidth || window.innerWidth; -} - -/** - * Fix the output of getInnerWidth() for test purposes. - * @param {number} width - Width. - */ -function setInnerWidth(width) { - innerWidth = width; -} - -/** - * Alter DOM as necessary before cfpb-expandables ExpandableTransition.init() - * so some elements won't be expanded by default. - */ -function beforeExpandableTransitionInit() { - const nodeList = document.querySelectorAll('.' + MOBILE_COLLAPSED_CLASS); - - // IE11 lacks NodeList.forEach - [].forEach.call(nodeList, (el) => { - if (getInnerWidth() <= MOBILE_WIDTH) { - el.classList.remove(OPEN_DEFAULT); - } - - // Always clean up this class, just used at init time - el.classList.remove(MOBILE_COLLAPSED_CLASS); - }); -} - -export { setInnerWidth, MOBILE_COLLAPSED_CLASS }; - -export default beforeExpandableTransitionInit; diff --git a/cfgov/unprocessed/apps/teachers-digital-platform/js/index.js b/cfgov/unprocessed/apps/teachers-digital-platform/js/index.js index 961adb6e500..d070ac414aa 100644 --- a/cfgov/unprocessed/apps/teachers-digital-platform/js/index.js +++ b/cfgov/unprocessed/apps/teachers-digital-platform/js/index.js @@ -1,24 +1,10 @@ -// External modules -import cfExpandables from './Expandable.js'; -import expandableFacets from './expandable-facets.js'; -import beforeExpandableTransitionInit from './expandable-mobile.js'; - // Internal modules import { init as searchInit } from './search.js'; import { bindAnalytics } from './tdp-analytics.js'; const app = { init: () => { - /** - * This must come before searchInit() because it will also initialize - * cfExpandables. - */ - beforeExpandableTransitionInit(); - searchInit(); - cfExpandables.init(); - expandableFacets.init(); - bindAnalytics(); }, }; diff --git a/cfgov/unprocessed/apps/teachers-digital-platform/js/search.js b/cfgov/unprocessed/apps/teachers-digital-platform/js/search.js index 3adea30304e..da574b07494 100644 --- a/cfgov/unprocessed/apps/teachers-digital-platform/js/search.js +++ b/cfgov/unprocessed/apps/teachers-digital-platform/js/search.js @@ -8,8 +8,6 @@ import { handleError, updateUrl, } from './search-utils.js'; -import expandableFacets from './expandable-facets.js'; -import cfExpandables from './Expandable.js'; import { handleClearAllClick, handleFetchSearchResults, @@ -42,8 +40,6 @@ function attachHandlers() { attach('clear-filter', 'click', clearFilter); attach('clear-all', 'click', clearFilters); attach('clear-search', 'clear', clearSearch); - cfExpandables.init(); - expandableFacets.init(); const inputContainsLabel = document.querySelector( '.tdp-activity-search .input-contains-label', ); diff --git a/test/unit_tests/apps/teachers-digital-platform/js/expandable-facets-spec.js b/test/unit_tests/apps/teachers-digital-platform/js/expandable-facets-spec.js deleted file mode 100644 index 8d865e0883e..00000000000 --- a/test/unit_tests/apps/teachers-digital-platform/js/expandable-facets-spec.js +++ /dev/null @@ -1,129 +0,0 @@ -import { jest } from '@jest/globals'; -import { simulateEvent } from '../../../../util/simulate-event.js'; -import ExpandableFacets from '../../../../../cfgov/unprocessed/apps/teachers-digital-platform/js/expandable-facets.js'; - -let ef; -let efLabel; -let efTarget; -let efBody; -let expandableFacet; - -const HTML_SNIPPET = ` - -`; - -const xhr = global.XMLHttpRequest; -global.console = { error: jest.fn(), log: jest.fn() }; - -describe('Expandable facets', () => { - beforeEach(() => { - // Reset global XHR - global.XMLHttpRequest = xhr; - // Load HTML fixture - document.body.innerHTML = HTML_SNIPPET; - // Fire `load` event - const event = new Event('load', { bubbles: true, cancelable: true }); - window.dispatchEvent(event); - - ef = document.querySelector('.o-expandable-facets'); - expandableFacet = new ExpandableFacets(ef); - expandableFacet.init(); - efLabel = document.querySelector( - '.o-expandable-facets_checkbox ~ .a-label', - ); - efTarget = document.querySelector('.o-expandable-facets_target'); - efBody = document.querySelector('.o-expandable-facets_content'); - - const mockXHR = { - open: jest.fn(), - send: jest.fn(), - readyState: 4, - status: 200, - onreadystatechange: jest.fn(), - responseText: [], - }; - global.XMLHttpRequest = jest.fn(() => mockXHR); - }); - - it('should not throw any errors on init', () => { - expect(() => ExpandableFacets.init()).not.toThrow(); - expect(efLabel.classList.contains('u-visually-hidden')).toEqual(false); - }); - - it('should collapse an expanded facet when target is clicked', () => { - expect(efTarget.classList.contains('is-open')).toEqual(false); - expect(efTarget.classList.contains('is-closed')).toEqual(true); - expect( - efBody.classList.contains('o-expandable-facets_content__expanded'), - ).toEqual(false); - expect( - efBody.classList.contains('o-expandable-facets_content__collapsed'), - ).toEqual(true); - - simulateEvent('click', efTarget); - - expect(efTarget.classList.contains('is-closed')).toEqual(false); - expect(efTarget.classList.contains('is-open')).toEqual(true); - expect( - efBody.classList.contains('o-expandable-facets_content__expanded'), - ).toEqual(true); - expect( - efBody.classList.contains('o-expandable-facets_content__collapsed'), - ).toEqual(false); - }); - - it('should expand a collapsed facet when target is clicked', () => { - expect(efTarget.classList.contains('is-open')).toEqual(false); - expect(efTarget.classList.contains('is-closed')).toEqual(true); - - simulateEvent('click', efTarget); - - expect(efTarget.classList.contains('is-closed')).toEqual(false); - expect(efTarget.classList.contains('is-open')).toEqual(true); - - simulateEvent('click', efTarget); - - expect(efTarget.classList.contains('is-closed')).toEqual(true); - expect(efTarget.classList.contains('is-open')).toEqual(false); - expect( - efBody.classList.contains('o-expandable-facets_content__expanded'), - ).toEqual(false); - expect( - efBody.classList.contains('o-expandable-facets_content__collapsed'), - ).toEqual(true); - }); -}); diff --git a/test/unit_tests/apps/teachers-digital-platform/js/expandable-mobile-spec.js b/test/unit_tests/apps/teachers-digital-platform/js/expandable-mobile-spec.js deleted file mode 100644 index 69f02223231..00000000000 --- a/test/unit_tests/apps/teachers-digital-platform/js/expandable-mobile-spec.js +++ /dev/null @@ -1,104 +0,0 @@ -import { jest } from '@jest/globals'; -import beforeExpandableTransitionInit, { - setInnerWidth, - MOBILE_COLLAPSED_CLASS, -} from '../../../../../cfgov/unprocessed/apps/teachers-digital-platform/js/expandable-mobile.js'; - -// Markup created with settings: is_expanded=true, is_collapsed_for_mobile=true -const HTML_SNIPPET = ` -
- - -
-
-
-
    -
  • -
    - - -
    -
  • -
-
-
-
-
-`; - -global.console = { error: jest.fn(), log: jest.fn() }; - -let expandableDiv; -const OPEN_DEFAULT_CLASS = 'o-expandable_content__onload-open'; - -describe('expandable-mobile', () => { - beforeEach(() => { - setInnerWidth(1000); - // Load HTML fixture - document.body.innerHTML = HTML_SNIPPET; - expandableDiv = document.querySelector('#test-div .o-expandable_content'); - }); - - it('should not throw any errors on init', () => { - expect(() => beforeExpandableTransitionInit()).not.toThrow(); - }); - - /** - * These tests just need to show that beforeExpandableTransitionInit() - * can conditionally remove some class names used in the - * cfExpandables.init() process, and clean up its own class in the - * "expandable" template organism. - */ - - it('should remove the OPEN_DEFAULT class on narrow innerWidth', () => { - setInnerWidth(900); - - expect(expandableDiv.classList.contains(OPEN_DEFAULT_CLASS)).toEqual(true); - beforeExpandableTransitionInit(); - expect(expandableDiv.classList.contains(OPEN_DEFAULT_CLASS)).toEqual(false); - }); - - it('should leave the OPEN_DEFAULT class for tablet innerWidth', () => { - setInnerWidth(901); - - expect(expandableDiv.classList.contains(OPEN_DEFAULT_CLASS)).toEqual(true); - beforeExpandableTransitionInit(); - expect(expandableDiv.classList.contains(OPEN_DEFAULT_CLASS)).toEqual(true); - }); - - it('should always remove its MOBILE_COLLAPSED_CLASS (narrow)', () => { - setInnerWidth(900); - - beforeExpandableTransitionInit(); - expect(expandableDiv.classList.contains(MOBILE_COLLAPSED_CLASS)).toEqual( - false, - ); - }); - - it('should always remove its MOBILE_COLLAPSED_CLASS (wide)', () => { - setInnerWidth(901); - - beforeExpandableTransitionInit(); - expect(expandableDiv.classList.contains(MOBILE_COLLAPSED_CLASS)).toEqual( - false, - ); - }); -});