Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

issue/2824-jsx JSX version of accordion #97

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d6695f6
issue/2824-jsx React version of accordion
olivermartinfoster Jul 5, 2020
a88494f
issue/2824-jsx var to const
oliverfoster Jul 14, 2020
2631865
issue/2824-jsx Converted model to import/export directives
olivermartinfoster Jul 15, 2020
2efb976
issue/2824-jsx switch to template string
oliverfoster Jul 16, 2020
8a4848a
issue/2824-jsx removed preventDefault
olivermartinfoster Jul 16, 2020
91c04e4
Merge branch 'master' into issue/2824-jsx
oliverfoster Jul 27, 2020
17e2da0
issue/2824-jsx classes > array syntax, fixed typo in _id reference
olivermartinfoster Jul 31, 2020
36a871d
issue/2824-jsx Removed unused variable
olivermartinfoster Jul 31, 2020
3690efc
issue/2824-jsx Switched to altered syntax
olivermartinfoster Aug 14, 2020
22cc033
issue/2824-jsx Fixed indentation to eslint rules
olivermartinfoster Aug 17, 2020
2ef524f
issue/2824-jsx Added whitespace and changed block styling
olivermartinfoster Aug 18, 2020
56d7fcb
issue/2824-jsx Added more whitespace
olivermartinfoster Aug 18, 2020
40d1a1e
issue/2824-jsx Added more whitespace
olivermartinfoster Aug 18, 2020
7bbe077
issue/2824-jsx Nesting reductions, image alt improvements
olivermartinfoster Aug 18, 2020
1877556
issue/2824-jsx Switched from get('_children') to getChildren()
oliverfoster Aug 21, 2020
ef60e8f
Update templates/accordion.jsx
oliverfoster Nov 16, 2020
f844bd8
Update templates/accordion.jsx
oliverfoster Nov 16, 2020
2ec9719
Update templates/accordion.jsx
oliverfoster Nov 16, 2020
8714b8d
Update templates/accordion.jsx
oliverfoster Nov 16, 2020
eae6a79
issue/3105 Updated
oliverfoster May 10, 2021
be95d9b
issue/3105 Added missing onClick bind
oliverfoster May 10, 2021
5fa44f9
issue/3105 Switched to image template
oliverfoster May 10, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 16 additions & 23 deletions js/accordionModel.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,23 @@
define([
'core/js/models/itemsComponentModel'
], function(ItemsComponentModel) {
import ItemsComponentModel from 'core/js/models/itemsComponentModel';

class AccordionModel extends ItemsComponentModel {
export default class AccordionModel extends ItemsComponentModel {

defaults() {
return ItemsComponentModel.resultExtend('defaults', {
_shouldCollapseItems: true,
_toggleSpeed: 200
}, this);
}

toggleItemsState(index) {
const item = this.getItem(index);
const previousActiveItem = this.getActiveItem();
defaults() {
return ItemsComponentModel.resultExtend('defaults', {
_shouldCollapseItems: true,
_toggleSpeed: 200
});
}

item.toggleActive();
item.toggleVisited(true);
toggleItemsState(index) {
const item = this.getItem(index);
const previousActiveItem = this.getActiveItem();

if (previousActiveItem && this.get('_shouldCollapseItems')) {
previousActiveItem.toggleActive(false);
}
}
item.toggleActive();
item.toggleVisited(true);

if (!previousActiveItem || !this.get('_shouldCollapseItems')) return;
previousActiveItem.toggleActive(false);
}

return AccordionModel;

});
}
119 changes: 44 additions & 75 deletions js/accordionView.js
Original file line number Diff line number Diff line change
@@ -1,86 +1,55 @@
define([
'core/js/views/componentView'
], function(ComponentView) {

class AccordionView extends ComponentView {

events() {
return {
'click .js-toggle-item': 'onClick'
};
}

preRender() {
this.checkIfResetOnRevisit();

this.model.resetActiveItems();

this.listenTo(this.model.get('_children'), {
'change:_isActive': this.onItemsActiveChange,
'change:_isVisited': this.onItemsVisitedChange
});
}

postRender() {
this.setReadyStatus();

if (this.model.get('_setCompletionOn') === 'inview') {
this.setupInviewCompletion();
}
}

checkIfResetOnRevisit() {
const isResetOnRevisit = this.model.get('_isResetOnRevisit');

// If reset is enabled set defaults
if (isResetOnRevisit) {
this.model.reset(isResetOnRevisit);
}
}

onClick(event) {
this.model.toggleItemsState($(event.currentTarget).parent().data('index'));
}

onItemsActiveChange(item, isActive) {
this.toggleItem(item, isActive);
}

onItemsVisitedChange(item, isVisited) {
if (!isVisited) return;

const $item = this.getItemElement(item);

$item.children('.accordion__item-btn').addClass('is-visited');
}

toggleItem(item, shouldExpand) {
const $item = this.getItemElement(item);
const $body = $item.children('.accordion__item-content').stop(true, true);
import ComponentView from 'core/js/views/componentView';

class AccordionView extends ComponentView {

preRender() {
this.checkIfResetOnRevisit();
this.model.resetActiveItems();
this.listenTo(this.model.getChildren(), {
'change:_isActive': this.onItemsActiveChange,
'change:_isVisited': this.onItemsVisitedChange,
'all': this.changed
});
}

$item.children('.accordion__item-btn')
.toggleClass('is-selected is-open', shouldExpand)
.toggleClass('is-closed', !shouldExpand)
.attr('aria-expanded', shouldExpand);
postRender() {
this.setReadyStatus();
if (this.model.get('_setCompletionOn') !== 'inview') return;
this.setupInviewCompletion();
}

if (!shouldExpand) {
$body.slideUp(this.model.get('_toggleSpeed'));
return;
}
checkIfResetOnRevisit() {
const isResetOnRevisit = this.model.get('_isResetOnRevisit');
// If reset is enabled set defaults
if (!isResetOnRevisit) return;
this.model.reset(isResetOnRevisit);
}

$body.slideDown(this.model.get('_toggleSpeed'));
}
onClick(event) {
this.model.toggleItemsState($(event.currentTarget).parent().data('index'));
}

getItemElement(item) {
const index = item.get('_index');
onItemsActiveChange(item, isActive) {
this.toggleItem(item, isActive);
}

return this.$('.accordion__item').filter(`[data-index="${index}"]`);
toggleItem(item, shouldExpand) {
const $item = this.getItemElement(item);
const $body = $item.children('.accordion__item-content').stop(true, true);
if (!shouldExpand) {
$body.slideUp(this.model.get('_toggleSpeed'));
return;
}
$body.slideDown(this.model.get('_toggleSpeed'));
}

getItemElement(item) {
const index = item.get('_index');
return this.$('.accordion__item').filter(`[data-index="${index}"]`);
}

AccordionView.template = 'accordion';
}

return AccordionView;
AccordionView.template = 'accordion.jsx';

});
export default AccordionView;
16 changes: 6 additions & 10 deletions js/adapt-contrib-accordion.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
define([
'core/js/adapt',
'./accordionModel',
'./accordionView'
], function(Adapt, AccordionModel, AccordionView) {

return Adapt.register('accordion', {
model: AccordionModel,
view: AccordionView
});
import Adapt from 'core/js/adapt';
import AccordionModel from './accordionModel';
import AccordionView from './accordionView';

export default Adapt.register('accordion', {
model: AccordionModel,
view: AccordionView
});
59 changes: 0 additions & 59 deletions templates/accordion.hbs

This file was deleted.

104 changes: 104 additions & 0 deletions templates/accordion.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import Adapt from 'core/js/adapt';
import { compile, classes, templates, html } from 'core/js/reactHelpers';

export default function (model, view) {
const data = model.toJSON();
data._globals = Adapt.course.get('_globals');
return (
<div className="component__inner accordion__inner">

{templates.component(model, view)}

<div className="component__widget accordion__widget">

{data._items.map(({ _graphic, _classes, title, body, _index, _isVisited, _isActive }, index) =>

<div
className={classes([
'accordion__item',
_graphic.src && 'has-image',
_classes && _classes
])}
key={_index}
data-index={_index}
>

<button
id={`${data._id}-${index}-accordion-button`}
className={classes([
'accordion__item-btn',
'js-toggle-item',
_isVisited && 'is-visited',
_isActive ? 'is-open is-selected' : 'is-closed'
])}
onClick={view.onClick.bind(view)}
aria-expanded={_isActive ? 'true' : 'false'}
>

<div className="accordion__item-btn-inner">

<div className="accordion__item-icon">
<div className="icon"></div>
</div>

<div className="accordion__item-title">
<div className="accordion__item-title-inner">
{html(title)}
</div>
</div>

</div>

</button>

<div
className="accordion__item-content"
role="region"
aria-labelledby={`${data._id}-${index}-accordion-button`}
>

<div className="accordion__item-content-inner">

{body &&
<div className="accordion__item-body">
<div className="accordion__item-body-inner">
{html(compile(body))}
</div>
</div>
}

{_graphic.src &&
<div className={classes([
'accordion__item-image-container',
_graphic.attribution && 'has-attribution'
])}>

<img
className="accordion__item-image"
src={_graphic.src}
aria-label={_graphic.alt ? Adapt.a11y.normalize(_graphic.alt) : ''}
aria-hidden={!_graphic.alt}
/>

{_graphic.attribution &&
<div className="component__attribution accordion__attribution">
<div className="component__attribution-inner accordion__attribution-inner">
{html(_graphic.attribution)}
</div>
</div>
}

</div>
}

</div>
</div>

</div>
)}

</div>

</div>
);
}