diff --git a/dist/client/ui/controls.js b/dist/client/ui/controls.js index e53aea898f31..83e48c4682f2 100644 --- a/dist/client/ui/controls.js +++ b/dist/client/ui/controls.js @@ -28,29 +28,55 @@ var _react = require('react'); var _react2 = _interopRequireDefault(_react); +var _text_filter = require('./text_filter'); + +var _text_filter2 = _interopRequireDefault(_text_filter); + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var StorybookControls = function (_React$Component) { (0, _inherits3.default)(StorybookControls, _React$Component); - function StorybookControls() { + function StorybookControls(props) { (0, _classCallCheck3.default)(this, StorybookControls); - return (0, _possibleConstructorReturn3.default)(this, (0, _getPrototypeOf2.default)(StorybookControls).apply(this, arguments)); + + var _this = (0, _possibleConstructorReturn3.default)(this, (0, _getPrototypeOf2.default)(StorybookControls).call(this, props)); + + _this.state = { + filterText: '' + }; + return _this; } (0, _createClass3.default)(StorybookControls, [{ key: 'getKindNames', value: function getKindNames() { + var _this2 = this; + var storyStore = this.props.storyStore; if (!storyStore) { return []; } - - return storyStore.map(function (_ref) { + var kindNames = storyStore.map(function (_ref) { var kind = _ref.kind; return kind; }); + + var filterdKindNames = kindNames.filter(function (kind) { + var selectedKind = _this2.props.selectedKind; + var filterText = _this2.state.filterText; + + + if (kind === selectedKind) { + // Always keep the selected kind name + return true; + } + + return kind.toLowerCase().indexOf(filterText.toLowerCase()) > -1; + }); + + return filterdKindNames; } }, { key: 'getStories', @@ -80,6 +106,16 @@ var StorybookControls = function (_React$Component) { if (onStory) onStory(story); } + }, { + key: 'filterStoryList', + value: function filterStoryList(filterText) { + this.setState({ filterText: filterText }); + } + }, { + key: 'clearFilterText', + value: function clearFilterText() { + this.setState({ filterText: '' }); + } }, { key: 'renderStory', value: function renderStory(story) { @@ -159,7 +195,6 @@ var StorybookControls = function (_React$Component) { var h1WrapStyle = { background: '#F7F7F7', - borderBottom: '1px solid #EEE', paddingBottom: '20px', position: 'absolute', top: '20px', @@ -181,10 +216,17 @@ var StorybookControls = function (_React$Component) { margin: 0 }; + var filterTextWrapStyle = { + position: 'absolute', + top: '68px', + right: '10px', + left: '20px' + }; + var listStyle = { overflowY: 'auto', position: 'absolute', - top: '68px', + top: '108px', right: '10px', bottom: 0, left: '20px' @@ -202,6 +244,15 @@ var StorybookControls = function (_React$Component) { 'React Storybook' ) ), + _react2.default.createElement( + 'div', + { style: filterTextWrapStyle }, + _react2.default.createElement(_text_filter2.default, { + filterText: this.state.filterText, + onChange: this.filterStoryList.bind(this), + onClear: this.clearFilterText.bind(this) + }) + ), _react2.default.createElement( 'div', { style: listStyle }, diff --git a/dist/client/ui/text_filter.js b/dist/client/ui/text_filter.js new file mode 100644 index 000000000000..13413aec2e0a --- /dev/null +++ b/dist/client/ui/text_filter.js @@ -0,0 +1,120 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of'); + +var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf); + +var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); + +var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); + +var _createClass2 = require('babel-runtime/helpers/createClass'); + +var _createClass3 = _interopRequireDefault(_createClass2); + +var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn'); + +var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); + +var _inherits2 = require('babel-runtime/helpers/inherits'); + +var _inherits3 = _interopRequireDefault(_inherits2); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var TextFilter = function (_React$Component) { + (0, _inherits3.default)(TextFilter, _React$Component); + + function TextFilter() { + (0, _classCallCheck3.default)(this, TextFilter); + return (0, _possibleConstructorReturn3.default)(this, (0, _getPrototypeOf2.default)(TextFilter).apply(this, arguments)); + } + + (0, _createClass3.default)(TextFilter, [{ + key: 'onChange', + value: function onChange(event) { + var filterText = event.target.value; + this.props.onChange(filterText); + } + }, { + key: 'render', + value: function render() { + var mainStyle = { + border: '1px solid #ECECEC', + borderRadius: 2 + }; + + var filterTextWrapStyle = { + background: '#F7F7F7', + paddingRight: 25 + }; + + var filterTextStyle = { + fontSize: 12, + color: '#828282', + border: 'none', + padding: 5, + display: 'block', + width: '100%', + boxSizing: 'border-box', + outline: 'none' + }; + + var clearButtonStyle = { + position: 'absolute', + color: '#B1B1B1', + border: 'none', + padding: 3, + width: 25, + right: 0, + top: 0, + textAlign: 'center', + boxSizing: 'border-box', + cursor: 'pointer' + }; + + return _react2.default.createElement( + 'div', + { style: mainStyle }, + _react2.default.createElement( + 'div', + { style: filterTextWrapStyle }, + _react2.default.createElement('input', { + style: filterTextStyle, + type: 'text', + placeholder: 'Filter', + name: 'filter-text', + value: this.props.filterText, + onChange: this.onChange.bind(this) + }) + ), + _react2.default.createElement( + 'div', + { + style: clearButtonStyle, + onClick: this.props.onClear + }, + 'x' + ) + ); + } + }]); + return TextFilter; +}(_react2.default.Component); + +exports.default = TextFilter; + + +TextFilter.propTypes = { + filterText: _react2.default.PropTypes.string, + onChange: _react2.default.PropTypes.func, + onClear: _react2.default.PropTypes.func +}; \ No newline at end of file diff --git a/src/client/ui/controls.js b/src/client/ui/controls.js index 625882409aeb..94cb0b107605 100644 --- a/src/client/ui/controls.js +++ b/src/client/ui/controls.js @@ -1,13 +1,34 @@ import React from 'react'; +import TextFilter from './text_filter'; export default class StorybookControls extends React.Component { + constructor(props) { + super(props); + this.state = { + filterText: '', + }; + } + getKindNames() { const { storyStore } = this.props; if (!storyStore) { return []; } + const kindNames = storyStore.map(({ kind }) => kind); + + const filterdKindNames = kindNames.filter(kind => { + const { selectedKind } = this.props; + const { filterText } = this.state; + + if (kind === selectedKind) { + // Always keep the selected kind name + return true; + } - return storyStore.map(({ kind }) => kind); + return kind.toLowerCase().indexOf(filterText.toLowerCase()) > -1; + }); + + return filterdKindNames; } getStories(kind) { @@ -30,6 +51,14 @@ export default class StorybookControls extends React.Component { if (onStory) onStory(story); } + filterStoryList(filterText) { + this.setState({ filterText }); + } + + clearFilterText() { + this.setState({ filterText: '' }); + } + renderStory(story) { const { selectedStory } = this.props; const storyStyle = { @@ -102,7 +131,6 @@ export default class StorybookControls extends React.Component { const h1WrapStyle = { background: '#F7F7F7', - borderBottom: '1px solid #EEE', paddingBottom: '20px', position: 'absolute', top: '20px', @@ -124,10 +152,17 @@ export default class StorybookControls extends React.Component { margin: 0, }; + const filterTextWrapStyle = { + position: 'absolute', + top: '68px', + right: '10px', + left: '20px', + }; + const listStyle = { overflowY: 'auto', position: 'absolute', - top: '68px', + top: '108px', right: '10px', bottom: 0, left: '20px', @@ -138,6 +173,13 @@ export default class StorybookControls extends React.Component {