@cmsgov/design-system-core
Advanced tools
Comparing version 1.0.0-rc.2 to 1.0.0
@@ -38,2 +38,3 @@ 'use strict'; | ||
var Choice = function Choice(props) { | ||
/* eslint-disable prefer-const */ | ||
var children = props.children, | ||
@@ -44,2 +45,3 @@ className = props.className, | ||
inputProps = _objectWithoutProperties(props, ['children', 'className', 'id', 'inversed']); | ||
/* eslint-enable prefer-const */ | ||
@@ -78,5 +80,4 @@ var inputClasses = (0, _classnames2.default)('ds-c-choice', { 'ds-c-choice--inverse': inversed }); | ||
/** | ||
* Setting this prop will render a read-only field and require an `onChange` | ||
* event handler if you'd want to check its checked stated. Use `defaultChecked` | ||
* if you want the field to be mutable. | ||
* **Note**: Setting this prop will render a read-only field. If the field should be | ||
* mutable, use `defaultChecked`. Otherwise, set either `onChange` or `readOnly` | ||
*/ | ||
@@ -89,4 +90,4 @@ checked: _propTypes2.default.bool, | ||
/** | ||
* Sets the initial checked state and allows the user to check/uncheck the | ||
* field without also requiring an `onChange` event handler. | ||
* Sets the initial checked state. Use this for an uncontrolled component; | ||
* otherwise, use the `checked` property. | ||
*/ | ||
@@ -104,3 +105,3 @@ defaultChecked: _propTypes2.default.bool, | ||
/** | ||
* The `input` `name` attribute | ||
* The `input` field's `name` attribute | ||
*/ | ||
@@ -107,0 +108,0 @@ name: _propTypes2.default.string.isRequired, |
@@ -51,10 +51,9 @@ 'use strict'; | ||
/** | ||
* A `ChoiceList` component can be used to render a `select` menu, radio | ||
* A `ChoiceList` component can be used to render a select menu, radio | ||
* button group, or checkbox group. | ||
* | ||
* You can manually pass in the `type` prop, but the real power of this component | ||
* is unleashed when you let it determine the type of fields for you. It takes | ||
* into account accessibility and usability best practices, so you can pass in | ||
* an array of choices and let it determine what type of field would be best for | ||
* the user. | ||
* By default the component determines the type of field for you, taking | ||
* into account accessibility and usability best practices. So, you can pass in | ||
* an array of `choices` and let it determine what type of field would be best for | ||
* the user, or alternatively you can manually pass in the `type` prop. | ||
*/ | ||
@@ -241,3 +240,3 @@ var ChoiceList = exports.ChoiceList = function (_React$PureComponent) { | ||
/** | ||
* Hint text | ||
* Additional hint text to display | ||
*/ | ||
@@ -250,3 +249,3 @@ hint: _propTypes2.default.node, | ||
/** | ||
* The label for the entire list of choices | ||
* Label for the field | ||
*/ | ||
@@ -263,2 +262,5 @@ label: _propTypes2.default.node.isRequired, | ||
multiple: _propTypes2.default.bool, | ||
/** | ||
* The field's `name` attribute | ||
*/ | ||
name: _propTypes2.default.string.isRequired, | ||
@@ -265,0 +267,0 @@ onBlur: _propTypes2.default.func, |
@@ -37,2 +37,3 @@ 'use strict'; | ||
var Select = function Select(props) { | ||
/* eslint-disable prefer-const */ | ||
var children = props.children, | ||
@@ -43,2 +44,3 @@ className = props.className, | ||
selectProps = _objectWithoutProperties(props, ['children', 'className', 'id', 'inversed']); | ||
/* eslint-enable prefer-const */ | ||
@@ -69,4 +71,4 @@ var classes = (0, _classnames2.default)('ds-c-field ds-c-field--select', { 'ds-c-field--inverse': inversed }, className); | ||
/** | ||
* Sets the initial `selected` state and allows the user to select a different | ||
* option without also requiring an `onChange` event handler. | ||
* Sets the initial selected state. Use this for an uncontrolled component; | ||
* otherwise, use the `selected` property. | ||
*/ | ||
@@ -85,4 +87,5 @@ defaultValue: _propTypes2.default.string, | ||
/** | ||
* Setting this prop to `true` will result in an error message due to | ||
* accessibility concerns. See the usability guidelines for more info. | ||
* Setting this prop will result in a PropTypes error message due to | ||
* accessibility concerns. Use checkboxes instead if you need to support multiple | ||
* selections. See the Guidance tab for more info. | ||
*/ | ||
@@ -96,2 +99,5 @@ multiple: function multiple(props, propName, componentName) { | ||
}, | ||
/** | ||
* The `select` field's `name` attribute | ||
*/ | ||
name: _propTypes2.default.string.isRequired, | ||
@@ -101,5 +107,4 @@ onBlur: _propTypes2.default.func, | ||
/** | ||
* Setting this prop will render a read-only field and require an `onChange` | ||
* event handler if you'd want to change its `selected` stated. Use | ||
* `defaultValue` if you want the field to be mutable. | ||
* **Note**: Setting this prop will render a read-only field. If the field should be | ||
* mutable, use `defaultValue`. Otherwise, set either `onChange` or `readOnly` | ||
*/ | ||
@@ -106,0 +111,0 @@ value: _propTypes2.default.string |
@@ -113,3 +113,3 @@ 'use strict'; | ||
/** | ||
* Hint text | ||
* Additional hint text to display | ||
*/ | ||
@@ -116,0 +116,0 @@ hint: _propTypes2.default.node, |
@@ -91,2 +91,14 @@ 'use strict'; | ||
var _SkipNav = require('./SkipNav/SkipNav'); | ||
Object.keys(_SkipNav).forEach(function (key) { | ||
if (key === "default" || key === "__esModule") return; | ||
Object.defineProperty(exports, key, { | ||
enumerable: true, | ||
get: function get() { | ||
return _SkipNav[key]; | ||
} | ||
}); | ||
}); | ||
var _Tab = require('./Tabs/Tab'); | ||
@@ -162,2 +174,14 @@ | ||
}); | ||
}); | ||
var _VerticalNavItemLabel = require('./VerticalNav/VerticalNavItemLabel'); | ||
Object.keys(_VerticalNavItemLabel).forEach(function (key) { | ||
if (key === "default" || key === "__esModule") return; | ||
Object.defineProperty(exports, key, { | ||
enumerable: true, | ||
get: function get() { | ||
return _VerticalNavItemLabel[key]; | ||
} | ||
}); | ||
}); |
@@ -89,4 +89,4 @@ 'use strict'; | ||
/** | ||
* You can optionally set the `href` attribute used for the tab. This can be | ||
* useful if you want to use relative links rather than a URL hash (the default) | ||
* Sets the `href` attribute used for the tab. This can be useful if you want | ||
* to use relative links rather than a URL hash (the default). | ||
*/ | ||
@@ -101,3 +101,3 @@ href: _propTypes2.default.string, | ||
/** | ||
* The `id` of the associated `TabPanel`. Used for the `aria-controls` attribute | ||
* The `id` of the associated `TabPanel`. Used for the `aria-controls` attribute. | ||
*/ | ||
@@ -104,0 +104,0 @@ panelId: _propTypes2.default.string.isRequired, |
@@ -22,2 +22,6 @@ 'use strict'; | ||
/** | ||
* A `TabPanel` is a presentational component which accepts a tab's content as | ||
* its `children`. | ||
*/ | ||
function TabPanel(props) { | ||
@@ -75,3 +79,3 @@ var classes = (0, _classnames2.default)('ds-c-tabs__panel', props.className); | ||
/** | ||
* The `id` of the associated `Tab`. Used for the `aria-labelledby` attribute | ||
* The `id` of the associated `Tab`. Used for the `aria-labelledby` attribute. | ||
*/ | ||
@@ -78,0 +82,0 @@ tabId: _propTypes2.default.string |
@@ -76,4 +76,4 @@ 'use strict'; | ||
/** | ||
* A container component that manages the state of your tabs for you. For most | ||
* cases, you'll want to use this component rather than the presentational | ||
* `Tabs` is a container component that manages the state of your tabs for you. | ||
* In most cases, you'll want to use this component rather than the presentational | ||
* components (`Tab`, `TabPanel`) on their own. | ||
@@ -207,4 +207,4 @@ */ | ||
/** | ||
* Default selected `TabPanel`'s `id`. If this isn't set, the first `TabPanel` | ||
* will be selected. | ||
* Sets the initial selected `TabPanel` state. If this isn't set, the first | ||
* `TabPanel` will be selected. | ||
*/ | ||
@@ -211,0 +211,0 @@ defaultSelectedId: _propTypes2.default.string, |
@@ -39,5 +39,4 @@ 'use strict'; | ||
/** | ||
The `TextField` component affords a user to type text into a form. | ||
By default it renders a field for capturing a single line of text, | ||
but can be configured to support multiline text. | ||
* A `TextField` component renders an input field as well as supporting UI | ||
* elements like a label, error message, and hint text. | ||
*/ | ||
@@ -108,8 +107,8 @@ var TextField = exports.TextField = function (_React$PureComponent) { | ||
/** | ||
* Additional classes to be added to the root element | ||
* Additional classes to be added to the root `div` element | ||
*/ | ||
className: _propTypes2.default.string, | ||
/** | ||
* Default value of the text field, if any. Use this for an uncontrolled | ||
* component; otherwise, use the `value` property | ||
* Sets the initial value. Use this for an uncontrolled component; otherwise, | ||
* use the `value` property. | ||
*/ | ||
@@ -124,3 +123,3 @@ defaultValue: _propTypes2.default.string, | ||
/** | ||
* Hint text | ||
* Additional hint text to display | ||
*/ | ||
@@ -133,7 +132,7 @@ hint: _propTypes2.default.node, | ||
/** | ||
* The label for the entire list of choices | ||
* Label for the input | ||
*/ | ||
label: _propTypes2.default.node.isRequired, | ||
/** | ||
* Additional classes to be added to the `FormLabel` | ||
* Additional classes to be added to the label | ||
*/ | ||
@@ -149,4 +148,4 @@ labelClassName: _propTypes2.default.string, | ||
/** | ||
* Optionally specify the number of visible text lines for the control. Only | ||
* applicable if this is a multiline field | ||
* Optionally specify the number of visible text lines for the field. Only | ||
* applicable if this is a multiline field. | ||
*/ | ||
@@ -159,4 +158,4 @@ rows: _propTypes2.default.oneOfType([_propTypes2.default.number, _propTypes2.default.string]), | ||
/** | ||
* Current value of the text field. Use this for a controlled component where | ||
* you are maintaining its current state; otherwise, use the `defaultValue` property | ||
* **Note**: Setting this prop will render a read-only field. If the field should be | ||
* mutable, use `defaultValue`. Otherwise, set `onChange` or `disabled`. | ||
*/ | ||
@@ -163,0 +162,0 @@ value: _propTypes2.default.string |
@@ -37,3 +37,3 @@ 'use strict'; | ||
/** | ||
* The `VerticalNav` React component accepts list items as a JSON object and | ||
* A `VerticalNav` component accepts list items as a JSON object and | ||
* includes additional functionality like collapsible nested menus. | ||
@@ -40,0 +40,0 @@ */ |
@@ -22,2 +22,6 @@ 'use strict'; | ||
var _VerticalNavItemLabel = require('./VerticalNavItemLabel'); | ||
var _VerticalNavItemLabel2 = _interopRequireDefault(_VerticalNavItemLabel); | ||
var _classnames = require('classnames'); | ||
@@ -47,10 +51,6 @@ | ||
_this.handleLinkClick = _this.handleLinkClick.bind(_this); | ||
_this.handleToggleClick = _this.handleToggleClick.bind(_this); | ||
_this.handleLabelClick = _this.handleLabelClick.bind(_this); | ||
_this.id = _this.props.id || (0, _lodash2.default)('VerticalNavItem_'); | ||
_this.subnavId = _this.id + '__subnav'; | ||
_this.state = { | ||
collapsed: _this.props.defaultCollapsed | ||
}; | ||
_this.state = { collapsed: _this.props.defaultCollapsed }; | ||
return _this; | ||
@@ -66,5 +66,28 @@ } | ||
} | ||
/** | ||
* Called when VerticalNavItemLabel is clicked. Since the "label" could be | ||
* a link, subnav toggle button, or plain text, we use this method to | ||
* determine what action to take and which event to actually fire. | ||
* @param {Object} SyntheticEvent | ||
*/ | ||
}, { | ||
key: 'handleLinkClick', | ||
value: function handleLinkClick(evt) { | ||
key: 'handleLabelClick', | ||
value: function handleLabelClick(evt) { | ||
if (this.hasSubnav()) { | ||
return this.handleToggleClick(); | ||
} | ||
return this.handleClick(evt); | ||
} | ||
/** | ||
* Note: This event handler will only get called when the VerticalNavItemLabel | ||
* is a link or plain text | ||
*/ | ||
}, { | ||
key: 'handleClick', | ||
value: function handleClick(evt) { | ||
if (this.props.onClick) { | ||
@@ -82,3 +105,3 @@ this.props.onClick(evt, this.id, this.props.url); | ||
value: function hasSubnav() { | ||
return this.props.items && this.props.items.length; | ||
return Boolean(this.props.items && this.props.items.length > 0); | ||
} | ||
@@ -88,2 +111,3 @@ | ||
* Check if this item is selected or if it is a parent of a selected item | ||
* @return {Boolean} | ||
*/ | ||
@@ -99,2 +123,4 @@ | ||
} | ||
return false; | ||
} | ||
@@ -105,2 +131,3 @@ | ||
* @param {Array} children - The nested items | ||
* @return {Boolean} | ||
*/ | ||
@@ -122,18 +149,15 @@ | ||
}, { | ||
key: 'renderSubnavToggle', | ||
value: function renderSubnavToggle() { | ||
if (this.hasSubnav()) { | ||
var label = this.state.collapsed ? this.props.ariaCollapsedStateButtonLabel : this.props.ariaExpandedStateButtonLabel; | ||
key: 'subnavItems', | ||
value: function subnavItems() { | ||
if (this.props.url) { | ||
// Since the VerticalNavItemLabel will just toggle the subnav, we | ||
// add a link to the top of the subnav for this item. Otherwise there | ||
// wouldn't be a way to actually visit its URL | ||
var item = Object.assign({}, this.props); | ||
delete item.items; | ||
return _react2.default.createElement( | ||
'button', | ||
{ | ||
'aria-controls': this.subnavId, | ||
'aria-expanded': !this.state.collapsed, | ||
className: 'ds-c-vertical-nav__subnav-toggle', | ||
onClick: this.handleToggleClick | ||
}, | ||
label | ||
); | ||
return [item].concat(this.props.items); | ||
} | ||
return this.props.items; | ||
} | ||
@@ -148,3 +172,3 @@ }, { | ||
id: this.subnavId, | ||
items: this.props.items, | ||
items: this.subnavItems(), | ||
nested: true | ||
@@ -158,11 +182,2 @@ }); | ||
var classes = (0, _classnames2.default)('ds-c-vertical-nav__item', this.props.className); | ||
var LinkComponent = this.props.url ? 'a' : 'div'; | ||
var linkProps = { | ||
className: (0, _classnames2.default)('ds-c-vertical-nav__link', { | ||
'ds-c-vertical-nav__link--current': this.isSelected(), | ||
'ds-c-vertical-nav__link--parent': this.hasSubnav() | ||
}), | ||
href: this.props.url ? this.props.url : undefined, | ||
onClick: this.props.onClick ? this.handleLinkClick : undefined | ||
}; | ||
@@ -172,8 +187,13 @@ return _react2.default.createElement( | ||
{ className: classes }, | ||
_react2.default.createElement( | ||
LinkComponent, | ||
linkProps, | ||
this.props.label | ||
), | ||
this.renderSubnavToggle(), | ||
_react2.default.createElement(_VerticalNavItemLabel2.default, { | ||
ariaCollapsedStateButtonLabel: this.props.ariaCollapsedStateButtonLabel, | ||
ariaExpandedStateButtonLabel: this.props.ariaExpandedStateButtonLabel, | ||
collapsed: this.state.collapsed, | ||
label: this.props.label, | ||
hasSubnav: this.hasSubnav(), | ||
onClick: this.handleLabelClick, | ||
selected: this.isSelected(), | ||
subnavId: this.subnavId, | ||
url: this.props.url | ||
}), | ||
this.renderSubnav() | ||
@@ -188,2 +208,5 @@ ); | ||
VerticalNavItem.defaultProps = { | ||
// Unfortunately, we're defining these default ARIA pros here and in | ||
// VerticalNavItemLabel. We define them here so they show in the docs. | ||
// TODO(sawyer): Update react-docgen so we don't have to do this | ||
ariaCollapsedStateButtonLabel: 'Expand sub-navigation', | ||
@@ -214,3 +237,3 @@ ariaExpandedStateButtonLabel: 'Collapse sub-navigation', | ||
/** | ||
* Called when the item is clicked, with the following arguments: | ||
* Called when the link is clicked, with the following arguments: | ||
* [`SyntheticEvent`](https://facebook.github.io/react/docs/events.html), | ||
@@ -217,0 +240,0 @@ * `id`, `url`. |
{ | ||
"name": "@cmsgov/design-system-core", | ||
"version": "1.0.0-rc.2", | ||
"version": "1.0.0", | ||
"publishConfig": { | ||
@@ -12,3 +12,3 @@ "access": "public" | ||
"dependencies": { | ||
"@cmsgov/design-system-support": "^1.0.0-rc.2", | ||
"@cmsgov/design-system-support": "^1.0.0", | ||
"classnames": "^2.2.5", | ||
@@ -15,0 +15,0 @@ "lodash.uniqueid": "^4.0.1", |
@@ -5,4 +5,5 @@ This package contains the following design system assets: | ||
- Utility classes | ||
- Core Sass/CSS components | ||
- Core React components | ||
- Sass/CSS and React components | ||
- Sass mixins and variables | ||
- Fonts and images | ||
@@ -29,3 +30,3 @@ ## Installation | ||
[Please view the documentation site for additional information.](https://cmsgov.github.io/design-system/) | ||
[Please view the documentation site for additional information.](https://design.cms.gov/) | ||
@@ -49,4 +50,6 @@ ## Examples | ||
``` | ||
├── dist Transpiled CSS and fonts | ||
└── src Sass and JSX | ||
├── dist Compiled CSS and JS | ||
├── fonts | ||
├── images | ||
└── src Non-compiled Sass and JSX | ||
├── base Base HTML styles | ||
@@ -56,6 +59,4 @@ ├── components Sass and React components | ||
│ └── etc... | ||
├── fonts | ||
├── generics Far reaching selectors | ||
├── images | ||
└── utilities Functional CSS classes to apply individual traits | ||
``` |
@@ -8,11 +8,10 @@ /* eslint-disable react/display-name */ | ||
<div> | ||
<Button>React button</Button> | ||
<Button>Button</Button> | ||
<Button | ||
className='ds-u-margin-left--1' | ||
href='http://example.com' | ||
target='_blank' | ||
href='javascript:void(0);' | ||
variation='primary' | ||
> | ||
React anchor button | ||
Anchor button | ||
</Button> | ||
@@ -19,0 +18,0 @@ </div> |
@@ -35,3 +35,3 @@ import PropTypes from 'prop-types'; | ||
let attrs = { | ||
const attrs = { | ||
className: this.classNames(), | ||
@@ -38,0 +38,0 @@ ...props |
@@ -14,2 +14,3 @@ import PropTypes from 'prop-types'; | ||
export const Choice = function(props) { | ||
/* eslint-disable prefer-const */ | ||
let { // Using let rather than const since we sometimes rewrite id | ||
@@ -22,2 +23,3 @@ children, | ||
} = props; | ||
/* eslint-enable prefer-const */ | ||
@@ -55,5 +57,4 @@ const inputClasses = classNames( | ||
/** | ||
* Setting this prop will render a read-only field and require an `onChange` | ||
* event handler if you'd want to check its checked stated. Use `defaultChecked` | ||
* if you want the field to be mutable. | ||
* **Note**: Setting this prop will render a read-only field. If the field should be | ||
* mutable, use `defaultChecked`. Otherwise, set either `onChange` or `readOnly` | ||
*/ | ||
@@ -66,4 +67,4 @@ checked: PropTypes.bool, | ||
/** | ||
* Sets the initial checked state and allows the user to check/uncheck the | ||
* field without also requiring an `onChange` event handler. | ||
* Sets the initial checked state. Use this for an uncontrolled component; | ||
* otherwise, use the `checked` property. | ||
*/ | ||
@@ -81,3 +82,3 @@ defaultChecked: PropTypes.bool, | ||
/** | ||
* The `input` `name` attribute | ||
* The `input` field's `name` attribute | ||
*/ | ||
@@ -84,0 +85,0 @@ name: PropTypes.string.isRequired, |
@@ -6,5 +6,5 @@ /* eslint-disable react/display-name */ | ||
function generateChoices(length) { | ||
let choices = []; | ||
const choices = []; | ||
for (var i = 0; i < length; i++) { | ||
for (let i = 0; i < length; i++) { | ||
choices.push({ | ||
@@ -20,4 +20,4 @@ label: `Choice ${i + 1}`, | ||
export default function() { | ||
let choices = generateChoices(4); | ||
let options = generateChoices(8); | ||
const choices = generateChoices(4); | ||
const options = generateChoices(8); | ||
@@ -49,15 +49,4 @@ choices[1].defaultChecked = true; | ||
/> | ||
<div className='ds-base--inverse ds-u-margin-top--4 ds-u-padding--1'> | ||
<ChoiceList | ||
choices={options} | ||
hint='Example hint text' | ||
inversed | ||
label='Select example' | ||
labelClassName='ds-u-margin-top--0' | ||
name='select_choices_field_inverse' | ||
/> | ||
</div> | ||
</div> | ||
); | ||
} |
@@ -10,10 +10,9 @@ import Choice from './Choice'; | ||
/** | ||
* A `ChoiceList` component can be used to render a `select` menu, radio | ||
* A `ChoiceList` component can be used to render a select menu, radio | ||
* button group, or checkbox group. | ||
* | ||
* You can manually pass in the `type` prop, but the real power of this component | ||
* is unleashed when you let it determine the type of fields for you. It takes | ||
* into account accessibility and usability best practices, so you can pass in | ||
* an array of choices and let it determine what type of field would be best for | ||
* the user. | ||
* By default the component determines the type of field for you, taking | ||
* into account accessibility and usability best practices. So, you can pass in | ||
* an array of `choices` and let it determine what type of field would be best for | ||
* the user, or alternatively you can manually pass in the `type` prop. | ||
*/ | ||
@@ -28,3 +27,3 @@ export class ChoiceList extends React.PureComponent { | ||
const ChoiceComponent = type === 'select' ? 'option' : Choice; | ||
let selectProps = {}; | ||
const selectProps = {}; | ||
@@ -181,3 +180,3 @@ const choices = this.props.choices.map(choice => { | ||
/** | ||
* Hint text | ||
* Additional hint text to display | ||
*/ | ||
@@ -190,3 +189,3 @@ hint: PropTypes.node, | ||
/** | ||
* The label for the entire list of choices | ||
* Label for the field | ||
*/ | ||
@@ -203,2 +202,5 @@ label: PropTypes.node.isRequired, | ||
multiple: PropTypes.bool, | ||
/** | ||
* The field's `name` attribute | ||
*/ | ||
name: PropTypes.string.isRequired, | ||
@@ -205,0 +207,0 @@ onBlur: PropTypes.func, |
@@ -6,5 +6,5 @@ import ChoiceList from './ChoiceList'; | ||
function generateChoices(length) { | ||
let choices = []; | ||
const choices = []; | ||
for (var i = 0; i < length; i++) { | ||
for (let i = 0; i < length; i++) { | ||
choices.push({ | ||
@@ -91,3 +91,3 @@ label: `Choice ${i + 1}`, | ||
it('passes checked prop', () => { | ||
let choices = generateChoices(4); | ||
const choices = generateChoices(4); | ||
choices[1].checked = true; | ||
@@ -101,3 +101,3 @@ const data = shallowRender({ choices }); | ||
it('passes defaultChecked prop', () => { | ||
let choices = generateChoices(4); | ||
const choices = generateChoices(4); | ||
choices[1].defaultChecked = true; | ||
@@ -111,3 +111,3 @@ const data = shallowRender({ choices }); | ||
it('passes disabled prop', () => { | ||
let choices = generateChoices(4); | ||
const choices = generateChoices(4); | ||
choices[1].disabled = true; | ||
@@ -114,0 +114,0 @@ const data = shallowRender({ choices }); |
@@ -13,3 +13,4 @@ import PropTypes from 'prop-types'; | ||
export const Select = function(props) { | ||
let { | ||
/* eslint-disable prefer-const */ | ||
let { // Using let rather than const since we sometimes rewrite id | ||
children, | ||
@@ -21,2 +22,3 @@ className, | ||
} = props; | ||
/* eslint-enable prefer-const */ | ||
@@ -51,4 +53,4 @@ const classes = classNames( | ||
/** | ||
* Sets the initial `selected` state and allows the user to select a different | ||
* option without also requiring an `onChange` event handler. | ||
* Sets the initial selected state. Use this for an uncontrolled component; | ||
* otherwise, use the `selected` property. | ||
*/ | ||
@@ -67,4 +69,5 @@ defaultValue: PropTypes.string, | ||
/** | ||
* Setting this prop to `true` will result in an error message due to | ||
* accessibility concerns. See the usability guidelines for more info. | ||
* Setting this prop will result in a PropTypes error message due to | ||
* accessibility concerns. Use checkboxes instead if you need to support multiple | ||
* selections. See the Guidance tab for more info. | ||
*/ | ||
@@ -81,2 +84,5 @@ multiple: function(props, propName, componentName) { | ||
}, | ||
/** | ||
* The `select` field's `name` attribute | ||
*/ | ||
name: PropTypes.string.isRequired, | ||
@@ -86,5 +92,4 @@ onBlur: PropTypes.func, | ||
/** | ||
* Setting this prop will render a read-only field and require an `onChange` | ||
* event handler if you'd want to change its `selected` stated. Use | ||
* `defaultValue` if you want the field to be mutable. | ||
* **Note**: Setting this prop will render a read-only field. If the field should be | ||
* mutable, use `defaultValue`. Otherwise, set either `onChange` or `readOnly` | ||
*/ | ||
@@ -91,0 +96,0 @@ value: PropTypes.string |
@@ -10,5 +10,5 @@ import React from 'react'; | ||
function generateOptions(count) { | ||
let options = []; | ||
const options = []; | ||
for (var i = 1; i < count + 1; i++) { | ||
for (let i = 1; i < count + 1; i++) { | ||
options.push(<option key={i} value={String(i)}>{i}</option>); | ||
@@ -15,0 +15,0 @@ } |
@@ -68,3 +68,3 @@ import PropTypes from 'prop-types'; | ||
/** | ||
* Hint text | ||
* Additional hint text to display | ||
*/ | ||
@@ -71,0 +71,0 @@ hint: PropTypes.node, |
@@ -10,2 +10,3 @@ 'use strict'; | ||
export * from './FormLabel/FormLabel'; | ||
export * from './SkipNav/SkipNav'; | ||
export * from './Tabs/Tab'; | ||
@@ -17,1 +18,2 @@ export * from './Tabs/Tabs'; | ||
export * from './VerticalNav/VerticalNavItem'; | ||
export * from './VerticalNav/VerticalNavItemLabel'; |
@@ -57,4 +57,4 @@ import PropTypes from 'prop-types'; | ||
/** | ||
* You can optionally set the `href` attribute used for the tab. This can be | ||
* useful if you want to use relative links rather than a URL hash (the default) | ||
* Sets the `href` attribute used for the tab. This can be useful if you want | ||
* to use relative links rather than a URL hash (the default). | ||
*/ | ||
@@ -69,3 +69,3 @@ href: PropTypes.string, | ||
/** | ||
* The `id` of the associated `TabPanel`. Used for the `aria-controls` attribute | ||
* The `id` of the associated `TabPanel`. Used for the `aria-controls` attribute. | ||
*/ | ||
@@ -72,0 +72,0 @@ panelId: PropTypes.string.isRequired, |
@@ -5,2 +5,6 @@ import PropTypes from 'prop-types'; | ||
/** | ||
* A `TabPanel` is a presentational component which accepts a tab's content as | ||
* its `children`. | ||
*/ | ||
export function TabPanel(props) { | ||
@@ -58,3 +62,3 @@ const classes = classnames('ds-c-tabs__panel', props.className); | ||
/** | ||
* The `id` of the associated `Tab`. Used for the `aria-labelledby` attribute | ||
* The `id` of the associated `Tab`. Used for the `aria-labelledby` attribute. | ||
*/ | ||
@@ -61,0 +65,0 @@ tabId: PropTypes.string |
@@ -45,4 +45,4 @@ import PropTypes from 'prop-types'; | ||
/** | ||
* A container component that manages the state of your tabs for you. For most | ||
* cases, you'll want to use this component rather than the presentational | ||
* `Tabs` is a container component that manages the state of your tabs for you. | ||
* In most cases, you'll want to use this component rather than the presentational | ||
* components (`Tab`, `TabPanel`) on their own. | ||
@@ -151,4 +151,4 @@ */ | ||
/** | ||
* Default selected `TabPanel`'s `id`. If this isn't set, the first `TabPanel` | ||
* will be selected. | ||
* Sets the initial selected `TabPanel` state. If this isn't set, the first | ||
* `TabPanel` will be selected. | ||
*/ | ||
@@ -155,0 +155,0 @@ defaultSelectedId: PropTypes.string, |
@@ -32,19 +32,4 @@ /* eslint-disable react/display-name */ | ||
/> | ||
<div className='ds-base--inverse ds-u-margin-top--3 ds-u-padding--2'> | ||
<TextField | ||
inversed | ||
label='Single line' | ||
labelClassName='ds-u-margin-top--0' | ||
name='inversed_single_example' | ||
/> | ||
<TextField | ||
label='Disabled field' | ||
disabled | ||
inversed | ||
name='inversed_disabled_example' | ||
/> | ||
</div> | ||
</div> | ||
); | ||
} |
@@ -8,5 +8,4 @@ import FormLabel from '../FormLabel/FormLabel'; | ||
/** | ||
The `TextField` component affords a user to type text into a form. | ||
By default it renders a field for capturing a single line of text, | ||
but can be configured to support multiline text. | ||
* A `TextField` component renders an input field as well as supporting UI | ||
* elements like a label, error message, and hint text. | ||
*/ | ||
@@ -71,8 +70,8 @@ export class TextField extends React.PureComponent { | ||
/** | ||
* Additional classes to be added to the root element | ||
* Additional classes to be added to the root `div` element | ||
*/ | ||
className: PropTypes.string, | ||
/** | ||
* Default value of the text field, if any. Use this for an uncontrolled | ||
* component; otherwise, use the `value` property | ||
* Sets the initial value. Use this for an uncontrolled component; otherwise, | ||
* use the `value` property. | ||
*/ | ||
@@ -87,3 +86,3 @@ defaultValue: PropTypes.string, | ||
/** | ||
* Hint text | ||
* Additional hint text to display | ||
*/ | ||
@@ -96,7 +95,7 @@ hint: PropTypes.node, | ||
/** | ||
* The label for the entire list of choices | ||
* Label for the input | ||
*/ | ||
label: PropTypes.node.isRequired, | ||
/** | ||
* Additional classes to be added to the `FormLabel` | ||
* Additional classes to be added to the label | ||
*/ | ||
@@ -112,4 +111,4 @@ labelClassName: PropTypes.string, | ||
/** | ||
* Optionally specify the number of visible text lines for the control. Only | ||
* applicable if this is a multiline field | ||
* Optionally specify the number of visible text lines for the field. Only | ||
* applicable if this is a multiline field. | ||
*/ | ||
@@ -125,4 +124,4 @@ rows: PropTypes.oneOfType([ | ||
/** | ||
* Current value of the text field. Use this for a controlled component where | ||
* you are maintaining its current state; otherwise, use the `defaultValue` property | ||
* **Note**: Setting this prop will render a read-only field. If the field should be | ||
* mutable, use `defaultValue`. Otherwise, set `onChange` or `disabled`. | ||
*/ | ||
@@ -129,0 +128,0 @@ value: PropTypes.string |
@@ -12,3 +12,3 @@ /* eslint-disable react/display-name */ | ||
label: 'Home', | ||
url: 'http://example.com' | ||
url: 'javascript:void(0);' | ||
}, | ||
@@ -21,3 +21,3 @@ { | ||
label: 'Team', | ||
url: 'http://example.com#team' | ||
url: 'javascript:void(0);' | ||
}, | ||
@@ -27,3 +27,3 @@ { | ||
label: 'Company', | ||
url: 'http://example.com#company' | ||
url: 'javascript:void(0);' | ||
} | ||
@@ -34,3 +34,3 @@ ] | ||
label: 'Contact', | ||
url: 'http://example.com#contact' | ||
url: 'javascript:void(0);' | ||
} | ||
@@ -37,0 +37,0 @@ ]} |
@@ -7,3 +7,3 @@ import PropTypes from 'prop-types'; | ||
/** | ||
* The `VerticalNav` React component accepts list items as a JSON object and | ||
* A `VerticalNav` component accepts list items as a JSON object and | ||
* includes additional functionality like collapsible nested menus. | ||
@@ -10,0 +10,0 @@ */ |
@@ -116,14 +116,14 @@ import {mount, shallow} from 'enzyme'; | ||
expect( | ||
parentWrapper.find('.ds-c-vertical-nav__link').first() | ||
.hasClass('ds-c-vertical-nav__link--current') | ||
parentWrapper.find('.ds-c-vertical-nav__label').first() | ||
.hasClass('ds-c-vertical-nav__label--current') | ||
).toBe(true); | ||
expect( | ||
childWrapper.find('.ds-c-vertical-nav__link').first() | ||
.hasClass('ds-c-vertical-nav__link--current') | ||
childWrapper.find('.ds-c-vertical-nav__label').first() | ||
.hasClass('ds-c-vertical-nav__label--current') | ||
).toBe(true); | ||
expect( | ||
grandchild1Wrapper.find('.ds-c-vertical-nav__link').first() | ||
.hasClass('ds-c-vertical-nav__link--current') | ||
grandchild1Wrapper.find('.ds-c-vertical-nav__label').first() | ||
.hasClass('ds-c-vertical-nav__label--current') | ||
).toBe(true); | ||
@@ -133,11 +133,11 @@ | ||
expect( | ||
grandchild2Wrapper.find('.ds-c-vertical-nav__link').first() | ||
.hasClass('ds-c-vertical-nav__link--current') | ||
grandchild2Wrapper.find('.ds-c-vertical-nav__label').first() | ||
.hasClass('ds-c-vertical-nav__label--current') | ||
).toBe(false); | ||
expect( | ||
fooWrapper.find('.ds-c-vertical-nav__link').first() | ||
.hasClass('ds-c-vertical-nav__link--current') | ||
fooWrapper.find('.ds-c-vertical-nav__label').first() | ||
.hasClass('ds-c-vertical-nav__label--current') | ||
).toBe(false); | ||
}); | ||
}); |
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import VerticalNav from './VerticalNav'; | ||
import VerticalNavItemLabel from './VerticalNavItemLabel'; | ||
import classNames from 'classnames'; | ||
@@ -10,10 +11,6 @@ import uniqueId from 'lodash.uniqueid'; | ||
super(props); | ||
this.handleLinkClick = this.handleLinkClick.bind(this); | ||
this.handleToggleClick = this.handleToggleClick.bind(this); | ||
this.handleLabelClick = this.handleLabelClick.bind(this); | ||
this.id = this.props.id || uniqueId('VerticalNavItem_'); | ||
this.subnavId = `${this.id}__subnav`; | ||
this.state = { | ||
collapsed: this.props.defaultCollapsed | ||
}; | ||
this.state = { collapsed: this.props.defaultCollapsed }; | ||
} | ||
@@ -27,3 +24,21 @@ | ||
handleLinkClick(evt) { | ||
/** | ||
* Called when VerticalNavItemLabel is clicked. Since the "label" could be | ||
* a link, subnav toggle button, or plain text, we use this method to | ||
* determine what action to take and which event to actually fire. | ||
* @param {Object} SyntheticEvent | ||
*/ | ||
handleLabelClick(evt) { | ||
if (this.hasSubnav()) { | ||
return this.handleToggleClick(); | ||
} | ||
return this.handleClick(evt); | ||
} | ||
/** | ||
* Note: This event handler will only get called when the VerticalNavItemLabel | ||
* is a link or plain text | ||
*/ | ||
handleClick(evt) { | ||
if (this.props.onClick) { | ||
@@ -43,3 +58,3 @@ this.props.onClick( | ||
hasSubnav() { | ||
return this.props.items && this.props.items.length; | ||
return Boolean(this.props.items && this.props.items.length > 0); | ||
} | ||
@@ -49,2 +64,3 @@ | ||
* Check if this item is selected or if it is a parent of a selected item | ||
* @return {Boolean} | ||
*/ | ||
@@ -57,2 +73,4 @@ isSelected() { | ||
} | ||
return false; | ||
} | ||
@@ -63,2 +81,3 @@ | ||
* @param {Array} children - The nested items | ||
* @return {Boolean} | ||
*/ | ||
@@ -78,19 +97,14 @@ childIsSelected(children) { | ||
renderSubnavToggle() { | ||
if (this.hasSubnav()) { | ||
const label = this.state.collapsed | ||
? this.props.ariaCollapsedStateButtonLabel | ||
: this.props.ariaExpandedStateButtonLabel; | ||
subnavItems() { | ||
if (this.props.url) { | ||
// Since the VerticalNavItemLabel will just toggle the subnav, we | ||
// add a link to the top of the subnav for this item. Otherwise there | ||
// wouldn't be a way to actually visit its URL | ||
const item = Object.assign({}, this.props); | ||
delete item.items; | ||
return ( | ||
<button | ||
aria-controls={this.subnavId} | ||
aria-expanded={!this.state.collapsed} | ||
className='ds-c-vertical-nav__subnav-toggle' | ||
onClick={this.handleToggleClick} | ||
> | ||
{label} | ||
</button> | ||
); | ||
return [item].concat(this.props.items); | ||
} | ||
return this.props.items; | ||
} | ||
@@ -105,3 +119,3 @@ | ||
id={this.subnavId} | ||
items={this.props.items} | ||
items={this.subnavItems()} | ||
nested | ||
@@ -115,21 +129,16 @@ /> | ||
const classes = classNames('ds-c-vertical-nav__item', this.props.className); | ||
const LinkComponent = this.props.url ? 'a' : 'div'; | ||
const linkProps = { | ||
className: classNames( | ||
'ds-c-vertical-nav__link', | ||
{ | ||
'ds-c-vertical-nav__link--current': this.isSelected(), | ||
'ds-c-vertical-nav__link--parent': this.hasSubnav() | ||
} | ||
), | ||
href: this.props.url ? this.props.url : undefined, | ||
onClick: this.props.onClick ? this.handleLinkClick : undefined | ||
}; | ||
return ( | ||
<li className={classes}> | ||
<LinkComponent {...linkProps}> | ||
{this.props.label} | ||
</LinkComponent> | ||
{this.renderSubnavToggle()} | ||
<VerticalNavItemLabel | ||
ariaCollapsedStateButtonLabel={this.props.ariaCollapsedStateButtonLabel} | ||
ariaExpandedStateButtonLabel={this.props.ariaExpandedStateButtonLabel} | ||
collapsed={this.state.collapsed} | ||
label={this.props.label} | ||
hasSubnav={this.hasSubnav()} | ||
onClick={this.handleLabelClick} | ||
selected={this.isSelected()} | ||
subnavId={this.subnavId} | ||
url={this.props.url} | ||
/> | ||
{this.renderSubnav()} | ||
@@ -142,2 +151,5 @@ </li> | ||
VerticalNavItem.defaultProps = { | ||
// Unfortunately, we're defining these default ARIA pros here and in | ||
// VerticalNavItemLabel. We define them here so they show in the docs. | ||
// TODO(sawyer): Update react-docgen so we don't have to do this | ||
ariaCollapsedStateButtonLabel: 'Expand sub-navigation', | ||
@@ -168,3 +180,3 @@ ariaExpandedStateButtonLabel: 'Collapse sub-navigation', | ||
/** | ||
* Called when the item is clicked, with the following arguments: | ||
* Called when the link is clicked, with the following arguments: | ||
* [`SyntheticEvent`](https://facebook.github.io/react/docs/events.html), | ||
@@ -171,0 +183,0 @@ * `id`, `url`. |
@@ -23,40 +23,12 @@ import React from 'react'; | ||
expect(wrapper.hasClass('ds-c-vertical-nav__item')).toBe(true); | ||
expect(wrapper.text()).toBe(data.props.label); | ||
}); | ||
it('is not a link', () => { | ||
it('renders VerticalNavItemLabel', () => { | ||
const data = shallowRender(); | ||
const wrapper = data.wrapper; | ||
const link = wrapper.find('.ds-c-vertical-nav__link').first(); | ||
const label = data.wrapper.find('VerticalNavItemLabel').first(); | ||
expect(link.is('div')).toBe(true); | ||
expect(link.prop('href')).toBeUndefined(); | ||
expect(link.hasClass('ds-c-vertical-nav__link--current')).toBe(false); | ||
expect(label.prop('collapsed')).toBe(data.wrapper.state('collapsed')); | ||
expect(label.prop('label')).toBe(data.props.label); | ||
}); | ||
it('is a link', () => { | ||
const data = shallowRender({ url: '/bar' }); | ||
const wrapper = data.wrapper; | ||
const link = wrapper.find('.ds-c-vertical-nav__link').first(); | ||
expect(link.is('a')).toBe(true); | ||
expect(link.prop('href')).toBe(data.props.url); | ||
}); | ||
it('accepts a node as a label', () => { | ||
const wrapper = shallowRender({ | ||
label: <strong>Foo</strong> | ||
}).wrapper; | ||
const link = wrapper.find('.ds-c-vertical-nav__link').first(); | ||
expect(link.html()).toMatch(/<strong>/); | ||
}); | ||
it('is selected', () => { | ||
const data = shallowRender({ selected: true }); | ||
const link = data.wrapper.find('.ds-c-vertical-nav__link').first(); | ||
expect(link.hasClass('ds-c-vertical-nav__link--current')).toBe(true); | ||
}); | ||
it('has additional class names', () => { | ||
@@ -69,16 +41,2 @@ const data = shallowRender({ className: 'bar' }); | ||
it('calls onClick', () => { | ||
const data = shallowRender({ | ||
id: 'bar', | ||
onClick: jest.fn(), | ||
url: '/bar' | ||
}); | ||
const link = data.wrapper.find('.ds-c-vertical-nav__link').first(); | ||
link.simulate('click'); | ||
expect(data.props.onClick.mock.calls.length).toBe(1); | ||
expect(data.props.onClick.mock.calls[0][1]).toBe(data.props.id); | ||
expect(data.props.onClick.mock.calls[0][2]).toBe(data.props.url); | ||
}); | ||
it('calls onSubnavToggle', () => { | ||
@@ -90,2 +48,3 @@ const data = shallowRender({ | ||
// Collapsed state changes, triggering the event! | ||
data.wrapper.setState({ collapsed: true }); | ||
@@ -101,3 +60,41 @@ | ||
describe('with nested menu', () => { | ||
describe('without subnav', () => { | ||
it('is not selected', () => { | ||
const data = shallowRender(); | ||
expect(data.wrapper.find('VerticalNavItemLabel').prop('selected')) | ||
.toBe(false); | ||
}); | ||
it('is selected', () => { | ||
const data = shallowRender({ selected: true }); | ||
expect(data.wrapper.find('VerticalNavItemLabel').prop('selected')) | ||
.toBe(true); | ||
}); | ||
it('has no subnav', () => { | ||
const data = shallowRender(); | ||
const label = data.wrapper.find('VerticalNavItemLabel').first(); | ||
expect(label.prop('hasSubnav')).toBe(false); | ||
expect(data.wrapper.find('VerticalNav').length).toBe(0); | ||
}); | ||
it('calls onClick', () => { | ||
const data = shallowRender({ | ||
id: 'bar', | ||
onClick: jest.fn(), | ||
url: '/bar' | ||
}); | ||
data.wrapper.find('VerticalNavItemLabel').first().simulate('click'); | ||
expect(data.props.onClick.mock.calls.length).toBe(1); | ||
expect(data.props.onClick.mock.calls[0][1]).toBe(data.props.id); | ||
expect(data.props.onClick.mock.calls[0][2]).toBe(data.props.url); | ||
}); | ||
}); | ||
describe('with subnav', () => { | ||
let props; | ||
@@ -118,23 +115,31 @@ | ||
it('renders subnavs', () => { | ||
it('has subnav', () => { | ||
const data = shallowRender(props); | ||
const label = data.wrapper.find('VerticalNavItemLabel').first(); | ||
const subnav = data.wrapper.find('VerticalNav').first(); | ||
expect(data.wrapper.render().find('ul').length) | ||
.toBe(2); | ||
expect(data.wrapper.find('VerticalNav').first().prop('collapsed')) | ||
expect(label.prop('hasSubnav')).toBe(true); | ||
expect(data.wrapper.render().find('ul').length).toBe(2); | ||
expect(subnav.prop('collapsed')).toBe(false); | ||
expect(subnav.prop('id')).not.toBeUndefined(); | ||
expect(subnav.prop('nested')).toBe(true); | ||
}); | ||
it('is not selected', () => { | ||
const data = shallowRender(props); | ||
expect(data.wrapper.find('VerticalNavItemLabel').prop('selected')) | ||
.toBe(false); | ||
expect(data.wrapper.find('VerticalNav').first().prop('id')) | ||
.not.toBeUndefined(); | ||
}); | ||
it('renders toggle button', () => { | ||
it('is selected', () => { | ||
props._selectedId = 'selected-child'; | ||
props.items[0].id = 'selected-child'; | ||
const data = shallowRender(props); | ||
const button = data.wrapper.find('.ds-c-vertical-nav__subnav-toggle'); | ||
const subnavId = data.wrapper.find('VerticalNav').prop('id'); | ||
expect(button.prop('aria-controls')).toBe(subnavId); | ||
expect(button.prop('aria-expanded')).toBe(true); | ||
expect(data.wrapper.find('VerticalNavItemLabel').prop('selected')) | ||
.toBe(true); | ||
}); | ||
it('is collapsed', () => { | ||
it('has collapsed subnav', () => { | ||
props.defaultCollapsed = true; | ||
@@ -148,23 +153,59 @@ const data = shallowRender(props); | ||
it('toggles collapsed state', () => { | ||
props.ariaExpandedStateButtonLabel = 'Collapse me'; | ||
props.ariaCollapsedStateButtonLabel = 'Expand me'; | ||
props.onClick = jest.fn(); | ||
const data = shallowRender(props); | ||
let button = data.wrapper.find('.ds-c-vertical-nav__subnav-toggle'); | ||
const label = data.wrapper.find('VerticalNavItemLabel').first(); | ||
expect(data.wrapper.find('VerticalNav').first().prop('collapsed')) | ||
.toBe(false); | ||
expect(button.text()) | ||
.toBe(data.props.ariaExpandedStateButtonLabel); | ||
button.simulate('click'); | ||
// Get updated render... | ||
label.simulate('click'); | ||
data.wrapper.update(); | ||
button = data.wrapper.find('.ds-c-vertical-nav__subnav-toggle'); | ||
expect(data.wrapper.find('VerticalNav').first().prop('collapsed')) | ||
.toBe(true); | ||
expect(button.text()) | ||
.toBe(data.props.ariaCollapsedStateButtonLabel); | ||
}); | ||
it('does not add top-level link to top of subnav', () => { | ||
const data = shallowRender(props); | ||
const subnav = data.wrapper.find('VerticalNav').first().shallow(); | ||
const firstSubnavItem = subnav.find('VerticalNavItem').first(); | ||
expect(firstSubnavItem.prop('label')).toBe(data.props.items[0].label); | ||
}); | ||
describe('with url', () => { | ||
beforeEach(() => { | ||
props.url = '/foo'; | ||
}); | ||
it('adds top-level link to top of subnav', () => { | ||
props.id = 'foo'; | ||
const data = shallowRender(props); | ||
const subnav = data.wrapper.find('VerticalNav').first().shallow(); | ||
const firstSubnavItem = subnav.find('VerticalNavItem').first(); | ||
expect(firstSubnavItem.prop('id')) | ||
.toBe(data.props.id); | ||
expect(firstSubnavItem.prop('items')) | ||
.toBeUndefined(); | ||
expect(firstSubnavItem.prop('label')) | ||
.toBe(data.props.label); | ||
expect(firstSubnavItem.prop('url')) | ||
.toBe(data.props.url); | ||
}); | ||
it('calls onSubnavToggle rather than onClick', () => { | ||
props.onClick = jest.fn(); | ||
props.onSubnavToggle = jest.fn(); | ||
const data = shallowRender(props); | ||
const label = data.wrapper.find('VerticalNavItemLabel').first(); | ||
label.simulate('click'); | ||
expect(data.props.onClick.mock.calls.length).toBe(0); | ||
expect(data.props.onSubnavToggle.mock.calls.length).toBe(1); | ||
}); | ||
}); | ||
}); | ||
}); |
'use strict'; | ||
export * from './components'; | ||
export * from './components'; // eslint-disable-line import/export |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 28 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 56 instances in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
4963
1
59
28
1279070
186
1