diff --git a/docs/api/components/Link.md b/docs/api/components/Link.md index 9f4a707ec7..c5efeaf460 100644 --- a/docs/api/components/Link.md +++ b/docs/api/components/Link.md @@ -36,9 +36,13 @@ your route handler with `this.getQuery()`. ### `activeClassName` -The className a `Link` receives when it's route is active. Defaults to +The className a `Link` receives when its route is active. Defaults to `active`. +### `activeStyle` + +Object, the styles to apply to the link element when its route is active. + ### `onClick` A custom handler for the click event. Works just like a handler on an `` @@ -67,5 +71,8 @@ active --> {user.name} + + +{user.name} ``` diff --git a/modules/components/Link.js b/modules/components/Link.js index 9ed4f9fbcf..14c9072679 100644 --- a/modules/components/Link.js +++ b/modules/components/Link.js @@ -42,6 +42,7 @@ var Link = React.createClass({ to: PropTypes.string.isRequired, params: PropTypes.object, query: PropTypes.object, + activeStyle: PropTypes.object, onClick: PropTypes.func }, @@ -87,12 +88,16 @@ var Link = React.createClass({ if (this.props.className) classNames[this.props.className] = true; - if (this.isActive(this.props.to, this.props.params, this.props.query)) + if (this.getActiveState()) classNames[this.props.activeClassName] = true; return classSet(classNames); }, + getActiveState: function () { + return this.isActive(this.props.to, this.props.params, this.props.query); + }, + render: function () { var props = assign({}, this.props, { href: this.getHref(), @@ -100,6 +105,9 @@ var Link = React.createClass({ onClick: this.handleClick }); + if (props.activeStyle && this.getActiveState()) + props.style = props.activeStyle; + return React.DOM.a(props, this.props.children); } diff --git a/modules/components/__tests__/Link-test.js b/modules/components/__tests__/Link-test.js index d1f83d4946..40e898199c 100644 --- a/modules/components/__tests__/Link-test.js +++ b/modules/components/__tests__/Link-test.js @@ -73,23 +73,82 @@ describe('A Link', function () { expect(a.className).toEqual('dontKillMe'); } - steps.push(() => { + steps.push(function () { + assertActive(); + TestLocation.push('/bar'); + }); + + steps.push(function () { + assertInactive(); + TestLocation.push('/foo'); + }); + + steps.push(function () { + assertActive(); + done(); + }); + + Router.run(routes, TestLocation, function (Handler) { + React.render(, div, function () { + steps.shift()(); + }); + }); + }); + + it('has applies activeStyle', function (done) { + var LinkHandler = React.createClass({ + render: function () { + return ( +
+ Link + +
+ ); + } + }); + + var routes = ( + + + + + ); + + var div = document.createElement('div'); + TestLocation.history = ['/foo']; + var steps = []; + + function assertActive () { + var a = div.querySelector('a'); + expect(a.style.color).toEqual('red'); + } + + function assertInactive () { + var a = div.querySelector('a'); + expect(a.style.color).toEqual('white'); + } + + steps.push(function () { assertActive(); TestLocation.push('/bar'); }); - steps.push(() => { + steps.push(function () { assertInactive(); TestLocation.push('/foo'); }); - steps.push(() => { + steps.push(function () { assertActive(); done(); }); Router.run(routes, TestLocation, function (Handler) { - React.render(, div, () => { + React.render(, div, function () { steps.shift()(); }); });