Skip to content

Commit

Permalink
Add keyboard handler and aria attributes to
Browse files Browse the repository at this point in the history
collapse/expand braces, strings and functions

Fixes mac-s-g#355
  • Loading branch information
nictownsend committed Jun 28, 2021
1 parent b6ae661 commit fbd30d8
Show file tree
Hide file tree
Showing 7 changed files with 229 additions and 105 deletions.
4 changes: 3 additions & 1 deletion src/js/components/DataTypes/Function.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import DataTypeLabel from './DataTypeLabel';
//theme
import Theme from './../../themes/getStyle';

import { generateExpanderProps } from '../../helpers/util';

//attribute store for storing collapsed state
import AttributeStore from './../../stores/ObjectAttributes';

Expand Down Expand Up @@ -48,7 +50,7 @@ export default class extends React.PureComponent {
<span
{...Theme(props.theme, 'function-value')}
class="rjv-function-container"
onClick={this.toggleCollapsed}
{...generateExpanderProps(this.toggleCollapsed, !collapsed)}
>
{this.getFunctionDisplay(collapsed)}
</span>
Expand Down
10 changes: 6 additions & 4 deletions src/js/components/DataTypes/Object.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { polyfill } from 'react-lifecycles-compat';
import { toType } from './../../helpers/util';
import { toType, generateExpanderProps } from './../../helpers/util';

//data type components
import { JsonObject } from './DataTypes';
Expand Down Expand Up @@ -156,10 +156,12 @@ class RjvObject extends React.PureComponent {
return (
<span>
<span
onClick={e => {
this.toggleCollapsed();
}}
{...generateExpanderProps(
this.toggleCollapsed,
this.state.expanded
)}
{...Theme(theme, 'brace-row')}
className="rjv-object-container"
>
<div
class="icon-container"
Expand Down
7 changes: 5 additions & 2 deletions src/js/components/DataTypes/String.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import DataTypeLabel from './DataTypeLabel';
import { toType } from './../../helpers/util';
import { toType, generateExpanderProps } from './../../helpers/util';

//theme
import Theme from './../../themes/getStyle';
Expand Down Expand Up @@ -67,7 +67,10 @@ export default class extends React.PureComponent {
<span
class="string-value"
{...style}
onClick={this.toggleCollapsed}
{...generateExpanderProps(
this.toggleCollapsed,
this.state.expanded
)}
>
{quotesOnValues ? '"' : ''}
{value}
Expand Down
17 changes: 17 additions & 0 deletions src/js/helpers/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,20 @@ export function isTheme(theme) {
}
return false;
}

export function generateExpanderProps(callback, isExpanded) {
function handler(e) {
if (e && e.key && e.key != 'Enter') {
return;
} else {
return callback(e);
}
}
return {
onClick: callback,
onKeyDown: handler,
role: 'button',
tabIndex: '0',
'aria-expanded': isExpanded
};
}
110 changes: 72 additions & 38 deletions test/tests/js/components/DataTypes/Function-test.js
Original file line number Diff line number Diff line change
@@ -1,86 +1,120 @@
import React from "react"
import { shallow, mount } from "enzyme"
import { expect } from "chai"
import React from 'react';
import { shallow, mount } from 'enzyme';
import { expect } from 'chai';

import JsonFunction from "./../../../../../src/js/components/DataTypes/Function"
import JsonFunction from './../../../../../src/js/components/DataTypes/Function';

import AttributeStore from "./../../../../../src/js/stores/ObjectAttributes"
import AttributeStore from './../../../../../src/js/stores/ObjectAttributes';

describe("<JsonFunction />", function() {
const rjvId = 1
describe('<JsonFunction />', function () {
const rjvId = 1;

it("function component should have a data type label", function() {
it('function component should have a data type label', function () {
const wrapper = mount(
<JsonFunction
value={function() {}}
value={function () {}}
rjvId={rjvId}
displayDataTypes={true}
theme="rjv-default"
/>
)
expect(wrapper.find(".data-type-label")).to.have.length(1)
})
);
expect(wrapper.find('.data-type-label')).to.have.length(1);
});

it("function component should not have a data type label", function() {
it('function component should not have a data type label', function () {
const wrapper = mount(
<JsonFunction
value={function() {}}
value={function () {}}
rjvId={rjvId}
displayDataTypes={false}
theme="rjv-default"
/>
)
expect(wrapper.find(".data-type-label")).to.have.length(0)
})
);
expect(wrapper.find('.data-type-label')).to.have.length(0);
});

it("function component expanded", function() {
AttributeStore.set(rjvId, "function-test", "collapsed", false)
it('function component expanded', function () {
AttributeStore.set(rjvId, 'function-test', 'collapsed', false);

const wrapper = shallow(
<JsonFunction
value={function() {}}
value={function () {}}
namespace="function-test"
rjvId={rjvId}
displayDataTypes={true}
theme="rjv-default"
/>
)
expect(wrapper.find(".function-collapsed")).to.have.length(0)
})
);
expect(wrapper.find('.function-collapsed')).to.have.length(0);
});

it("function component collapsed", function() {
AttributeStore.set(rjvId, "function-test", "collapsed", true)
it('function component collapsed', function () {
AttributeStore.set(rjvId, 'function-test', 'collapsed', true);

const wrapper = shallow(
<JsonFunction
value={function() {}}
value={function () {}}
namespace="function-test"
rjvId={rjvId}
displayDataTypes={true}
theme="rjv-default"
/>
)
);

expect(wrapper.find(".function-collapsed")).to.have.length(1)
})
expect(wrapper.find('.function-collapsed')).to.have.length(1);
});

it("function component click to expand", function() {
AttributeStore.set(rjvId, "function-test", "collapsed", true)
it('function component click to expand', function () {
AttributeStore.set(rjvId, 'function-test', 'collapsed', true);

const wrapper = shallow(
<JsonFunction
value={function() {}}
value={function () {}}
namespace="function-test"
rjvId={rjvId}
displayDataTypes={true}
theme="rjv-default"
/>
)
);

expect(wrapper.find(".function-collapsed")).to.have.length(1)
expect(wrapper.find('.function-collapsed')).to.have.length(1);
expect(
wrapper.find('.rjv-function-container').prop('aria-expanded')
).to.equal(false);

wrapper.find(".rjv-function-container").simulate("click")
wrapper.find('.rjv-function-container').simulate('click');

expect(wrapper.find(".function-collapsed")).to.have.length(0)
})
})
expect(wrapper.find('.function-collapsed')).to.have.length(0);
expect(
wrapper.find('.rjv-function-container').prop('aria-expanded')
).to.equal(true);
});

