Skip to content

Commit

Permalink
Fix: Convert template to JSX (fixes adaptlearning#89) (adaptlearning#90)
Browse files Browse the repository at this point in the history
  • Loading branch information
swashbuck authored Jan 16, 2023
1 parent b477d81 commit e4e426e
Show file tree
Hide file tree
Showing 9 changed files with 222 additions and 163 deletions.
2 changes: 1 addition & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* A sentence describing each fix

### Update
* A sentence describing each udpate
* A sentence describing each update

### New
* A sentence describing each new feature
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ The attributes listed below are used in *course.json* to configure **Resources**
No known limitations.

----------------------------
**Version number:** 5.0.1 <a href="https://community.adaptlearning.org/" target="_blank"><img src="https://github.com/adaptlearning/documentation/blob/master/04_wiki_assets/plug-ins/images/adapt-logo-mrgn-lft.jpg" alt="adapt learning logo" align="right"></a>
**Framework versions:** 5.19.1+
**Author / maintainer:** Adapt Core Team with [contributors](https://github.com/adaptlearning/adapt-contrib-resources/graphs/contributors)
**Accessibility support:** WAI AA
**RTL support:** Yes
**Cross-platform coverage:** Chrome, Chrome for Android, Firefox (ESR + latest version), Edge, IE11, Safari 12+13 for macOS/iOS/iPadOS, Opera
**Version number:** 5.3.2 <a href="https://community.adaptlearning.org/" target="_blank"><img src="https://github.com/adaptlearning/documentation/blob/master/04_wiki_assets/plug-ins/images/adapt-logo-mrgn-lft.jpg" alt="Adapt Learning logo" align="right"></a>
**Framework versions:** 5.19.1+
**Author / maintainer:** Adapt Core Team with [contributors](https://github.com/adaptlearning/adapt-contrib-resources/graphs/contributors)
**Accessibility support:** WAI AA
**RTL support:** Yes
**Cross-platform coverage:** Chrome, Chrome for Android, Firefox (ESR + latest version), Edge, IE11, Safari 12+13 for macOS/iOS/iPadOS, Opera
42 changes: 0 additions & 42 deletions js/ResourcesHelpers.js

This file was deleted.

41 changes: 6 additions & 35 deletions js/ResourcesView.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import Adapt from 'core/js/adapt';
import a11y from 'core/js/a11y';
import React from 'react';
import ReactDOM from 'react-dom';
import { templates } from 'core/js/reactHelpers';

export default class ResourcesView extends Backbone.View {

Expand All @@ -12,17 +14,12 @@ export default class ResourcesView extends Backbone.View {
this.render();
}

events() {
return {
'click .js-resources-filter-btn-click': 'onFilterClicked'
};
}

render() {
this.$el.html(Handlebars.templates.resources({
const data = {
model: this.model.toJSON(),
resources: this.model.get('_resources')
}));
};
ReactDOM.render(<templates.resources {...data} />, this.el);

_.defer(() => {
this.listenTo(Adapt, 'drawer:closed', this.remove);
Expand All @@ -31,30 +28,4 @@ export default class ResourcesView extends Backbone.View {
return this;
}

onFilterClicked(e) {
if (e && e.preventDefault) e.preventDefault();

const $resources = this.$('#resources');
const $clickedButton = this.$(e.currentTarget);
const clickedTabId = $clickedButton.attr('id');

this.$('.js-resources-filter-btn-click').removeClass('is-selected').attr('aria-selected', false);

$resources.attr('aria-labelledby', clickedTabId);
$clickedButton.attr('aria-selected', true);

let items;
const filter = $clickedButton.addClass('is-selected').attr('data-filter');
if (filter === 'all') {
items = this.$('.js-resources-item').removeClass('u-display-none');
} else {
this.$('.js-resources-item')
.removeClass('u-display-none').not('.is-' + filter)
.addClass('u-display-none');
items = this.$('.js-resources-item.is-' + filter);
}

if (items.length < 0) return;
a11y.focusFirst($(items[0]));
}
}
1 change: 0 additions & 1 deletion js/adapt-contrib-resources.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import Adapt from 'core/js/adapt';
import drawer from 'core/js/drawer';
import ResourcesView from './ResourcesView';
import './ResourcesHelpers';

class Resources extends Backbone.Controller {

Expand Down
78 changes: 0 additions & 78 deletions templates/resources.hbs

This file was deleted.

109 changes: 109 additions & 0 deletions templates/resources.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import React, { useState, useEffect } from 'react';
import Adapt from 'core/js/adapt';
import a11y from 'core/js/a11y';
import { classes, templates } from 'core/js/reactHelpers';

export default function Resources (props) {
const {
resources
} = props;

const _globals = Adapt.course.get('_globals');
const resourceTypes = ['all', 'document', 'media', 'link']; // must contain 'all'

function resourcesHasMultipleTypes(resources) {
if (resources.length === 1) return false;

const allSameType = resources.every(_.matcher({ _type: resources[0]._type }));
return !allSameType;
}

function resourcesGetColumnCount(resources) {
return _.uniq(_.pluck(resources, '_type')).length + 1; // add 1 for the 'All' button column
}

const [selectedFilter, setSelectedFilter] = useState('all');
const [selectedId, setSelectedId] = useState('resources__show-all');
const [focusFlag, setFocusFlag] = useState(false);

useEffect(() => {
if (focusFlag) {
let $items;
if (selectedFilter === 'all') {
$items = $('.resources__item');
} else {
$items = $('.resources__item.is-' + selectedFilter);
}

if ($items.length < 0) return;

a11y.focusFirst($items);

setFocusFlag(false);
}
}, [focusFlag]);

const onFilterClicked = e => {
if (e && e.preventDefault) e.preventDefault();

const $clickedButton = this.$(e.currentTarget);
const filter = $clickedButton.data('filter');
const id = $clickedButton.attr('id');

setSelectedFilter(filter);
setSelectedId(id);
setFocusFlag(true);
};

return (
<div className="component__inner resources__inner">

<templates.header {...props} />

{resourcesHasMultipleTypes(resources) &&
<div className={classes([
'resources__filter',
`has-${resourcesGetColumnCount(resources)}-columns`
])}>
<div className="resources__filter-inner" role="tablist">

<div className="aria-label" aria-label={_globals._extensions._resources.resources} />

{resourceTypes.map((type, index) =>
<templates.resourcesFilterButton {...props}
key={index}
resources={resources}
_filter={type}
onClick={onFilterClicked}
selected={selectedFilter} />
)}

</div>
</div>
}

<div id="resources" className="resources__item-container" role="tabpanel" aria-labelledby={selectedId}>

<div role="list">

{resources.map(({ title, description, _link, _type, _isGlobal, filename, _forceDownload }, index) =>
<templates.resourcesItem {...props}
key={index}
title={title}
description={description}
_link={_link}
_type={_type}
_isGlobal={_isGlobal}
selectedFilter={selectedFilter}
filename={ filename}
_forceDownload={_forceDownload} />
)};

</div>

</div>

</div>

);
}
37 changes: 37 additions & 0 deletions templates/resourcesFilterButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react';
import { classes } from 'core/js/reactHelpers';

export default function ResourcesFilterButton (props) {
const {
model,
onClick,
resources,
selected,
_filter
} = props;

const buttonText = model._filterButtons[_filter];
const ariaLabel = model._filterAria[`${_filter}Aria`];

function resourcesHasType(resources, type) {
return resources.some(_.matcher({ _type: type }));
}

if (!resourcesHasType(resources, _filter) && _filter !== 'all') return null;

return (
<button
id={`resources__show-${_filter}`}
className={classes([
'resources__filter-btn',
selected === _filter && 'is-selected'
])}
onClick={onClick}
data-filter={_filter}
aria-label={ariaLabel}
role="tab"
aria-selected={selected === _filter}
aria-controls="resources"
dangerouslySetInnerHTML={{ __html: buttonText }} />
);
}
Loading

0 comments on commit e4e426e

Please sign in to comment.