Skip to content

Commit cb30941

Browse files
Added thumbnail component including docs and tests
1 parent 83d6220 commit cb30941

13 files changed

+183
-10
lines changed

docs/assets/thumbnail.png

3.84 KB
Loading

docs/assets/thumbnaildiv.png

4.06 KB
Loading

docs/client.js

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import './assets/style.css';
55
import './assets/carousel.png';
66
import './assets/logo.png';
77
import './assets/favicon.ico';
8+
import './assets/thumbnail.png';
9+
import './assets/thumbnaildiv.png';
810

911
import 'codemirror/mode/javascript/javascript';
1012
import 'codemirror/theme/solarized.css';

docs/examples/.eslintrc

+2-1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
"Table",
4949
"TabPane",
5050
"Tooltip",
51-
"Well"
51+
"Well",
52+
"Thumbnail"
5253
}
5354
}

docs/examples/ThumbnailAnchor.js

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const thumbnailInstance = (
2+
<Grid>
3+
<Row>
4+
<Col xs={6} md={3}>
5+
<Thumbnail href='#' alt='171x180' src='/assets/thumbnail.png' />
6+
</Col>
7+
<Col xs={6} md={3}>
8+
<Thumbnail href='#' alt='171x180' src='/assets/thumbnail.png' />
9+
</Col>
10+
<Col xs={6} md={3}>
11+
<Thumbnail href='#' alt='171x180' src='/assets/thumbnail.png' />
12+
</Col>
13+
</Row>
14+
</Grid>
15+
);
16+
17+
React.render(thumbnailInstance, mountNode);

docs/examples/ThumbnailDiv.js

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
const thumbnailInstance = (
2+
<Grid>
3+
<Row>
4+
<Col xs={6} md={4}>
5+
<Thumbnail src='/assets/thumbnaildiv.png' alt='242x200'>
6+
<h3>Thumbnail label</h3>
7+
<p>Description</p>
8+
<p>
9+
<Button bsStyle='primary'>Button</Button>&nbsp;
10+
<Button bsStyle='default'>Button</Button>
11+
</p>
12+
</Thumbnail>
13+
</Col>
14+
<Col xs={6} md={4}>
15+
<Thumbnail src='/assets/thumbnaildiv.png' alt='242x200'>
16+
<h3>Thumbnail label</h3>
17+
<p>Description</p>
18+
<p>
19+
<Button bsStyle='primary'>Button</Button>&nbsp;
20+
<Button bsStyle='default'>Button</Button>
21+
</p>
22+
</Thumbnail>
23+
</Col>
24+
<Col xs={6} md={4}>
25+
<Thumbnail src='/assets/thumbnaildiv.png' alt='242x200'>
26+
<h3>Thumbnail label</h3>
27+
<p>Description</p>
28+
<p>
29+
<Button bsStyle='primary'>Button</Button>&nbsp;
30+
<Button bsStyle='default'>Button</Button>
31+
</p>
32+
</Thumbnail>
33+
</Col>
34+
</Row>
35+
</Grid>
36+
);
37+
38+
React.render(thumbnailInstance, mountNode);

docs/src/ComponentsPage.js