it('function component keydown to expand', function () {
AttributeStore.set(rjvId, 'function-test', 'collapsed', true);

const wrapper = shallow(
<JsonFunction
value={function () {}}
namespace="function-test"
rjvId={rjvId}
displayDataTypes={true}
theme="rjv-default"
/>
);

expect(wrapper.find('.function-collapsed')).to.have.length(1);
expect(
wrapper.find('.rjv-function-container').prop('aria-expanded')
).to.equal(false);

wrapper
.find('.rjv-function-container')
.simulate('keydown', { key: 'Enter' });

expect(wrapper.find('.function-collapsed')).to.have.length(0);
expect(
wrapper.find('.rjv-function-container').prop('aria-expanded')
).to.equal(true);
});
});
54 changes: 53 additions & 1 deletion test/tests/js/components/DataTypes/Object-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import { expect } from 'chai';
import JsonObject from './../../../../../src/js/components/DataTypes/Object';

describe('<JsonObject />', function () {
const rjvId = 1;
let rjvId = 1;

beforeEach(() => {
rjvId++;
});

it('Object component should have a data type label', function () {
let src = {
Expand Down Expand Up @@ -373,4 +377,52 @@ describe('<JsonObject />', function () {
);
expect(wrapper.text()).to.equal('"":{"d":"d""b":"b""a":"a""c":"c"}');
});

it('Object click to expand', function () {
let src = {
obj: {
test: true
}
};
const wrapper = shallow(
<JsonObject src={src} rjvId={rjvId} namespace={['root']} />
);
expect(
wrapper.find('.rjv-object-container').prop('aria-expanded')
).to.equal(false);
wrapper.find('.rjv-object-container').simulate('click');
expect(
wrapper.find('.rjv-object-container').prop('aria-expanded')
).to.equal(true);
});

it('Object keydown to expand', function () {
let src = {
obj: {
test: true
}
};
const wrapper = shallow(
<JsonObject src={src} rjvId={rjvId} namespace={['root']} />
);

expect(
wrapper.find('.rjv-object-container').prop('aria-expanded')
).to.equal(false);

wrapper
.find('.rjv-object-container')
.simulate('keydown', { key: 'Space' });

expect(
wrapper.find('.rjv-object-container').prop('aria-expanded')
).to.equal(false);

wrapper
.find('.rjv-object-container')
.simulate('keydown', { key: 'Enter' });
expect(
wrapper.find('.rjv-object-container').at(0).prop('aria-expanded')
).to.equal(true);
});
});
Loading

0 comments on commit fbd30d8

Please sign in to comment.