stardust
Advanced tools
Comparing version 0.17.0 to 0.18.0
@@ -5,6 +5,14 @@ # Change Log | ||
[Full Changelog](https://github.com/TechnologyAdvice/stardust/compare/v0.16.4...HEAD) | ||
[Full Changelog](https://github.com/TechnologyAdvice/stardust/compare/v0.17.0...HEAD) | ||
**Merged pull requests:** | ||
- Add "all" custom prop type and fix issues [\#323](https://github.com/TechnologyAdvice/stardust/pull/323) ([levithomason](https://github.com/levithomason)) | ||
## [v0.17.0](https://github.com/TechnologyAdvice/stardust/tree/v0.17.0) (2016-07-04) | ||
[Full Changelog](https://github.com/TechnologyAdvice/stardust/compare/v0.16.4...v0.17.0) | ||
**Implemented enhancements:** | ||
- \<Accordion /\> Component [\#189](https://github.com/TechnologyAdvice/stardust/issues/189) | ||
- ListItem updates and fixes [\#102](https://github.com/TechnologyAdvice/stardust/issues/102) | ||
@@ -28,2 +36,3 @@ | ||
- Fix getComponentDocInfo docPath on windows [\#312](https://github.com/TechnologyAdvice/stardust/pull/312) ([levithomason](https://github.com/levithomason)) | ||
- Add Accordion Component [\#246](https://github.com/TechnologyAdvice/stardust/pull/246) ([levithomason](https://github.com/levithomason)) | ||
@@ -30,0 +39,0 @@ ## [v0.16.4](https://github.com/TechnologyAdvice/stardust/tree/v0.16.4) (2016-06-28) |
@@ -85,3 +85,3 @@ 'use strict'; | ||
/** Color of the header. */ | ||
color: _react.PropTypes.oneOf(_Header._meta.props.colors), | ||
color: _react.PropTypes.oneOf(_Header._meta.props.color), | ||
@@ -88,0 +88,0 @@ /** Align header content */ |
@@ -6,3 +6,3 @@ 'use strict'; | ||
}); | ||
exports.Statistic = exports.Items = exports.Item = exports.Dropdown = exports.ModalHeader = exports.ModalFooter = exports.ModalContent = exports.Modal = exports.Progress = exports.Checkbox = exports.Accordion = exports.Segments = exports.Segment = exports.ListItem = exports.List = exports.Label = exports.Input = exports.Image = exports.Icon = exports.Header = exports.Divider = exports.Container = exports.Buttons = exports.Button = exports.TableColumn = exports.Table = exports.Message = exports.MenuItem = exports.Menu = exports.Row = exports.Column = exports.Grid = exports.Fields = exports.Field = exports.Form = exports.Select = exports.Textarea = exports.Confirm = undefined; | ||
exports.Statistic = exports.Items = exports.Item = exports.Dropdown = exports.ModalHeader = exports.ModalFooter = exports.ModalContent = exports.Modal = exports.Progress = exports.Checkbox = exports.Accordion = exports.Segments = exports.Segment = exports.ListItem = exports.List = exports.Label = exports.Input = exports.Image = exports.Icon = exports.Header = exports.Flag = exports.Divider = exports.Container = exports.Buttons = exports.Button = exports.TableColumn = exports.Table = exports.Message = exports.MenuItem = exports.Menu = exports.Row = exports.Column = exports.Grid = exports.Fields = exports.Field = exports.Form = exports.Select = exports.Textarea = exports.Confirm = undefined; | ||
@@ -59,2 +59,6 @@ var _deprecate = require('./utils/deprecate'); | ||
var _Flag2 = require('./elements/Flag/Flag'); | ||
var _Flag3 = _interopRequireDefault(_Flag2); | ||
var _Header2 = require('./elements/Header/Header'); | ||
@@ -156,2 +160,3 @@ | ||
exports.Divider = _Divider3.default; | ||
exports.Flag = _Flag3.default; | ||
exports.Header = _Header3.default; | ||
@@ -158,0 +163,0 @@ exports.Icon = _Icon3.default; |
@@ -190,3 +190,3 @@ 'use strict'; | ||
/** Accordion.Title and Accordion.Content components. Mutually exclusive with the panels prop. */ | ||
children: _propUtils.customPropTypes.mutuallyExclusive('panels'), | ||
children: _propUtils.customPropTypes.all([_propUtils.customPropTypes.mutuallyExclusive(['panels']), _react.PropTypes.node]), | ||
@@ -213,7 +213,8 @@ /** Classes to add to the Accordion className. */ | ||
*/ | ||
panels: _react.PropTypes.arrayOf(_react.PropTypes.shape({ | ||
panels: _propUtils.customPropTypes.all([_propUtils.customPropTypes.mutuallyExclusive(['children']), _react.PropTypes.arrayOf(_react.PropTypes.shape({ | ||
active: _react.PropTypes.bool, | ||
title: _react.PropTypes.string, | ||
content: _react.PropTypes.string | ||
})), | ||
content: _react.PropTypes.string, | ||
onClick: _react.PropTypes.func | ||
}))]), | ||
@@ -220,0 +221,0 @@ /** Adds some basic styling to accordion panels. */ |
@@ -24,6 +24,18 @@ 'use strict'; | ||
var _forEach2 = require('lodash/forEach'); | ||
var _isFunction2 = require('lodash/isFunction'); | ||
var _forEach3 = _interopRequireDefault(_forEach2); | ||
var _isFunction3 = _interopRequireDefault(_isFunction2); | ||
var _map2 = require('lodash/map'); | ||
var _map3 = _interopRequireDefault(_map2); | ||
var _has2 = require('lodash/has'); | ||
var _has3 = _interopRequireDefault(_has2); | ||
var _isEmpty2 = require('lodash/isEmpty'); | ||
var _isEmpty3 = _interopRequireDefault(_isEmpty2); | ||
var _get2 = require('lodash/get'); | ||
@@ -37,2 +49,14 @@ | ||
var _compact2 = require('lodash/compact'); | ||
var _compact3 = _interopRequireDefault(_compact2); | ||
var _isArray2 = require('lodash/isArray'); | ||
var _isArray3 = _interopRequireDefault(_isArray2); | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; | ||
var _templateObject = _taggedTemplateLiteral([' See ', ' prop `', '`.'], [' See ', ' prop \\`', '\\`.']); | ||
var _react = require('react'); | ||
@@ -52,20 +76,27 @@ | ||
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } | ||
function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } /* eslint-disable react/no-multi-comp */ | ||
// =============================================================== | ||
// Custom PropTypes | ||
// =============================================================== | ||
/* eslint-disable react/no-multi-comp */ | ||
var customPropTypes = exports.customPropTypes = { | ||
/** | ||
* Ensures children are of a set of types. | ||
* Similar to `oneOfType` built-in validator | ||
* @param {String[]} allowedTypes Collection of allowed Stardust component types | ||
* Ensures children are of a set of types. Matches are made against the component _meta.name property. | ||
* @param {String[]} allowedTypes Collection of allowed component types. | ||
*/ | ||
ofComponentTypes: function ofComponentTypes(allowedTypes) { | ||
return function (props, propName, componentName) { | ||
var children = props.children; | ||
var disallowed = _react.Children.map(children, function (child) { | ||
if (propName !== 'children') { | ||
throw new Error('ofComponentTypes can only be used on the `children` prop, not ' + propName + '.'); | ||
} | ||
if (!(0, _isArray3.default)(allowedTypes)) { | ||
throw new Error(['Invalid argument supplied to ofComponentTypes, expected an instance of array.'(_templateObject, componentName, propName)].join('')); | ||
} | ||
var disallowed = (0, _compact3.default)(_react.Children.map(props.children, function (child) { | ||
return (0, _includes3.default)(allowedTypes, (0, _get3.default)(child, 'type._meta.name')) ? null : child; | ||
}); | ||
if (disallowed && disallowed.length !== 0) { | ||
})); | ||
if (!(0, _isEmpty3.default)(disallowed)) { | ||
return new Error('`' + componentName + '` should only have children of type `' + allowedTypes + '`.'); | ||
@@ -75,14 +106,47 @@ } | ||
}, | ||
/** | ||
* Verifies exclusivity of a given prop | ||
* @param {string} exclusives property used for exclusivity check | ||
* Verifies exclusivity of a given prop. | ||
* @param {string[]} exclusives An array of props that cannot be used with this prop. | ||
*/ | ||
mutuallyExclusive: function mutuallyExclusive(exclusives) { | ||
return function (props, propName, componentName) { | ||
(0, _forEach3.default)(exclusives, function (exclusiveProp) { | ||
if (props[propName] && props[exclusiveProp]) { | ||
return new Error('`' + componentName + '` should only have one of type `' + propName + '` or `' + exclusiveProp + '` not both.'); | ||
if (!(0, _isArray3.default)(exclusives)) { | ||
throw new Error(['Invalid argument supplied to mutuallyExclusive, expected an instance of array.'(_templateObject, componentName, propName)].join('')); | ||
} | ||
// mutually exclusive | ||
var disallowed = exclusives.reduce(function (acc, exclusive) { | ||
if ((0, _has3.default)(props, propName) && (0, _has3.default)(props, exclusive)) { | ||
return [].concat(_toConsumableArray(acc), [exclusive]); | ||
} | ||
}); | ||
return acc; | ||
}, []); | ||
if (!(0, _isEmpty3.default)(disallowed)) { | ||
return new Error(['`' + componentName + '` prop `' + propName + '` conflicts with props: `' + disallowed.join('`, `') + '`.', 'They cannot be defined together, choose one or the other.'].join(' ')); | ||
} | ||
}; | ||
}, | ||
/** | ||
* Ensure a prop adherers to multiple prop type validators. | ||
* @param {function[]} validators An array of propType functions. | ||
*/ | ||
all: function all(validators) { | ||
return function (props, propName, componentName) { | ||
if (!(0, _isArray3.default)(validators)) { | ||
throw new Error(['Invalid argument supplied to all, expected an instance of array.', 'See ' + componentName + ' prop `' + propName + '`.'].join(' ')); | ||
} | ||
var errors = (0, _compact3.default)((0, _map3.default)(validators, function (validator) { | ||
if (!(0, _isFunction3.default)(validator)) { | ||
throw new Error('all() "validators" functions, received: ' + (typeof validator === 'undefined' ? 'undefined' : _typeof(validator)) + '.'); | ||
} | ||
return validator(props, propName, componentName); | ||
})); | ||
// we can only return one error at a time | ||
return errors[0]; | ||
}; | ||
} | ||
@@ -89,0 +153,0 @@ }; |
@@ -119,6 +119,6 @@ 'use strict'; | ||
Item.propTypes = { | ||
children: _react.PropTypes.node, | ||
children: _propUtils.customPropTypes.all([_propUtils.customPropTypes.mutuallyExclusive(['description']), _react.PropTypes.node]), | ||
className: _react.PropTypes.string, | ||
contentClassName: _react.PropTypes.string, | ||
description: _propUtils.customPropTypes.mutuallyExclusive(['children']), | ||
description: _propUtils.customPropTypes.all([_propUtils.customPropTypes.mutuallyExclusive(['children']), _react.PropTypes.node]), | ||
extra: _react.PropTypes.node, | ||
@@ -125,0 +125,0 @@ header: _react.PropTypes.node, |
{ | ||
"name": "stardust", | ||
"version": "0.17.0", | ||
"version": "0.18.0", | ||
"description": "The official Semantic-UI-React integration.", | ||
@@ -124,3 +124,3 @@ "main": "dist/index.js", | ||
"style-loader": "^0.13.1", | ||
"ta-scripts": "^2.3.1", | ||
"ta-scripts": "^2.4.2", | ||
"through2": "^2.0.0", | ||
@@ -127,0 +127,0 @@ "watch": "^0.18.0", |
@@ -80,3 +80,3 @@ import cx from 'classnames' | ||
/** Color of the header. */ | ||
color: PropTypes.oneOf(_Header._meta.props.colors), | ||
color: PropTypes.oneOf(_Header._meta.props.color), | ||
@@ -83,0 +83,0 @@ /** Align header content */ |
@@ -40,2 +40,3 @@ import { deprecateComponent } from './utils/deprecate' | ||
export Divider from './elements/Divider/Divider' | ||
export Flag from './elements/Flag/Flag' | ||
export Header from './elements/Header/Header' | ||
@@ -42,0 +43,0 @@ export Icon from './elements/Icon/Icon' |
@@ -25,3 +25,6 @@ import _ from 'lodash' | ||
/** Accordion.Title and Accordion.Content components. Mutually exclusive with the panels prop. */ | ||
children: customPropTypes.mutuallyExclusive('panels'), | ||
children: customPropTypes.all([ | ||
customPropTypes.mutuallyExclusive(['panels']), | ||
PropTypes.node, | ||
]), | ||
@@ -48,7 +51,11 @@ /** Classes to add to the Accordion className. */ | ||
*/ | ||
panels: PropTypes.arrayOf(PropTypes.shape({ | ||
active: PropTypes.bool, | ||
title: PropTypes.string, | ||
content: PropTypes.string, | ||
})), | ||
panels: customPropTypes.all([ | ||
customPropTypes.mutuallyExclusive(['children']), | ||
PropTypes.arrayOf(PropTypes.shape({ | ||
active: PropTypes.bool, | ||
title: PropTypes.string, | ||
content: PropTypes.string, | ||
onClick: PropTypes.func, | ||
})), | ||
]), | ||
@@ -55,0 +62,0 @@ /** Adds some basic styling to accordion panels. */ |
@@ -13,13 +13,20 @@ /* eslint-disable react/no-multi-comp */ | ||
/** | ||
* Ensures children are of a set of types. | ||
* Similar to `oneOfType` built-in validator | ||
* @param {String[]} allowedTypes Collection of allowed Stardust component types | ||
* Ensures children are of a set of types. Matches are made against the component _meta.name property. | ||
* @param {String[]} allowedTypes Collection of allowed component types. | ||
*/ | ||
ofComponentTypes: (allowedTypes) => { | ||
return (props, propName, componentName) => { | ||
const { children } = props | ||
const disallowed = Children.map(children, child => { | ||
if (propName !== 'children') { | ||
throw new Error(`ofComponentTypes can only be used on the \`children\` prop, not ${propName}.`) | ||
} | ||
if (!_.isArray(allowedTypes)) { | ||
throw new Error([ | ||
'Invalid argument supplied to ofComponentTypes, expected an instance of array.' | ||
` See ${componentName} prop \`${propName}\`.`, | ||
].join('')) | ||
} | ||
const disallowed = _.compact(Children.map(props.children, child => { | ||
return _.includes(allowedTypes, _.get(child, 'type._meta.name')) ? null : child | ||
}) | ||
if (disallowed && disallowed.length !== 0) { | ||
})) | ||
if (!_.isEmpty(disallowed)) { | ||
return new Error( | ||
@@ -31,17 +38,57 @@ `\`${componentName}\` should only have children of type \`${allowedTypes}\`.` | ||
}, | ||
/** | ||
* Verifies exclusivity of a given prop | ||
* @param {string} exclusives property used for exclusivity check | ||
* Verifies exclusivity of a given prop. | ||
* @param {string[]} exclusives An array of props that cannot be used with this prop. | ||
*/ | ||
mutuallyExclusive: exclusives => { | ||
return (props, propName, componentName) => { | ||
_.forEach(exclusives, exclusiveProp => { | ||
if (props[propName] && props[exclusiveProp]) { | ||
return new Error( | ||
`\`${componentName}\` should only have one of type \`${propName}\` or \`${exclusiveProp}\` not both.` | ||
) | ||
if (!_.isArray(exclusives)) { | ||
throw new Error([ | ||
'Invalid argument supplied to mutuallyExclusive, expected an instance of array.' | ||
` See ${componentName} prop \`${propName}\`.`, | ||
].join('')) | ||
} | ||
// mutually exclusive | ||
const disallowed = exclusives.reduce((acc, exclusive) => { | ||
if (_.has(props, propName) && _.has(props, exclusive)) { | ||
return [...acc, exclusive] | ||
} | ||
}) | ||
return acc | ||
}, []) | ||
if (!_.isEmpty(disallowed)) { | ||
return new Error([ | ||
`\`${componentName}\` prop \`${propName}\` conflicts with props: \`${disallowed.join('`, `')}\`.`, | ||
'They cannot be defined together, choose one or the other.', | ||
].join(' ')) | ||
} | ||
} | ||
}, | ||
/** | ||
* Ensure a prop adherers to multiple prop type validators. | ||
* @param {function[]} validators An array of propType functions. | ||
*/ | ||
all: (validators) => { | ||
return (props, propName, componentName) => { | ||
if (!_.isArray(validators)) { | ||
throw new Error([ | ||
'Invalid argument supplied to all, expected an instance of array.', | ||
`See ${componentName} prop \`${propName}\`.`, | ||
].join(' ')) | ||
} | ||
const errors = _.compact(_.map(validators, validator => { | ||
if (!_.isFunction(validator)) { | ||
throw new Error(`all() "validators" functions, received: ${typeof validator}.`) | ||
} | ||
return validator(props, propName, componentName) | ||
})) | ||
// we can only return one error at a time | ||
return errors[0] | ||
} | ||
}, | ||
} | ||
@@ -48,0 +95,0 @@ |
@@ -11,6 +11,12 @@ import _ from 'lodash' | ||
static propTypes = { | ||
children: PropTypes.node, | ||
children: customPropTypes.all([ | ||
customPropTypes.mutuallyExclusive(['description']), | ||
PropTypes.node, | ||
]), | ||
className: PropTypes.string, | ||
contentClassName: PropTypes.string, | ||
description: customPropTypes.mutuallyExclusive(['children']), | ||
description: customPropTypes.all([ | ||
customPropTypes.mutuallyExclusive(['children']), | ||
PropTypes.node, | ||
]), | ||
extra: PropTypes.node, | ||
@@ -17,0 +23,0 @@ header: PropTypes.node, |
443049
135
9160