mirror of
				https://github.com/reduxjs/redux-devtools.git
				synced 2025-10-31 16:07:45 +03:00 
			
		
		
		
	Use prettier
This commit is contained in:
		
							parent
							
								
									458f9019aa
								
							
						
					
					
						commit
						6907c48147
					
				
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							|  | @ -6,3 +6,4 @@ umd | |||
| build | ||||
| coverage | ||||
| node_modules | ||||
| __snapshots__ | ||||
|  |  | |||
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							|  | @ -7,3 +7,4 @@ umd | |||
| build | ||||
| coverage | ||||
| .idea | ||||
| .eslintcache | ||||
|  |  | |||
|  | @ -8,5 +8,5 @@ cache: | |||
|     - "node_modules" | ||||
| script: | ||||
|   - yarn build:all | ||||
|   - yarn lint | ||||
|   - yarn lint:all | ||||
|   - yarn test | ||||
|  |  | |||
|  | @ -11,4 +11,3 @@ Project maintainers have the right and responsibility to remove, edit, or reject | |||
| Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. | ||||
| 
 | ||||
| This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/) | ||||
| 
 | ||||
|  |  | |||
|  | @ -15,6 +15,7 @@ By default, the websocket server is running on `ws://localhost:8000/socketcluste | |||
| The client driver provides a way to connect to the server via websockets (see the docs for the selected client). | ||||
| 
 | ||||
| ##### JavaScript | ||||
| 
 | ||||
| ```js | ||||
| var socket = socketCluster.connect({ | ||||
|   hostname: 'localhost', | ||||
|  | @ -23,6 +24,7 @@ var socket = socketCluster.connect({ | |||
| ``` | ||||
| 
 | ||||
| ##### Python | ||||
| 
 | ||||
| ```py | ||||
| socket = Socketcluster.socket("ws://localhost:8000/socketcluster/") | ||||
| socket.connect() | ||||
|  | @ -35,6 +37,7 @@ socket.connect() | |||
| SocketCluster client handles reconnecting for you, but you still might want to know when the connection is established, or when it failed to connect. | ||||
| 
 | ||||
| ##### JavaScript | ||||
| 
 | ||||
| ```js | ||||
| socket.on('connect', status => { | ||||
|   // Here will come the next step | ||||
|  | @ -48,6 +51,7 @@ socket.on('error', error => { | |||
| ``` | ||||
| 
 | ||||
| ##### Python | ||||
| 
 | ||||
| ```py | ||||
| def onconnect(socket): | ||||
|   // Here will call the next step | ||||
|  | @ -66,9 +70,13 @@ socket.setBasicListener(onconnect, ondisconnect, onConnectError) | |||
| We're not providing an authorizing mechanism yet. All you have to do is to emit a `login` event, and you'll get a `channelName` you should subscribe for, and watch for messages and events. Make sure to pass the `master` event, otherwise it should be a monitor, not a client app. | ||||
| 
 | ||||
| ##### JavaScript | ||||
| 
 | ||||
| ```js | ||||
| socket.emit('login', 'master', (error, channelName) => { | ||||
|   if (error) { console.log(error); return; } | ||||
|   if (error) { | ||||
|     console.log(error); | ||||
|     return; | ||||
|   } | ||||
|   channel = socket.subscribe(channelName); | ||||
|   channel.watch(handleMessages); | ||||
|   socket.on(channelName, handleMessages); | ||||
|  | @ -80,6 +88,7 @@ function handleMessages(message) { | |||
| ``` | ||||
| 
 | ||||
| ##### Python | ||||
| 
 | ||||
| ```py | ||||
| socket.emitack("login", "master", login) | ||||
| 
 | ||||
|  | @ -99,6 +108,7 @@ You could just emit the `login` event, and omit subscribing (and point `5` bello | |||
| To send your data to the monitor use `log` or `log-noid` channel. The latter will add the socket id to the message from the server side (useful when the message was sent before the connection was established). | ||||
| 
 | ||||
| The message object includes the following: | ||||
| 
 | ||||
| - `type` - usually should be `ACTION`. If you want to indicate that we're starting a new log (clear all actions emitted before and add `@@INIT`), use `INIT`. In case you have a lifted state similar to one provided by [`redux-devtools-instrument`](https://github.com/zalmoxisus/redux-devtools-instrument), use `STATE`. | ||||
| - `action` - the action object. It is recommended to lift it in another object, and add `timestamp` to show when the action was fired off: `{ timestamp: Date.now(), action: { type: 'SOME_ACTION' } }`. | ||||
| - `payload` - usually the state or lifted state object. | ||||
|  | @ -107,6 +117,7 @@ The message object includes the following: | |||
| - `id` - socket connection id, which should be either `socket.id` or should not provided and use `log-noid` channel. | ||||
| 
 | ||||
| ##### JavaScript | ||||
| 
 | ||||
| ```js | ||||
| const message = { | ||||
|   type: 'ACTION', | ||||
|  | @ -120,6 +131,7 @@ socket.emit(socket.id ? 'log' : 'log-noid', message); | |||
| ``` | ||||
| 
 | ||||
| ##### Python | ||||
| 
 | ||||
| ```py | ||||
| class Message: | ||||
|   def __init__(self, action, state): | ||||
|  | @ -133,6 +145,7 @@ socket.emit(socket.id if "log" else "log-noid", Message(action, state)); | |||
| #### 5. Listening for monitor events | ||||
| 
 | ||||
| When a monitor action is emitted, you'll get an event on the subscribed function. The argument object includes a `type` key, which can be: | ||||
| 
 | ||||
| - `DISPATCH` - a monitor action dispatched on Redux DevTools monitor, like `{ type: 'DISPATCH', payload: { type: 'JUMP_TO_STATE', 'index': 2 }`. See [`redux-devtools-instrument`](https://github.com/zalmoxisus/redux-devtools-instrument/blob/master/src/instrument.js) for details. Additionally to that API, you'll get also a stringified `state` object when needed. So, for example, for time travelling (`JUMP_TO_STATE`) you can just parse and set the state (see the example). Usually implementing this type of actions would be enough. | ||||
| - `ACTION` - the user requested to dispatch an action remotely like `{ type: 'ACTION', action: '{ type: \'INCREMENT_COUNTER\' }' }`. The `action` can be either a stringified javascript object which should be evalled or a function which arguments should be evalled like [here](https://github.com/zalmoxisus/remotedev-utils/blob/master/src/index.js#L62-L70). | ||||
| - `START` - a monitor was opened. You could handle this event in order not to do extra tasks when the app is not monitored. | ||||
|  | @ -141,6 +154,7 @@ When a monitor action is emitted, you'll get an event on the subscribed function | |||
| See [`mobx-remotedev`](https://github.com/zalmoxisus/mobx-remotedev/blob/master/src/monitorActions.js) for an example of implementation without [`redux-devtools-instrument`](https://github.com/zalmoxisus/redux-devtools-instrument/blob/master/src/instrument.js). | ||||
| 
 | ||||
| ##### JavaScript | ||||
| 
 | ||||
| ```js | ||||
| function handleMessages(message) { | ||||
|   if (message.type === 'DISPATCH' && message.payload.type === 'JUMP_TO_STATE') { | ||||
|  | @ -150,6 +164,7 @@ function handleMessages(message) { | |||
| ``` | ||||
| 
 | ||||
| ##### Python | ||||
| 
 | ||||
| ```py | ||||
| def handleMessages(key, message): | ||||
|   if message.type === "DISPATCH" and message.payload.type === "JUMP_TO_STATE": | ||||
|  |  | |||
|  | @ -46,10 +46,12 @@ const DevTools = createDevTools( | |||
|   // Consult their repositories to learn about those props. | ||||
|   // Here, we put LogMonitor inside a DockMonitor. | ||||
|   // Note: DockMonitor is visible by default. | ||||
|   <DockMonitor toggleVisibilityKey='ctrl-h' | ||||
|                changePositionKey='ctrl-q' | ||||
|                defaultIsVisible={true}> | ||||
|     <LogMonitor theme='tomorrow' /> | ||||
|   <DockMonitor | ||||
|     toggleVisibilityKey="ctrl-h" | ||||
|     changePositionKey="ctrl-q" | ||||
|     defaultIsVisible={true} | ||||
|   > | ||||
|     <LogMonitor theme="tomorrow" /> | ||||
|   </DockMonitor> | ||||
| ); | ||||
| 
 | ||||
|  | @ -60,9 +62,7 @@ Note that you can use `LogMonitor` directly without wrapping it in `DockMonitor` | |||
| 
 | ||||
| ```js | ||||
| // If you'd rather not use docking UI, use <LogMonitor> directly | ||||
| const DevTools = createDevTools( | ||||
|   <LogMonitor theme='solarized' /> | ||||
| ); | ||||
| const DevTools = createDevTools(<LogMonitor theme="solarized" />); | ||||
| ``` | ||||
| 
 | ||||
| #### Use `DevTools.instrument()` Store Enhancer | ||||
|  | @ -75,7 +75,7 @@ The easiest way to apply several store enhancers in a row is to use the [`compos | |||
| 
 | ||||
| You can add additional options to it: `DevTools.instrument({ maxAge: 50, shouldCatchErrors: true })`. See [`redux-devtools-instrument`'s API](https://github.com/reduxjs/redux-devtools/tree/master/packages/redux-devtools-instrument#api) for more details. | ||||
| 
 | ||||
| It’s important that you should add `DevTools.instrument()` *after* `applyMiddleware` in your `compose()` function arguments. This is because `applyMiddleware` is potentially asynchronous, but `DevTools.instrument()` expects all actions to be plain objects rather than actions interpreted by asynchronous middleware such as [redux-promise](https://github.com/acdlite/redux-promise) or [redux-thunk](https://github.com/gaearon/redux-thunk). So make sure `applyMiddleware()` goes first in the `compose()` call, and `DevTools.instrument()` goes after it. | ||||
| It’s important that you should add `DevTools.instrument()` _after_ `applyMiddleware` in your `compose()` function arguments. This is because `applyMiddleware` is potentially asynchronous, but `DevTools.instrument()` expects all actions to be plain objects rather than actions interpreted by asynchronous middleware such as [redux-promise](https://github.com/acdlite/redux-promise) or [redux-thunk](https://github.com/gaearon/redux-thunk). So make sure `applyMiddleware()` goes first in the `compose()` call, and `DevTools.instrument()` goes after it. | ||||
| 
 | ||||
| ##### `store/configureStore.js` | ||||
| 
 | ||||
|  | @ -99,7 +99,9 @@ export default function configureStore(initialState) { | |||
|   // Hot reload reducers (requires Webpack or Browserify HMR to be enabled) | ||||
|   if (module.hot) { | ||||
|     module.hot.accept('../reducers', () => | ||||
|       store.replaceReducer(require('../reducers')/*.default if you use Babel 6+ */) | ||||
|       store.replaceReducer( | ||||
|         require('../reducers') /*.default if you use Babel 6+ */ | ||||
|       ) | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|  | @ -126,7 +128,7 @@ function getDebugSessionKey() { | |||
|   // You can write custom logic here! | ||||
|   // By default we try to read the key from ?debug_session=<key> in the address bar | ||||
|   const matches = window.location.href.match(/[?&]debug_session=([^&#]+)\b/); | ||||
|   return (matches && matches.length > 0)? matches[1] : null; | ||||
|   return matches && matches.length > 0 ? matches[1] : null; | ||||
| } | ||||
| 
 | ||||
| export default function configureStore(initialState) { | ||||
|  | @ -181,7 +183,7 @@ export default function configureStore(initialState) { | |||
|   // Note: only Redux >= 3.1.0 supports passing enhancer as third argument. | ||||
|   // See https://github.com/rackt/redux/releases/tag/v3.1.0 | ||||
|   return createStore(rootReducer, initialState, enhancer); | ||||
| }; | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| ##### `store/configureStore.dev.js` | ||||
|  | @ -205,7 +207,7 @@ function getDebugSessionKey() { | |||
|   // You can write custom logic here! | ||||
|   // By default we try to read the key from ?debug_session=<key> in the address bar | ||||
|   const matches = window.location.href.match(/[?&]debug_session=([^&]+)\b/); | ||||
|   return (matches && matches.length > 0)? matches[1] : null; | ||||
|   return matches && matches.length > 0 ? matches[1] : null; | ||||
| } | ||||
| 
 | ||||
| export default function configureStore(initialState) { | ||||
|  | @ -216,7 +218,9 @@ export default function configureStore(initialState) { | |||
|   // Hot reload reducers (requires Webpack or Browserify HMR to be enabled) | ||||
|   if (module.hot) { | ||||
|     module.hot.accept('../reducers', () => | ||||
|       store.replaceReducer(require('../reducers')/*.default if you use Babel 6+ */) | ||||
|       store.replaceReducer( | ||||
|         require('../reducers') /*.default if you use Babel 6+ */ | ||||
|       ) | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|  | @ -346,7 +350,11 @@ import { render } from 'react-dom'; | |||
| import DevTools from './containers/DevTools'; | ||||
| 
 | ||||
| export default function showDevTools(store) { | ||||
|   const popup = window.open(null, 'Redux DevTools', 'menubar=no,location=no,resizable=yes,scrollbars=no,status=no'); | ||||
|   const popup = window.open( | ||||
|     null, | ||||
|     'Redux DevTools', | ||||
|     'menubar=no,location=no,resizable=yes,scrollbars=no,status=no' | ||||
|   ); | ||||
|   // Reload in case it already exists | ||||
|   popup.location.reload(); | ||||
| 
 | ||||
|  | @ -366,11 +374,11 @@ Note that there are no useful props you can pass to the `DevTools` component oth | |||
| 
 | ||||
| ### Gotchas | ||||
| 
 | ||||
| * **Your reducers have to be pure and free of side effects to work correctly with DevTools.** For example, even generating a random ID in reducer makes it impure and non-deterministic. Instead, do this in action creators. | ||||
| - **Your reducers have to be pure and free of side effects to work correctly with DevTools.** For example, even generating a random ID in reducer makes it impure and non-deterministic. Instead, do this in action creators. | ||||
| 
 | ||||
| * **Make sure to only apply `DevTools.instrument()` and render `<DevTools>` in development!** In production, this will be terribly slow because actions just accumulate forever. As described above, you need to use conditional `require`s and use `DefinePlugin` (Webpack) or `loose-envify` (Browserify) together with Uglify to remove the dead code. Here is [an example](https://github.com/erikras/react-redux-universal-hot-example/) that adds Redux DevTools handling the production case correctly. | ||||
| - **Make sure to only apply `DevTools.instrument()` and render `<DevTools>` in development!** In production, this will be terribly slow because actions just accumulate forever. As described above, you need to use conditional `require`s and use `DefinePlugin` (Webpack) or `loose-envify` (Browserify) together with Uglify to remove the dead code. Here is [an example](https://github.com/erikras/react-redux-universal-hot-example/) that adds Redux DevTools handling the production case correctly. | ||||
| 
 | ||||
| * **It is important that `DevTools.instrument()` store enhancer should be added to your middleware stack *after* `applyMiddleware` in the `compose`d functions, as `applyMiddleware` is potentially asynchronous.** Otherwise, DevTools won’t see the raw actions emitted by asynchronous middleware such as [redux-promise](https://github.com/acdlite/redux-promise) or [redux-thunk](https://github.com/gaearon/redux-thunk). | ||||
| - **It is important that `DevTools.instrument()` store enhancer should be added to your middleware stack _after_ `applyMiddleware` in the `compose`d functions, as `applyMiddleware` is potentially asynchronous.** Otherwise, DevTools won’t see the raw actions emitted by asynchronous middleware such as [redux-promise](https://github.com/acdlite/redux-promise) or [redux-thunk](https://github.com/gaearon/redux-thunk). | ||||
| 
 | ||||
| ### What Next? | ||||
| 
 | ||||
|  |  | |||
|  | @ -8,9 +8,5 @@ | |||
|       "allowBranch": "master" | ||||
|     } | ||||
|   }, | ||||
|   "ignoreChanges": [ | ||||
|     "**/test/**", | ||||
|     "**/examples/**", | ||||
|     "**/*.md" | ||||
|   ] | ||||
|   "ignoreChanges": ["**/test/**", "**/examples/**", "**/*.md"] | ||||
| } | ||||
|  |  | |||
							
								
								
									
										17
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								package.json
									
									
									
									
									
								
							|  | @ -9,7 +9,8 @@ | |||
|     "eslint-plugin-react": "7.12.3", | ||||
|     "jest": "^23.6.0", | ||||
|     "lerna": "3.9.0", | ||||
|     "pre-commit": "^1.1.3" | ||||
|     "lint-staged": "^8.1.0", | ||||
|     "prettier": "^1.15.3" | ||||
|   }, | ||||
|   "scripts": { | ||||
|     "lerna": "lerna", | ||||
|  | @ -21,13 +22,23 @@ | |||
|     "lint": "eslint '**/*.{js,jsx}' --cache", | ||||
|     "lint:fix": "eslint '**/*.{js,jsx}' --fix --cache", | ||||
|     "lint:all": "eslint '**/*.{js,jsx}'", | ||||
|     "prettify": "prettier '**/*.{js,jsx,json,css,html,md}' --ignore-path .eslintignore --single-quote --write", | ||||
|     "precommit": "lint-staged", | ||||
|     "test": "jest --onlyChanged", | ||||
|     "test:all": "jest" | ||||
|   }, | ||||
|   "workspaces": [ | ||||
|     "packages/*" | ||||
|   ], | ||||
|   "pre-commit": [ | ||||
|     "lint" | ||||
|   "lint-staged": { | ||||
|     "*.{js,jsx}": [ | ||||
|       "prettier --single-quote --write", | ||||
|       "yarn lint:fix", | ||||
|       "git add" | ||||
|     ], | ||||
|     "*.{json,css,html,md}": [ | ||||
|       "prettier --single-quote --write", | ||||
|       "git add" | ||||
|     ] | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -1,5 +1,4 @@ | |||
| d3tooltip | ||||
| ========================= | ||||
| # d3tooltip | ||||
| 
 | ||||
| This tooltip aims for a minimal yet highly configurable API. It has a long way to go, but the essentials are there. | ||||
| It was created by [@romseguy](https://github.com/romseguy) and merged from [`romseguy/d3tooltip`](https://github.com/romseguy/d3tooltip). | ||||
|  | @ -47,9 +46,9 @@ vis.selectAll('circle').data(someData).enter() | |||
| 
 | ||||
| ## API | ||||
| 
 | ||||
| Option                    | Type         | Default             | Description | ||||
| --------------------------|--------------|---------------------|-------------------------------------------------------------- | ||||
| `root`                    | DOM.Element  | `body`              | The tooltip will be added as a child of that element. You can also use a D3 [selection](https://github.com/mbostock/d3/wiki/Selections#d3_select) | ||||
| `left`                    | Number       | `undefined`         | Sets the tooltip `x` absolute position instead of the mouse `x` position, relative to the `root` element | ||||
| `top`                     | Number       | `undefined`         | Sets the tooltip `y` absolute position instead of the mouse `y` position, relative to the `root` element | ||||
| `offset`                  | Object       | `{left: 0, top: 0}` | Sets the distance, starting from the cursor position, until the tooltip is rendered. **Warning**: only applicable if you don't provide a `left` or `top` option | ||||
| | Option   | Type        | Default             | Description                                                                                                                                                     | | ||||
| | -------- | ----------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||||
| | `root`   | DOM.Element | `body`              | The tooltip will be added as a child of that element. You can also use a D3 [selection](https://github.com/mbostock/d3/wiki/Selections#d3_select)               | | ||||
| | `left`   | Number      | `undefined`         | Sets the tooltip `x` absolute position instead of the mouse `x` position, relative to the `root` element                                                        | | ||||
| | `top`    | Number      | `undefined`         | Sets the tooltip `y` absolute position instead of the mouse `y` position, relative to the `root` element                                                        | | ||||
| | `offset` | Object      | `{left: 0, top: 0}` | Sets the distance, starting from the cursor position, until the tooltip is rendered. **Warning**: only applicable if you don't provide a `left` or `top` option | | ||||
|  |  | |||
							
								
								
									
										18
									
								
								packages/d3tooltip/src/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								packages/d3tooltip/src/index.js
									
									
									
									
										vendored
									
									
								
							|  | @ -10,14 +10,9 @@ const defaultOptions = { | |||
| }; | ||||
| 
 | ||||
| export default function tooltip(d3, className = 'tooltip', options = {}) { | ||||
|   const { | ||||
|     left, | ||||
|     top, | ||||
|     offset, | ||||
|     root | ||||
|     } = {...defaultOptions, ...options}; | ||||
|   const { left, top, offset, root } = { ...defaultOptions, ...options }; | ||||
| 
 | ||||
|   let attrs = {'class': className}; | ||||
|   let attrs = { class: className }; | ||||
|   let text = () => ''; | ||||
|   let styles = {}; | ||||
| 
 | ||||
|  | @ -33,7 +28,8 @@ export default function tooltip(d3, className = 'tooltip', options = {}) { | |||
| 
 | ||||
|         anchor.selectAll(`div.${className}`).remove(); | ||||
| 
 | ||||
|         el = anchor.append('div') | ||||
|         el = anchor | ||||
|           .append('div') | ||||
|           .attr(prependClass(className)(attrs)) | ||||
|           .style({ | ||||
|             position: 'absolute', | ||||
|  | @ -49,12 +45,10 @@ export default function tooltip(d3, className = 'tooltip', options = {}) { | |||
|         let [mouseX, mouseY] = d3.mouse(rootNode); | ||||
|         let [x, y] = [left || mouseX + offset.left, top || mouseY - offset.top]; | ||||
| 
 | ||||
|         el | ||||
|           .style({ | ||||
|         el.style({ | ||||
|           left: x + 'px', | ||||
|           top: y + 'px' | ||||
|           }) | ||||
|           .html(() => text(node)); | ||||
|         }).html(() => text(node)); | ||||
|       }, | ||||
| 
 | ||||
|       'mouseout.tip': () => el.remove() | ||||
|  |  | |||
|  | @ -1,7 +1,6 @@ | |||
| const path = require('path'); | ||||
| 
 | ||||
| module.exports = (env = {}) => ( | ||||
|   { | ||||
| module.exports = (env = {}) => ({ | ||||
|   mode: 'production', | ||||
|   entry: { | ||||
|     app: ['./src/index.js'] | ||||
|  | @ -27,5 +26,4 @@ module.exports = (env = {}) => ( | |||
|   performance: { | ||||
|     hints: false | ||||
|   } | ||||
|   } | ||||
| ); | ||||
| }); | ||||
|  |  | |||
|  | @ -7,5 +7,6 @@ const parse = require('git-url-parse'); | |||
| var ghUrl = process.argv[2]; | ||||
| const parsedUrl = parse(ghUrl); | ||||
| 
 | ||||
| const ghPagesUrl = 'https://' + parsedUrl.owner + '.github.io/' + parsedUrl.name; | ||||
| const ghPagesUrl = | ||||
|   'https://' + parsedUrl.owner + '.github.io/' + parsedUrl.name; | ||||
| console.log(ghPagesUrl); | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ var exposedProperties = ['window', 'navigator', 'document']; | |||
| 
 | ||||
| global.document = jsdom(''); | ||||
| global.window = document.defaultView; | ||||
| Object.keys(document.defaultView).forEach((property) => { | ||||
| Object.keys(document.defaultView).forEach(property => { | ||||
|   if (typeof global[property] === 'undefined') { | ||||
|     exposedProperties.push(property); | ||||
|     global[property] = document.defaultView[property]; | ||||
|  | @ -27,7 +27,7 @@ global.navigator = { | |||
| 
 | ||||
| process.on('unhandledRejection', function(error) { | ||||
|   console.error('Unhandled Promise Rejection:'); | ||||
|   console.error(error && error.stack || error); | ||||
|   console.error((error && error.stack) || error); | ||||
| }); | ||||
| 
 | ||||
| require('./user/pretest.js'); | ||||
|  |  | |||
|  | @ -5,7 +5,8 @@ import { withKnobs } from '@storybook/addon-knobs'; | |||
| import { withTheme } from './themeAddon/theme'; | ||||
| import '../src/presets.js'; | ||||
| 
 | ||||
| addDecorator(withOptions({ | ||||
| addDecorator( | ||||
|   withOptions({ | ||||
|     name: 'DevUI', | ||||
|     url: 'https://github.com/reduxjs/redux-devtools/tree/master/packages/devui', | ||||
|     goFullScreen: false, | ||||
|  | @ -13,7 +14,8 @@ addDecorator(withOptions({ | |||
|     showAddonPanel: true, | ||||
|     showSearchBox: false, | ||||
|     addonPanelInRight: true | ||||
| })); | ||||
|   }) | ||||
| ); | ||||
| 
 | ||||
| addDecorator(withTheme); | ||||
| addDecorator(withKnobs); | ||||
|  |  | |||
|  | @ -11,10 +11,11 @@ | |||
|     min-height: 400px; | ||||
|     margin: 0; | ||||
|     padding: 0; | ||||
|     font-family: "Helvetica Neue", "Lucida Grande", sans-serif; | ||||
|     font-family: 'Helvetica Neue', 'Lucida Grande', sans-serif; | ||||
|     font-size: 11px; | ||||
|   } | ||||
|   #root, #root > div { | ||||
|   #root, | ||||
|   #root > div { | ||||
|     height: 100%; | ||||
|   } | ||||
|   #root > div > div { | ||||
|  |  | |||
|  | @ -7,10 +7,7 @@ addons.register(ADDON_ID, api => { | |||
|   const channel = addons.getChannel(); | ||||
|   addons.addPanel(PANEL_ID, { | ||||
|     title: 'Theme', | ||||
|     render: ({ active }) => ( | ||||
|       active ? | ||||
|         <Panel channel={channel} api={api} /> | ||||
|         : null | ||||
|     ) | ||||
|     render: ({ active }) => | ||||
|       active ? <Panel channel={channel} api={api} /> : null | ||||
|   }); | ||||
| }); | ||||
|  |  | |||
|  | @ -4,7 +4,8 @@ | |||
|   font-style: normal; | ||||
|   font-weight: 400; | ||||
|   src: local('Source Code Pro'), local('SourceCodePro-Regular'), | ||||
|   url('./source-code-pro-v6-latin/source-code-pro-v6-latin-regular.woff2') format('woff2'); | ||||
|     url('./source-code-pro-v6-latin/source-code-pro-v6-latin-regular.woff2') | ||||
|       format('woff2'); | ||||
| } | ||||
| /* source-sans-pro-regular - latin */ | ||||
| @font-face { | ||||
|  | @ -12,7 +13,8 @@ | |||
|   font-style: normal; | ||||
|   font-weight: 400; | ||||
|   src: local('Source Sans Pro'), local('SourceSansPro-Regular'), | ||||
|   url('./source-sans-pro-v9-latin/source-sans-pro-v9-latin-regular.woff2') format('woff2'); | ||||
|     url('./source-sans-pro-v9-latin/source-sans-pro-v9-latin-regular.woff2') | ||||
|       format('woff2'); | ||||
| } | ||||
| /* source-sans-pro-600 - latin */ | ||||
| @font-face { | ||||
|  | @ -20,7 +22,8 @@ | |||
|   font-style: normal; | ||||
|   font-weight: 600; | ||||
|   src: local('Source Sans Pro Semibold'), local('SourceSansPro-Semibold'), | ||||
|   url('./source-sans-pro-v9-latin/source-sans-pro-v9-latin-600.woff2') format('woff2'); | ||||
|     url('./source-sans-pro-v9-latin/source-sans-pro-v9-latin-600.woff2') | ||||
|       format('woff2'); | ||||
| } | ||||
| 
 | ||||
| /* roboto-regular - latin */ | ||||
|  | @ -37,7 +40,8 @@ | |||
|   font-style: normal; | ||||
|   font-weight: 400; | ||||
|   src: local('Roboto Mono'), local('RobotoMono-Regular'), | ||||
|   url('./roboto-mono-v4-latin/roboto-mono-v4-latin-regular.woff2') format('woff2'); | ||||
|     url('./roboto-mono-v4-latin/roboto-mono-v4-latin-regular.woff2') | ||||
|       format('woff2'); | ||||
| } | ||||
| 
 | ||||
| /* Generated with https://google-webfonts-helper.herokuapp.com */ | ||||
|  |  | |||
|  | @ -1,15 +1,16 @@ | |||
| { | ||||
|   "name": "devui", | ||||
|   "version": "1.0.0-3", | ||||
|   "description": | ||||
|     "Reusable React components for building DevTools monitors and apps.", | ||||
|   "files": ["lib", "fonts"], | ||||
|   "description": "Reusable React components for building DevTools monitors and apps.", | ||||
|   "files": [ | ||||
|     "lib", | ||||
|     "fonts" | ||||
|   ], | ||||
|   "repository": { | ||||
|     "type": "git", | ||||
|     "url": "https://github.com/reduxjs/redux-devtools.git" | ||||
|   }, | ||||
|   "author": | ||||
|     "Mihail Diordiev <zalmoxisus@gmail.com> (https://github.com/zalmoxisus)", | ||||
|   "author": "Mihail Diordiev <zalmoxisus@gmail.com> (https://github.com/zalmoxisus)", | ||||
|   "license": "MIT", | ||||
|   "scripts": { | ||||
|     "start": "npm run storybook", | ||||
|  |  | |||
|  | @ -10,13 +10,15 @@ const CommonWrapper = createStyledComponent(commonStyle); | |||
| 
 | ||||
| export default class Button extends Component { | ||||
|   shouldComponentUpdate(nextProps) { | ||||
|     return nextProps.children !== this.props.children || | ||||
|     return ( | ||||
|       nextProps.children !== this.props.children || | ||||
|       nextProps.disabled !== this.props.disabled || | ||||
|       nextProps.mark !== this.props.mark || | ||||
|       nextProps.size !== this.props.size || | ||||
|       nextProps.primary !== this.props.primary || | ||||
|       nextProps.tooltipPosition !== this.props.tooltipPosition || | ||||
|       nextProps.title !== this.props.title; | ||||
|       nextProps.title !== this.props.title | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   onMouseUp = e => { | ||||
|  | @ -56,15 +58,32 @@ export default class Button extends Component { | |||
| Button.propTypes = { | ||||
|   children: PropTypes.any.isRequired, | ||||
|   title: PropTypes.string, | ||||
|   tooltipPosition: PropTypes.oneOf(['top', 'bottom', 'left', 'right', | ||||
|     'bottom-left', 'bottom-right', 'top-left', 'top-right']), | ||||
|   tooltipPosition: PropTypes.oneOf([ | ||||
|     'top', | ||||
|     'bottom', | ||||
|     'left', | ||||
|     'right', | ||||
|     'bottom-left', | ||||
|     'bottom-right', | ||||
|     'top-left', | ||||
|     'top-right' | ||||
|   ]), | ||||
|   onClick: PropTypes.func, | ||||
|   type: PropTypes.string, | ||||
|   disabled: PropTypes.bool, | ||||
|   primary: PropTypes.bool, | ||||
|   size: PropTypes.oneOf(['big', 'normal', 'small']), | ||||
|   mark: PropTypes.oneOf([false, 'base08', 'base09', 'base0A', 'base0B', | ||||
|     'base0C', 'base0D', 'base0E', 'base0F']), | ||||
|   mark: PropTypes.oneOf([ | ||||
|     false, | ||||
|     'base08', | ||||
|     'base09', | ||||
|     'base0A', | ||||
|     'base0B', | ||||
|     'base0C', | ||||
|     'base0D', | ||||
|     'base0E', | ||||
|     'base0F' | ||||
|   ]), | ||||
|   theme: PropTypes.object | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -16,16 +16,20 @@ export const Container = styled.div` | |||
| 
 | ||||
| storiesOf('Button', module) | ||||
|   .addDecorator(withKnobs) | ||||
|   .add( | ||||
|     'default', | ||||
|     () => ( | ||||
|   .add('default', () => ( | ||||
|     <Container> | ||||
|       <Button | ||||
|         title={text('Title', 'Hello Tooltip! \\a And from new line hello!')} | ||||
|           tooltipPosition={ | ||||
|             select('tooltipPosition', ['top', 'bottom', 'left', 'right', | ||||
|              'bottom-left', 'bottom-right', 'top-left', 'top-right']) | ||||
|           } | ||||
|         tooltipPosition={select('tooltipPosition', [ | ||||
|           'top', | ||||
|           'bottom', | ||||
|           'left', | ||||
|           'right', | ||||
|           'bottom-left', | ||||
|           'bottom-right', | ||||
|           'top-left', | ||||
|           'top-right' | ||||
|         ])} | ||||
|         primary={boolean('primary', true)} | ||||
|         size={select('size', ['big', 'normal', 'small'], 'normal')} | ||||
|         disabled={boolean('Disabled', false)} | ||||
|  | @ -34,20 +38,35 @@ storiesOf('Button', module) | |||
|         {text('Label', 'Hello Button')} | ||||
|       </Button> | ||||
|     </Container> | ||||
|     ) | ||||
|   ) | ||||
|   .add( | ||||
|     'mark', | ||||
|     () => ( | ||||
|   )) | ||||
|   .add('mark', () => ( | ||||
|     <Container> | ||||
|       <Button | ||||
|           mark={select('mark', ['base08', 'base09', 'base0A', 'base0B', | ||||
|             'base0C', 'base0D', 'base0E', 'base0F'], 'base08')} | ||||
|         mark={select( | ||||
|           'mark', | ||||
|           [ | ||||
|             'base08', | ||||
|             'base09', | ||||
|             'base0A', | ||||
|             'base0B', | ||||
|             'base0C', | ||||
|             'base0D', | ||||
|             'base0E', | ||||
|             'base0F' | ||||
|           ], | ||||
|           'base08' | ||||
|         )} | ||||
|         title={text('Title', 'Hello Tooltip')} | ||||
|           tooltipPosition={ | ||||
|             select('tooltipPosition', ['top', 'bottom', 'left', 'right', | ||||
|              'bottom-left', 'bottom-right', 'top-left', 'top-right']) | ||||
|           } | ||||
|         tooltipPosition={select('tooltipPosition', [ | ||||
|           'top', | ||||
|           'bottom', | ||||
|           'left', | ||||
|           'right', | ||||
|           'bottom-left', | ||||
|           'bottom-right', | ||||
|           'top-left', | ||||
|           'top-right' | ||||
|         ])} | ||||
|         size={select('size', ['big', 'normal', 'small'], 'normal')} | ||||
|         disabled={boolean('Disabled', false)} | ||||
|         onClick={action('button clicked')} | ||||
|  | @ -55,5 +74,4 @@ storiesOf('Button', module) | |||
|         <MdFiberManualRecord /> | ||||
|       </Button> | ||||
|     </Container> | ||||
|     ) | ||||
|   ); | ||||
|   )); | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ import { css } from 'styled-components'; | |||
| import { fadeIn } from '../../utils/animations'; | ||||
| import colorEffect from '../../utils/color'; | ||||
| 
 | ||||
| const both = (tooltipPosition) => { | ||||
| const both = tooltipPosition => { | ||||
|   switch (tooltipPosition) { | ||||
|     case 'bottom': | ||||
|       return ` | ||||
|  | @ -46,7 +46,7 @@ const both = (tooltipPosition) => { | |||
|   } | ||||
| }; | ||||
| 
 | ||||
| const before = (tooltipPosition) => { | ||||
| const before = tooltipPosition => { | ||||
|   switch (tooltipPosition) { | ||||
|     case 'bottom-left': | ||||
|       return ` | ||||
|  | @ -110,12 +110,13 @@ const after = (tooltipPosition, color) => { | |||
|   } | ||||
| }; | ||||
| 
 | ||||
| const getDirection = (tooltipPosition) => { | ||||
|   return (tooltipPosition.indexOf('-') > 0) ? | ||||
|     tooltipPosition.substring(0, tooltipPosition.indexOf('-')) : tooltipPosition; | ||||
| const getDirection = tooltipPosition => { | ||||
|   return tooltipPosition.indexOf('-') > 0 | ||||
|     ? tooltipPosition.substring(0, tooltipPosition.indexOf('-')) | ||||
|     : tooltipPosition; | ||||
| }; | ||||
| 
 | ||||
| const getSize = (size) => { | ||||
| const getSize = size => { | ||||
|   switch (size) { | ||||
|     case 'big': | ||||
|       return 'min-height: 34px; padding: 2px 12px;'; | ||||
|  | @ -144,8 +145,13 @@ export const commonStyle = ({ theme, mark, size }) => css` | |||
|       pointer-events: none; | ||||
|     } | ||||
| 
 | ||||
|     ${mark && ` | ||||
|     background-color: ${colorEffect(theme[mark], 'fade', theme.light ? 0.92 : 0.82)}; | ||||
|     ${mark && | ||||
|       ` | ||||
|     background-color: ${colorEffect( | ||||
|       theme[mark], | ||||
|       'fade', | ||||
|       theme.light ? 0.92 : 0.82 | ||||
|     )}; | ||||
|    | ||||
|     > svg { | ||||
|       color: ${theme[mark]}; | ||||
|  | @ -158,7 +164,13 @@ export const commonStyle = ({ theme, mark, size }) => css` | |||
|   } | ||||
| `;
 | ||||
| 
 | ||||
| export const tooltipStyle = ({ theme, tooltipTitle, tooltipPosition, mark, size }) => css` | ||||
| export const tooltipStyle = ({ | ||||
|   theme, | ||||
|   tooltipTitle, | ||||
|   tooltipPosition, | ||||
|   mark, | ||||
|   size | ||||
| }) => css` | ||||
|   ${commonStyle({ theme, mark, size })} | ||||
| 
 | ||||
|   &:before { | ||||
|  | @ -170,7 +182,9 @@ export const tooltipStyle = ({ theme, tooltipTitle, tooltipPosition, mark, size | |||
|     border-radius: 3px; | ||||
|     background: ${theme.base01}; | ||||
|     border: 1px solid ${theme.base02}; | ||||
|     box-shadow: 1px 1px 2px -1px ${theme.base02}, 1px 1px 2px 0px ${theme.base02}; | ||||
|     box-shadow: 1px 1px 2px -1px ${theme.base02}, 1px 1px 2px 0px ${ | ||||
|   theme.base02 | ||||
| }; | ||||
|   } | ||||
| 
 | ||||
|   &:after, | ||||
|  | @ -194,7 +208,8 @@ export const tooltipStyle = ({ theme, tooltipTitle, tooltipPosition, mark, size | |||
|     ${theme.type === 'material' ? `animation: ${fadeIn} 500ms;` : ''} | ||||
|   } | ||||
| 
 | ||||
|   ${theme.type !== 'material' && ` | ||||
|   ${theme.type !== 'material' && | ||||
|     ` | ||||
|   &:after { | ||||
|     content: ""; | ||||
|     border-style: solid; | ||||
|  |  | |||
|  | @ -11,21 +11,30 @@ export const style = ({ theme, primary, disabled }) => css` | |||
|   margin: auto 0; | ||||
|   border: 1px solid ${theme.base02}; | ||||
|   border-radius: 4px; | ||||
|   ${primary ? ` | ||||
|   ${ | ||||
|     primary | ||||
|       ? ` | ||||
|   background-color: ${theme.base05}; | ||||
|   color: ${theme.base00}; | ||||
|   ` : ` | ||||
|   ` | ||||
|       : ` | ||||
|   background-color: ${theme.base01}; | ||||
|   color: ${theme.base05}; | ||||
|  `}
 | ||||
|   ${disabled ? ` | ||||
|  ` | ||||
|   } | ||||
|   ${ | ||||
|     disabled | ||||
|       ? ` | ||||
|   cursor: not-allowed; | ||||
|   opacity: 0.6; | ||||
|   ` : ` | ||||
|   ` | ||||
|       : ` | ||||
|   cursor: pointer; | ||||
|   `}
 | ||||
|   ` | ||||
|   } | ||||
| 
 | ||||
|   ${!disabled && ` | ||||
|   ${!disabled && | ||||
|     ` | ||||
|   &:hover, | ||||
|   &:focus { | ||||
|     background-color: ${primary ? theme.base07 : theme.base02}; | ||||
|  |  | |||
|  | @ -13,20 +13,24 @@ export const style = ({ theme, primary, disabled }) => css` | |||
|   text-transform: uppercase; | ||||
|   margin: auto 0; | ||||
|   background-color: ${primary ? theme.base05 : theme.base01}; | ||||
|   ${disabled ? ` | ||||
|   ${disabled | ||||
|     ? ` | ||||
|   cursor: not-allowed; | ||||
|   color: ${theme.base04}; | ||||
|   opacity: 0.6; | ||||
|   ` : ` | ||||
|   ` | ||||
|     : ` | ||||
|   cursor: pointer; | ||||
|   color: ${primary ? theme.base00 : theme.base05}; | ||||
|   `}
 | ||||
|   ${!disabled ? ` | ||||
|   ${!disabled | ||||
|     ? ` | ||||
|     box-shadow: | ||||
|       0 2px 2px 0 ${theme.base03}, | ||||
|       0 3px 1px -2px ${theme.base02}, | ||||
|       0 1px 5px 0 ${theme.base02}; | ||||
|   ` : ''}
 | ||||
|   ` | ||||
|     : ''} | ||||
| 
 | ||||
| 
 | ||||
|   &:hover, &:focus:not(:active) { | ||||
|  |  | |||
|  | @ -10,12 +10,20 @@ export const MainContainerWrapper = styled.div` | |||
|   color: ${props => props.theme.base07}; | ||||
|   font-size: 12px; | ||||
| 
 | ||||
|   div, input, textarea, keygen, select, button { | ||||
|   div, | ||||
|   input, | ||||
|   textarea, | ||||
|   keygen, | ||||
|   select, | ||||
|   button { | ||||
|     font-family: ${props => props.theme.fontFamily || 'monaco, monospace'}; | ||||
|   } | ||||
| 
 | ||||
|  .CodeMirror div, pre, .monitor-LogMonitor * { | ||||
|    font-family: ${props => props.theme.codeFontFamily || props.theme.fontFamily || 'monospace'}; | ||||
|   .CodeMirror div, | ||||
|   pre, | ||||
|   .monitor-LogMonitor * { | ||||
|     font-family: ${props => | ||||
|       props.theme.codeFontFamily || props.theme.fontFamily || 'monospace'}; | ||||
|   } | ||||
| 
 | ||||
|   .monitor { | ||||
|  |  | |||
|  | @ -12,8 +12,10 @@ export default class ContextMenu extends Component { | |||
|   } | ||||
| 
 | ||||
|   componentWillReceiveProps(nextProps) { | ||||
|     if (nextProps.items !== this.props.items || | ||||
|       nextProps.visible !== this.props.visible) { | ||||
|     if ( | ||||
|       nextProps.items !== this.props.items || | ||||
|       nextProps.visible !== this.props.visible | ||||
|     ) { | ||||
|       this.updateItems(nextProps.items); | ||||
|     } | ||||
|   } | ||||
|  | @ -32,7 +34,7 @@ export default class ContextMenu extends Component { | |||
|     e.target.blur(); | ||||
|   }; | ||||
| 
 | ||||
|   onClick = (e) => { | ||||
|   onClick = e => { | ||||
|     this.props.onClick(e.target.value); | ||||
|   }; | ||||
| 
 | ||||
|  | @ -78,7 +80,7 @@ export default class ContextMenu extends Component { | |||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   menuRef = (c) => { | ||||
|   menuRef = c => { | ||||
|     this.menu = c; | ||||
|   }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -16,9 +16,7 @@ export const Container = styled.div` | |||
| 
 | ||||
| storiesOf('ContextMenu', module) | ||||
|   .addDecorator(withKnobs) | ||||
|   .add( | ||||
|     'default', | ||||
|     () => ( | ||||
|   .add('default', () => ( | ||||
|     <Container> | ||||
|       <ContextMenu | ||||
|         visible | ||||
|  | @ -28,5 +26,4 @@ storiesOf('ContextMenu', module) | |||
|         items={items} | ||||
|       /> | ||||
|     </Container> | ||||
|     ) | ||||
|   ); | ||||
|   )); | ||||
|  |  | |||
|  | @ -1,11 +1,13 @@ | |||
| import { css } from 'styled-components'; | ||||
| 
 | ||||
| export default ({ theme, left, top, visible }) => css` | ||||
|   ${visible ? ` | ||||
|   ${visible | ||||
|     ? ` | ||||
|     visibility: visible; | ||||
|     opacity: 1; | ||||
|     transition: opacity 0.2s linear; | ||||
|     ` : ` | ||||
|     ` | ||||
|     : ` | ||||
|     visibility: hidden; | ||||
|     opacity: 0; | ||||
|     transition: visibility 0s 0.2s, opacity 0.2s linear; | ||||
|  |  | |||
|  | @ -59,40 +59,40 @@ export default class Dialog extends (PureComponent || Component) { | |||
|             {children} | ||||
|             {schema && ( | ||||
|               <Form {...rest}> | ||||
|                 {!noFooter && | ||||
|                   ( | ||||
|                 {!noFooter && ( | ||||
|                   <input | ||||
|                     type="submit" | ||||
|                     ref={this.getFormButtonRef} | ||||
|                     className="mc-dialog--hidden" | ||||
|                   /> | ||||
|                   ) | ||||
|                 } | ||||
|                 )} | ||||
|               </Form> | ||||
|             )} | ||||
|           </div> | ||||
|           { | ||||
|             !noFooter && | ||||
|               (actions ? | ||||
|           {!noFooter && | ||||
|             (actions ? ( | ||||
|               <div className="mc-dialog--footer"> | ||||
|                   {submitText ? | ||||
|                     [...actions, | ||||
|                       <Button key="default-submit" primary onClick={this.onSubmit}> | ||||
|                 {submitText | ||||
|                   ? [ | ||||
|                       ...actions, | ||||
|                       <Button | ||||
|                         key="default-submit" | ||||
|                         primary | ||||
|                         onClick={this.onSubmit} | ||||
|                       > | ||||
|                         {submitText} | ||||
|                       </Button> | ||||
|                     ] | ||||
|                     : actions | ||||
|                   } | ||||
|                   : actions} | ||||
|               </div> | ||||
|               : | ||||
|             ) : ( | ||||
|               <div className="mc-dialog--footer"> | ||||
|                 <Button onClick={onDismiss}>Cancel</Button> | ||||
|                 <Button primary onClick={this.onSubmit}> | ||||
|                   {submitText || 'Submit'} | ||||
|                 </Button> | ||||
|               </div> | ||||
|               ) | ||||
|           } | ||||
|             ))} | ||||
|         </div> | ||||
|       </DialogWrapper> | ||||
|     ); | ||||
|  |  | |||
|  | @ -7,9 +7,7 @@ import { schema, uiSchema, formData } from '../../Form/stories/schema'; | |||
| 
 | ||||
| storiesOf('Dialog', module) | ||||
|   .addDecorator(withKnobs) | ||||
|   .add( | ||||
|     'default', | ||||
|     () => ( | ||||
|   .add('default', () => ( | ||||
|     <Dialog | ||||
|       title={text('title', 'Dialog Title')} | ||||
|       submitText={text('submitText', 'Submit!')} | ||||
|  | @ -23,11 +21,8 @@ storiesOf('Dialog', module) | |||
|     > | ||||
|       {text('children', 'Hello Dialog!')} | ||||
|     </Dialog> | ||||
|     ) | ||||
|   ) | ||||
|   .add( | ||||
|     'with form', | ||||
|     () => ( | ||||
|   )) | ||||
|   .add('with form', () => ( | ||||
|     <Dialog | ||||
|       open={boolean('open', true)} | ||||
|       noHeader={boolean('noHeader', false)} | ||||
|  | @ -41,5 +36,4 @@ storiesOf('Dialog', module) | |||
|       onSubmit={action('form submitted')} | ||||
|       onDismiss={action('dialog dismissed')} | ||||
|     /> | ||||
|     ) | ||||
|   ); | ||||
|   )); | ||||
|  |  | |||
|  | @ -36,10 +36,8 @@ export const style = ({ theme, open, fullWidth }) => css` | |||
|     border: 1px outset ${theme.base01}; | ||||
|     border-radius: 2px; | ||||
|     background-color: ${theme.base00}; | ||||
|     box-shadow: | ||||
|       0 9px 46px 8px rgba(0, 0, 0, 0.14), | ||||
|       0 11px 15px -7px rgba(0, 0, 0, 0.12), | ||||
|       0 24px 38px 3px rgba(0, 0, 0, 0.2); | ||||
|     box-shadow: 0 9px 46px 8px rgba(0, 0, 0, 0.14), | ||||
|       0 11px 15px -7px rgba(0, 0, 0, 0.12), 0 24px 38px 3px rgba(0, 0, 0, 0.2); | ||||
| 
 | ||||
|     > div.mc-dialog--header { | ||||
|       display: flex; | ||||
|  | @ -77,14 +75,22 @@ export const style = ({ theme, open, fullWidth }) => css` | |||
|       > form { | ||||
|         padding: 0; | ||||
| 
 | ||||
|         > .form-group { margin-bottom: 0; } | ||||
| 
 | ||||
|         > div > fieldset { | ||||
|           legend { display: none; } | ||||
|           #root__description { margin-top: 0; } | ||||
|         > .form-group { | ||||
|           margin-bottom: 0; | ||||
|         } | ||||
| 
 | ||||
|         .mc-dialog--hidden { display: none; } | ||||
|         > div > fieldset { | ||||
|           legend { | ||||
|             display: none; | ||||
|           } | ||||
|           #root__description { | ||||
|             margin-top: 0; | ||||
|           } | ||||
|         } | ||||
| 
 | ||||
|         .mc-dialog--hidden { | ||||
|           display: none; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -35,10 +35,8 @@ export const style = ({ theme, open, fullWidth }) => css` | |||
|     margin-bottom: 16px; | ||||
|     border: none; | ||||
|     background-color: ${theme.base00}; | ||||
|     box-shadow: | ||||
|       0 9px 46px 8px rgba(0, 0, 0, 0.14), | ||||
|       0 11px 15px -7px rgba(0, 0, 0, 0.12), | ||||
|       0 24px 38px 3px rgba(0, 0, 0, 0.2); | ||||
|     box-shadow: 0 9px 46px 8px rgba(0, 0, 0, 0.14), | ||||
|       0 11px 15px -7px rgba(0, 0, 0, 0.12), 0 24px 38px 3px rgba(0, 0, 0, 0.2); | ||||
| 
 | ||||
|     > div.mc-dialog--header { | ||||
|       display: flex; | ||||
|  | @ -74,14 +72,22 @@ export const style = ({ theme, open, fullWidth }) => css` | |||
|       > form { | ||||
|         padding: 0; | ||||
| 
 | ||||
|         > .form-group { margin-bottom: 0; } | ||||
| 
 | ||||
|         > div > fieldset { | ||||
|           legend { display: none; } | ||||
|           #root__description { margin-top: 0; } | ||||
|         > .form-group { | ||||
|           margin-bottom: 0; | ||||
|         } | ||||
| 
 | ||||
|         .mc-dialog--hidden { display: none; } | ||||
|         > div > fieldset { | ||||
|           legend { | ||||
|             display: none; | ||||
|           } | ||||
|           #root__description { | ||||
|             margin-top: 0; | ||||
|           } | ||||
|         } | ||||
| 
 | ||||
|         .mc-dialog--hidden { | ||||
|           display: none; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -4,15 +4,13 @@ import styled from 'styled-components'; | |||
| import CodeMirror from 'codemirror'; | ||||
| import { defaultStyle, themedStyle } from './styles'; | ||||
| 
 | ||||
| const EditorContainer = styled.div('', | ||||
|   ({ theme }) => (theme.scheme === 'default' && theme.light ? defaultStyle : themedStyle(theme)) | ||||
| const EditorContainer = styled.div('', ({ theme }) => | ||||
|   theme.scheme === 'default' && theme.light ? defaultStyle : themedStyle(theme) | ||||
| ); | ||||
| 
 | ||||
| export default class Editor extends Component { | ||||
|   componentDidMount() { | ||||
|     this.cm = CodeMirror( // eslint-disable-line new-cap
 | ||||
|       this.node, | ||||
|       { | ||||
|     this.cm = CodeMirror(this.node, { | ||||
|       value: this.props.value, | ||||
|       mode: this.props.mode, | ||||
|       lineNumbers: this.props.lineNumbers, | ||||
|  | @ -21,11 +19,12 @@ export default class Editor extends Component { | |||
|       autofocus: this.props.autofocus, | ||||
|       foldGutter: this.props.foldGutter, | ||||
|       gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'] | ||||
|       } | ||||
|     ); | ||||
|     }); | ||||
| 
 | ||||
|     if (this.props.onChange) { | ||||
|       this.cm.on('change', (doc, change) => { this.props.onChange(doc.getValue(), change); }); | ||||
|       this.cm.on('change', (doc, change) => { | ||||
|         this.props.onChange(doc.getValue(), change); | ||||
|       }); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|  |  | |||
|  | @ -34,7 +34,9 @@ export default class WithTabs extends Component { | |||
|           } | ||||
|         ]} | ||||
|         selected={this.state.selected} | ||||
|         onClick={selected => { this.setState({ selected }); }} | ||||
|         onClick={selected => { | ||||
|           this.setState({ selected }); | ||||
|         }} | ||||
|         align={select('align', ['left', 'right', 'center'], 'left')} | ||||
|       /> | ||||
|     ); | ||||
|  |  | |||
|  | @ -30,11 +30,6 @@ storiesOf('Editor', module) | |||
|     ), | ||||
|     { info: 'Based on [CodeMirror](http://codemirror.net/).' } | ||||
|   ) | ||||
|   .add( | ||||
|     'with tabs', | ||||
|     () => ( | ||||
|       <WithTabs | ||||
|         lineNumbers={boolean('lineNumbers', true)} | ||||
|       /> | ||||
|     ) | ||||
|   ); | ||||
|   .add('with tabs', () => ( | ||||
|     <WithTabs lineNumbers={boolean('lineNumbers', true)} /> | ||||
|   )); | ||||
|  |  | |||
|  | @ -19,37 +19,79 @@ export const themedStyle = theme => css` | |||
|     background-color: ${theme.base00}; | ||||
|     color: ${theme.base04}; | ||||
| 
 | ||||
|     .cm-header { color: ${theme.base05}; } | ||||
|     .cm-quote { color: ${theme.base09}; } | ||||
|     .cm-header { | ||||
|       color: ${theme.base05}; | ||||
|     } | ||||
|     .cm-quote { | ||||
|       color: ${theme.base09}; | ||||
|     } | ||||
| 
 | ||||
|     .cm-keyword { color: ${theme.base0F}; } | ||||
|     .cm-atom { color: ${theme.base0F}; } | ||||
|     .cm-number { color: ${theme.base0F}; } | ||||
|     .cm-def { color: ${theme.base0D}; } | ||||
|     .cm-keyword { | ||||
|       color: ${theme.base0F}; | ||||
|     } | ||||
|     .cm-atom { | ||||
|       color: ${theme.base0F}; | ||||
|     } | ||||
|     .cm-number { | ||||
|       color: ${theme.base0F}; | ||||
|     } | ||||
|     .cm-def { | ||||
|       color: ${theme.base0D}; | ||||
|     } | ||||
| 
 | ||||
|     .cm-variable { color: ${theme.base05}; } | ||||
|     .cm-variable-2 { color: ${theme.base0A}; } | ||||
|     .cm-variable-3 { color: ${theme.base0E}; } | ||||
|     .cm-variable { | ||||
|       color: ${theme.base05}; | ||||
|     } | ||||
|     .cm-variable-2 { | ||||
|       color: ${theme.base0A}; | ||||
|     } | ||||
|     .cm-variable-3 { | ||||
|       color: ${theme.base0E}; | ||||
|     } | ||||
| 
 | ||||
|     .cm-property { color: ${theme.base0C}; } | ||||
|     .cm-operator { color: ${theme.base0E}; } | ||||
|     .cm-property { | ||||
|       color: ${theme.base0C}; | ||||
|     } | ||||
|     .cm-operator { | ||||
|       color: ${theme.base0E}; | ||||
|     } | ||||
| 
 | ||||
|     .cm-comment { | ||||
|       color: ${theme.base05}; | ||||
|       font-style: italic; | ||||
|     } | ||||
| 
 | ||||
|     .cm-string { color: ${theme.base0B}; } | ||||
|     .cm-string-2 { color: ${theme.base0A}; } | ||||
|     .cm-string { | ||||
|       color: ${theme.base0B}; | ||||
|     } | ||||
|     .cm-string-2 { | ||||
|       color: ${theme.base0A}; | ||||
|     } | ||||
| 
 | ||||
|     .cm-meta { color: ${theme.base0B}; } | ||||
|     .cm-qualifier { color: ${theme.base0A}; } | ||||
|     .cm-builtin { color: ${theme.base0F}; } | ||||
|     .cm-bracket { color: ${theme.base09}; } | ||||
|     .CodeMirror-matchingbracket { color: ${theme.base0B}; } | ||||
|     .CodeMirror-nonmatchingbracket { color: ${theme.base08}; } | ||||
|     .cm-tag { color: ${theme.base02}; } | ||||
|     .cm-attribute { color: ${theme.base0C}; } | ||||
|     .cm-meta { | ||||
|       color: ${theme.base0B}; | ||||
|     } | ||||
|     .cm-qualifier { | ||||
|       color: ${theme.base0A}; | ||||
|     } | ||||
|     .cm-builtin { | ||||
|       color: ${theme.base0F}; | ||||
|     } | ||||
|     .cm-bracket { | ||||
|       color: ${theme.base09}; | ||||
|     } | ||||
|     .CodeMirror-matchingbracket { | ||||
|       color: ${theme.base0B}; | ||||
|     } | ||||
|     .CodeMirror-nonmatchingbracket { | ||||
|       color: ${theme.base08}; | ||||
|     } | ||||
|     .cm-tag { | ||||
|       color: ${theme.base02}; | ||||
|     } | ||||
|     .cm-attribute { | ||||
|       color: ${theme.base0C}; | ||||
|     } | ||||
| 
 | ||||
|     .cm-hr { | ||||
|       color: transparent; | ||||
|  | @ -62,7 +104,9 @@ export const themedStyle = theme => css` | |||
|       cursor: pointer; | ||||
|     } | ||||
| 
 | ||||
|     .cm-special { color: ${theme.base0E}; } | ||||
|     .cm-special { | ||||
|       color: ${theme.base0E}; | ||||
|     } | ||||
| 
 | ||||
|     .cm-em { | ||||
|       color: #999; | ||||
|  | @ -70,7 +114,9 @@ export const themedStyle = theme => css` | |||
|       text-decoration-style: dotted; | ||||
|     } | ||||
| 
 | ||||
|     .cm-strong { color: ${theme.base01}; } | ||||
|     .cm-strong { | ||||
|       color: ${theme.base01}; | ||||
|     } | ||||
| 
 | ||||
|     .cm-error, | ||||
|     .cm-invalidchar { | ||||
|  | @ -78,7 +124,9 @@ export const themedStyle = theme => css` | |||
|       border-bottom: 1px dotted ${theme.base08}; | ||||
|     } | ||||
| 
 | ||||
|     div.CodeMirror-selected { background: ${theme.base01}; } | ||||
|     div.CodeMirror-selected { | ||||
|       background: ${theme.base01}; | ||||
|     } | ||||
| 
 | ||||
|     .CodeMirror-line::selection, | ||||
|     .CodeMirror-line > span::selection, | ||||
|  | @ -106,17 +154,27 @@ export const themedStyle = theme => css` | |||
|       padding: 0 5px; | ||||
|     } | ||||
| 
 | ||||
|     .CodeMirror-guttermarker-subtle { color: ${theme.base05}; } | ||||
|     .CodeMirror-guttermarker { color: ${theme.base09}; } | ||||
|     .CodeMirror-guttermarker-subtle { | ||||
|       color: ${theme.base05}; | ||||
|     } | ||||
|     .CodeMirror-guttermarker { | ||||
|       color: ${theme.base09}; | ||||
|     } | ||||
| 
 | ||||
|     .CodeMirror-gutter .CodeMirror-gutter-text { | ||||
|       color: ${theme.base05}; | ||||
|     } | ||||
| 
 | ||||
|     .CodeMirror-cursor { border-left: 1px solid #819090; } | ||||
|     .CodeMirror-cursor { | ||||
|       border-left: 1px solid #819090; | ||||
|     } | ||||
| 
 | ||||
|     .cm-fat-cursor .CodeMirror-cursor { background: ${theme.base02}; } | ||||
|     .cm-animate-fat-cursor { background-color: ${theme.base02}; } | ||||
|     .cm-fat-cursor .CodeMirror-cursor { | ||||
|       background: ${theme.base02}; | ||||
|     } | ||||
|     .cm-animate-fat-cursor { | ||||
|       background-color: ${theme.base02}; | ||||
|     } | ||||
| 
 | ||||
|     .CodeMirror-activeline-background { | ||||
|       background: ${theme.base07}; | ||||
|  |  | |||
|  | @ -10,16 +10,30 @@ const FormContainer = createStyledComponent(styles, JSONSchemaForm); | |||
| 
 | ||||
| export default class Form extends (PureComponent || Component) { | ||||
|   render() { | ||||
|     const { widgets, children, submitText, primaryButton, noSubmit, ...rest } = this.props; | ||||
|     const { | ||||
|       widgets, | ||||
|       children, | ||||
|       submitText, | ||||
|       primaryButton, | ||||
|       noSubmit, | ||||
|       ...rest | ||||
|     } = this.props; | ||||
|     return ( | ||||
|       <FormContainer {...rest} widgets={{ ...customWidgets, ...widgets }}> | ||||
|         { | ||||
|           noSubmit ? <noscript /> : | ||||
|             children || | ||||
|               <Button size="big" primary={primaryButton} theme={rest.theme} type="submit"> | ||||
|         {noSubmit ? ( | ||||
|           <noscript /> | ||||
|         ) : ( | ||||
|           children || ( | ||||
|             <Button | ||||
|               size="big" | ||||
|               primary={primaryButton} | ||||
|               theme={rest.theme} | ||||
|               type="submit" | ||||
|             > | ||||
|               {submitText || 'Submit'} | ||||
|             </Button> | ||||
|         } | ||||
|           ) | ||||
|         )} | ||||
|       </FormContainer> | ||||
|     ); | ||||
|   } | ||||
|  | @ -33,5 +47,7 @@ Form.propTypes = { | |||
|   schema: PropTypes.object.isRequired, | ||||
|   uiSchema: PropTypes.object, | ||||
|   formData: PropTypes.any, | ||||
|   widgets: PropTypes.objectOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object])) | ||||
|   widgets: PropTypes.objectOf( | ||||
|     PropTypes.oneOfType([PropTypes.func, PropTypes.object]) | ||||
|   ) | ||||
| }; | ||||
|  |  | |||
|  | @ -19,8 +19,9 @@ storiesOf('Form', module) | |||
|         onSubmit={action('form submitted')} | ||||
|       /> | ||||
|     ), | ||||
|     { info: | ||||
|         'Wrapper around [`react-jsonschema-form`](https://github.com/mozilla-services/react-jsonschema-form)' | ||||
|         + ' with custom widgets.' | ||||
|     { | ||||
|       info: | ||||
|         'Wrapper around [`react-jsonschema-form`](https://github.com/mozilla-services/react-jsonschema-form)' + | ||||
|         ' with custom widgets.' | ||||
|     } | ||||
|   ); | ||||
|  |  | |||
|  | @ -27,31 +27,19 @@ module.exports = { | |||
|         title: 'A multiple choices list', | ||||
|         items: { | ||||
|           type: 'string', | ||||
|           enum: [ | ||||
|             'foo', | ||||
|             'bar', | ||||
|             'fuzz' | ||||
|           ] | ||||
|           enum: ['foo', 'bar', 'fuzz'] | ||||
|         }, | ||||
|         uniqueItems: true | ||||
|       }, | ||||
|       numberEnum: { | ||||
|         type: 'number', | ||||
|         title: 'Number enum', | ||||
|         enum: [ | ||||
|           1, | ||||
|           2, | ||||
|           3 | ||||
|         ] | ||||
|         enum: [1, 2, 3] | ||||
|       }, | ||||
|       numberEnumRadio: { | ||||
|         type: 'number', | ||||
|         title: 'Number enum', | ||||
|         enum: [ | ||||
|           1, | ||||
|           2, | ||||
|           3 | ||||
|         ] | ||||
|         enum: [1, 2, 3] | ||||
|       }, | ||||
|       integerRange: { | ||||
|         title: 'Integer range', | ||||
|  |  | |||
|  | @ -87,10 +87,10 @@ textarea.form-control { | |||
|     cursor: pointer; | ||||
|   } | ||||
| 
 | ||||
| .radio input[type="radio"], | ||||
| .radio-inline input[type="radio"], | ||||
| .checkbox input[type="checkbox"], | ||||
| .checkbox-inline input[type="checkbox"] { | ||||
|   .radio input[type='radio'], | ||||
|   .radio-inline input[type='radio'], | ||||
|   .checkbox input[type='checkbox'], | ||||
|   .checkbox-inline input[type='checkbox'] { | ||||
|     position: absolute; | ||||
|     margin-left: -20px; | ||||
|     margin-top: 4px \\9; | ||||
|  | @ -125,20 +125,20 @@ textarea.form-control { | |||
|     padding-left: 25px; | ||||
|   } | ||||
| 
 | ||||
| .radio input[type="radio"], | ||||
| .radio-inline input[type="radio"], | ||||
| .checkbox input[type="radio"], | ||||
| .checkbox-inline input[type="radio"], | ||||
| .radio input[type="checkbox"], | ||||
| .radio-inline input[type="checkbox"], | ||||
| .checkbox input[type="checkbox"], | ||||
| .checkbox-inline input[type="checkbox"] { | ||||
|   .radio input[type='radio'], | ||||
|   .radio-inline input[type='radio'], | ||||
|   .checkbox input[type='radio'], | ||||
|   .checkbox-inline input[type='radio'], | ||||
|   .radio input[type='checkbox'], | ||||
|   .radio-inline input[type='checkbox'], | ||||
|   .checkbox input[type='checkbox'], | ||||
|   .checkbox-inline input[type='checkbox'] { | ||||
|     margin-left: -25px; | ||||
|   } | ||||
| 
 | ||||
| input[type="radio"], | ||||
| .radio input[type="radio"], | ||||
| .radio-inline input[type="radio"] { | ||||
|   input[type='radio'], | ||||
|   .radio input[type='radio'], | ||||
|   .radio-inline input[type='radio'] { | ||||
|     position: relative; | ||||
|     margin-top: 6px; | ||||
|     margin-right: 4px; | ||||
|  | @ -149,19 +149,19 @@ input[type="radio"], | |||
|     cursor: pointer; | ||||
|   } | ||||
| 
 | ||||
| input[type="radio"]:focus, | ||||
| .radio input[type="radio"]:focus, | ||||
| .radio-inline input[type="radio"]:focus { | ||||
|   input[type='radio']:focus, | ||||
|   .radio input[type='radio']:focus, | ||||
|   .radio-inline input[type='radio']:focus { | ||||
|     outline: none; | ||||
|   } | ||||
| 
 | ||||
| input[type="radio"]:before, | ||||
| .radio input[type="radio"]:before, | ||||
| .radio-inline input[type="radio"]:before, | ||||
| input[type="radio"]:after, | ||||
| .radio input[type="radio"]:after, | ||||
| .radio-inline input[type="radio"]:after { | ||||
|   content: ""; | ||||
|   input[type='radio']:before, | ||||
|   .radio input[type='radio']:before, | ||||
|   .radio-inline input[type='radio']:before, | ||||
|   input[type='radio']:after, | ||||
|   .radio input[type='radio']:after, | ||||
|   .radio-inline input[type='radio']:after { | ||||
|     content: ''; | ||||
|     display: block; | ||||
|     width: 18px; | ||||
|     height: 18px; | ||||
|  | @ -170,9 +170,9 @@ input[type="radio"]:after, | |||
|     box-sizing: border-box; | ||||
|   } | ||||
| 
 | ||||
| input[type="radio"]:before, | ||||
| .radio input[type="radio"]:before, | ||||
| .radio-inline input[type="radio"]:before { | ||||
|   input[type='radio']:before, | ||||
|   .radio input[type='radio']:before, | ||||
|   .radio-inline input[type='radio']:before { | ||||
|     position: absolute; | ||||
|     left: 0; | ||||
|     top: -3px; | ||||
|  | @ -180,44 +180,44 @@ input[type="radio"]:before, | |||
|     transform: scale(0); | ||||
|   } | ||||
| 
 | ||||
| input[type="radio"]:after, | ||||
| .radio input[type="radio"]:after, | ||||
| .radio-inline input[type="radio"]:after { | ||||
|   input[type='radio']:after, | ||||
|   .radio input[type='radio']:after, | ||||
|   .radio-inline input[type='radio']:after { | ||||
|     position: relative; | ||||
|     top: -3px; | ||||
|     border: 2px solid ${theme.base03}; | ||||
|   } | ||||
| 
 | ||||
| input[type="radio"]:checked:before, | ||||
| .radio input[type="radio"]:checked:before, | ||||
| .radio-inline input[type="radio"]:checked:before { | ||||
|   input[type='radio']:checked:before, | ||||
|   .radio input[type='radio']:checked:before, | ||||
|   .radio-inline input[type='radio']:checked:before { | ||||
|     transform: scale(0.5); | ||||
|   } | ||||
| 
 | ||||
| input[type="radio"]:disabled:checked:before, | ||||
| .radio input[type="radio"]:disabled:checked:before, | ||||
| .radio-inline input[type="radio"]:disabled:checked:before { | ||||
|   input[type='radio']:disabled:checked:before, | ||||
|   .radio input[type='radio']:disabled:checked:before, | ||||
|   .radio-inline input[type='radio']:disabled:checked:before { | ||||
|     background-color: ${theme.base03}; | ||||
|   } | ||||
| 
 | ||||
| input[type="radio"]:checked:after, | ||||
| .radio input[type="radio"]:checked:after, | ||||
| .radio-inline input[type="radio"]:checked:after { | ||||
|   input[type='radio']:checked:after, | ||||
|   .radio input[type='radio']:checked:after, | ||||
|   .radio-inline input[type='radio']:checked:after { | ||||
|     border-color: ${theme.base0D}; | ||||
|   } | ||||
| 
 | ||||
| input[type="radio"]:disabled:after, | ||||
| .radio input[type="radio"]:disabled:after, | ||||
| .radio-inline input[type="radio"]:disabled:after, | ||||
| input[type="radio"]:disabled:checked:after, | ||||
| .radio input[type="radio"]:disabled:checked:after, | ||||
| .radio-inline input[type="radio"]:disabled:checked:after { | ||||
|   input[type='radio']:disabled:after, | ||||
|   .radio input[type='radio']:disabled:after, | ||||
|   .radio-inline input[type='radio']:disabled:after, | ||||
|   input[type='radio']:disabled:checked:after, | ||||
|   .radio input[type='radio']:disabled:checked:after, | ||||
|   .radio-inline input[type='radio']:disabled:checked:after { | ||||
|     border-color: ${theme.base03}; | ||||
|   } | ||||
| 
 | ||||
| input[type="checkbox"], | ||||
| .checkbox input[type="checkbox"], | ||||
| .checkbox-inline input[type="checkbox"] { | ||||
|   input[type='checkbox'], | ||||
|   .checkbox input[type='checkbox'], | ||||
|   .checkbox-inline input[type='checkbox'] { | ||||
|     position: relative; | ||||
|     border: none; | ||||
|     margin-bottom: -4px; | ||||
|  | @ -225,22 +225,22 @@ input[type="checkbox"], | |||
|     cursor: pointer; | ||||
|   } | ||||
| 
 | ||||
| input[type="checkbox"]:focus, | ||||
| .checkbox input[type="checkbox"]:focus, | ||||
| .checkbox-inline input[type="checkbox"]:focus { | ||||
|   input[type='checkbox']:focus, | ||||
|   .checkbox input[type='checkbox']:focus, | ||||
|   .checkbox-inline input[type='checkbox']:focus { | ||||
|     outline: none; | ||||
|   } | ||||
| 
 | ||||
| input[type="checkbox"]:focus:after, | ||||
| .checkbox input[type="checkbox"]:focus:after, | ||||
| .checkbox-inline input[type="checkbox"]:focus:after { | ||||
|   input[type='checkbox']:focus:after, | ||||
|   .checkbox input[type='checkbox']:focus:after, | ||||
|   .checkbox-inline input[type='checkbox']:focus:after { | ||||
|     border-color: ${theme.base0D}; | ||||
|   } | ||||
| 
 | ||||
| input[type="checkbox"]:after, | ||||
| .checkbox input[type="checkbox"]:after, | ||||
| .checkbox-inline input[type="checkbox"]:after { | ||||
|   content: ""; | ||||
|   input[type='checkbox']:after, | ||||
|   .checkbox input[type='checkbox']:after, | ||||
|   .checkbox-inline input[type='checkbox']:after { | ||||
|     content: ''; | ||||
|     display: block; | ||||
|     width: 18px; | ||||
|     height: 18px; | ||||
|  | @ -252,10 +252,10 @@ input[type="checkbox"]:after, | |||
|     box-sizing: border-box; | ||||
|   } | ||||
| 
 | ||||
| input[type="checkbox"]:checked:before, | ||||
| .checkbox input[type="checkbox"]:checked:before, | ||||
| .checkbox-inline input[type="checkbox"]:checked:before { | ||||
|   content: ""; | ||||
|   input[type='checkbox']:checked:before, | ||||
|   .checkbox input[type='checkbox']:checked:before, | ||||
|   .checkbox-inline input[type='checkbox']:checked:before { | ||||
|     content: ''; | ||||
|     position: absolute; | ||||
|     top: 0; | ||||
|     left: 6px; | ||||
|  | @ -269,32 +269,32 @@ input[type="checkbox"]:checked:before, | |||
|     box-sizing: border-box; | ||||
|   } | ||||
| 
 | ||||
| input[type="checkbox"]:checked:after, | ||||
| .checkbox input[type="checkbox"]:checked:after, | ||||
| .checkbox-inline input[type="checkbox"]:checked:after { | ||||
|   input[type='checkbox']:checked:after, | ||||
|   .checkbox input[type='checkbox']:checked:after, | ||||
|   .checkbox-inline input[type='checkbox']:checked:after { | ||||
|     background-color: ${theme.base0D}; | ||||
|     border-color: ${theme.base0D}; | ||||
|   } | ||||
| 
 | ||||
| input[type="checkbox"]:disabled:after, | ||||
| .checkbox input[type="checkbox"]:disabled:after, | ||||
| .checkbox-inline input[type="checkbox"]:disabled:after { | ||||
|   input[type='checkbox']:disabled:after, | ||||
|   .checkbox input[type='checkbox']:disabled:after, | ||||
|   .checkbox-inline input[type='checkbox']:disabled:after { | ||||
|     border-color: ${theme.base03}; | ||||
|   } | ||||
| 
 | ||||
| input[type="checkbox"]:disabled:checked:after, | ||||
| .checkbox input[type="checkbox"]:disabled:checked:after, | ||||
| .checkbox-inline input[type="checkbox"]:disabled:checked:after { | ||||
|   input[type='checkbox']:disabled:checked:after, | ||||
|   .checkbox input[type='checkbox']:disabled:checked:after, | ||||
|   .checkbox-inline input[type='checkbox']:disabled:checked:after { | ||||
|     background-color: ${theme.base03}; | ||||
|     border-color: transparent; | ||||
|   } | ||||
| 
 | ||||
| input[type="radio"][disabled], | ||||
| input[type="checkbox"][disabled], | ||||
| input[type="radio"].disabled, | ||||
| input[type="checkbox"].disabled, | ||||
| fieldset[disabled] input[type="radio"], | ||||
| fieldset[disabled] input[type="checkbox"] { | ||||
|   input[type='radio'][disabled], | ||||
|   input[type='checkbox'][disabled], | ||||
|   input[type='radio'].disabled, | ||||
|   input[type='checkbox'].disabled, | ||||
|   fieldset[disabled] input[type='radio'], | ||||
|   fieldset[disabled] input[type='checkbox'] { | ||||
|     cursor: not-allowed; | ||||
|   } | ||||
| 
 | ||||
|  |  | |||
|  | @ -8,7 +8,9 @@ const SelectWidget = ({ options, multi, ...rest }) => ( | |||
| ); | ||||
| 
 | ||||
| const RangeWidget = ({ | ||||
|   schema, readonly, autofocus, | ||||
|   schema, | ||||
|   readonly, | ||||
|   autofocus, | ||||
|   label, // eslint-disable-line
 | ||||
|   options, // eslint-disable-line
 | ||||
|   formContext, // eslint-disable-line
 | ||||
|  |  | |||
|  | @ -11,16 +11,22 @@ const NotificationWrapper = createStyledComponent(styles); | |||
| 
 | ||||
| export default class Notification extends Component { | ||||
|   shouldComponentUpdate(nextProps) { | ||||
|     return nextProps.children !== this.props.children || | ||||
|       nextProps.type !== this.props.type; | ||||
|     return ( | ||||
|       nextProps.children !== this.props.children || | ||||
|       nextProps.type !== this.props.type | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   getIcon = () => { | ||||
|     switch (this.props.type) { | ||||
|       case 'warning': return <WarningIcon />; | ||||
|       case 'error': return <ErrorIcon />; | ||||
|       case 'success': return <SuccessIcon />; | ||||
|       default: return null; | ||||
|       case 'warning': | ||||
|         return <WarningIcon />; | ||||
|       case 'error': | ||||
|         return <ErrorIcon />; | ||||
|       case 'success': | ||||
|         return <SuccessIcon />; | ||||
|       default: | ||||
|         return null; | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|  | @ -29,9 +35,11 @@ export default class Notification extends Component { | |||
|       <NotificationWrapper type={this.props.type} theme={this.props.theme}> | ||||
|         {this.getIcon()} | ||||
|         <span>{this.props.children}</span> | ||||
|         {this.props.onClose && | ||||
|           <button onClick={this.props.onClose}><CloseIcon /></button> | ||||
|         } | ||||
|         {this.props.onClose && ( | ||||
|           <button onClick={this.props.onClose}> | ||||
|             <CloseIcon /> | ||||
|           </button> | ||||
|         )} | ||||
|       </NotificationWrapper> | ||||
|     ); | ||||
|   } | ||||
|  |  | |||
|  | @ -15,18 +15,17 @@ export const Container = styled.div` | |||
| 
 | ||||
| storiesOf('Notification', module) | ||||
|   .addDecorator(withKnobs) | ||||
|   .add( | ||||
|     'default', | ||||
|     () => ( | ||||
|   .add('default', () => ( | ||||
|     <Container> | ||||
|       <Notification | ||||
|           type={ | ||||
|             select('type', ['info', 'success', 'warning', 'error'], 'warning') | ||||
|           } | ||||
|         type={select( | ||||
|           'type', | ||||
|           ['info', 'success', 'warning', 'error'], | ||||
|           'warning' | ||||
|         )} | ||||
|         onClose={action('notification closed')} | ||||
|       > | ||||
|         {text('Message', 'Hello Notification')} | ||||
|       </Notification> | ||||
|     </Container> | ||||
|     ) | ||||
|   ); | ||||
|   )); | ||||
|  |  | |||
|  | @ -49,7 +49,8 @@ export default ({ theme, type }) => css` | |||
|     opacity: 0.8; | ||||
|   } | ||||
| 
 | ||||
|   & > button:hover, & > button:active { | ||||
|   & > button:hover, | ||||
|   & > button:active { | ||||
|     opacity: 1; | ||||
|   } | ||||
| 
 | ||||
|  |  | |||
|  | @ -7,8 +7,10 @@ const SegmentedWrapper = createStyledComponent(styles); | |||
| 
 | ||||
| export default class SegmentedControl extends Component { | ||||
|   shouldComponentUpdate(nextProps) { | ||||
|     return nextProps.disabled !== this.props.disabled || | ||||
|       nextProps.selected !== this.props.selected; | ||||
|     return ( | ||||
|       nextProps.disabled !== this.props.disabled || | ||||
|       nextProps.selected !== this.props.selected | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   onClick = e => { | ||||
|  |  | |||
|  | @ -15,9 +15,7 @@ export const Container = styled.div` | |||
| 
 | ||||
| storiesOf('SegmentedControl', module) | ||||
|   .addDecorator(withKnobs) | ||||
|   .add( | ||||
|     'default', | ||||
|     () => ( | ||||
|   .add('default', () => ( | ||||
|     <Container> | ||||
|       <SegmentedControl | ||||
|         values={['Button1', 'Button2', 'Button3']} | ||||
|  | @ -26,5 +24,4 @@ storiesOf('SegmentedControl', module) | |||
|         disabled={boolean('Disabled', false)} | ||||
|       /> | ||||
|     </Container> | ||||
|     ) | ||||
|   ); | ||||
|   )); | ||||
|  |  | |||
|  | @ -5,7 +5,8 @@ export default ({ theme, disabled }) => css` | |||
|   display: flex; | ||||
|   flex-shrink: 0; | ||||
| 
 | ||||
|   > [data-selected], > [data-selected]:hover { | ||||
|   > [data-selected], | ||||
|   > [data-selected]:hover { | ||||
|     background-color: ${theme.base04}; | ||||
|     color: ${theme.base00}; | ||||
|   } | ||||
|  | @ -19,10 +20,12 @@ export default ({ theme, disabled }) => css` | |||
|     border: 1px solid ${color(theme.base03, 'alpha', 0.4)}; | ||||
|     border-left-width: 0; | ||||
|     padding: 5px 10px; | ||||
|     ${disabled ? ` | ||||
|     ${disabled | ||||
|       ? ` | ||||
|     cursor: not-allowed; | ||||
|     opacity: 0.6; | ||||
|     ` : ` | ||||
|     ` | ||||
|       : ` | ||||
|     cursor: pointer; | ||||
|     color: ${theme.base05}; | ||||
|     background-color: ${theme.base01}; | ||||
|  |  | |||
|  | @ -26,4 +26,9 @@ Select.propTypes = { | |||
|   openOuterUp: PropTypes.bool // value to control the opening direction
 | ||||
| }; | ||||
| 
 | ||||
| Select.defaultProps = { autosize: true, clearable: false, simpleValue: true, menuMaxHeight: 200 }; | ||||
| Select.defaultProps = { | ||||
|   autosize: true, | ||||
|   clearable: false, | ||||
|   simpleValue: true, | ||||
|   menuMaxHeight: 200 | ||||
| }; | ||||
|  |  | |||
|  | @ -39,8 +39,9 @@ storiesOf('Select', module) | |||
|         /> | ||||
|       </Container> | ||||
|     ), | ||||
|     { info:  | ||||
|         'Wrapper around [React Select](https://github.com/JedWatson/react-select) with themes ' | ||||
|         + 'and new props like `openOuterUp` and `menuMaxHeight`.' | ||||
|     { | ||||
|       info: | ||||
|         'Wrapper around [React Select](https://github.com/JedWatson/react-select) with themes ' + | ||||
|         'and new props like `openOuterUp` and `menuMaxHeight`.' | ||||
|     } | ||||
|   ); | ||||
|  |  | |||
|  | @ -59,10 +59,9 @@ export default ({ theme, openOuterUp, menuMaxHeight }) => css` | |||
|   } | ||||
| 
 | ||||
|   &.is-open > .Select-control { | ||||
|     border-radius: ${openOuterUp ? | ||||
|       `0 0 ${theme.inputBorderRadius}px ${theme.inputBorderRadius}px` : | ||||
|       `${theme.inputBorderRadius}px ${theme.inputBorderRadius}px 0 0` | ||||
|     }; | ||||
|     border-radius: ${openOuterUp | ||||
|       ? `0 0 ${theme.inputBorderRadius}px ${theme.inputBorderRadius}px` | ||||
|       : `${theme.inputBorderRadius}px ${theme.inputBorderRadius}px 0 0`}; | ||||
|   } | ||||
| 
 | ||||
|   &.is-searchable { | ||||
|  | @ -212,9 +211,7 @@ export default ({ theme, openOuterUp, menuMaxHeight }) => css` | |||
|   .Select-arrow { | ||||
|     border-color: ${theme.base03} transparent transparent; | ||||
|     border-style: solid; | ||||
|     border-width: | ||||
|       ${theme.selectArrowWidth}px | ||||
|       ${theme.selectArrowWidth}px | ||||
|     border-width: ${theme.selectArrowWidth}px ${theme.selectArrowWidth}px | ||||
|       ${theme.selectArrowWidth / 2}px; | ||||
|     display: inline-block; | ||||
|     height: 0; | ||||
|  | @ -317,7 +314,8 @@ export default ({ theme, openOuterUp, menuMaxHeight }) => css` | |||
|       border-bottom-right-radius: ${theme.inputBorderRadius}px; | ||||
|       border-top-right-radius: ${theme.inputBorderRadius}px; | ||||
|       cursor: default; | ||||
|       padding: ${Math.floor(theme.inputPadding / 4)}px ${Math.floor(theme.inputPadding / 2)}px; | ||||
|       padding: ${Math.floor(theme.inputPadding / 4)}px | ||||
|         ${Math.floor(theme.inputPadding / 2)}px; | ||||
|     } | ||||
| 
 | ||||
|     a.Select-value-label { | ||||
|  |  | |||
|  | @ -9,12 +9,14 @@ const ContainerWithValue = createStyledComponent(containerStyle); | |||
| 
 | ||||
| export default class Slider extends Component { | ||||
|   shouldComponentUpdate(nextProps) { | ||||
|     return nextProps.label !== this.props.label || | ||||
|     return ( | ||||
|       nextProps.label !== this.props.label || | ||||
|       nextProps.value !== this.props.value || | ||||
|       nextProps.max !== this.props.max || | ||||
|       nextProps.min !== this.props.min || | ||||
|       nextProps.withValue !== this.props.withValue || | ||||
|       nextProps.disabled !== this.props.disabled; | ||||
|       nextProps.disabled !== this.props.disabled | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   onChange = e => { | ||||
|  | @ -25,7 +27,7 @@ export default class Slider extends Component { | |||
|     const { label, sublabel, withValue, theme, ...rest } = this.props; | ||||
|     const { value, max, min, disabled } = rest; | ||||
|     const absMax = max - min; | ||||
|     const percent = (value - min) / absMax * 100; | ||||
|     const percent = ((value - min) / absMax) * 100; | ||||
|     const slider = <input {...rest} onChange={this.onChange} type="range" />; | ||||
| 
 | ||||
|     return ( | ||||
|  | @ -35,13 +37,19 @@ export default class Slider extends Component { | |||
|         withLabel={!!label} | ||||
|         theme={theme} | ||||
|       > | ||||
|         {label && <label>{label} {sublabel && <span>{sublabel}</span>}</label>} | ||||
|         {!withValue ? slider : | ||||
|         {label && ( | ||||
|           <label> | ||||
|             {label} {sublabel && <span>{sublabel}</span>} | ||||
|           </label> | ||||
|         )} | ||||
|         {!withValue ? ( | ||||
|           slider | ||||
|         ) : ( | ||||
|           <ContainerWithValue theme={theme}> | ||||
|             {slider} | ||||
|             <div>{value}</div> | ||||
|           </ContainerWithValue> | ||||
|         } | ||||
|         )} | ||||
|       </SliderWrapper> | ||||
|     ); | ||||
|   } | ||||
|  |  | |||
|  | @ -15,9 +15,7 @@ export const Container = styled.div` | |||
| 
 | ||||
| storiesOf('Slider', module) | ||||
|   .addDecorator(withKnobs) | ||||
|   .add( | ||||
|     'default', | ||||
|     () => ( | ||||
|   .add('default', () => ( | ||||
|     <Container> | ||||
|       <Slider | ||||
|         value={number('value', 0)} | ||||
|  | @ -30,5 +28,4 @@ storiesOf('Slider', module) | |||
|         onChange={action('slider changed')} | ||||
|       /> | ||||
|     </Container> | ||||
|     ) | ||||
|   ); | ||||
|   )); | ||||
|  |  | |||
|  | @ -42,21 +42,32 @@ export const style = ({ theme, percent, disabled, withLabel }) => css` | |||
|     border-radius: 0.8em/1.1em; | ||||
|     font-size: 1em; | ||||
|     cursor: pointer; | ||||
|     background: linear-gradient(${theme.base02}, ${theme.base00}) padding-box, 50% 50% border-box; | ||||
|     background: linear-gradient(${theme.base02}, ${ | ||||
|   theme.base00 | ||||
| }) padding-box, 50% 50% border-box; | ||||
|     background-size: 100% 100%; | ||||
|   } | ||||
| 
 | ||||
|   ${prefixSelectors('input', ['webkit-slider-runnable-track', 'moz-range-track', 'ms-track'], `{
 | ||||
|   ${prefixSelectors( | ||||
|     'input', | ||||
|     ['webkit-slider-runnable-track', 'moz-range-track', 'ms-track'], | ||||
|     `{
 | ||||
|     position: relative; | ||||
|     height: 0.8em; | ||||
|     border-radius: 0.5em; | ||||
|     box-shadow: 0 0 .125em ${theme.base04}; | ||||
|     background: linear-gradient(${theme.base01}, ${theme.base02} 40%, ${theme.base01}) | ||||
|     background: linear-gradient(${theme.base01}, ${theme.base02} 40%, ${ | ||||
|       theme.base01 | ||||
|     }) | ||||
|       no-repeat ${theme.base00}; | ||||
|     background-size: ${percent}% 100%; | ||||
|   }`)}
 | ||||
|   }` | ||||
|   )} | ||||
| 
 | ||||
|  ${prefixSelectors('input', ['webkit-slider-thumb', 'moz-range-thumb', 'ms-thumb'], `{
 | ||||
|  ${prefixSelectors( | ||||
|    'input', | ||||
|    ['webkit-slider-thumb', 'moz-range-thumb', 'ms-thumb'], | ||||
|    `{
 | ||||
|     position: relative; | ||||
|     appearance: none; | ||||
|     cursor: ew-resize; | ||||
|  | @ -68,13 +79,16 @@ export const style = ({ theme, percent, disabled, withLabel }) => css` | |||
|     height: 1.5em; | ||||
|     border-radius: 50%; | ||||
|     cursor: pointer; | ||||
|   }`)}
 | ||||
|   }` | ||||
|  )} | ||||
| 
 | ||||
|  ${prefixSelectors('input:focus:not(:active)', | ||||
|  ${prefixSelectors( | ||||
|    'input:focus:not(:active)', | ||||
|    ['webkit-slider-thumb', 'moz-range-thumb', 'ms-thumb'], | ||||
|    `{
 | ||||
|     box-shadow: 0 0 1px 2px ${theme.base0D}; | ||||
|   }`)}
 | ||||
|   }` | ||||
|  )} | ||||
| 
 | ||||
|   input::-moz-focus-outer { | ||||
|     border: 0; | ||||
|  |  | |||
|  | @ -19,7 +19,9 @@ export const style = ({ theme, percent, disabled, withLabel }) => css` | |||
|     width: 100%; | ||||
|     color: ${theme.base06}; | ||||
| 
 | ||||
|     > span { color: ${theme.base04}; }  | ||||
|     > span { | ||||
|       color: ${theme.base04}; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   input { | ||||
|  | @ -32,8 +34,12 @@ export const style = ({ theme, percent, disabled, withLabel }) => css` | |||
|     cursor: pointer; | ||||
|     color: inherit; | ||||
|     background-color: ${theme.base02}; | ||||
|     background-image: | ||||
|       linear-gradient(90deg, currentcolor, currentcolor ${percent}%, transparent ${percent}%); | ||||
|     background-image: linear-gradient( | ||||
|       90deg, | ||||
|       currentcolor, | ||||
|       currentcolor ${percent}%, | ||||
|       transparent ${percent}% | ||||
|     ); | ||||
|     background-clip: content-box; | ||||
|     height: 0.5em; | ||||
|     border-radius: 999px; | ||||
|  | @ -41,7 +47,10 @@ export const style = ({ theme, percent, disabled, withLabel }) => css` | |||
|     font-size: 1em; | ||||
|   } | ||||
| 
 | ||||
|  ${prefixSelectors('input', ['webkit-slider-thumb', 'moz-range-thumb', 'ms-thumb'], `{
 | ||||
|   ${prefixSelectors( | ||||
|     'input', | ||||
|     ['webkit-slider-thumb', 'moz-range-thumb', 'ms-thumb'], | ||||
|     `{
 | ||||
|     width: 1.5em; | ||||
|     height: 1.5em; | ||||
|     background-image: none; | ||||
|  | @ -53,14 +62,17 @@ export const style = ({ theme, percent, disabled, withLabel }) => css` | |||
|       border 0.18s ${animationCurve}, | ||||
|       box-shadow 0.18s ${animationCurve}, | ||||
|       background 0.28s ${animationCurve}; | ||||
|   }`)}
 | ||||
|   }` | ||||
|   )} | ||||
| 
 | ||||
|  ${prefixSelectors('input:focus:not(:active)', | ||||
|   ${prefixSelectors( | ||||
|     'input:focus:not(:active)', | ||||
|     ['webkit-slider-thumb', 'moz-range-thumb', 'ms-thumb'], | ||||
|     `{
 | ||||
|     box-shadow: 0 0 0 8px ${color(theme.base0D, 'alpha', 0.5)}; | ||||
|     transform: scale(1.2); | ||||
|   }`)}
 | ||||
|   }` | ||||
|   )} | ||||
| 
 | ||||
|   input::-moz-focus-outer { | ||||
|     border: 0; | ||||
|  |  | |||
|  | @ -75,7 +75,9 @@ export default class Tabs extends Component { | |||
|     return ( | ||||
|       <TabsContainer position={this.props.position}> | ||||
|         {tabsHeader} | ||||
|         <div><this.SelectedComponent {...(this.selector && this.selector())} /></div> | ||||
|         <div> | ||||
|           <this.SelectedComponent {...this.selector && this.selector()} /> | ||||
|         </div> | ||||
|       </TabsContainer> | ||||
|     ); | ||||
|   } | ||||
|  |  | |||
|  | @ -22,9 +22,11 @@ export default class TabsHeader extends Component { | |||
|   } | ||||
| 
 | ||||
|   componentWillReceiveProps(nextProps) { | ||||
|     if (nextProps.tabs !== this.props.tabs || | ||||
|     if ( | ||||
|       nextProps.tabs !== this.props.tabs || | ||||
|       nextProps.selected !== this.props.selected || | ||||
|       nextProps.collapsible !== this.props.collapsible) { | ||||
|       nextProps.collapsible !== this.props.collapsible | ||||
|     ) { | ||||
|       this.setState({ hiddenTabs: [], visibleTabs: nextProps.tabs.slice() }); | ||||
|     } | ||||
|   } | ||||
|  | @ -47,7 +49,9 @@ export default class TabsHeader extends Component { | |||
|     if (this.iconWidth === 0) { | ||||
|       const tabButtons = this.tabsRef.children; | ||||
|       if (this.tabsRef.children[tabButtons.length - 1].value === 'expandIcon') { | ||||
|         this.iconWidth = tabButtons[tabButtons.length - 1].getBoundingClientRect().width; | ||||
|         this.iconWidth = tabButtons[ | ||||
|           tabButtons.length - 1 | ||||
|         ].getBoundingClientRect().width; | ||||
|         shouldCollapse = true; | ||||
|       } | ||||
|     } else if (this.state.hiddenTabs.length === 0) { | ||||
|  | @ -96,7 +100,8 @@ export default class TabsHeader extends Component { | |||
| 
 | ||||
|     if (tabsRefRight >= tabsWrapperRight - this.iconWidth) { | ||||
|       if ( | ||||
|         this.props.position === 'right' && hiddenTabs.length > 0 && | ||||
|         this.props.position === 'right' && | ||||
|         hiddenTabs.length > 0 && | ||||
|         tabsRef.getBoundingClientRect().width + this.hiddenTabsWidth[0] < | ||||
|           tabsWrapperRef.getBoundingClientRect().width | ||||
|       ) { | ||||
|  | @ -111,12 +116,16 @@ export default class TabsHeader extends Component { | |||
|         } | ||||
|       } else { | ||||
|         while ( | ||||
|           i > 0 && tabButtons[i] && | ||||
|           tabButtons[i].getBoundingClientRect().right >= tabsWrapperRight - this.iconWidth | ||||
|           i > 0 && | ||||
|           tabButtons[i] && | ||||
|           tabButtons[i].getBoundingClientRect().right >= | ||||
|             tabsWrapperRight - this.iconWidth | ||||
|         ) { | ||||
|           if (tabButtons[i].value !== selected) { | ||||
|             hiddenTabs.unshift(...visibleTabs.splice(i, 1)); | ||||
|             this.hiddenTabsWidth.unshift(tabButtons[i].getBoundingClientRect().width); | ||||
|             this.hiddenTabsWidth.unshift( | ||||
|               tabButtons[i].getBoundingClientRect().width | ||||
|             ); | ||||
|           } else { | ||||
|             tabsWrapperRight -= tabButtons[i].getBoundingClientRect().width; | ||||
|           } | ||||
|  | @ -125,9 +134,10 @@ export default class TabsHeader extends Component { | |||
|       } | ||||
|     } else { | ||||
|       while ( | ||||
|         i < tabs.length - 1 && tabButtons[i] && | ||||
|         tabButtons[i].getBoundingClientRect().right + | ||||
|         this.hiddenTabsWidth[0] < tabsWrapperRight - this.iconWidth | ||||
|         i < tabs.length - 1 && | ||||
|         tabButtons[i] && | ||||
|         tabButtons[i].getBoundingClientRect().right + this.hiddenTabsWidth[0] < | ||||
|           tabsWrapperRight - this.iconWidth | ||||
|       ) { | ||||
|         hiddenTab = hiddenTabs.shift(); | ||||
|         visibleTabs.splice(Number(hiddenTab.key), 0, hiddenTab); | ||||
|  | @ -150,7 +160,7 @@ export default class TabsHeader extends Component { | |||
|     this.tabsRef = node; | ||||
|   }; | ||||
| 
 | ||||
|   expandMenu = (e) => { | ||||
|   expandMenu = e => { | ||||
|     const rect = e.currentTarget.children[0].getBoundingClientRect(); | ||||
|     this.setState({ | ||||
|       contextMenu: { | ||||
|  | @ -171,11 +181,14 @@ export default class TabsHeader extends Component { | |||
|       > | ||||
|         <div ref={this.getTabsRef}> | ||||
|           {visibleTabs} | ||||
|           {this.props.collapsible && visibleTabs.length < this.props.items.length && | ||||
|             <button onClick={this.expandMenu} value="expandIcon"><CollapseIcon /></button> | ||||
|           } | ||||
|           {this.props.collapsible && | ||||
|             visibleTabs.length < this.props.items.length && ( | ||||
|               <button onClick={this.expandMenu} value="expandIcon"> | ||||
|                 <CollapseIcon /> | ||||
|               </button> | ||||
|             )} | ||||
|         </div> | ||||
|         {this.props.collapsible && contextMenu && | ||||
|         {this.props.collapsible && contextMenu && ( | ||||
|           <ContextMenu | ||||
|             items={hiddenTabs} | ||||
|             onClick={this.props.onClick} | ||||
|  | @ -183,7 +196,7 @@ export default class TabsHeader extends Component { | |||
|             y={contextMenu.top} | ||||
|             visible={this.state.subMenuOpened} | ||||
|           /> | ||||
|         } | ||||
|         )} | ||||
|       </TabsWrapper> | ||||
|     ); | ||||
|   } | ||||
|  | @ -198,4 +211,3 @@ TabsHeader.propTypes = { | |||
|   collapsible: PropTypes.bool, | ||||
|   selected: PropTypes.string | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -38,4 +38,5 @@ export const tabs = [ | |||
| ]; | ||||
| 
 | ||||
| export const simple10Tabs = []; | ||||
| for (let i = 1; i <= 10; i++) simple10Tabs.push({ name: `Tab${i}`, value: `${i}` }); | ||||
| for (let i = 1; i <= 10; i++) | ||||
|   simple10Tabs.push({ name: `Tab${i}`, value: `${i}` }); | ||||
|  |  | |||
|  | @ -16,22 +16,19 @@ const Container = styled.div` | |||
| 
 | ||||
| storiesOf('Tabs', module) | ||||
|   .addDecorator(withKnobs) | ||||
|   .add( | ||||
|     'default', | ||||
|     () => ( | ||||
|       <Container><Tabs | ||||
|   .add('default', () => ( | ||||
|     <Container> | ||||
|       <Tabs | ||||
|         tabs={simple10Tabs} | ||||
|         selected={text('selected', '2')} | ||||
|         main={boolean('main', true)} | ||||
|         onClick={action('tab selected')} | ||||
|         collapsible={boolean('collapsible', true)} | ||||
|         position={select('position', ['left', 'right', 'center'], 'left')} | ||||
|       /></Container> | ||||
|     ) | ||||
|   ) | ||||
|   .add( | ||||
|     'with content', | ||||
|     () => ( | ||||
|       /> | ||||
|     </Container> | ||||
|   )) | ||||
|   .add('with content', () => ( | ||||
|     <Tabs | ||||
|       tabs={tabs} | ||||
|       selected={text('selected', 'Tab2')} | ||||
|  | @ -40,5 +37,4 @@ storiesOf('Tabs', module) | |||
|       collapsible={boolean('collapsible', false)} | ||||
|       position={select('position', ['left', 'right', 'center'], 'left')} | ||||
|     /> | ||||
|     ) | ||||
|   ); | ||||
|   )); | ||||
|  |  | |||
|  | @ -11,10 +11,14 @@ export const TabsContainer = styled.div` | |||
|   height: 100%; | ||||
| 
 | ||||
|   > div > div:first-child { | ||||
|     ${props => props.position !== 'left' && ` | ||||
|     ${props => | ||||
|       props.position !== 'left' && | ||||
|       ` | ||||
|       margin-left: auto !important; | ||||
|     `}
 | ||||
|     ${props => props.position === 'center' && ` | ||||
|     ${props => | ||||
|       props.position === 'center' && | ||||
|       ` | ||||
|       margin-right: auto !important; | ||||
|     `}
 | ||||
|   } | ||||
|  |  | |||
|  | @ -7,7 +7,8 @@ export const style = ({ theme, main }) => css` | |||
|   background-color: ${theme.base01}; | ||||
|   width: 100%; | ||||
|   overflow: hidden; | ||||
|   ${!main && ` | ||||
|   ${!main && | ||||
|     ` | ||||
|   border-top: 1px solid ${theme.base01}; | ||||
|   border-bottom: 1px solid ${theme.base02}; | ||||
|   `}
 | ||||
|  | @ -39,9 +40,10 @@ export const style = ({ theme, main }) => css` | |||
|     } | ||||
| 
 | ||||
|     > [data-selected] { | ||||
|       ${main ? | ||||
|       `border-bottom: 2px solid ${theme.base0D};` : | ||||
|       ` | ||||
|       ${ | ||||
|         main | ||||
|           ? `border-bottom: 2px solid ${theme.base0D};` | ||||
|           : ` | ||||
|       background-color: ${theme.base00}; | ||||
|       border: 1px solid ${theme.base02}; | ||||
|       border-bottom: 1px solid ${theme.base00}; | ||||
|  |  | |||
|  | @ -8,7 +8,8 @@ export const style = ({ theme, main }) => css` | |||
|   background-color: ${theme.base01}; | ||||
|   width: 100%; | ||||
|   overflow: hidden; | ||||
|   ${!main && ` | ||||
|   ${!main && | ||||
|     ` | ||||
|   border-top: 1px solid ${theme.base01}; | ||||
|   border-bottom: 1px solid ${theme.base02}; | ||||
|   `}
 | ||||
|  |  | |||
|  | @ -2,12 +2,27 @@ import React from 'react'; | |||
| import { storiesOf } from '@storybook/react'; | ||||
| import { action } from '@storybook/addon-actions'; | ||||
| import styled from 'styled-components'; | ||||
| import { withKnobs, text, number, boolean, select } from '@storybook/addon-knobs'; | ||||
| import { | ||||
|   withKnobs, | ||||
|   text, | ||||
|   number, | ||||
|   boolean, | ||||
|   select | ||||
| } from '@storybook/addon-knobs'; | ||||
| import PlayIcon from 'react-icons/lib/md/play-arrow'; | ||||
| import RecordIcon from 'react-icons/lib/md/fiber-manual-record'; | ||||
| import LeftIcon from 'react-icons/lib/md/keyboard-arrow-left'; | ||||
| import RightIcon from 'react-icons/lib/md/keyboard-arrow-right'; | ||||
| import { Toolbar, Divider, Spacer, Button, Select, Slider, SegmentedControl, Tabs } from '../../'; | ||||
| import { | ||||
|   Toolbar, | ||||
|   Divider, | ||||
|   Spacer, | ||||
|   Button, | ||||
|   Select, | ||||
|   Slider, | ||||
|   SegmentedControl, | ||||
|   Tabs | ||||
| } from '../../'; | ||||
| import { options } from '../../Select/stories/options'; | ||||
| import { simple10Tabs } from '../../Tabs/stories/data'; | ||||
| 
 | ||||
|  | @ -26,17 +41,21 @@ export const SliderContainer = styled.div` | |||
| 
 | ||||
| storiesOf('Toolbar', module) | ||||
|   .addDecorator(withKnobs) | ||||
|   .add( | ||||
|     'default', | ||||
|     () => ( | ||||
|   .add('default', () => ( | ||||
|     <Container> | ||||
|       <Toolbar borderPosition={select('borderPosition', ['top', 'bottom'])}> | ||||
|         <Button | ||||
|           title={text('Title', 'Hello Tooltip')} | ||||
|             tooltipPosition={ | ||||
|               select('tooltipPosition', ['top', 'bottom', 'left', 'right', | ||||
|                 'bottom-left', 'bottom-right', 'top-left', 'top-right']) | ||||
|             } | ||||
|           tooltipPosition={select('tooltipPosition', [ | ||||
|             'top', | ||||
|             'bottom', | ||||
|             'left', | ||||
|             'right', | ||||
|             'bottom-left', | ||||
|             'bottom-right', | ||||
|             'top-left', | ||||
|             'top-right' | ||||
|           ])} | ||||
|           disabled={boolean('Disabled', false)} | ||||
|           onClick={action('button clicked')} | ||||
|         > | ||||
|  | @ -45,10 +64,16 @@ storiesOf('Toolbar', module) | |||
|         <Divider /> | ||||
|         <Button | ||||
|           title={text('Title', 'Hello Tooltip')} | ||||
|             tooltipPosition={ | ||||
|               select('tooltipPosition', ['top', 'bottom', 'left', 'right', | ||||
|                 'bottom-left', 'bottom-right', 'top-left', 'top-right']) | ||||
|             } | ||||
|           tooltipPosition={select('tooltipPosition', [ | ||||
|             'top', | ||||
|             'bottom', | ||||
|             'left', | ||||
|             'right', | ||||
|             'bottom-left', | ||||
|             'bottom-right', | ||||
|             'top-left', | ||||
|             'top-right' | ||||
|           ])} | ||||
|           disabled={boolean('Disabled', false)} | ||||
|           onClick={action('button clicked')} | ||||
|         > | ||||
|  | @ -59,19 +84,22 @@ storiesOf('Toolbar', module) | |||
|         <Select options={options} /> | ||||
|       </Toolbar> | ||||
|     </Container> | ||||
|     ) | ||||
|   ) | ||||
|   .add( | ||||
|     'tabs', | ||||
|     () => ( | ||||
|   )) | ||||
|   .add('tabs', () => ( | ||||
|     <Container> | ||||
|       <Toolbar> | ||||
|         <Button | ||||
|           title={text('Title', 'Hello Tooltip')} | ||||
|             tooltipPosition={ | ||||
|               select('tooltipPosition', ['top', 'bottom', 'left', 'right', | ||||
|                 'bottom-left', 'bottom-right', 'top-left', 'top-right']) | ||||
|             } | ||||
|           tooltipPosition={select('tooltipPosition', [ | ||||
|             'top', | ||||
|             'bottom', | ||||
|             'left', | ||||
|             'right', | ||||
|             'bottom-left', | ||||
|             'bottom-right', | ||||
|             'top-left', | ||||
|             'top-right' | ||||
|           ])} | ||||
|           disabled={boolean('Disabled', false)} | ||||
|           onClick={action('button clicked')} | ||||
|         > | ||||
|  | @ -87,10 +115,16 @@ storiesOf('Toolbar', module) | |||
|         /> | ||||
|         <Button | ||||
|           title={text('Title', 'Hello Tooltip')} | ||||
|             tooltipPosition={ | ||||
|               select('tooltipPosition', ['top', 'bottom', 'left', 'right', | ||||
|                 'bottom-left', 'bottom-right', 'top-left', 'top-right']) | ||||
|             } | ||||
|           tooltipPosition={select('tooltipPosition', [ | ||||
|             'top', | ||||
|             'bottom', | ||||
|             'left', | ||||
|             'right', | ||||
|             'bottom-left', | ||||
|             'bottom-right', | ||||
|             'top-left', | ||||
|             'top-right' | ||||
|           ])} | ||||
|           disabled={boolean('Disabled', false)} | ||||
|           onClick={action('button clicked')} | ||||
|         > | ||||
|  | @ -98,20 +132,23 @@ storiesOf('Toolbar', module) | |||
|         </Button> | ||||
|       </Toolbar> | ||||
|     </Container> | ||||
|     ) | ||||
|   ) | ||||
|   .add( | ||||
|     'with slider', | ||||
|     () => ( | ||||
|   )) | ||||
|   .add('with slider', () => ( | ||||
|     <Container> | ||||
|       <SliderContainer> | ||||
|         <Toolbar noBorder fullHeight compact> | ||||
|           <Button | ||||
|             title={text('play title', 'Play')} | ||||
|               tooltipPosition={ | ||||
|                 select('tooltipPosition', ['top', 'bottom', 'left', 'right', | ||||
|                   'bottom-left', 'bottom-right', 'top-left', 'top-right']) | ||||
|               } | ||||
|             tooltipPosition={select('tooltipPosition', [ | ||||
|               'top', | ||||
|               'bottom', | ||||
|               'left', | ||||
|               'right', | ||||
|               'bottom-left', | ||||
|               'bottom-right', | ||||
|               'top-left', | ||||
|               'top-right' | ||||
|             ])} | ||||
|             onClick={action('button clicked')} | ||||
|           > | ||||
|             <PlayIcon /> | ||||
|  | @ -126,10 +163,16 @@ storiesOf('Toolbar', module) | |||
|           /> | ||||
|           <Button | ||||
|             title="Previous state" | ||||
|               tooltipPosition={ | ||||
|                 select('tooltipPosition', ['top', 'bottom', 'left', 'right', | ||||
|                   'bottom-left', 'bottom-right', 'top-left', 'top-right']) | ||||
|               } | ||||
|             tooltipPosition={select('tooltipPosition', [ | ||||
|               'top', | ||||
|               'bottom', | ||||
|               'left', | ||||
|               'right', | ||||
|               'bottom-left', | ||||
|               'bottom-right', | ||||
|               'top-left', | ||||
|               'top-right' | ||||
|             ])} | ||||
|             disabled | ||||
|             onClick={action('previous state clicked')} | ||||
|           > | ||||
|  | @ -137,10 +180,16 @@ storiesOf('Toolbar', module) | |||
|           </Button> | ||||
|           <Button | ||||
|             title="Next state" | ||||
|               tooltipPosition={ | ||||
|                 select('tooltipPosition', ['top', 'bottom', 'left', 'right', | ||||
|                   'bottom-left', 'bottom-right', 'top-left', 'top-right']) | ||||
|               } | ||||
|             tooltipPosition={select('tooltipPosition', [ | ||||
|               'top', | ||||
|               'bottom', | ||||
|               'left', | ||||
|               'right', | ||||
|               'bottom-left', | ||||
|               'bottom-right', | ||||
|               'top-left', | ||||
|               'top-right' | ||||
|             ])} | ||||
|             onClick={action('next state clicked')} | ||||
|           > | ||||
|             <RightIcon /> | ||||
|  | @ -153,5 +202,4 @@ storiesOf('Toolbar', module) | |||
|         </Toolbar> | ||||
|       </SliderContainer> | ||||
|     </Container> | ||||
|     ) | ||||
|   ); | ||||
|   )); | ||||
|  |  | |||
|  | @ -14,8 +14,7 @@ const Toolbar = styled.div` | |||
|   text-align: center; | ||||
|   position: relative; | ||||
|   ${({ borderPosition, theme }) => | ||||
|     borderPosition && `border-${borderPosition}: 1px solid ${theme.base02};` | ||||
|   } | ||||
|     borderPosition && `border-${borderPosition}: 1px solid ${theme.base02};`} | ||||
|    | ||||
|   & > div { | ||||
|     margin: auto ${props => (props.noBorder ? '0' : '1px;')}; | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| export default (colors) => ({ | ||||
| export default colors => ({ | ||||
|   ...colors, | ||||
|   fontFamily: "'Source Sans Pro', sans-serif", | ||||
|   codeFontFamily: "'Source Code Pro', monospace", | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| export default (colors) => ({ | ||||
| export default colors => ({ | ||||
|   fontFamily: "'Roboto', sans-serif", | ||||
|   codeFontFamily: "'Roboto Mono', monospace", | ||||
|   inputPadding: 5, | ||||
|  |  | |||
|  | @ -36,7 +36,9 @@ export const ripple = theme => ` | |||
|     top: 0; | ||||
|     left: 0; | ||||
|     pointer-events: none; | ||||
|     background-image: radial-gradient(circle, ${theme.base07} 11%, transparent 11%); | ||||
|     background-image: radial-gradient(circle, ${ | ||||
|       theme.base07 | ||||
|     } 11%, transparent 11%); | ||||
|     background-repeat: no-repeat; | ||||
|     background-position: 50%; | ||||
|     transform: scale(10, 10); | ||||
|  |  | |||
|  | @ -7,6 +7,10 @@ import Color from 'color'; | |||
|     effect('#000000', 'alpha', 0.5); | ||||
| */ | ||||
| 
 | ||||
| export default (color, effect, val) => new Color(color)[effect](val).hsl().string(); | ||||
| export default (color, effect, val) => | ||||
|   new Color(color) | ||||
|     [effect](val) | ||||
|     .hsl() | ||||
|     .string(); | ||||
| 
 | ||||
| // TODO: memoize it
 | ||||
|  |  | |||
|  | @ -1,17 +1,19 @@ | |||
| import styled from 'styled-components'; | ||||
| import getDefaultTheme from '../themes/default'; | ||||
| 
 | ||||
| const getStyle = (styles, type) => ( | ||||
|   typeof styles === 'object' ? styles[type] || styles.default : styles | ||||
| ); | ||||
| const getStyle = (styles, type) => | ||||
|   typeof styles === 'object' ? styles[type] || styles.default : styles; | ||||
| 
 | ||||
| export default (styles, component) => | ||||
|   styled(component || 'div')`${ | ||||
|     props => ( | ||||
|       props.theme.type ? getStyle(styles, props.theme.type) : | ||||
|         // used outside of container (theme provider)
 | ||||
|         getStyle(styles, 'default')({ ...props, theme: getDefaultTheme(props.theme) }) | ||||
|     ) | ||||
|   }`;
 | ||||
|   styled(component || 'div')` | ||||
|     ${props => | ||||
|       props.theme.type | ||||
|         ? getStyle(styles, props.theme.type) | ||||
|         : // used outside of container (theme provider)
 | ||||
|           getStyle(styles, 'default')({ | ||||
|             ...props, | ||||
|             theme: getDefaultTheme(props.theme) | ||||
|           })} | ||||
|   `;
 | ||||
| 
 | ||||
| // TODO: memoize it?
 | ||||
|  |  | |||
|  | @ -5,7 +5,10 @@ import * as additionalSchemes from '../colorSchemes'; | |||
| import invertColors from '../utils/invertColors'; | ||||
| 
 | ||||
| export const schemes = { ...baseSchemes, ...additionalSchemes }; | ||||
| export const listSchemes = () => Object.keys(schemes).slice(1).sort(); // remove `__esModule`
 | ||||
| export const listSchemes = () => | ||||
|   Object.keys(schemes) | ||||
|     .slice(1) | ||||
|     .sort(); // remove `__esModule`
 | ||||
| export const listThemes = () => Object.keys(themes); | ||||
| 
 | ||||
| export const getTheme = ({ theme: type, scheme, light }) => { | ||||
|  |  | |||
|  | @ -6,7 +6,9 @@ import { Container } from '../src'; | |||
| describe('Container', function() { | ||||
|   it('renders correctly', () => { | ||||
|     const wrapper = render( | ||||
|       <Container themeData={{ theme: 'default', scheme: 'default', invert: false }}> | ||||
|       <Container | ||||
|         themeData={{ theme: 'default', scheme: 'default', invert: false }} | ||||
|       > | ||||
|         Text | ||||
|       </Container> | ||||
|     ); | ||||
|  |  | |||
|  | @ -7,26 +7,20 @@ import { items } from '../src/ContextMenu/stories/data'; | |||
| describe('ContextMenu', function() { | ||||
|   it('renders correctly', () => { | ||||
|     const wrapper = render( | ||||
|       <ContextMenu | ||||
|         items={items} | ||||
|         onClick={() => {}} | ||||
|         x={100} | ||||
|         y={100} | ||||
|       /> | ||||
|       <ContextMenu items={items} onClick={() => {}} x={100} y={100} /> | ||||
|     ); | ||||
|     expect(renderToJson(wrapper)).toMatchSnapshot(); | ||||
|   }); | ||||
|   it('should handle the click event', () => { | ||||
|     const onClick = jest.fn(); | ||||
|     const wrapper = mount( | ||||
|     <ContextMenu | ||||
|       items={items} | ||||
|       onClick={onClick} | ||||
|       x={100} | ||||
|       y={100} | ||||
|     />); | ||||
|       <ContextMenu items={items} onClick={onClick} x={100} y={100} /> | ||||
|     ); | ||||
| 
 | ||||
|     wrapper.find('button').first().simulate('click'); | ||||
|     wrapper | ||||
|       .find('button') | ||||
|       .first() | ||||
|       .simulate('click'); | ||||
|     expect(onClick).toBeCalled(); | ||||
|   }); | ||||
| }); | ||||
|  |  | |||
|  | @ -11,11 +11,7 @@ describe('Dialog', function () { | |||
| 
 | ||||
|   it('renders with props', () => { | ||||
|     const wrapper = render( | ||||
|       <Dialog | ||||
|         title="Dialog Title" | ||||
|         open | ||||
|         fullWidth | ||||
|       > | ||||
|       <Dialog title="Dialog Title" open fullWidth> | ||||
|         Hello Dialog! | ||||
|       </Dialog> | ||||
|     ); | ||||
|  | @ -31,7 +27,10 @@ describe('Dialog', function () { | |||
|     const onDismiss = jest.fn(); | ||||
|     const wrapper = mount(<Dialog open onDismiss={onDismiss} />); | ||||
| 
 | ||||
|     wrapper.find('button').first().simulate('click'); | ||||
|     wrapper | ||||
|       .find('button') | ||||
|       .first() | ||||
|       .simulate('click'); | ||||
|     expect(onDismiss).toBeCalled(); | ||||
|   }); | ||||
| 
 | ||||
|  | @ -39,7 +38,10 @@ describe('Dialog', function () { | |||
|     const onSubmit = jest.fn(); | ||||
|     const wrapper = mount(<Dialog open onSubmit={onSubmit} />); | ||||
| 
 | ||||
|     wrapper.find('button').last().simulate('click'); | ||||
|     wrapper | ||||
|       .find('button') | ||||
|       .last() | ||||
|       .simulate('click'); | ||||
|     expect(onSubmit).toBeCalled(); | ||||
|   }); | ||||
| }); | ||||
|  |  | |||
|  | @ -7,11 +7,8 @@ import { schema, uiSchema, formData } from '../src/Form/stories/schema'; | |||
| describe('Form', function() { | ||||
|   it('renders correctly', () => { | ||||
|     const wrapper = shallow( | ||||
|       <Form | ||||
|         formData={formData} | ||||
|         schema={schema} | ||||
|         uiSchema={uiSchema} | ||||
|       />); | ||||
|       <Form formData={formData} schema={schema} uiSchema={uiSchema} /> | ||||
|     ); | ||||
|     expect(shallowToJson(wrapper)).toMatchSnapshot(); | ||||
|   }); | ||||
| 
 | ||||
|  | @ -23,18 +20,15 @@ describe('Form', function () { | |||
|         formData={formData} | ||||
|         schema={schema} | ||||
|         uiSchema={uiSchema} | ||||
|       />); | ||||
|       /> | ||||
|     ); | ||||
|     expect(shallowToJson(wrapper)).toMatchSnapshot(); | ||||
|   }); | ||||
| 
 | ||||
|   it('renders with no button', () => { | ||||
|     const wrapper = shallow( | ||||
|       <Form | ||||
|         formData={formData} | ||||
|         schema={schema} | ||||
|         uiSchema={uiSchema} | ||||
|         noSubmit | ||||
|       />); | ||||
|       <Form formData={formData} schema={schema} uiSchema={uiSchema} noSubmit /> | ||||
|     ); | ||||
|     expect(shallowToJson(wrapper)).toMatchSnapshot(); | ||||
|   }); | ||||
| 
 | ||||
|  |  | |||
|  | @ -11,14 +11,18 @@ describe('Notification', function () { | |||
| 
 | ||||
|   it('renders with props', () => { | ||||
|     const wrapper = render( | ||||
|       <Notification type="error" onClose={() => {}}>Message</Notification> | ||||
|       <Notification type="error" onClose={() => {}}> | ||||
|         Message | ||||
|       </Notification> | ||||
|     ); | ||||
|     expect(renderToJson(wrapper)).toMatchSnapshot(); | ||||
|   }); | ||||
| 
 | ||||
|   it('should handle the click event', () => { | ||||
|     const onClose = jest.fn(); | ||||
|     const wrapper = mount(<Notification onClose={onClose}>Message</Notification>); | ||||
|     const wrapper = mount( | ||||
|       <Notification onClose={onClose}>Message</Notification> | ||||
|     ); | ||||
| 
 | ||||
|     wrapper.find('button').simulate('click'); | ||||
|     expect(onClose).toBeCalled(); | ||||
|  |  | |||
|  | @ -17,7 +17,8 @@ describe('SegmentedControl', function () { | |||
|   }); | ||||
|   it('should handle the click event', () => { | ||||
|     const onClick = jest.fn(); | ||||
|     const wrapper = mount(<SegmentedControl | ||||
|     const wrapper = mount( | ||||
|       <SegmentedControl | ||||
|         values={['Button1', 'Button2', 'Button3']} | ||||
|         selected="Button1" | ||||
|         disabled={false} | ||||
|  | @ -25,7 +26,10 @@ describe('SegmentedControl', function () { | |||
|       /> | ||||
|     ); | ||||
| 
 | ||||
|     wrapper.find('button').first().simulate('click'); | ||||
|     wrapper | ||||
|       .find('button') | ||||
|       .first() | ||||
|       .simulate('click'); | ||||
|     expect(onClick).toBeCalled(); | ||||
|   }); | ||||
| }); | ||||
|  |  | |||
|  | @ -12,22 +12,14 @@ describe('Tabs', function () { | |||
| 
 | ||||
|   it('renders with props', () => { | ||||
|     const wrapper = render( | ||||
|       <Tabs | ||||
|         tabs={tabs} | ||||
|         onClick={() => {}} | ||||
|         selected="Tab2" | ||||
|       /> | ||||
|       <Tabs tabs={tabs} onClick={() => {}} selected="Tab2" /> | ||||
|     ); | ||||
|     expect(renderToJson(wrapper)).toMatchSnapshot(); | ||||
|   }); | ||||
| 
 | ||||
|   it('renders tabs without inner components', () => { | ||||
|     const wrapper = render( | ||||
|       <Tabs | ||||
|         tabs={simple10Tabs} | ||||
|         onClick={() => {}} | ||||
|         selected="5" | ||||
|       /> | ||||
|       <Tabs tabs={simple10Tabs} onClick={() => {}} selected="5" /> | ||||
|     ); | ||||
|     expect(renderToJson(wrapper)).toMatchSnapshot(); | ||||
|   }); | ||||
|  | @ -36,7 +28,10 @@ describe('Tabs', function () { | |||
|     const onClick = jest.fn(); | ||||
|     const wrapper = mount(<Tabs tabs={tabs} onClick={onClick} />); | ||||
| 
 | ||||
|     wrapper.find('button').first().simulate('click'); | ||||
|     wrapper | ||||
|       .find('button') | ||||
|       .first() | ||||
|       .simulate('click'); | ||||
|     expect(onClick).toBeCalled(); | ||||
|   }); | ||||
| }); | ||||
|  |  | |||
|  | @ -17,9 +17,7 @@ describe('Toolbar', function () { | |||
|   }); | ||||
| 
 | ||||
|   it('renders with props', () => { | ||||
|     const wrapper = render( | ||||
|       <Toolbar borderPosition="top" /> | ||||
|     ); | ||||
|     const wrapper = render(<Toolbar borderPosition="top" />); | ||||
|     expect(renderToJson(wrapper)).toMatchSnapshot(); | ||||
|   }); | ||||
| }); | ||||
|  |  | |||
|  | @ -2,10 +2,10 @@ | |||
| 
 | ||||
| exports[`Button renders correctly 1`] = ` | ||||
| <div | ||||
|   class="sc-ifAKCX jTewnV" | ||||
|   class="sc-ifAKCX evScRP" | ||||
| > | ||||
|   <button | ||||
|     class="sc-htpNat fWcQZ" | ||||
|     class="sc-htpNat ldLqpm" | ||||
|   > | ||||
|     Text | ||||
|   </button> | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ | |||
| 
 | ||||
| exports[`Container renders correctly 1`] = ` | ||||
| <div | ||||
|   class="sc-bdVaJa dRsjcb" | ||||
|   class="sc-bdVaJa ODaHo" | ||||
| > | ||||
|   Text | ||||
| </div> | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ | |||
| 
 | ||||
| exports[`ContextMenu renders correctly 1`] = ` | ||||
| <div | ||||
|   class="sc-EHOje dIpPFG" | ||||
|   class="sc-EHOje cfLLnh" | ||||
| > | ||||
|   <button | ||||
|     value="Menu Item 1" | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ | |||
| 
 | ||||
| exports[`Dialog renders correctly 1`] = ` | ||||
| <div | ||||
|   class="sc-iwsKbI fOBkrR" | ||||
|   class="sc-iwsKbI islPis" | ||||
| > | ||||
|   <div /> | ||||
|   <div> | ||||
|  | @ -21,19 +21,19 @@ exports[`Dialog renders correctly 1`] = ` | |||
|       class="mc-dialog--footer" | ||||
|     > | ||||
|       <div | ||||
|         class="sc-ifAKCX jTewnV" | ||||
|         class="sc-ifAKCX evScRP" | ||||
|       > | ||||
|         <button | ||||
|           class="sc-htpNat fWcQZ" | ||||
|           class="sc-htpNat ldLqpm" | ||||
|         > | ||||
|           Cancel | ||||
|         </button> | ||||
|       </div> | ||||
|       <div | ||||
|         class="sc-ifAKCX jTewnV" | ||||
|         class="sc-ifAKCX evScRP" | ||||
|       > | ||||
|         <button | ||||
|           class="sc-htpNat iMkoYt" | ||||
|           class="sc-htpNat cvNnmn" | ||||
|         > | ||||
|           Submit | ||||
|         </button> | ||||
|  | @ -45,7 +45,7 @@ exports[`Dialog renders correctly 1`] = ` | |||
| 
 | ||||
| exports[`Dialog renders modal 1`] = ` | ||||
| <div | ||||
|   class="sc-iwsKbI fOBkrR" | ||||
|   class="sc-iwsKbI islPis" | ||||
| > | ||||
|   <div /> | ||||
|   <div> | ||||
|  | @ -61,19 +61,19 @@ exports[`Dialog renders modal 1`] = ` | |||
|       class="mc-dialog--footer" | ||||
|     > | ||||
|       <div | ||||
|         class="sc-ifAKCX jTewnV" | ||||
|         class="sc-ifAKCX evScRP" | ||||
|       > | ||||
|         <button | ||||
|           class="sc-htpNat fWcQZ" | ||||
|           class="sc-htpNat ldLqpm" | ||||
|         > | ||||
|           Cancel | ||||
|         </button> | ||||
|       </div> | ||||
|       <div | ||||
|         class="sc-ifAKCX jTewnV" | ||||
|         class="sc-ifAKCX evScRP" | ||||
|       > | ||||
|         <button | ||||
|           class="sc-htpNat iMkoYt" | ||||
|           class="sc-htpNat cvNnmn" | ||||
|         > | ||||
|           Submit | ||||
|         </button> | ||||
|  | @ -85,7 +85,7 @@ exports[`Dialog renders modal 1`] = ` | |||
| 
 | ||||
| exports[`Dialog renders with props 1`] = ` | ||||
| <div | ||||
|   class="sc-iwsKbI fpUYbC" | ||||
|   class="sc-iwsKbI hRSLqU" | ||||
|   open="" | ||||
| > | ||||
|   <div /> | ||||
|  | @ -109,19 +109,19 @@ exports[`Dialog renders with props 1`] = ` | |||
|       class="mc-dialog--footer" | ||||
|     > | ||||
|       <div | ||||
|         class="sc-ifAKCX jTewnV" | ||||
|         class="sc-ifAKCX evScRP" | ||||
|       > | ||||
|         <button | ||||
|           class="sc-htpNat fWcQZ" | ||||
|           class="sc-htpNat ldLqpm" | ||||
|         > | ||||
|           Cancel | ||||
|         </button> | ||||
|       </div> | ||||
|       <div | ||||
|         class="sc-ifAKCX jTewnV" | ||||
|         class="sc-ifAKCX evScRP" | ||||
|       > | ||||
|         <button | ||||
|           class="sc-htpNat iMkoYt" | ||||
|           class="sc-htpNat cvNnmn" | ||||
|         > | ||||
|           Submit | ||||
|         </button> | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ exports[`Editor renders correctly 1`] = ` | |||
|     innerRef={[Function]} | ||||
|   > | ||||
|     <div | ||||
|       className="sc-gZMcBi eROHUl" | ||||
|       className="sc-gZMcBi bFOJgt" | ||||
|     /> | ||||
|   </styled.div> | ||||
| </Editor> | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ | |||
| 
 | ||||
| exports[`Notification renders correctly 1`] = ` | ||||
| <div | ||||
|   class="sc-fjdhpX fmuodm" | ||||
|   class="sc-fjdhpX gcvrGp" | ||||
|   type="info" | ||||
| > | ||||
|   <span> | ||||
|  | @ -13,7 +13,7 @@ exports[`Notification renders correctly 1`] = ` | |||
| 
 | ||||
| exports[`Notification renders with props 1`] = ` | ||||
| <div | ||||
|   class="sc-fjdhpX fmuodm" | ||||
|   class="sc-fjdhpX gcvrGp" | ||||
|   type="error" | ||||
| > | ||||
|   <svg | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ | |||
| 
 | ||||
| exports[`SegmentedControl renders correctly 1`] = ` | ||||
| <div | ||||
|   class="sc-jTzLTM jHNWjD" | ||||
|   class="sc-jTzLTM bwMlok" | ||||
| > | ||||
|   <button | ||||
|     data-selected="true" | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ | |||
| 
 | ||||
| exports[`Select renders correctly 1`] = ` | ||||
| <div | ||||
|   class="Select sc-bZQynM lpCNM is-searchable Select--single" | ||||
|   class="Select sc-bZQynM eKUTFA is-searchable Select--single" | ||||
| > | ||||
|   <div | ||||
|     class="Select-control" | ||||
|  | @ -47,7 +47,7 @@ exports[`Select renders correctly 1`] = ` | |||
| 
 | ||||
| exports[`Select renders with props 1`] = ` | ||||
| <div | ||||
|   class="Select sc-bZQynM dVPEwd has-value is-clearable is-disabled is-loading Select--multi" | ||||
|   class="Select sc-bZQynM lbesTc has-value is-clearable is-disabled is-loading Select--multi" | ||||
| > | ||||
|   <div | ||||
|     class="Select-control" | ||||
|  | @ -155,7 +155,7 @@ exports[`Select should select another option 1`] = ` | |||
|       autosize={true} | ||||
|       backspaceRemoves={true} | ||||
|       backspaceToRemoveMessage="Press backspace to remove {label}" | ||||
|       className="sc-bZQynM lpCNM" | ||||
|       className="sc-bZQynM eKUTFA" | ||||
|       clearAllText="Clear all" | ||||
|       clearRenderer={[Function]} | ||||
|       clearValueText="Clear value" | ||||
|  | @ -215,7 +215,7 @@ exports[`Select should select another option 1`] = ` | |||
|       valueKey="value" | ||||
|     > | ||||
|       <div | ||||
|         className="Select sc-bZQynM lpCNM is-open is-searchable Select--single" | ||||
|         className="Select sc-bZQynM eKUTFA is-open is-searchable Select--single" | ||||
|       > | ||||
|         <div | ||||
|           className="Select-control" | ||||
|  | @ -404,7 +404,7 @@ exports[`Select shouldn't find any results 1`] = ` | |||
|       autosize={true} | ||||
|       backspaceRemoves={true} | ||||
|       backspaceToRemoveMessage="Press backspace to remove {label}" | ||||
|       className="sc-bZQynM lpCNM" | ||||
|       className="sc-bZQynM eKUTFA" | ||||
|       clearAllText="Clear all" | ||||
|       clearRenderer={[Function]} | ||||
|       clearValueText="Clear value" | ||||
|  | @ -464,7 +464,7 @@ exports[`Select shouldn't find any results 1`] = ` | |||
|       valueKey="value" | ||||
|     > | ||||
|       <div | ||||
|         className="Select sc-bZQynM lpCNM is-open is-searchable Select--single" | ||||
|         className="Select sc-bZQynM eKUTFA is-open is-searchable Select--single" | ||||
|       > | ||||
|         <div | ||||
|           className="Select-control" | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ | |||
| 
 | ||||
| exports[`Slider renders correctly 1`] = ` | ||||
| <div | ||||
|   class="sc-gzVnrw gTqmBD" | ||||
|   class="sc-gzVnrw hKBSWW" | ||||
| > | ||||
|   <input | ||||
|     max="100" | ||||
|  | @ -15,7 +15,7 @@ exports[`Slider renders correctly 1`] = ` | |||
| 
 | ||||
| exports[`Slider renders with props 1`] = ` | ||||
| <div | ||||
|   class="sc-gzVnrw csqRof" | ||||
|   class="sc-gzVnrw gnJNaZ" | ||||
|   disabled="" | ||||
| > | ||||
|   <label> | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ exports[`Tabs renders correctly 1`] = ` | |||
|   class="sc-VigVT fmiisu" | ||||
| > | ||||
|   <div | ||||
|     class="sc-gqjmRU gEvsQs" | ||||
|     class="sc-gqjmRU kpDKzc" | ||||
|   > | ||||
|     <div> | ||||
|       <button | ||||
|  | @ -33,7 +33,7 @@ exports[`Tabs renders tabs without inner components 1`] = ` | |||
|   class="sc-VigVT fmiisu" | ||||
| > | ||||
|   <div | ||||
|     class="sc-gqjmRU gEvsQs" | ||||
|     class="sc-gqjmRU kpDKzc" | ||||
|   > | ||||
|     <div> | ||||
|       <button | ||||
|  | @ -97,7 +97,7 @@ exports[`Tabs renders with props 1`] = ` | |||
|   class="sc-VigVT fmiisu" | ||||
| > | ||||
|   <div | ||||
|     class="sc-gqjmRU gEvsQs" | ||||
|     class="sc-gqjmRU kpDKzc" | ||||
|   > | ||||
|     <div> | ||||
|       <button | ||||
|  |  | |||
|  | @ -5,10 +5,10 @@ exports[`Toolbar renders correctly 1`] = ` | |||
|   class="sc-jzJRlG bBrbNn" | ||||
| > | ||||
|   <div | ||||
|     class="sc-ifAKCX jTewnV" | ||||
|     class="sc-ifAKCX evScRP" | ||||
|   > | ||||
|     <button | ||||
|       class="sc-htpNat fWcQZ" | ||||
|       class="sc-htpNat ldLqpm" | ||||
|     > | ||||
|       1 | ||||
|     </button> | ||||
|  | @ -20,10 +20,10 @@ exports[`Toolbar renders correctly 1`] = ` | |||
|     class="sc-kAzzGY lcEaIs" | ||||
|   /> | ||||
|   <div | ||||
|     class="sc-ifAKCX jTewnV" | ||||
|     class="sc-ifAKCX evScRP" | ||||
|   > | ||||
|     <button | ||||
|       class="sc-htpNat fWcQZ" | ||||
|       class="sc-htpNat ldLqpm" | ||||
|     > | ||||
|       2 | ||||
|     </button> | ||||
|  |  | |||
|  | @ -5,15 +5,16 @@ The following opinions must be taken into account since the primary use case of | |||
| - Objects and arrays deeply nested within collections are not converted into a tree structure. See `someNestedObject` and `someNestedArray` in the [output](https://github.com/romseguy/map2tree#output) below, or the [corresponding test](https://github.com/romseguy/map2tree/blob/master/test/map2tree.js#L140). | ||||
| - Provides support for [Immutable.js](https://github.com/facebook/immutable-js) data structures (only List and Map though). | ||||
| 
 | ||||
| 
 | ||||
| # Usage | ||||
| 
 | ||||
| 
 | ||||
| ```javascript | ||||
| map2tree(someMap, options = { | ||||
| map2tree( | ||||
|   someMap, | ||||
|   (options = { | ||||
|     key: 'state', // the name you want for as the root node of the output tree | ||||
|     pushMethod: 'push' // use 'unshift' to change the order children nodes are added | ||||
|   }) | ||||
| ); | ||||
| ``` | ||||
| 
 | ||||
| # Input | ||||
|  |  | |||
|  | @ -19,16 +19,24 @@ function visit(parent, visitFn, childrenFn) { | |||
| function getNode(tree, key) { | ||||
|   let node = null; | ||||
| 
 | ||||
|   visit(tree, d => { | ||||
|   visit( | ||||
|     tree, | ||||
|     d => { | ||||
|       if (d.name === key) { | ||||
|         node = d; | ||||
|       } | ||||
|   }, d => d.children); | ||||
|     }, | ||||
|     d => d.children | ||||
|   ); | ||||
| 
 | ||||
|   return node; | ||||
| } | ||||
| 
 | ||||
| export default function map2tree(root, options = {}, tree = {name: options.key || 'state', children: []}) { | ||||
| export default function map2tree( | ||||
|   root, | ||||
|   options = {}, | ||||
|   tree = { name: options.key || 'state', children: [] } | ||||
| ) { | ||||
|   if (!isPlainObject(root) && root && !root.toJS) { | ||||
|     return {}; | ||||
|   } | ||||
|  | @ -41,7 +49,10 @@ export default function map2tree(root, options = {}, tree = {name: options.key | | |||
|   } | ||||
| 
 | ||||
|   mapValues(root && root.toJS ? root.toJS() : root, (maybeImmutable, key) => { | ||||
|     const value = maybeImmutable && maybeImmutable.toJS ? maybeImmutable.toJS() : maybeImmutable; | ||||
|     const value = | ||||
|       maybeImmutable && maybeImmutable.toJS | ||||
|         ? maybeImmutable.toJS() | ||||
|         : maybeImmutable; | ||||
|     let newNode = { name: key }; | ||||
| 
 | ||||
|     if (isArray(value)) { | ||||
|  |  | |||
|  | @ -16,9 +16,7 @@ describe('# shallow map', () => { | |||
| 
 | ||||
|     const expected = { | ||||
|       name: 'state', | ||||
|       children: [ | ||||
|         {name: 'a', value: null} | ||||
|       ] | ||||
|       children: [{ name: 'a', value: null }] | ||||
|     }; | ||||
| 
 | ||||
|     expect(map2tree(map)).toEqual(expected); | ||||
|  | @ -33,10 +31,7 @@ describe('# shallow map', () => { | |||
| 
 | ||||
|     const expected = { | ||||
|       name: 'state', | ||||
|       children: [ | ||||
|         {name: 'a', value: 'foo'}, | ||||
|         {name: 'b', value: 'bar'} | ||||
|       ] | ||||
|       children: [{ name: 'a', value: 'foo' }, { name: 'b', value: 'bar' }] | ||||
|     }; | ||||
| 
 | ||||
|     expect(map2tree(map)).toEqual(expected); | ||||
|  | @ -50,9 +45,7 @@ describe('# shallow map', () => { | |||
| 
 | ||||
|     const expected = { | ||||
|       name: 'state', | ||||
|       children: [ | ||||
|         {name: 'a', children: [{name: 'aa', value: 'foo'}]} | ||||
|       ] | ||||
|       children: [{ name: 'a', children: [{ name: 'aa', value: 'foo' }] }] | ||||
|     }; | ||||
| 
 | ||||
|     expect(map2tree(map)).toEqual(expected); | ||||
|  | @ -67,12 +60,15 @@ describe('# shallow map', () => { | |||
|     const expected = { | ||||
|       name: 'state', | ||||
|       children: [ | ||||
|         {name: 'a', children: [{name: 'aa', value: 'foo'}, {name: 'ab', value: 'bar'}]} | ||||
|         { | ||||
|           name: 'a', | ||||
|           children: [{ name: 'aa', value: 'foo' }, { name: 'ab', value: 'bar' }] | ||||
|         } | ||||
|       ] | ||||
|     }; | ||||
| 
 | ||||
|     expect(map2tree(map)).toEqual(expected); | ||||
|   }) | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| describe('# deep map', () => { | ||||
|  | @ -113,9 +109,7 @@ describe('# deep map', () => { | |||
|           children: [ | ||||
|             { | ||||
|               name: 'aa', | ||||
|               children: [ | ||||
|                 {name: 'aaa', value: 'foo'} | ||||
|               ] | ||||
|               children: [{ name: 'aaa', value: 'foo' }] | ||||
|             } | ||||
|           ] | ||||
|         } | ||||
|  | @ -129,21 +123,18 @@ describe('# deep map', () => { | |||
| 
 | ||||
| describe('# array map', () => { | ||||
|   const map = { | ||||
|     a: [ | ||||
|       1, | ||||
|       2 | ||||
|     ] | ||||
|     a: [1, 2] | ||||
|   }; | ||||
| 
 | ||||
|   test('## push', () => { | ||||
|     const expected = { | ||||
|       name: 'state', | ||||
|       children: [{ | ||||
|         name: 'a', | ||||
|       children: [ | ||||
|           {name: 'a[0]', value: 1}, | ||||
|           {name: 'a[1]', value: 2}] | ||||
|       }] | ||||
|         { | ||||
|           name: 'a', | ||||
|           children: [{ name: 'a[0]', value: 1 }, { name: 'a[1]', value: 2 }] | ||||
|         } | ||||
|       ] | ||||
|     }; | ||||
| 
 | ||||
|     expect(map2tree(map)).toEqual(expected); | ||||
|  | @ -154,13 +145,12 @@ describe('# array map', () => { | |||
|     const options = { pushMethod: 'unshift' }; | ||||
|     const expected = { | ||||
|       name: 'state', | ||||
|       children: [{ | ||||
|         name: 'a', | ||||
|       children: [ | ||||
|           {name: 'a[1]', value: 2}, | ||||
|           {name: 'a[0]', value: 1} | ||||
|         { | ||||
|           name: 'a', | ||||
|           children: [{ name: 'a[1]', value: 2 }, { name: 'a[0]', value: 1 }] | ||||
|         } | ||||
|       ] | ||||
|       }] | ||||
|     }; | ||||
| 
 | ||||
|     expect(map2tree(map, options)).toEqual(expected); | ||||
|  | @ -169,33 +159,28 @@ describe('# array map', () => { | |||
| 
 | ||||
|   test('## null', () => { | ||||
|     const map = { | ||||
|       a: [ | ||||
|         null | ||||
|       ] | ||||
|       a: [null] | ||||
|     }; | ||||
| 
 | ||||
|     const expected = { | ||||
|       name: 'state', | ||||
|       children: [{ | ||||
|         name: 'a', | ||||
|       children: [ | ||||
|           {name: 'a[0]', value: null} | ||||
|         { | ||||
|           name: 'a', | ||||
|           children: [{ name: 'a[0]', value: null }] | ||||
|         } | ||||
|       ] | ||||
|       }] | ||||
|     }; | ||||
| 
 | ||||
|     expect(map2tree(map)).toEqual(expected); | ||||
|     expect(map2tree(immutable.fromJS(map))).toEqual(expected); | ||||
|   }) | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| describe('# collection map', () => { | ||||
|   test('## value', () => { | ||||
|     const map = { | ||||
|       a: [ | ||||
|         {aa: 1}, | ||||
|         {aa: 2} | ||||
|       ] | ||||
|       a: [{ aa: 1 }, { aa: 2 }] | ||||
|     }; | ||||
| 
 | ||||
|     const expected = { | ||||
|  | @ -217,9 +202,7 @@ describe('# collection map', () => { | |||
| 
 | ||||
|   test('## object', () => { | ||||
|     const map = { | ||||
|       a: [ | ||||
|         {aa: {aaa: 'foo'}} | ||||
|       ] | ||||
|       a: [{ aa: { aaa: 'foo' } }] | ||||
|     }; | ||||
| 
 | ||||
|     const expected = { | ||||
|  | @ -227,14 +210,12 @@ describe('# collection map', () => { | |||
|       children: [ | ||||
|         { | ||||
|           name: 'a', | ||||
|           children: [ | ||||
|             {name: 'a[0]', object: {aa: {aaa: 'foo'}}} | ||||
|           ] | ||||
|           children: [{ name: 'a[0]', object: { aa: { aaa: 'foo' } } }] | ||||
|         } | ||||
|       ] | ||||
|     }; | ||||
| 
 | ||||
|     expect(map2tree(map)).toEqual(expected); | ||||
|     expect(map2tree(immutable.fromJS(map))).toEqual(expected); | ||||
|   }) | ||||
|   }); | ||||
| }); | ||||
|  |  | |||
|  | @ -1,7 +1,6 @@ | |||
| const path = require('path'); | ||||
| 
 | ||||
| module.exports = (env = {}) => ( | ||||
|   { | ||||
| module.exports = (env = {}) => ({ | ||||
|   mode: 'production', | ||||
|   entry: { | ||||
|     app: ['./src/index.js'] | ||||
|  | @ -27,5 +26,4 @@ module.exports = (env = {}) => ( | |||
|   performance: { | ||||
|     hints: false | ||||
|   } | ||||
|   } | ||||
| ); | ||||
| }); | ||||
|  |  | |||
|  | @ -2,7 +2,6 @@ The MIT License (MIT) | |||
| 
 | ||||
| Copyright (c) 2015 Shusaku Uesugi, (c) 2016-present Alexander Kuznetsov | ||||
| 
 | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
|  |  | |||
|  | @ -33,6 +33,7 @@ Check out [examples](examples) directory for more details. | |||
| ### Theming | ||||
| 
 | ||||
| This component now uses [react-base16-styling](https://github.com/alexkuz/react-base16-styling) module, which allows to customize component via `theme` property, which can be the following: | ||||
| 
 | ||||
| - [base16](http://chriskempson.github.io/base16) theme data. [The example theme data can be found here](https://github.com/gaearon/redux-devtools/tree/75322b15ee7ba03fddf10ac3399881e302848874/src/react/themes). | ||||
| - object that contains style objects, strings (that treated as classnames) or functions. A function is used to extend its first argument `{ style, className }` and should return an object with the same structure. Other arguments depend on particular context (and should be described here). See [createStylingFromTheme.js](https://github.com/alexkuz/react-json-tree/blob/feature-refactor-styling/src/createStylingFromTheme.js) for the list of styling object keys. Also, this object can extend `base16` theme via `extend` property. | ||||
| 
 | ||||
|  | @ -62,8 +63,7 @@ const theme = { | |||
| 
 | ||||
| <div> | ||||
|   <JSONTree data={data} theme={theme} invertTheme={false} /> | ||||
| </div> | ||||
| 
 | ||||
| </div>; | ||||
| ``` | ||||
| 
 | ||||
| #### Result (Monokai theme, dark background): | ||||
|  | @ -74,7 +74,9 @@ const theme = { | |||
| 
 | ||||
| ```jsx | ||||
| <div> | ||||
|   <JSONTree data={data} theme={{ | ||||
|   <JSONTree | ||||
|     data={data} | ||||
|     theme={{ | ||||
|       extend: theme, | ||||
|       // underline keys for literal values | ||||
|       valueLabel: { | ||||
|  | @ -88,7 +90,8 @@ const theme = { | |||
|           textTransform: expanded ? 'uppercase' : style.textTransform | ||||
|         } | ||||
|       }) | ||||
|   }} /> | ||||
|     }} | ||||
|   /> | ||||
| </div> | ||||
| ``` | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,5 +1,4 @@ | |||
| react-hot-boilerplate | ||||
| ===================== | ||||
| # react-hot-boilerplate | ||||
| 
 | ||||
| The minimal dev environment to enable live-editing React components. | ||||
| 
 | ||||
|  | @ -32,16 +31,16 @@ This boilerplate is purposefully simple to show the minimal configuration for Re | |||
| 
 | ||||
| ### Dependencies | ||||
| 
 | ||||
| * React | ||||
| * Webpack | ||||
| * [webpack-dev-server](https://github.com/webpack/webpack-dev-server) | ||||
| * [babel-loader](https://github.com/babel/babel-loader) | ||||
| * [react-hot-loader](https://github.com/gaearon/react-hot-loader) | ||||
| - React | ||||
| - Webpack | ||||
| - [webpack-dev-server](https://github.com/webpack/webpack-dev-server) | ||||
| - [babel-loader](https://github.com/babel/babel-loader) | ||||
| - [react-hot-loader](https://github.com/gaearon/react-hot-loader) | ||||
| 
 | ||||
| ### Resources | ||||
| 
 | ||||
| * [Demo video](http://vimeo.com/100010922) | ||||
| * [react-hot-loader on Github](https://github.com/gaearon/react-hot-loader) | ||||
| * [Integrating JSX live reload into your workflow](http://gaearon.github.io/react-hot-loader/getstarted/) | ||||
| * [Troubleshooting guide](https://github.com/gaearon/react-hot-loader/blob/master/docs/Troubleshooting.md) | ||||
| * Ping dan_abramov on Twitter or #reactjs IRC | ||||
| - [Demo video](http://vimeo.com/100010922) | ||||
| - [react-hot-loader on Github](https://github.com/gaearon/react-hot-loader) | ||||
| - [Integrating JSX live reload into your workflow](http://gaearon.github.io/react-hot-loader/getstarted/) | ||||
| - [Troubleshooting guide](https://github.com/gaearon/react-hot-loader/blob/master/docs/Troubleshooting.md) | ||||
| - Ping dan_abramov on Twitter or #reactjs IRC | ||||
|  |  | |||
|  | @ -10,8 +10,7 @@ | |||
|     </style> | ||||
|   </head> | ||||
|   <body> | ||||
|     <div id='root'> | ||||
|     </div> | ||||
|     <div id="root"></div> | ||||
|     <script src="/static/bundle.js"></script> | ||||
|   </body> | ||||
| </html> | ||||
|  |  | |||
|  | @ -23,7 +23,8 @@ module.exports = { | |||
|     }), | ||||
|     new webpack.HotModuleReplacementPlugin(), | ||||
|     new webpack.NoEmitOnErrorsPlugin(), | ||||
|     isProduction && new webpack.optimize.UglifyJsPlugin({ | ||||
|     isProduction && | ||||
|       new webpack.optimize.UglifyJsPlugin({ | ||||
|         compress: { warnings: false }, | ||||
|         output: { comments: false }, | ||||
|         sourceMap: true | ||||
|  | @ -33,19 +34,22 @@ module.exports = { | |||
|     alias: { | ||||
|       'react-json-tree/lib': path.join(__dirname, '..', 'src'), | ||||
|       'react-json-tree': path.join(__dirname, '..', 'src'), | ||||
|       'react': path.join(__dirname, 'node_modules', 'react') | ||||
|       react: path.join(__dirname, 'node_modules', 'react') | ||||
|     }, | ||||
|     extensions: ['.js'] | ||||
|   }, | ||||
|   module: { | ||||
|     loaders: [{ | ||||
|     loaders: [ | ||||
|       { | ||||
|         test: /\.js$/, | ||||
|         loaders: ['babel-loader'].filter(Boolean), | ||||
|         include: path.join(__dirname, 'src') | ||||
|     }, { | ||||
|       }, | ||||
|       { | ||||
|         test: /\.js$/, | ||||
|         loaders: ['babel-loader'].filter(Boolean), | ||||
|         include: path.join(__dirname, '..', 'src') | ||||
|     }] | ||||
|       } | ||||
|     ] | ||||
|   } | ||||
| }; | ||||
|  |  | |||
|  | @ -22,7 +22,10 @@ | |||
|     "type": "git", | ||||
|     "url": "https://github.com/reduxjs/redux-devtools.git" | ||||
|   }, | ||||
|   "keywords": ["react", "json viewer"], | ||||
|   "keywords": [ | ||||
|     "react", | ||||
|     "json viewer" | ||||
|   ], | ||||
|   "author": "Shu Uesugi <shu@chibicode.com> (http://github.com/chibicode)", | ||||
|   "contributors": [ | ||||
|     "Alexander Kuznetsov <alexkuz@gmail.com> (http://kuzya.org/)", | ||||
|  |  | |||
							
								
								
									
										5
									
								
								packages/react-json-tree/src/JSONNode.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								packages/react-json-tree/src/JSONNode.js
									
									
									
									
										vendored
									
									
								
							|  | @ -86,7 +86,10 @@ const JSONNode = ({ | |||
|       return <JSONValueNode {...simpleNodeProps} />; | ||||
|     default: | ||||
|       return ( | ||||
|         <JSONValueNode {...simpleNodeProps} valueGetter={() => `<${nodeType}>`} /> | ||||
|         <JSONValueNode | ||||
|           {...simpleNodeProps} | ||||
|           valueGetter={() => `<${nodeType}>`} | ||||
|         /> | ||||
|       ); | ||||
|   } | ||||
| }; | ||||
|  |  | |||
							
								
								
									
										3
									
								
								packages/react-json-tree/src/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								packages/react-json-tree/src/index.js
									
									
									
									
										vendored
									
									
								
							|  | @ -117,8 +117,7 @@ export default class JSONTree extends React.Component { | |||
|   } | ||||
| 
 | ||||
|   shouldComponentUpdate(nextProps) { | ||||
|     return !!Object.keys(nextProps).find( | ||||
|       k => | ||||
|     return !!Object.keys(nextProps).find(k => | ||||
|       k === 'keyPath' | ||||
|         ? nextProps[k].join('/') !== this.props[k].join('/') | ||||
|         : nextProps[k] !== this.props[k] | ||||
|  |  | |||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue
	
	Block a user