Skip to content

Commit

Permalink
refactor: implementing automatic activation of tabs. Resolve #1
Browse files Browse the repository at this point in the history
  • Loading branch information
nachocinalli committed Jul 27, 2022
1 parent 2a555e4 commit fb3fa8a
Show file tree
Hide file tree
Showing 9 changed files with 170 additions and 114 deletions.
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ The attributes listed below are used in components.json and are properly formatt
### Attributes
**_setCompletionOn** (string)

**_groupActive** (number)

**_groups** (array)

>**title** (string)
Expand Down Expand Up @@ -44,7 +42,7 @@ The attributes listed below are used in components.json and are properly formatt
No known limitations.

----------------------------
**Version number:** 1.0.0
**Version number:** 2.0.0
**Framework versions:** 5.14.0+
**Author / maintainer:** [Ignacio Cinalli] (https://github.com/nachocinalli)
**Accessibility support:**
Expand Down
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"url": "git://github.com/nachocinalli/adapt-groupItems.git"
},
"framework": ">=5.14.0",
"version": "1.0.0",
"version": "2.0.0",
"homepage": "https://github.com/nachocinalli/adapt-groupItems",
"issues": "https://github.com/nachocinalli/adapt-groupItems/issues",
"component": "groupItems",
Expand Down
1 change: 0 additions & 1 deletion example.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
"body": "This is optional body text.",
"instruction": "This is the instruction text.",
"_setCompletionOn": "allItems",
"_groupActive": 1,
"_groups": [
{
"title": "Group 1",
Expand Down
17 changes: 10 additions & 7 deletions js/GroupItemsModel.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import ItemsComponentModel from 'core/js/models/itemsComponentModel';

import ItemModel from 'core/js/models/itemModel';
export default class GroupItemsModel extends ItemsComponentModel {
defaults() {
return ItemsComponentModel.resultExtend('defaults', {
_group: 0,
_groupActive: null
});
}

setActive(group) {
this.resetActiveItems();
const itemsGroup = this.getChildren().filter({ _group: group + 1 });
itemsGroup.forEach((child, index) => child.set({ _isVisited: true, _isActive: true }));
this.set('_groupActive', group);
setUpItems() {
const items = this.get('_items') || [];
items.forEach((item, index) => (item._index = index));
this.set('_groupItems', items);

const groups = this.get('_groups') || [];
groups.forEach((group, index) => (group._index = index));
this.setChildren(new Backbone.Collection(groups, { model: ItemModel }));

}
}
38 changes: 23 additions & 15 deletions js/GroupItemsView.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import ComponentView from 'core/js/views/componentView';

import a11y from 'core/js/a11y';
class GroupItemsView extends ComponentView {

preRender() {
this.onClick = this.onClick.bind(this);
this.reset();
this.listenTo(this.model.get('_children'), 'change:_isActive', this.onItemsActiveChange);
this.setActive = this.setActive.bind(this);
}

postRender () {
Expand All @@ -13,22 +15,28 @@ class GroupItemsView extends ComponentView {
if (this.model.get('_setCompletionOn') === 'inview') {
this.setupInviewCompletion('.component__widget');
}
const items = this.model.getChildren();
if (!items || !items.length) return;
const activeItem = this.model.getActiveItem();
if (!activeItem) {
this.model.setActive(this.model.get('_groupActive') - 1);
} else {
items.trigger('change:_isActive', activeItem, true);
}
}

onItemsActiveChange(item, isActive) {
if (!isActive) return;
this.model.set('_groupActive', item.get('_index'));
item.toggleVisited(true);
}

reset() {
this.model.resetActiveItems();
this.model.set('_groupActive', 0);
const firstItem = this.model.getItem(this.model.get('_groupActive'));

if (!firstItem) return;
firstItem.toggleActive(true);
firstItem.toggleVisited(true);
}

onClick(event) {
const $btn = $(event.currentTarget);
const itemIndex = $btn.data('index');
if (itemIndex === this.model.get('_groupActive')) return;
this.model.setActive(itemIndex);
setActive(index) {
this.model.setActiveItem(index);
const button = document.getElementById(`${this.model.get('_id')}-button-${index}`);
a11y.focus(button);
}
}

Expand Down
31 changes: 23 additions & 8 deletions less/group-items.less
Original file line number Diff line number Diff line change
@@ -1,26 +1,41 @@
.groupitems {
&__container-groups {
display: flex;
margin-bottom: 1rem;
}

&__group {
margin-right: 1rem;
background-color: @item-color;
color: @item-color-inverted;

&.is-visited {
background-color: @visited;
color: @visited-inverted;
}

&.is-active {
background-color: @black;
color: @white;
background-color: @item-color-selected;
color: @item-color-inverted-selected;
}

& > * {
pointer-events: none;
}
}

&__container-items {
display: flex;
display: none;
flex-direction: column;

&.is-active {
display: flex;
}
}

&__item {
display: none;
margin-right: 1rem;
&.is-active {
display: block;
}
}

@media (min-width: @device-width-large) {
&__container-items {
flex-direction: row;
Expand Down
14 changes: 1 addition & 13 deletions properties.schema
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,7 @@
"help": "This is the instruction text",
"translatable": true
},
"_groupActive": {
"type": "number",
"required": true,
"default": 1,
"isSetting": true,
"title": "Group active",
"inputType": "Number",
"validators": [
"number"
],
"help": "Set initial state"
},


"_setCompletionOn": {
"type": "string",
"required": true,
Expand Down
6 changes: 0 additions & 6 deletions schema/component.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,6 @@
"enum": ["inview", "allItems"],
"_backboneForms": "Select"
},
"_groupActive": {
"type": "number",
"title": "Group active",
"description": "Set initial state. Use 1 to the first group.",
"default": 1
},
"_groups": {
"type": "array",
"title": "Groups",
Expand Down
171 changes: 111 additions & 60 deletions templates/group-items.jsx
Original file line number Diff line number Diff line change
@@ -1,83 +1,134 @@
import React from 'react';
import { templates, classes, html, compile } from 'core/js/reactHelpers';

export default function GroupItems({
onClick,
_groups,
_items,
_groupActive,
...props
}) {
import a11y from 'core/js/a11y';
export default function GroupItems(props) {
const {
_id,
_items,
_groupItems,
_groupActive,
_globals,
setActive
} = props;
const onButtonClick = (index, event) => {
setActive(index);
};
const onKeyDown = (event) => {
let flag = false;
let currentIndex = _groupActive;
switch (event.which) {
case 35:
currentIndex = _items.length - 1;
flag = true;
break;
case 36:
currentIndex = 0;
flag = true;
break;
case 37:
case 38:
if (currentIndex === 0) currentIndex = _items.length;
currentIndex--;
flag = true;
break;
case 39:
case 40:
if (currentIndex === _items.length - 1) currentIndex = -1;
currentIndex++;
flag = true;
}
if (flag) {
setActive(currentIndex);
event.stopPropagation();
event.preventDefault();
}
};
return (
<div className='component__inner groupitems__inner'>
<templates.header {...props} />
<div className='component__widget groupitems__widget'>
<div className='groupitems__container-groups' role='list'>
{_groups.map(({ title, _icon }, _index) => (
<button onClick={onClick}
<div className='groupitems__container-groups' aria-labelledby={`${_id}-heading`} role='tablist'>
{_items.map(({ title, _icon, _isVisited, _isActive }, _index) => (
<button
id={`${_id}-button-${_index}`}
className={classes([
'btn-text',
'groupitems__group',
_groupActive === _index ? 'is-active' : ''
_isActive ? 'is-active' : '',
_isVisited && 'is-visited'
])}
type='button'
key={_index}
data-index={_index}
role="listitem"
role='tab'
aria-selected ={_isActive}
aria-controls={`${_id}-panel-${_index}`}
aria-hidden={!_isActive || null}
aria-label={`${title}.${_isVisited ? ` ${_globals._accessibility._ariaLabels.visited}` : ''}`}
tabIndex={_isActive ? null : -1}
onClick={(e) => onButtonClick(_index, e)}
onKeyDown={onKeyDown}
>
<div className={classes([
'icon',
_icon._classes
])}>
{_icon.src && (
<img src={_icon.src} alt={_icon.alt} />
)}
</div>
{_icon._classes && (
<span aria-hidden='true' className={classes([
'icon',
_icon._classes
])}>
</span>)}
{_icon.src && (
<img aria-hidden='true' src={_icon.src} alt={_icon.alt} />
)}
{title && (
<div className='groupitems__group-title'>
<span className='groupitems__group-title'>
{html(compile(title))}
</div>
</span>
)}

</button>
))}
</div>
<div className='groupitems__container-items' role='list'>
{_items.map(({ _group, title, body, _graphic, _isActive, _isVisited, _classes }, _index) => (
<div
className={classes([
'groupitems__item',
_graphic.src && 'has-image',
_isActive && 'is-active',
_isVisited && 'is-visited',
_classes
])}
key={_index}
data-index={_index}
role="listitem"
>

{title && (
<div className='groupitems__item__content-title'>
{html(compile(title))}
</div>
)}
{body && (
<div className='groupitems__item__content-body'>
{html(compile(body))}
</div>
)}
{
<templates.image {..._graphic}
classNamePrefixes={[
'component',
'groupitems'
]}
/>
}
</div>
{_items.map(({ _isVisited, _isActive, _index }, _groupindex) => (
<div
id={`${_id}-panel-${_index}`}
key={_index}
className={classes([
'groupitems__container-items',
_isActive ? 'is-active' : '',
_isVisited && 'is-visited'
])}
role='tabpanel'
tabIndex='0'
arial-labelledby={`${_id}-button-${_index}`}>
{_groupItems.filter(item => item._group === _index + 1).map(({ title, body, _graphic, _classes }, _index) => (
<div
className={classes([
'groupitems__item',
_graphic.src && 'has-image',
_classes
])}
key={_index}>
{title && (
<div className='groupitems__item__content-title' role='heading' aria-level={a11y.ariaLevel('componentItem')}>
{html(compile(title))}
</div>
)}
{body && (
<div className='groupitems__item__content-body'>
{html(compile(body))}
</div>
)}
{
<templates.image {..._graphic}
classNamePrefixes={[
'component',
'groupitems'
]}
/>
}
</div>

))}
</div>
))}
</div>
))}
</div>
</div>
);
Expand Down

0 comments on commit fb3fa8a

Please sign in to comment.