+24-9
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,20 @@ const ComponentsPage = React.createClass({
449449
<ReactPlayground codeText={Samples.GridBasic} exampleClassName='bs-example-tabs' />
450450
</div>
451451

452+
{/* Thumbnail */}
453+
<div className='bs-docs-section'>
454+
<h1 id='thumbnail' className='page-header'>Thumbnail</h1>
455+
<p>Thumbnails are designed to showcase linked images with minimal required markup. You can extend the grid component with thumbnails.</p>
456+
457+
<h3>Anchor Thumbnail</h3>
458+
<p>Creates an anchor wrapping an image.</p>
459+
<ReactPlayground codeText={Samples.ThumbnailAnchor} />
460+
461+
<h3>Divider Thumbnail</h3>
462+
<p>Creates a divider wrapping an image and other children elements.</p>
463+
<ReactPlayground codeText={Samples.ThumbnailDiv} />
464+
</div>
465+
452466
{/* ListGroup */}
453467
<div className='bs-docs-section'>
454468
<h1 id='listgroup' className='page-header'>List group<small> ListGroup, ListGroupItem</small></h1>
@@ -606,15 +620,16 @@ const ComponentsPage = React.createClass({
606620
<NavItem href='#alerts' key={13}>Alerts</NavItem>
607621
<NavItem href='#carousels' key={14}>Carousels</NavItem>
608622
<NavItem href='#grids' key={15}>Grids</NavItem>
609-
<NavItem href='#listgroup' key={16}>List group</NavItem>
610-
<NavItem href='#labels' key={17}>Labels</NavItem>
611-
<NavItem href='#badges' key={18}>Badges</NavItem>
612-
<NavItem href='#jumbotron' key={19}>Jumbotron</NavItem>
613-
<NavItem href='#page-header' key={20}>Page Header</NavItem>
614-
<NavItem href='#wells' key={21}>Wells</NavItem>
615-
<NavItem href='#glyphicons' key={22}>Glyphicons</NavItem>
616-
<NavItem href='#tables' key={23}>Tables</NavItem>
617-
<NavItem href='#input' key={24}>Input</NavItem>
623+
<NavItem href='#thumbnail' key={16}>Thumbnail</NavItem>
624+
<NavItem href='#listgroup' key={17}>List group</NavItem>
625+
<NavItem href='#labels' key={18}>Labels</NavItem>
626+
<NavItem href='#badges' key={19}>Badges</NavItem>
627+
<NavItem href='#jumbotron' key={20}>Jumbotron</NavItem>
628+
<NavItem href='#page-header' key={21}>Page Header</NavItem>
629+
<NavItem href='#wells' key={22}>Wells</NavItem>
630+
<NavItem href='#glyphicons' key={23}>Glyphicons</NavItem>
631+
<NavItem href='#tables' key={24}>Tables</NavItem>
632+
<NavItem href='#input' key={25}>Input</NavItem>
618633
</Nav>
619634
<a className='back-to-top' href='#top'>
620635
Back to top

docs/src/ReactPlayground.js

+2
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import * as modSplitButton from '../../src/SplitButton';
4040
import * as modTabbedArea from '../../src/TabbedArea';
4141
import * as modTable from '../../src/Table';
4242
import * as modTabPane from '../../src/TabPane';
43+
import * as modThumbnail from '../../src/Thumbnail';
4344
import * as modTooltip from '../../src/Tooltip';
4445
import * as modWell from '../../src/Well';
4546

@@ -88,6 +89,7 @@ const SplitButton = modSplitButton.default;
8889
const TabbedArea = modTabbedArea.default;
8990
const Table = modTable.default;
9091
const TabPane = modTabPane.default;
92+
const Thumbnail = modThumbnail.default;
9193
const Tooltip = modTooltip.default;
9294
const Well = modWell.default;
9395
/* eslint-enable */

docs/src/Samples.js

+2
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ export default {
6767
CarouselUncontrolled: require('fs').readFileSync(__dirname + '/../examples/CarouselUncontrolled.js', 'utf8'),
6868
CarouselControlled: require('fs').readFileSync(__dirname + '/../examples/CarouselControlled.js', 'utf8'),
6969
GridBasic: require('fs').readFileSync(__dirname + '/../examples/GridBasic.js', 'utf8'),
70+
ThumbnailAnchor: require('fs').readFileSync(__dirname + '/../examples/ThumbnailAnchor.js', 'utf8'),
71+
ThumbnailDiv: require('fs').readFileSync(__dirname + '/../examples/ThumbnailDiv.js', 'utf8'),
7072
ListGroupDefault: require('fs').readFileSync(__dirname + '/../examples/ListGroupDefault.js', 'utf8'),
7173
ListGroupLinked: require('fs').readFileSync(__dirname + '/../examples/ListGroupLinked.js', 'utf8'),
7274
ListGroupActive: require('fs').readFileSync(__dirname + '/../examples/ListGroupActive.js', 'utf8'),

src/Thumbnail.js

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import React from 'react';
2+
import classSet from 'classnames';
3+
import BootstrapMixin from './BootstrapMixin';
4+
5+
const Thumbnail = React.createClass({
6+
mixins: [BootstrapMixin],
7+
8+
getDefaultProps() {
9+
return {
10+
bsClass: 'thumbnail'
11+
};
12+
},
13+
14+
render() {
15+
let classes = this.getBsClassSet();
16+
17+
if(this.props.href) {
18+
return (
19+
<a {...this.props} href={this.props.href} className={classSet(this.props.className, classes)}>
20+
<img src={this.props.src} alt={this.props.alt} />
21+
</a>
22+
);
23+
}
24+
else {
25+
if(this.props.children) {
26+
return (
27+
<div {...this.props} className={classSet(this.props.className, classes)}>
28+
<img src={this.props.src} alt={this.props.alt} />
29+
<div className="caption">
30+
{this.props.children}
31+
</div>
32+
</div>
33+
);
34+
}
35+
else {
36+
return (
37+
<div {...this.props} className={classSet(this.props.className, classes)}>
38+
<img src={this.props.src} alt={this.props.alt} />
39+
</div>
40+
);
41+
}
42+
}
43+
}
44+
});
45+
46+
export default Thumbnail;

src/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import SubNav from './SubNav';
4848
import TabbedArea from './TabbedArea';
4949
import Table from './Table';
5050
import TabPane from './TabPane';
51+
import Thumbnail from './Thumbnail';
5152
import Tooltip from './Tooltip';
5253
import Well from './Well';
5354
import styleMaps from './styleMaps';
@@ -103,6 +104,7 @@ export default {
103104
TabbedArea,
104105
Table,
105106
TabPane,
107+
Thumbnail,
106108
Tooltip,
107109
Well,
108110
styleMaps

src/styleMaps.js

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const styleMaps = {
99
'form': 'form',
1010
'glyphicon': 'glyphicon',
1111
'label': 'label',
12+
'thumbnail': 'thumbnail',
1213
'list-group-item': 'list-group-item',
1314
'panel': 'panel',
1415
'panel-group': 'panel-group',

test/ThumbnailSpec.js

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import React from 'react';
2+
import ReactTestUtils from 'react/lib/ReactTestUtils';
3+
import Thumbnail from '../src/Thumbnail';
4+
5+
describe('Thumbnail', function () {
6+
it('Should have a thumbnail class and be an anchor', function () {
7+
let instance = ReactTestUtils.renderIntoDocument(
8+
<Thumbnail href="#" src="#" alt="test" />
9+
);
10+
assert.ok(instance.getDOMNode().className.match(/\bthumbnail\b/));
11+
assert.ok(ReactTestUtils.findRenderedDOMComponentWithTag(instance, 'a'));
12+
});
13+
14+
it('Should have an image', function () {
15+
let instance = ReactTestUtils.renderIntoDocument(
16+
<Thumbnail href="#" src="#" alt="test" />
17+
);
18+
assert.ok(ReactTestUtils.findRenderedDOMComponentWithTag(instance, 'img'));
19+
});
20+
21+
it('Should have a thumbnail class and be a div', function () {
22+
let instance = ReactTestUtils.renderIntoDocument(
23+
<Thumbnail src="#" alt="test" />
24+
);
25+
assert.ok(instance.getDOMNode().className.match(/\bthumbnail\b/));
26+
assert.equal(instance.getDOMNode().nodeName, 'DIV');
27+
});
28+
29+
it('Should have an image', function () {
30+
let instance = ReactTestUtils.renderIntoDocument(
31+
<Thumbnail src="#" alt="test" />
32+
);
33+
assert.ok(ReactTestUtils.findRenderedDOMComponentWithTag(instance, 'img'));
34+
});
35+
36+
it('Should have an inner div with class caption', function () {
37+
let instance = ReactTestUtils.renderIntoDocument(
38+
<Thumbnail src="#" alt="test">
39+
Test
40+
<div>
41+
Test child element
42+
</div>
43+
</Thumbnail>
44+
);
45+
assert.ok(instance.getDOMNode().lastChild.className.match(/\bcaption\b/));
46+
});
47+
});

0 commit comments

Comments
 (0)