Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@khanacademy/wonder-blocks-link

Package Overview
Dependencies
Maintainers
1
Versions
299
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@khanacademy/wonder-blocks-link - npm Package Compare versions

Comparing version 1.0.1 to 2.0.0

components/link.md

51

components/link-core.js

@@ -5,2 +5,3 @@ // @flow

import {Link} from "react-router-dom";
import PropTypes from "prop-types";

@@ -23,20 +24,23 @@ import {addStyle} from "@khanacademy/wonder-blocks-core";

const StyledAnchor = addStyle("a");
// $FlowFixMe: pass props directly to StyledLink instead of to Tag
const StyledLink = addStyle(Link);
export default class LinkCore extends React.Component<Props> {
getProps() {
static contextTypes = {router: PropTypes.any};
render() {
const {
caret, // eslint-disable-line no-unused-vars
children,
skipClientNav,
focused,
hovered,
href,
kind,
light,
pressed,
style,
testId,
style,
hovered,
focused,
pressed,
href,
clientNav,
...handlers
} = this.props;
const {router} = this.context;

@@ -53,26 +57,18 @@ const linkStyles = _generateStyles(kind, light);

const props = {
const commonProps = {
"data-test-id": testId,
style: [defaultStyles, style],
"data-test-id": testId,
...handlers,
};
if (clientNav) {
// $FlowFixMe
props.to = href;
} else {
// $FlowFixMe
props.href = href;
}
return props;
return router && !skipClientNav ? (
<StyledLink {...commonProps} to={href}>
{children}
</StyledLink>
) : (
<StyledAnchor {...commonProps} href={href}>
{children}
</StyledAnchor>
);
}
render() {
const {children, clientNav} = this.props;
const Tag = clientNav ? StyledLink : StyledAnchor;
return <Tag {...this.getProps()}>{children}</Tag>;
}
}

@@ -121,2 +117,3 @@

color: light ? mix(fade(blue, 0.32), white) : mix(offBlack32, blue),
textDecoration: "underline currentcolor solid",
":visited": {

@@ -123,0 +120,0 @@ color: light

// @flow
import * as React from "react";
import PropTypes from "prop-types";

@@ -25,3 +26,3 @@ import LinkCore from "./link-core.js";

/**
* Kind of Link. Note: Secondary light Links ar enot supported.
* Kind of Link. Note: Secondary light Links are not supported.
*/

@@ -41,7 +42,8 @@ kind: "primary" | "secondary",

/**
* Whether to use client-side navigation.
* Whether to avoid using client-side navigation.
*
* If the URL passed to href is local to the client-side, e.g.
* /math/algebra/eval-exprs, then it uses react-router-dom's Link
* component which handles the client-side navigation.
* /math/algebra/eval-exprs, then it tries to use react-router-dom's Link
* component which handles the client-side navigation. You can set
* `skipClientNav` to true avoid using client-side nav entirely.
*

@@ -52,3 +54,3 @@ * NOTE: All URLs containing a protocol are considered external, e.g.

*/
clientNav?: boolean,
skipClientNav?: boolean,

@@ -68,6 +70,7 @@ /**

*/
|};
type Props = {|
...SharedProps,
// NOTE(jeresig): Currently React Docgen (used by Styleguidist) doesn't
// support ... inside of an exact object type. Thus we had to move the
// following propers into this SharedProps, even though they should be
// external. Once that's fixed we can split them back apart.

@@ -103,3 +106,3 @@ /**

*/
export default class Link extends React.Component<Props> {
export default class Link extends React.Component<SharedProps> {
static defaultProps = {

@@ -111,8 +114,16 @@ caret: false,

static contextTypes = {router: PropTypes.any};
render() {
const {onClick, href, clientNav, children, ...sharedProps} = this.props;
const {
onClick,
href,
skipClientNav,
children,
...sharedProps
} = this.props;
const ClickableBehavior = getClickableBehavior(
href,
clientNav,
skipClientNav,
this.context.router,

@@ -129,3 +140,3 @@ );

{...handlers}
clientNav={clientNav}
skipClientNav={skipClientNav}
href={href}

@@ -132,0 +143,0 @@ >

// @flow
import React from "react";
import {mount} from "enzyme";
import {MemoryRouter, Route, Switch} from "react-router-dom";
import {mount, unmountAll} from "../../../utils/testing/mount.js";
import Link from "./link.js";
describe("Link", () => {
test("TODO", () => {
const wrapper = mount(<Link href="#">Hello World!</Link>);
wrapper.simulate("click");
beforeEach(() => {
unmountAll();
});
});
test("client-side navigation", () => {
// Arrange
const wrapper = mount(
<MemoryRouter>
<div>
<Link testId="link" href="/foo">
Click me!
</Link>
<Switch>
<Route path="/foo">
<div id="foo">Hello, world!</div>
</Route>
</Switch>
</div>
</MemoryRouter>,
);
// Act
const buttonWrapper = wrapper.find(`[data-test-id="link"]`).first();
buttonWrapper.simulate("click", {button: 0});
// Assert
expect(wrapper.find("#foo").exists()).toBe(true);
});
test("client-side navigation with unknown URL fails", () => {
// Arrange
const wrapper = mount(
<MemoryRouter>
<div>
<Link testId="link" href="/unknown">
Click me!
</Link>
<Switch>
<Route path="/foo">
<div id="foo">Hello, world!</div>
</Route>
</Switch>
</div>
</MemoryRouter>,
);
// Act
const buttonWrapper = wrapper.find(`[data-test-id="link"]`).first();
buttonWrapper.simulate("click", {button: 0});
// Assert
expect(wrapper.find("#foo").exists()).toBe(false);
});
test("client-side navigation with `skipClientNav` set to `true` fails", () => {
// Arrange
const wrapper = mount(
<MemoryRouter>
<div>
<Link testId="link" href="/foo" skipClientNav>
Click me!
</Link>
<Switch>
<Route path="/foo">
<div id="foo">Hello, world!</div>
</Route>
</Switch>
</div>
</MemoryRouter>,
);
// Act
const buttonWrapper = wrapper.find(`[data-test-id="link"]`).first();
buttonWrapper.simulate("click", {button: 0});
// Assert
expect(wrapper.find("#foo").exists()).toBe(false);
});
});

@@ -18,3 +18,5 @@ // @flow

onKeyUp: () => void 0,
onFocus: () => void 0,
onBlur: () => void 0,
tabIndex: 0,
};

@@ -44,3 +46,2 @@

{...defaultHandlers}
tabIndex={0}
>

@@ -47,0 +48,0 @@ Click me

@@ -85,3 +85,3 @@ module.exports =

/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 7);
/******/ return __webpack_require__(__webpack_require__.s = 8);
/******/ })

@@ -99,3 +99,3 @@ /************************************************************************/

module.exports = require("react");
module.exports = require("prop-types");

@@ -106,3 +106,3 @@ /***/ }),

module.exports = require("@khanacademy/wonder-blocks-color");
module.exports = require("react");

@@ -113,3 +113,3 @@ /***/ }),

module.exports = require("react-router-dom");
module.exports = require("@khanacademy/wonder-blocks-color");

@@ -120,6 +120,12 @@ /***/ }),

module.exports = require("react-router-dom");
/***/ }),
/* 5 */
/***/ (function(module, exports) {
module.exports = require("aphrodite");
/***/ }),
/* 5 */
/* 6 */
/***/ (function(module, exports, __webpack_require__) {

@@ -138,13 +144,17 @@

var _react = __webpack_require__(1);
var _react = __webpack_require__(2);
var _react2 = _interopRequireDefault(_react);
var _aphrodite = __webpack_require__(4);
var _aphrodite = __webpack_require__(5);
var _reactRouterDom = __webpack_require__(3);
var _reactRouterDom = __webpack_require__(4);
var _propTypes = __webpack_require__(1);
var _propTypes2 = _interopRequireDefault(_propTypes);
var _wonderBlocksCore = __webpack_require__(0);
var _wonderBlocksColor = __webpack_require__(2);
var _wonderBlocksColor = __webpack_require__(3);

@@ -164,3 +174,2 @@ var _wonderBlocksColor2 = _interopRequireDefault(_wonderBlocksColor);

var StyledAnchor = (0, _wonderBlocksCore.addStyle)("a");
// $FlowFixMe: pass props directly to StyledLink instead of to Tag
var StyledLink = (0, _wonderBlocksCore.addStyle)(_reactRouterDom.Link);

@@ -178,17 +187,21 @@

_createClass(LinkCore, [{
key: "getProps",
value: function getProps() {
key: "render",
value: function render() {
var _props = this.props,
caret = _props.caret,
children = _props.children,
skipClientNav = _props.skipClientNav,
focused = _props.focused,
hovered = _props.hovered,
href = _props.href,
kind = _props.kind,
light = _props.light,
pressed = _props.pressed,
style = _props.style,
testId = _props.testId,
style = _props.style,
hovered = _props.hovered,
focused = _props.focused,
pressed = _props.pressed,
href = _props.href,
clientNav = _props.clientNav,
handlers = _objectWithoutProperties(_props, ["caret", "kind", "light", "testId", "style", "hovered", "focused", "pressed", "href", "clientNav"]);
handlers = _objectWithoutProperties(_props, ["caret", "children", "skipClientNav", "focused", "hovered", "href", "kind", "light", "pressed", "style", "testId"]);
var router = this.context.router;
var linkStyles = _generateStyles(kind, light);

@@ -198,31 +211,15 @@

var props = _extends({
style: [defaultStyles, style],
"data-test-id": testId
var commonProps = _extends({
"data-test-id": testId,
style: [defaultStyles, style]
}, handlers);
if (clientNav) {
// $FlowFixMe
props.to = href;
} else {
// $FlowFixMe
props.href = href;
}
return props;
}
}, {
key: "render",
value: function render() {
var _props2 = this.props,
children = _props2.children,
clientNav = _props2.clientNav;
var Tag = clientNav ? StyledLink : StyledAnchor;
return _react2.default.createElement(
Tag,
this.getProps(),
return router && !skipClientNav ? _react2.default.createElement(
StyledLink,
_extends({}, commonProps, { to: href }),
children
) : _react2.default.createElement(
StyledAnchor,
_extends({}, commonProps, { href: href }),
children
);

@@ -235,2 +232,3 @@ }

LinkCore.contextTypes = { router: _propTypes2.default.any };
exports.default = LinkCore;

@@ -284,2 +282,3 @@

color: light ? (0, _wonderBlocksColor.mix)((0, _wonderBlocksColor.fade)(blue, 0.32), white) : (0, _wonderBlocksColor.mix)(offBlack32, blue),
textDecoration: "underline currentcolor solid",
":visited": {

@@ -296,3 +295,3 @@ color: light ? (0, _wonderBlocksColor.mix)((0, _wonderBlocksColor.fade)(blue, 0.32), white) : (0, _wonderBlocksColor.mix)(offBlack32, linkPurple)

/***/ }),
/* 6 */
/* 7 */
/***/ (function(module, exports, __webpack_require__) {

@@ -311,8 +310,12 @@

var _react = __webpack_require__(1);
var _react = __webpack_require__(2);
var React = _interopRequireWildcard(_react);
var _linkCore = __webpack_require__(5);
var _propTypes = __webpack_require__(1);
var _propTypes2 = _interopRequireDefault(_propTypes);
var _linkCore = __webpack_require__(6);
var _linkCore2 = _interopRequireDefault(_linkCore);

@@ -366,7 +369,7 @@

href = _props.href,
clientNav = _props.clientNav,
skipClientNav = _props.skipClientNav,
children = _props.children,
sharedProps = _objectWithoutProperties(_props, ["onClick", "href", "clientNav", "children"]);
sharedProps = _objectWithoutProperties(_props, ["onClick", "href", "skipClientNav", "children"]);
var ClickableBehavior = (0, _wonderBlocksCore.getClickableBehavior)(href, clientNav, this.context.router);
var ClickableBehavior = (0, _wonderBlocksCore.getClickableBehavior)(href, skipClientNav, this.context.router);

@@ -380,3 +383,3 @@ return React.createElement(

_extends({}, sharedProps, state, handlers, {
clientNav: clientNav,
skipClientNav: skipClientNav,
href: href

@@ -399,6 +402,7 @@ }),

};
Link.contextTypes = { router: _propTypes2.default.any };
exports.default = Link;
/***/ }),
/* 7 */
/* 8 */
/***/ (function(module, exports, __webpack_require__) {

@@ -414,3 +418,3 @@

var _link = __webpack_require__(6);
var _link = __webpack_require__(7);

@@ -417,0 +421,0 @@ var _link2 = _interopRequireDefault(_link);

@@ -15,8 +15,37 @@ // This file is auto-generated by gen-snapshot-tests.js

it("example 1", () => {
const Color = require("@khanacademy/wonder-blocks-color").default;
const {View} = require("@khanacademy/wonder-blocks-core");
const example = (
<p>
Lorem ipsum <Link href="#nonexistent-link">Link</Link> dolor sit
amet, consectetur <Link href="#">Visited Link</Link> adipiscing
elit
</p>
<View>
<p>
I am a <Link href="#nonexistent-link">Primary Link</Link>.{" "}
<span style={{color: Color.offBlack64}}>
My friend the
<Link
href="#secondary-nonexistent-link"
kind="secondary"
>
Secondary Link
</Link>{" "}
is used here with a lighter text.
</span>{" "}
We also have a
<Link href="#">Visited Link</Link> friend.
</p>
<p
style={{
backgroundColor: Color.darkBlue,
color: Color.white64,
padding: 10,
}}
>
I am a{" "}
<Link href="#dark-link" light={true}>
Primary Link
</Link>{" "}
used on a dark background. My friend the Secondary Link
isn't supported on this dark background.
</p>
</View>
);

@@ -23,0 +52,0 @@ const tree = renderer.create(example).toJSON();

{
"name": "@khanacademy/wonder-blocks-link",
"version": "1.0.1",
"version": "2.0.0",
"design": "v1",

@@ -17,5 +17,11 @@ "publishConfig": {

"dependencies": {
"@khanacademy/wonder-blocks-color": "^1.0.4",
"@khanacademy/wonder-blocks-core": "^1.0.4"
"@khanacademy/wonder-blocks-color": "^1.0.5",
"@khanacademy/wonder-blocks-core": "^1.1.0"
},
"peerDependencies": {
"aphrodite": "^1.2.5",
"prop-types": "^15.6.2",
"react": "^16.4.1",
"react-router-dom": "^4.2.2"
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc