mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2025-01-31 11:51:41 +03:00
commit
2a3f358002
9
.eslintignore
Normal file
9
.eslintignore
Normal file
|
@ -0,0 +1,9 @@
|
|||
*.log
|
||||
.idea
|
||||
lib
|
||||
dist
|
||||
umd
|
||||
build
|
||||
coverage
|
||||
node_modules
|
||||
__snapshots__
|
34
.eslintrc
Normal file
34
.eslintrc
Normal file
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"parser": "babel-eslint",
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:react/recommended",
|
||||
"prettier"
|
||||
],
|
||||
"globals": {
|
||||
"chrome": true
|
||||
},
|
||||
"env": {
|
||||
"es6": true,
|
||||
"browser": true,
|
||||
"jest": true,
|
||||
"node": true
|
||||
},
|
||||
"rules": {
|
||||
"eol-last": ["warn"],
|
||||
"max-len": ["warn", { "code": 120 , "ignoreComments": true }],
|
||||
"quotes": ["warn", "single", "avoid-escape"],
|
||||
"jsx-quotes": ["warn", "prefer-double"],
|
||||
"react/prop-types": 0
|
||||
},
|
||||
"plugins": [
|
||||
"prettier",
|
||||
"react",
|
||||
"babel"
|
||||
],
|
||||
"settings": {
|
||||
"react": {
|
||||
"version": "detect"
|
||||
}
|
||||
}
|
||||
}
|
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/)
|
||||
|
||||
|
|
14
babel.config.js
Executable file
14
babel.config.js
Executable file
|
@ -0,0 +1,14 @@
|
|||
module.exports = {
|
||||
presets: ['@babel/preset-env', '@babel/preset-react', '@babel/preset-flow'],
|
||||
plugins: [
|
||||
[
|
||||
'@babel/plugin-transform-runtime',
|
||||
{
|
||||
regenerator: true
|
||||
}
|
||||
],
|
||||
['@babel/plugin-proposal-decorators', { legacy: true }],
|
||||
'@babel/plugin-proposal-class-properties',
|
||||
'@babel/plugin-proposal-export-default-from'
|
||||
]
|
||||
};
|
|
@ -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?
|
||||
|
||||
|
|
3
jest.config.js
Normal file
3
jest.config.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
module.exports = {
|
||||
setupFiles: ['devui/tests/setup.js']
|
||||
};
|
|
@ -8,9 +8,5 @@
|
|||
"allowBranch": "master"
|
||||
}
|
||||
},
|
||||
"ignoreChanges": [
|
||||
"**/test/**",
|
||||
"**/examples/**",
|
||||
"**/*.md"
|
||||
]
|
||||
"ignoreChanges": ["**/test/**", "**/examples/**", "**/*.md"]
|
||||
}
|
||||
|
|
41
package.json
41
package.json
|
@ -2,10 +2,15 @@
|
|||
"private": true,
|
||||
"devDependencies": {
|
||||
"babel-eslint": "^10.0.0",
|
||||
"eslint-plugin-react": "7.4.0",
|
||||
"eslint-plugin-flowtype": "3.2.0",
|
||||
"lerna": "3.4.2",
|
||||
"pre-commit": "^1.1.3"
|
||||
"eslint": "^5.12.0",
|
||||
"eslint-config-prettier": "^3.3.0",
|
||||
"eslint-plugin-babel": "^5.3.0",
|
||||
"eslint-plugin-prettier": "^3.0.1",
|
||||
"eslint-plugin-react": "7.12.3",
|
||||
"jest": "^24.1.0",
|
||||
"lerna": "3.9.0",
|
||||
"lint-staged": "^8.1.0",
|
||||
"prettier": "^1.15.3"
|
||||
},
|
||||
"scripts": {
|
||||
"lerna": "lerna",
|
||||
|
@ -14,15 +19,29 @@
|
|||
"publish": "lerna publish",
|
||||
"canary": "lerna publish --canary preminor --npm-tag alpha",
|
||||
"next": "lerna publish --bump prerelease --npm-tag next",
|
||||
"lint": "lerna run lint --since master -- --color",
|
||||
"lint:all": "lerna run lint -- --color",
|
||||
"test": "lerna run test --since master -- --colors",
|
||||
"test:all": "lerna run test -- --colors"
|
||||
"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"
|
||||
]
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{js,jsx}": [
|
||||
"prettier --single-quote --write",
|
||||
"yarn lint:fix",
|
||||
"git add"
|
||||
],
|
||||
"*.{json,css,html,md}": [
|
||||
"prettier --single-quote --write",
|
||||
"git add"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
{
|
||||
"presets": ["es2015-loose", "stage-0"]
|
||||
"presets": ["@babel/preset-env"]
|
||||
}
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
lib
|
||||
**/node_modules
|
||||
**/webpack.config.js
|
||||
examples/**/server.js
|
|
@ -1,16 +0,0 @@
|
|||
{
|
||||
"extends": "eslint-config-airbnb",
|
||||
"env": {
|
||||
"browser": true,
|
||||
"mocha": true,
|
||||
"node": true
|
||||
},
|
||||
"rules": {
|
||||
"react/jsx-uses-react": 2,
|
||||
"react/jsx-uses-vars": 2,
|
||||
"react/react-in-jsx-scope": 2
|
||||
},
|
||||
"plugins": [
|
||||
"react"
|
||||
]
|
||||
}
|
|
@ -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 |
|
||||
|
|
|
@ -5,15 +5,13 @@
|
|||
"main": "lib/index.js",
|
||||
"scripts": {
|
||||
"clean": "rimraf lib dist",
|
||||
"lint": "eslint src",
|
||||
"build": "npm run build:lib && npm run build:umd && npm run build:umd:min",
|
||||
"build:lib": "babel src --out-dir lib",
|
||||
"build:umd": "webpack src/index.js dist/d3tooltip.js --config webpack.config.development.js",
|
||||
"build:umd:min": "webpack src/index.js dist/d3tooltip.min.js --config webpack.config.production.js",
|
||||
"build": "babel src --out-dir lib",
|
||||
"build:umd": "webpack --progress --config webpack.config.umd.js",
|
||||
"build:umd:min": "webpack --env.minimize --progress --config webpack.config.umd.js",
|
||||
"version": "npm run build",
|
||||
"postversion": "git push && git push --tags && npm run clean",
|
||||
"prepare": "npm run clean && npm run build",
|
||||
"prepublishOnly": "npm run lint && npm run clean && npm run build"
|
||||
"prepublishOnly": "npm run clean && npm run build && npm run build:umd && npm run build:umd:min"
|
||||
},
|
||||
"files": [
|
||||
"lib",
|
||||
|
@ -35,18 +33,13 @@
|
|||
},
|
||||
"homepage": "https://github.com/reduxjs/redux-devtools",
|
||||
"devDependencies": {
|
||||
"babel-cli": "^6.3.15",
|
||||
"babel-core": "^6.1.20",
|
||||
"babel-eslint": "^5.0.0-beta4",
|
||||
"babel-loader": "^6.2.0",
|
||||
"babel-preset-es2015-loose": "^6.1.3",
|
||||
"babel-preset-react": "^6.3.13",
|
||||
"babel-preset-stage-0": "^6.3.13",
|
||||
"eslint": "^0.24",
|
||||
"eslint-config-airbnb": "0.0.6",
|
||||
"eslint-plugin-react": "^3.6.3",
|
||||
"@babel/cli": "^7.2.3",
|
||||
"@babel/core": "^7.2.2",
|
||||
"@babel/preset-env": "^7.3.1",
|
||||
"babel-loader": "^8.0.5",
|
||||
"rimraf": "^2.3.4",
|
||||
"webpack": "^1.9.6"
|
||||
"webpack": "^4.27.1",
|
||||
"webpack-cli": "^3.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ramda": "^0.17.1"
|
||||
|
|
28
packages/d3tooltip/src/index.js
vendored
28
packages/d3tooltip/src/index.js
vendored
|
@ -5,19 +5,14 @@ const { prependClass, functor } = utils.default || utils;
|
|||
const defaultOptions = {
|
||||
left: undefined, // mouseX
|
||||
top: undefined, // mouseY
|
||||
offset: {left: 0, top: 0},
|
||||
offset: { left: 0, top: 0 },
|
||||
root: undefined
|
||||
};
|
||||
|
||||
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({
|
||||
left: x + 'px',
|
||||
top: y + 'px'
|
||||
})
|
||||
.html(() => text(node));
|
||||
el.style({
|
||||
left: x + 'px',
|
||||
top: y + 'px'
|
||||
}).html(() => text(node));
|
||||
},
|
||||
|
||||
'mouseout.tip': () => el.remove()
|
||||
|
@ -63,14 +57,14 @@ export default function tooltip(d3, className = 'tooltip', options = {}) {
|
|||
|
||||
tip.attr = function setAttr(d) {
|
||||
if (is(Object, d)) {
|
||||
attrs = {...attrs, ...d};
|
||||
attrs = { ...attrs, ...d };
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
tip.style = function setStyle(d) {
|
||||
if (is(Object, d)) {
|
||||
styles = {...styles, ...d};
|
||||
styles = { ...styles, ...d };
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
module: {
|
||||
loaders: [
|
||||
{ test: /\.js$/, loaders: ['babel-loader'], exclude: /node_modules/ }
|
||||
]
|
||||
},
|
||||
output: {
|
||||
library: 'd3tooltip',
|
||||
libraryTarget: 'umd'
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['', '.js']
|
||||
}
|
||||
};
|
|
@ -1,14 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
var webpack = require('webpack');
|
||||
var baseConfig = require('./webpack.config.base');
|
||||
|
||||
var config = Object.create(baseConfig);
|
||||
config.plugins = [
|
||||
new webpack.optimize.OccurenceOrderPlugin(),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.NODE_ENV': JSON.stringify('development')
|
||||
})
|
||||
];
|
||||
|
||||
module.exports = config;
|
|
@ -1,20 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
var webpack = require('webpack');
|
||||
var baseConfig = require('./webpack.config.base');
|
||||
|
||||
var config = Object.create(baseConfig);
|
||||
config.plugins = [
|
||||
new webpack.optimize.OccurenceOrderPlugin(),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.NODE_ENV': JSON.stringify('production')
|
||||
}),
|
||||
new webpack.optimize.UglifyJsPlugin({
|
||||
compressor: {
|
||||
screw_ie8: true,
|
||||
warnings: false
|
||||
}
|
||||
})
|
||||
];
|
||||
|
||||
module.exports = config;
|
29
packages/d3tooltip/webpack.config.umd.js
Normal file
29
packages/d3tooltip/webpack.config.umd.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
const path = require('path');
|
||||
|
||||
module.exports = (env = {}) => ({
|
||||
mode: 'production',
|
||||
entry: {
|
||||
app: ['./src/index.js']
|
||||
},
|
||||
output: {
|
||||
library: 'd3tooltip',
|
||||
libraryTarget: 'umd',
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
filename: env.minimize ? 'd3tooltip.min.js' : 'd3tooltip.js'
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
loader: 'babel-loader',
|
||||
exclude: /node_modules/
|
||||
}
|
||||
]
|
||||
},
|
||||
optimization: {
|
||||
minimize: !!env.minimize
|
||||
},
|
||||
performance: {
|
||||
hints: false
|
||||
}
|
||||
});
|
|
@ -1,3 +1,4 @@
|
|||
{
|
||||
"presets": ["es2015", "stage-0", "react"]
|
||||
"presets": ["@babel/preset-env", "@babel/preset-react"],
|
||||
"plugins": ["@babel/plugin-proposal-class-properties", "@babel/plugin-proposal-export-default-from"]
|
||||
}
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
{
|
||||
"extends": "airbnb",
|
||||
"rules": {
|
||||
"arrow-body-style": 0,
|
||||
"prefer-arrow-callback": 0,
|
||||
"func-names": 0,
|
||||
"comma-dangle": ["error", "never"],
|
||||
"newline-per-chained-call": 0,
|
||||
"react/sort-comp": 0,
|
||||
"react/jsx-no-bind": 0,
|
||||
"react/jsx-uses-react": 1,
|
||||
"react/prefer-stateless-function": 0
|
||||
},
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true,
|
||||
"jest": true
|
||||
},
|
||||
"parser": "babel-eslint"
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
// IMPORTANT
|
||||
// ---------
|
||||
// This is an auto generated file with React CDK.
|
||||
// Do not modify this file.
|
||||
// Use `.scripts/user/pretest.js instead`.
|
||||
|
||||
require('babel-core/register');
|
||||
require('babel-polyfill');
|
||||
|
||||
// Add jsdom support, which is required for enzyme.
|
||||
var jsdom = require('jsdom').jsdom;
|
||||
|
||||
var exposedProperties = ['window', 'navigator', 'document'];
|
||||
|
||||
global.document = jsdom('');
|
||||
global.window = document.defaultView;
|
||||
Object.keys(document.defaultView).forEach((property) => {
|
||||
if (typeof global[property] === 'undefined') {
|
||||
exposedProperties.push(property);
|
||||
global[property] = document.defaultView[property];
|
||||
}
|
||||
});
|
||||
|
||||
global.navigator = {
|
||||
userAgent: 'node.js'
|
||||
};
|
||||
|
||||
process.on('unhandledRejection', function (error) {
|
||||
console.error('Unhandled Promise Rejection:');
|
||||
console.error(error && error.stack || error);
|
||||
});
|
||||
|
||||
require('./user/pretest.js');
|
|
@ -1,23 +1,25 @@
|
|||
import { configure, setAddon, addDecorator } from '@storybook/react';
|
||||
import { setOptions } from '@storybook/addon-options';
|
||||
import infoAddon from '@storybook/addon-info';
|
||||
import { withOptions } from '@storybook/addon-options';
|
||||
import { withInfo } from '@storybook/addon-info';
|
||||
import { withKnobs } from '@storybook/addon-knobs';
|
||||
import { withTheme } from './themeAddon/theme';
|
||||
import '../src/presets.js';
|
||||
|
||||
setAddon(infoAddon);
|
||||
setOptions({
|
||||
name: 'DevUI',
|
||||
url: 'https://github.com/reduxjs/redux-devtools/tree/master/packages/devui',
|
||||
goFullScreen: false,
|
||||
showLeftPanel: true,
|
||||
showDownPanel: true,
|
||||
showSearchBox: false,
|
||||
downPanelInRight: true
|
||||
});
|
||||
addDecorator(
|
||||
withOptions({
|
||||
name: 'DevUI',
|
||||
url: 'https://github.com/reduxjs/redux-devtools/tree/master/packages/devui',
|
||||
goFullScreen: false,
|
||||
showStoriesPanel: true,
|
||||
showAddonPanel: true,
|
||||
showSearchBox: false,
|
||||
addonPanelInRight: true
|
||||
})
|
||||
);
|
||||
|
||||
addDecorator(withTheme);
|
||||
addDecorator(withKnobs);
|
||||
addDecorator(withInfo);
|
||||
|
||||
const req = require.context('../src/', true, /stories\/index\.js$/);
|
||||
|
||||
|
|
|
@ -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 > div > div {
|
||||
#root,
|
||||
#root > div {
|
||||
height: 100%;
|
||||
}
|
||||
#root > div > div {
|
||||
|
@ -22,5 +23,6 @@
|
|||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -25,6 +25,8 @@ export default class Panel extends React.Component {
|
|||
this.setState(state);
|
||||
};
|
||||
|
||||
onClick = () => {};
|
||||
|
||||
render() {
|
||||
const { theme, scheme, light } = this.state;
|
||||
return (
|
||||
|
@ -50,6 +52,7 @@ export default class Panel extends React.Component {
|
|||
}
|
||||
]}
|
||||
onFieldChange={this.onChange}
|
||||
onFieldClick={this.onClick}
|
||||
/>
|
||||
</FormWrapper>
|
||||
);
|
||||
|
|
|
@ -7,6 +7,7 @@ addons.register(ADDON_ID, api => {
|
|||
const channel = addons.getChannel();
|
||||
addons.addPanel(PANEL_ID, {
|
||||
title: 'Theme',
|
||||
render: () => <Panel channel={channel} api={api} />
|
||||
render: ({ active }) =>
|
||||
active ? <Panel channel={channel} api={api} /> : null
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,22 +1,8 @@
|
|||
import React from 'react';
|
||||
import addons from '@storybook/addons';
|
||||
import styled from 'styled-components';
|
||||
import { EVENT_ID_DATA, DEFAULT_THEME_STATE } from './constant';
|
||||
import { Container } from '../../src';
|
||||
|
||||
const ContainerStyled = styled(Container)`
|
||||
> div {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
> div {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const channel = addons.getChannel();
|
||||
|
||||
class Theme extends React.Component {
|
||||
|
@ -35,7 +21,7 @@ class Theme extends React.Component {
|
|||
};
|
||||
|
||||
render() {
|
||||
return <ContainerStyled themeData={this.state}>{this.props.children}</ContainerStyled>;
|
||||
return <Container themeData={this.state}>{this.props.children}</Container>;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
module.exports = function (config) {
|
||||
// This is the default webpack config defined in the `../webpack.config.js`
|
||||
// modify as you need.
|
||||
};
|
|
@ -1,26 +1,8 @@
|
|||
const path = require('path');
|
||||
const updateConfig = require('./user/modify_webpack_config');
|
||||
|
||||
const config = {
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.css?$/,
|
||||
use: [{ loader: 'style-loader' }, { loader: 'raw-loader' }],
|
||||
include: path.resolve(__dirname, '../')
|
||||
},
|
||||
{
|
||||
test: /\.json?$/,
|
||||
loader: 'json-loader',
|
||||
include: path.resolve(__dirname, '../')
|
||||
},
|
||||
{
|
||||
test: /\.woff2?(\?\S*)?$/,
|
||||
loader: 'url?limit=65000&mimetype=application/font-woff'
|
||||
}
|
||||
]
|
||||
}
|
||||
module.exports = (baseConfig, env, defaultConfig) => {
|
||||
// Add custom webpack config here like:
|
||||
// defaultConfig.module.rules.push
|
||||
|
||||
return defaultConfig;
|
||||
};
|
||||
|
||||
updateConfig(config);
|
||||
module.exports = config;
|
||||
|
|
|
@ -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 */
|
||||
|
@ -29,7 +32,7 @@
|
|||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Roboto'), local('Roboto-Regular'),
|
||||
url('./roboto-v15-latin/roboto-v15-latin-regular.woff2') format('woff2');
|
||||
url('./roboto-v15-latin/roboto-v15-latin-regular.woff2') format('woff2');
|
||||
}
|
||||
/* roboto-mono-regular - latin */
|
||||
@font-face {
|
||||
|
@ -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,78 +1,60 @@
|
|||
{
|
||||
"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",
|
||||
"build": "rimraf ./lib && babel ./src --out-dir ./lib --ignore tests,stories",
|
||||
"lint": "eslint src",
|
||||
"lintfix": "eslint src --fix",
|
||||
"lint:css": "stylelint './src/**/styles/*.js'",
|
||||
"format": "prettier-eslint --write ./src/**/*.js",
|
||||
"test:update": "npm run jest -- -u",
|
||||
"test": "jest --no-cache",
|
||||
"storybook": "start-storybook -p 9001 -c .storybook -s ./fonts",
|
||||
"publish-storybook": "bash .scripts/publish_storybook.sh",
|
||||
"prepare": "npm run build",
|
||||
"prepublishOnly": "npm run lint && npm run test && npm run build"
|
||||
"prepublishOnly": "npm run test && npm run build"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/reduxjs/redux-devtools/issues"
|
||||
},
|
||||
"homepage": "https://github.com/reduxjs/redux-devtools",
|
||||
"devDependencies": {
|
||||
"@storybook/addon-actions": "^3.2.13",
|
||||
"@storybook/addon-info": "^3.2.13",
|
||||
"@storybook/addon-knobs": "^3.2.13",
|
||||
"@storybook/addon-options": "^3.2.13",
|
||||
"@storybook/react": "^3.2.13",
|
||||
"babel-cli": "^6.26.0",
|
||||
"babel-core": "^6.26.0",
|
||||
"babel-eslint": "^6.0.2",
|
||||
"babel-jest": "^21.2.0",
|
||||
"babel-loader": "^7.1.2",
|
||||
"babel-plugin-transform-runtime": "^6.23.0",
|
||||
"babel-polyfill": "^6.26.0",
|
||||
"babel-preset-es2015": "^6.24.1",
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"babel-preset-stage-0": "^6.16.0",
|
||||
"css-loader": "^0.28.7",
|
||||
"@babel/cli": "^7.2.3",
|
||||
"@babel/core": "^7.2.2",
|
||||
"@babel/plugin-proposal-class-properties": "^7.3.0",
|
||||
"@babel/plugin-proposal-decorators": "^7.3.0",
|
||||
"@babel/plugin-proposal-export-default-from": "^7.2.0",
|
||||
"@babel/plugin-transform-runtime": "^7.2.0",
|
||||
"@babel/preset-env": "^7.3.1",
|
||||
"@babel/preset-react": "^7.0.0",
|
||||
"@storybook/addon-actions": "^4.1.4",
|
||||
"@storybook/addon-info": "^4.1.4",
|
||||
"@storybook/addon-knobs": "^4.1.4",
|
||||
"@storybook/addon-options": "^4.1.4",
|
||||
"@storybook/react": "4.0.9",
|
||||
"enzyme": "^3.1.0",
|
||||
"enzyme-adapter-react-16": "^1.0.2",
|
||||
"enzyme-to-json": "^3.1.4",
|
||||
"eslint": "^2.7.0",
|
||||
"eslint-config-airbnb": "^7.0.0",
|
||||
"eslint-plugin-babel": "^3.2.0",
|
||||
"eslint-plugin-jsx-a11y": "^0.6.2",
|
||||
"eslint-plugin-react": "^4.3.0",
|
||||
"file-loader": "^1.1.5",
|
||||
"git-url-parse": "^7.0.1",
|
||||
"jest": "^21.2.1",
|
||||
"jest": "^24.1.0",
|
||||
"jsdom": "^11.3.0",
|
||||
"node-sass": "^3.13.0",
|
||||
"postcss-loader": "^2.0.8",
|
||||
"prettier-eslint-cli": "^4.4.0",
|
||||
"raw-loader": "^0.5.1",
|
||||
"react": "^16.0.0",
|
||||
"react-addons-test-utils": "^15.6.2",
|
||||
"react-dom": "^16.0.0",
|
||||
"react-test-renderer": "^16.0.0",
|
||||
"rimraf": "^2.6.2",
|
||||
"sass-loader": "^4.0.2",
|
||||
"style-loader": "^0.19.0",
|
||||
"stylelint": "^7.6.0",
|
||||
"stylelint-config-standard": "^15.0.0",
|
||||
"stylelint-processor-styled-components": "^0.0.4",
|
||||
"url-loader": "^0.6.2"
|
||||
"stylelint-processor-styled-components": "^0.0.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^0.14.9 || ^15.3.0"
|
||||
|
|
|
@ -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,46 +16,62 @@ export const Container = styled.div`
|
|||
|
||||
storiesOf('Button', module)
|
||||
.addDecorator(withKnobs)
|
||||
.addWithInfo(
|
||||
'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'])
|
||||
}
|
||||
primary={boolean('primary', true)}
|
||||
size={select('size', ['big', 'normal', 'small'], 'normal')}
|
||||
disabled={boolean('Disabled', false)}
|
||||
onClick={action('button clicked')}
|
||||
>
|
||||
{text('Label', 'Hello Button')}
|
||||
</Button>
|
||||
</Container>
|
||||
)
|
||||
)
|
||||
.addWithInfo(
|
||||
'mark',
|
||||
'',
|
||||
() => (
|
||||
<Container>
|
||||
<Button
|
||||
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'])
|
||||
}
|
||||
size={select('size', ['big', 'normal', 'small'], 'normal')}
|
||||
disabled={boolean('Disabled', false)}
|
||||
onClick={action('button clicked')}
|
||||
>
|
||||
<MdFiberManualRecord />
|
||||
</Button>
|
||||
</Container>
|
||||
)
|
||||
);
|
||||
.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'
|
||||
])}
|
||||
primary={boolean('primary', true)}
|
||||
size={select('size', ['big', 'normal', 'small'], 'normal')}
|
||||
disabled={boolean('Disabled', false)}
|
||||
onClick={action('button clicked')}
|
||||
>
|
||||
{text('Label', 'Hello Button')}
|
||||
</Button>
|
||||
</Container>
|
||||
))
|
||||
.add('mark', () => (
|
||||
<Container>
|
||||
<Button
|
||||
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'
|
||||
])}
|
||||
size={select('size', ['big', 'normal', 'small'], 'normal')}
|
||||
disabled={boolean('Disabled', false)}
|
||||
onClick={action('button clicked')}
|
||||
>
|
||||
<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,15 +10,23 @@ export const MainContainerWrapper = styled.div`
|
|||
color: ${props => props.theme.base07};
|
||||
font-size: 12px;
|
||||
|
||||
div, input, textarea, keygen, select, button {
|
||||
font-family: ${props => props.theme.fontFamily || 'monaco, monospace'};
|
||||
}
|
||||
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 {
|
||||
.monitor {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
|
|
|
@ -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,18 +16,14 @@ export const Container = styled.div`
|
|||
|
||||
storiesOf('ContextMenu', module)
|
||||
.addDecorator(withKnobs)
|
||||
.addWithInfo(
|
||||
'default',
|
||||
'',
|
||||
() => (
|
||||
<Container>
|
||||
<ContextMenu
|
||||
visible
|
||||
onClick={action('menu item clicked')}
|
||||
x={number('x', 100)}
|
||||
y={number('y', 100)}
|
||||
items={items}
|
||||
/>
|
||||
</Container>
|
||||
)
|
||||
);
|
||||
.add('default', () => (
|
||||
<Container>
|
||||
<ContextMenu
|
||||
visible
|
||||
onClick={action('menu item clicked')}
|
||||
x={number('x', 100)}
|
||||
y={number('y', 100)}
|
||||
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;
|
||||
|
@ -36,7 +38,7 @@ export default ({ theme, left, top, visible }) => css`
|
|||
color: ${theme.base07};
|
||||
}
|
||||
&:focus {
|
||||
outline:0;
|
||||
outline: 0;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
|
|
@ -52,47 +52,47 @@ export default class Dialog extends (PureComponent || Component) {
|
|||
{!noHeader && (
|
||||
<div className="mc-dialog--header">
|
||||
<div>{schema ? schema.title || title : title}</div>
|
||||
{!modal && <button onClick={onDismiss}>×</button>}
|
||||
{!modal && <button onClick={onDismiss}>×</button>}
|
||||
</div>
|
||||
)}
|
||||
<div className="mc-dialog--body">
|
||||
{children}
|
||||
{schema && (
|
||||
<Form {...rest}>
|
||||
{!noFooter &&
|
||||
(
|
||||
{!noFooter && (
|
||||
<input
|
||||
type="submit"
|
||||
ref={this.getFormButtonRef}
|
||||
className="mc-dialog--hidden"
|
||||
/>
|
||||
)
|
||||
}
|
||||
)}
|
||||
</Form>
|
||||
)}
|
||||
</div>
|
||||
{
|
||||
!noFooter &&
|
||||
(actions ?
|
||||
<div className="mc-dialog--footer">
|
||||
{submitText ?
|
||||
[...actions,
|
||||
<Button key="default-submit" primary onClick={this.onSubmit}>
|
||||
{!noFooter &&
|
||||
(actions ? (
|
||||
<div className="mc-dialog--footer">
|
||||
{submitText
|
||||
? [
|
||||
...actions,
|
||||
<Button
|
||||
key="default-submit"
|
||||
primary
|
||||
onClick={this.onSubmit}
|
||||
>
|
||||
{submitText}
|
||||
</Button>
|
||||
]
|
||||
: actions
|
||||
}
|
||||
</div>
|
||||
:
|
||||
<div className="mc-dialog--footer">
|
||||
<Button onClick={onDismiss}>Cancel</Button>
|
||||
<Button primary onClick={this.onSubmit}>
|
||||
{submitText || 'Submit'}
|
||||
</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
: actions}
|
||||
</div>
|
||||
) : (
|
||||
<div className="mc-dialog--footer">
|
||||
<Button onClick={onDismiss}>Cancel</Button>
|
||||
<Button primary onClick={this.onSubmit}>
|
||||
{submitText || 'Submit'}
|
||||
</Button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</DialogWrapper>
|
||||
);
|
||||
|
|
|
@ -7,40 +7,33 @@ import { schema, uiSchema, formData } from '../../Form/stories/schema';
|
|||
|
||||
storiesOf('Dialog', module)
|
||||
.addDecorator(withKnobs)
|
||||
.addWithInfo(
|
||||
'default',
|
||||
'',
|
||||
() => (
|
||||
<Dialog
|
||||
title={text('title', 'Dialog Title')}
|
||||
children={text('children', 'Hello Dialog!')}
|
||||
submitText={text('submitText', 'Submit!')}
|
||||
open={boolean('open', true)}
|
||||
noHeader={boolean('noHeader', false)}
|
||||
noFooter={boolean('noFooter', false)}
|
||||
modal={boolean('modal', false)}
|
||||
fullWidth={boolean('fullWidth', false)}
|
||||
onDismiss={action('dialog dismissed')}
|
||||
onSubmit={action('dialog submitted')}
|
||||
/>
|
||||
)
|
||||
)
|
||||
.addWithInfo(
|
||||
'with form',
|
||||
'',
|
||||
() => (
|
||||
<Dialog
|
||||
open={boolean('open', true)}
|
||||
noHeader={boolean('noHeader', false)}
|
||||
noFooter={boolean('noFooter', false)}
|
||||
fullWidth={boolean('fullWidth', false)}
|
||||
submitText={text('submitText', 'Submit!')}
|
||||
formData={object('formData', formData)}
|
||||
schema={object('schema', schema)}
|
||||
uiSchema={object('uiSchema', uiSchema)}
|
||||
onChange={action('form changed')}
|
||||
onSubmit={action('form submitted')}
|
||||
onDismiss={action('dialog dismissed')}
|
||||
/>
|
||||
)
|
||||
);
|
||||
.add('default', () => (
|
||||
<Dialog
|
||||
title={text('title', 'Dialog Title')}
|
||||
submitText={text('submitText', 'Submit!')}
|
||||
open={boolean('open', true)}
|
||||
noHeader={boolean('noHeader', false)}
|
||||
noFooter={boolean('noFooter', false)}
|
||||
modal={boolean('modal', false)}
|
||||
fullWidth={boolean('fullWidth', false)}
|
||||
onDismiss={action('dialog dismissed')}
|
||||
onSubmit={action('dialog submitted')}
|
||||
>
|
||||
{text('children', 'Hello Dialog!')}
|
||||
</Dialog>
|
||||
))
|
||||
.add('with form', () => (
|
||||
<Dialog
|
||||
open={boolean('open', true)}
|
||||
noHeader={boolean('noHeader', false)}
|
||||
noFooter={boolean('noFooter', false)}
|
||||
fullWidth={boolean('fullWidth', false)}
|
||||
submitText={text('submitText', 'Submit!')}
|
||||
formData={object('formData', formData)}
|
||||
schema={object('schema', schema)}
|
||||
uiSchema={object('uiSchema', uiSchema)}
|
||||
onChange={action('form changed')}
|
||||
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,28 +4,27 @@ 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,
|
||||
{
|
||||
value: this.props.value,
|
||||
mode: this.props.mode,
|
||||
lineNumbers: this.props.lineNumbers,
|
||||
lineWrapping: this.props.lineWrapping,
|
||||
readOnly: this.props.readOnly,
|
||||
autofocus: this.props.autofocus,
|
||||
foldGutter: this.props.foldGutter,
|
||||
gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter']
|
||||
}
|
||||
);
|
||||
this.cm = CodeMirror(this.node, {
|
||||
value: this.props.value,
|
||||
mode: this.props.mode,
|
||||
lineNumbers: this.props.lineNumbers,
|
||||
lineWrapping: this.props.lineWrapping,
|
||||
readOnly: this.props.readOnly,
|
||||
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')}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -15,9 +15,8 @@ function getThemes() {
|
|||
|
||||
storiesOf('Editor', module)
|
||||
.addDecorator(withKnobs)
|
||||
.addWithInfo(
|
||||
.add(
|
||||
'default',
|
||||
'Based on [CodeMirror](http://codemirror.net/).',
|
||||
() => (
|
||||
<Editor
|
||||
value={text('value', value)}
|
||||
|
@ -28,14 +27,9 @@ storiesOf('Editor', module)
|
|||
onChange={action('change')}
|
||||
autofocus
|
||||
/>
|
||||
)
|
||||
),
|
||||
{ info: 'Based on [CodeMirror](http://codemirror.net/).' }
|
||||
)
|
||||
.addWithInfo(
|
||||
'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">
|
||||
{submitText || 'Submit'}
|
||||
</Button>
|
||||
}
|
||||
{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])
|
||||
)
|
||||
};
|
||||
|
|
|
@ -7,9 +7,8 @@ import { schema, uiSchema, formData } from './schema';
|
|||
|
||||
storiesOf('Form', module)
|
||||
.addDecorator(withKnobs)
|
||||
.addWithInfo(
|
||||
.add(
|
||||
'default',
|
||||
'Wrapper around [`react-jsonschema-form`](https://github.com/mozilla-services/react-jsonschema-form) with custom widgets.',
|
||||
() => (
|
||||
<Form
|
||||
formData={object('formData', formData)}
|
||||
|
@ -19,5 +18,10 @@ storiesOf('Form', module)
|
|||
onChange={action('form changed')}
|
||||
onSubmit={action('form submitted')}
|
||||
/>
|
||||
)
|
||||
),
|
||||
{
|
||||
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',
|
||||
|
|
|
@ -1,368 +1,368 @@
|
|||
import { css } from 'styled-components';
|
||||
|
||||
export default ({ theme }) => css`
|
||||
padding: 10px;
|
||||
line-height: 1.846;
|
||||
font-size: 14px;
|
||||
color: ${theme.base06};
|
||||
padding: 10px;
|
||||
line-height: 1.846;
|
||||
font-size: 14px;
|
||||
color: ${theme.base06};
|
||||
|
||||
fieldset {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
min-width: 0;
|
||||
}
|
||||
fieldset {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
legend {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
font-size: 20px;
|
||||
color: ${theme.base04};
|
||||
border: 0;
|
||||
}
|
||||
legend {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
font-size: 20px;
|
||||
color: ${theme.base04};
|
||||
border: 0;
|
||||
}
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
font-weight: bold;
|
||||
}
|
||||
label {
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
font-size: 12px;
|
||||
width: 100%;
|
||||
color: ${theme.base05};
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
line-height: ${theme.inputInternalHeight}px;
|
||||
padding: 0 ${theme.inputPadding}px;
|
||||
border-style: solid;
|
||||
border-width: ${theme.inputBorderWidth}px;
|
||||
border-color: ${theme.inputBorderColor};
|
||||
border-radius: ${theme.inputBorderRadius}px;
|
||||
}
|
||||
.form-control {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
font-size: 12px;
|
||||
width: 100%;
|
||||
color: ${theme.base05};
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
line-height: ${theme.inputInternalHeight}px;
|
||||
padding: 0 ${theme.inputPadding}px;
|
||||
border-style: solid;
|
||||
border-width: ${theme.inputBorderWidth}px;
|
||||
border-color: ${theme.inputBorderColor};
|
||||
border-radius: ${theme.inputBorderRadius}px;
|
||||
}
|
||||
|
||||
.form-control:focus,
|
||||
input.form-control:focus {
|
||||
outline: 0;
|
||||
${theme.inputFocusedStyle}
|
||||
}
|
||||
.form-control:focus,
|
||||
input.form-control:focus {
|
||||
outline: 0;
|
||||
${theme.inputFocusedStyle}
|
||||
}
|
||||
|
||||
.form-control[disabled],
|
||||
.form-control[readonly],
|
||||
fieldset[disabled] .form-control {
|
||||
background-color: transparent;
|
||||
opacity: 1;
|
||||
}
|
||||
.form-control[disabled],
|
||||
.form-control[readonly],
|
||||
fieldset[disabled] .form-control {
|
||||
background-color: transparent;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.form-control[disabled],
|
||||
fieldset[disabled] .form-control {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.form-control[disabled],
|
||||
fieldset[disabled] .form-control {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
textarea.form-control {
|
||||
height: auto;
|
||||
}
|
||||
textarea.form-control {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.form-group {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.radio,
|
||||
.checkbox {
|
||||
position: relative;
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.radio,
|
||||
.checkbox {
|
||||
position: relative;
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.radio label,
|
||||
.checkbox label {
|
||||
min-height: 23px;
|
||||
padding-left: 20px;
|
||||
margin-bottom: 0;
|
||||
font-weight: normal;
|
||||
cursor: pointer;
|
||||
}
|
||||
.radio label,
|
||||
.checkbox label {
|
||||
min-height: 23px;
|
||||
padding-left: 20px;
|
||||
margin-bottom: 0;
|
||||
font-weight: normal;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
.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;
|
||||
}
|
||||
|
||||
.radio + .radio,
|
||||
.checkbox + .checkbox {
|
||||
margin-top: -5px;
|
||||
}
|
||||
.radio + .radio,
|
||||
.checkbox + .checkbox {
|
||||
margin-top: -5px;
|
||||
}
|
||||
|
||||
.radio-inline,
|
||||
.checkbox-inline {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
padding-left: 25px;
|
||||
margin-bottom: 0;
|
||||
vertical-align: middle;
|
||||
font-weight: normal;
|
||||
cursor: pointer;
|
||||
}
|
||||
.radio-inline,
|
||||
.checkbox-inline {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
padding-left: 25px;
|
||||
margin-bottom: 0;
|
||||
vertical-align: middle;
|
||||
font-weight: normal;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.radio-inline + .radio-inline,
|
||||
.checkbox-inline + .checkbox-inline {
|
||||
margin-top: 0;
|
||||
margin-left: 10px;
|
||||
}
|
||||
.radio-inline + .radio-inline,
|
||||
.checkbox-inline + .checkbox-inline {
|
||||
margin-top: 0;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.radio label,
|
||||
.radio-inline label,
|
||||
.checkbox label,
|
||||
.checkbox-inline label {
|
||||
padding-left: 25px;
|
||||
}
|
||||
.radio label,
|
||||
.radio-inline label,
|
||||
.checkbox label,
|
||||
.checkbox-inline label {
|
||||
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"] {
|
||||
margin-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'] {
|
||||
margin-left: -25px;
|
||||
}
|
||||
|
||||
input[type="radio"],
|
||||
.radio input[type="radio"],
|
||||
.radio-inline input[type="radio"] {
|
||||
position: relative;
|
||||
margin-top: 6px;
|
||||
margin-right: 4px;
|
||||
vertical-align: top;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
appearance: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
input[type='radio'],
|
||||
.radio input[type='radio'],
|
||||
.radio-inline input[type='radio'] {
|
||||
position: relative;
|
||||
margin-top: 6px;
|
||||
margin-right: 4px;
|
||||
vertical-align: top;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
appearance: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input[type="radio"]:focus,
|
||||
.radio input[type="radio"]:focus,
|
||||
.radio-inline input[type="radio"]:focus {
|
||||
outline: none;
|
||||
}
|
||||
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: "";
|
||||
display: block;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 50%;
|
||||
transition: 240ms;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
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;
|
||||
border-radius: 50%;
|
||||
transition: 240ms;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
input[type="radio"]:before,
|
||||
.radio input[type="radio"]:before,
|
||||
.radio-inline input[type="radio"]:before {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: -3px;
|
||||
background-color: ${theme.base0D};
|
||||
transform: scale(0);
|
||||
}
|
||||
input[type='radio']:before,
|
||||
.radio input[type='radio']:before,
|
||||
.radio-inline input[type='radio']:before {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: -3px;
|
||||
background-color: ${theme.base0D};
|
||||
transform: scale(0);
|
||||
}
|
||||
|
||||
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']: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 {
|
||||
transform: scale(0.5);
|
||||
}
|
||||
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 {
|
||||
background-color: ${theme.base03};
|
||||
}
|
||||
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 {
|
||||
border-color: ${theme.base0D};
|
||||
}
|
||||
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 {
|
||||
border-color: ${theme.base03};
|
||||
}
|
||||
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"] {
|
||||
position: relative;
|
||||
border: none;
|
||||
margin-bottom: -4px;
|
||||
appearance: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
input[type='checkbox'],
|
||||
.checkbox input[type='checkbox'],
|
||||
.checkbox-inline input[type='checkbox'] {
|
||||
position: relative;
|
||||
border: none;
|
||||
margin-bottom: -4px;
|
||||
appearance: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input[type="checkbox"]:focus,
|
||||
.checkbox input[type="checkbox"]:focus,
|
||||
.checkbox-inline input[type="checkbox"]:focus {
|
||||
outline: none;
|
||||
}
|
||||
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 {
|
||||
border-color: ${theme.base0D};
|
||||
}
|
||||
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: "";
|
||||
display: block;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin-top: -2px;
|
||||
margin-right: 5px;
|
||||
border: 2px solid ${theme.base03};
|
||||
border-radius: 4px;
|
||||
transition: 240ms;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
input[type='checkbox']:after,
|
||||
.checkbox input[type='checkbox']:after,
|
||||
.checkbox-inline input[type='checkbox']:after {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin-top: -2px;
|
||||
margin-right: 5px;
|
||||
border: 2px solid ${theme.base03};
|
||||
border-radius: 4px;
|
||||
transition: 240ms;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
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;
|
||||
display: table;
|
||||
width: 6px;
|
||||
height: 12px;
|
||||
border: 2px solid #fff;
|
||||
border-top-width: 0;
|
||||
border-left-width: 0;
|
||||
transform: rotate(45deg);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
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;
|
||||
display: table;
|
||||
width: 6px;
|
||||
height: 12px;
|
||||
border: 2px solid #fff;
|
||||
border-top-width: 0;
|
||||
border-left-width: 0;
|
||||
transform: rotate(45deg);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
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']: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 {
|
||||
border-color: ${theme.base03};
|
||||
}
|
||||
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 {
|
||||
background-color: ${theme.base03};
|
||||
border-color: transparent;
|
||||
}
|
||||
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"] {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
.radio-inline.disabled,
|
||||
.checkbox-inline.disabled,
|
||||
fieldset[disabled] .radio-inline,
|
||||
fieldset[disabled] .checkbox-inline {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.radio-inline.disabled,
|
||||
.checkbox-inline.disabled,
|
||||
fieldset[disabled] .radio-inline,
|
||||
fieldset[disabled] .checkbox-inline {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.radio.disabled label,
|
||||
.checkbox.disabled label,
|
||||
fieldset[disabled] .radio label,
|
||||
fieldset[disabled] .checkbox label {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.radio.disabled label,
|
||||
.checkbox.disabled label,
|
||||
fieldset[disabled] .radio label,
|
||||
fieldset[disabled] .checkbox label {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.has-error .help-block,
|
||||
.has-error .control-label,
|
||||
.has-error .radio,
|
||||
.has-error .checkbox,
|
||||
.has-error .radio-inline,
|
||||
.has-error .checkbox-inline,
|
||||
.has-error.radio label,
|
||||
.has-error.checkbox label,
|
||||
.has-error.radio-inline label,
|
||||
.has-error.checkbox-inline label {
|
||||
color: ${theme.base08};
|
||||
}
|
||||
.has-error .help-block,
|
||||
.has-error .control-label,
|
||||
.has-error .radio,
|
||||
.has-error .checkbox,
|
||||
.has-error .radio-inline,
|
||||
.has-error .checkbox-inline,
|
||||
.has-error.radio label,
|
||||
.has-error.checkbox label,
|
||||
.has-error.radio-inline label,
|
||||
.has-error.checkbox-inline label {
|
||||
color: ${theme.base08};
|
||||
}
|
||||
|
||||
.panel {
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 1px 4px ${theme.base03};
|
||||
margin-bottom: 23px;
|
||||
}
|
||||
.panel {
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 1px 4px ${theme.base03};
|
||||
margin-bottom: 23px;
|
||||
}
|
||||
|
||||
.panel-heading {
|
||||
padding: 5px 15px;
|
||||
}
|
||||
.panel-heading {
|
||||
padding: 5px 15px;
|
||||
}
|
||||
|
||||
.panel-title {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
font-size: 15px;
|
||||
}
|
||||
.panel-title {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.panel-danger {
|
||||
box-shadow: 0 1px 4px ${theme.base08};
|
||||
}
|
||||
.panel-danger {
|
||||
box-shadow: 0 1px 4px ${theme.base08};
|
||||
}
|
||||
|
||||
.panel-danger>.panel-heading {
|
||||
color: ${theme.base00};
|
||||
background-color: ${theme.base08};
|
||||
}
|
||||
.panel-danger > .panel-heading {
|
||||
color: ${theme.base00};
|
||||
background-color: ${theme.base08};
|
||||
}
|
||||
|
||||
.text-danger {
|
||||
color: ${theme.base08};
|
||||
}
|
||||
.text-danger {
|
||||
color: ${theme.base08};
|
||||
}
|
||||
|
||||
.list-group {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.list-group {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
position: relative;
|
||||
display: block;
|
||||
padding: 10px 15px;
|
||||
}
|
||||
.list-group-item {
|
||||
position: relative;
|
||||
display: block;
|
||||
padding: 10px 15px;
|
||||
}
|
||||
`;
|
||||
|
|
|
@ -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,19 +15,17 @@ export const Container = styled.div`
|
|||
|
||||
storiesOf('Notification', module)
|
||||
.addDecorator(withKnobs)
|
||||
.addWithInfo(
|
||||
'default',
|
||||
'',
|
||||
() => (
|
||||
<Container>
|
||||
<Notification
|
||||
type={
|
||||
select('type', ['info', 'success', 'warning', 'error'], 'warning')
|
||||
}
|
||||
onClose={action('notification closed')}
|
||||
>
|
||||
{text('Message', 'Hello Notification')}
|
||||
</Notification>
|
||||
</Container>
|
||||
)
|
||||
);
|
||||
.add('default', () => (
|
||||
<Container>
|
||||
<Notification
|
||||
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,17 +15,13 @@ export const Container = styled.div`
|
|||
|
||||
storiesOf('SegmentedControl', module)
|
||||
.addDecorator(withKnobs)
|
||||
.addWithInfo(
|
||||
'default',
|
||||
'',
|
||||
() => (
|
||||
<Container>
|
||||
<SegmentedControl
|
||||
values={['Button1', 'Button2', 'Button3']}
|
||||
selected={text('selected', 'Button1')}
|
||||
onClick={action('button selected')}
|
||||
disabled={boolean('Disabled', false)}
|
||||
/>
|
||||
</Container>
|
||||
)
|
||||
);
|
||||
.add('default', () => (
|
||||
<Container>
|
||||
<SegmentedControl
|
||||
values={['Button1', 'Button2', 'Button3']}
|
||||
selected={text('selected', 'Button1')}
|
||||
onClick={action('button selected')}
|
||||
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};
|
||||
|
|
|
@ -13,17 +13,22 @@ export default class Select extends (PureComponent || Component) {
|
|||
}
|
||||
|
||||
Select.propTypes = {
|
||||
autosize: PropTypes.bool, // whether to enable autosizing or not
|
||||
clearable: PropTypes.bool, // should it be possible to reset value
|
||||
disabled: PropTypes.bool, // whether the Select is disabled or not
|
||||
isLoading: PropTypes.bool, // whether the Select is loading externally or not
|
||||
menuMaxHeight: PropTypes.number, // maximum css height for the opened menu of options
|
||||
multi: PropTypes.bool, // multi-value input
|
||||
searchable: PropTypes.bool, // whether to enable searching feature or not
|
||||
simpleValue: PropTypes.bool, // pass the value with label to onChange
|
||||
value: PropTypes.any, // initial field value
|
||||
valueKey: PropTypes.string, // path of the label value in option objects
|
||||
openOuterUp: PropTypes.bool // value to control the opening direction
|
||||
autosize: PropTypes.bool, // whether to enable autosizing or not
|
||||
clearable: PropTypes.bool, // should it be possible to reset value
|
||||
disabled: PropTypes.bool, // whether the Select is disabled or not
|
||||
isLoading: PropTypes.bool, // whether the Select is loading externally or not
|
||||
menuMaxHeight: PropTypes.number, // maximum css height for the opened menu of options
|
||||
multi: PropTypes.bool, // multi-value input
|
||||
searchable: PropTypes.bool, // whether to enable searching feature or not
|
||||
simpleValue: PropTypes.bool, // pass the value with label to onChange
|
||||
value: PropTypes.any, // initial field value
|
||||
valueKey: PropTypes.string, // path of the label value in option objects
|
||||
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
|
||||
};
|
||||
|
|
|
@ -20,9 +20,8 @@ export const Container = styled.div`
|
|||
|
||||
storiesOf('Select', module)
|
||||
.addDecorator(withKnobs)
|
||||
.addWithInfo(
|
||||
.add(
|
||||
'default',
|
||||
'Wrapper around [React Select](https://github.com/JedWatson/react-select) with themes and new props like `openOuterUp` and `menuMaxHeight`.',
|
||||
() => (
|
||||
<Container>
|
||||
<Select
|
||||
|
@ -39,5 +38,10 @@ storiesOf('Select', module)
|
|||
openOuterUp={boolean('openOuterUp', false)}
|
||||
/>
|
||||
</Container>
|
||||
)
|
||||
),
|
||||
{
|
||||
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,21 +15,17 @@ export const Container = styled.div`
|
|||
|
||||
storiesOf('Slider', module)
|
||||
.addDecorator(withKnobs)
|
||||
.addWithInfo(
|
||||
'default',
|
||||
'',
|
||||
() => (
|
||||
<Container>
|
||||
<Slider
|
||||
value={number('value', 0)}
|
||||
min={number('min', 0)}
|
||||
max={number('max', 100)}
|
||||
label={text('label', 'Slider label')}
|
||||
sublabel={text('sublabel', '(sublabel)')}
|
||||
withValue={boolean('withValue', false)}
|
||||
disabled={boolean('disabled', false)}
|
||||
onChange={action('slider changed')}
|
||||
/>
|
||||
</Container>
|
||||
)
|
||||
);
|
||||
.add('default', () => (
|
||||
<Container>
|
||||
<Slider
|
||||
value={number('value', 0)}
|
||||
min={number('min', 0)}
|
||||
max={number('max', 100)}
|
||||
label={text('label', 'Slider label')}
|
||||
sublabel={text('sublabel', '(sublabel)')}
|
||||
withValue={boolean('withValue', false)}
|
||||
disabled={boolean('disabled', false)}
|
||||
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)',
|
||||
['webkit-slider-thumb', 'moz-range-thumb', 'ms-thumb'],
|
||||
`{
|
||||
${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)',
|
||||
['webkit-slider-thumb', 'moz-range-thumb', 'ms-thumb'],
|
||||
`{
|
||||
${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,14 +100,15 @@ 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
|
||||
tabsWrapperRef.getBoundingClientRect().width
|
||||
) {
|
||||
while (
|
||||
i < tabs.length - 1 &&
|
||||
tabsRef.getBoundingClientRect().width + this.hiddenTabsWidth[0] <
|
||||
tabsWrapperRef.getBoundingClientRect().width
|
||||
tabsWrapperRef.getBoundingClientRect().width
|
||||
) {
|
||||
hiddenTab = hiddenTabs.shift();
|
||||
visibleTabs.splice(Number(hiddenTab.key), 0, hiddenTab);
|
||||
|
@ -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,31 +16,25 @@ const Container = styled.div`
|
|||
|
||||
storiesOf('Tabs', module)
|
||||
.addDecorator(withKnobs)
|
||||
.addWithInfo(
|
||||
'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>
|
||||
)
|
||||
)
|
||||
.addWithInfo(
|
||||
'with content',
|
||||
'',
|
||||
() => (
|
||||
<Tabs
|
||||
tabs={tabs}
|
||||
selected={text('selected', 'Tab2')}
|
||||
main={boolean('main', false)}
|
||||
onClick={action('tab selected')}
|
||||
collapsible={boolean('collapsible', false)}
|
||||
position={select('position', ['left', 'right', 'center'], 'left')}
|
||||
/>
|
||||
)
|
||||
);
|
||||
</Container>
|
||||
))
|
||||
.add('with content', () => (
|
||||
<Tabs
|
||||
tabs={tabs}
|
||||
selected={text('selected', 'Tab2')}
|
||||
main={boolean('main', false)}
|
||||
onClick={action('tab selected')}
|
||||
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};
|
||||
`}
|
||||
|
@ -37,7 +38,7 @@ export const style = ({ theme, main }) => css`
|
|||
border-bottom: 2px solid ${theme.base03};
|
||||
color: ${theme.base04};
|
||||
}
|
||||
&.collapsed{
|
||||
&.collapsed {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,135 +41,165 @@ export const SliderContainer = styled.div`
|
|||
|
||||
storiesOf('Toolbar', module)
|
||||
.addDecorator(withKnobs)
|
||||
.addWithInfo(
|
||||
'default',
|
||||
'',
|
||||
() => (
|
||||
<Container>
|
||||
<Toolbar borderPosition={select('borderPosition', ['top', 'bottom'])}>
|
||||
.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'
|
||||
])}
|
||||
disabled={boolean('Disabled', false)}
|
||||
onClick={action('button clicked')}
|
||||
>
|
||||
{text('Label', 'Hello Button')}
|
||||
</Button>
|
||||
<Divider />
|
||||
<Button
|
||||
title={text('Title', 'Hello Tooltip')}
|
||||
tooltipPosition={select('tooltipPosition', [
|
||||
'top',
|
||||
'bottom',
|
||||
'left',
|
||||
'right',
|
||||
'bottom-left',
|
||||
'bottom-right',
|
||||
'top-left',
|
||||
'top-right'
|
||||
])}
|
||||
disabled={boolean('Disabled', false)}
|
||||
onClick={action('button clicked')}
|
||||
>
|
||||
<RecordIcon />
|
||||
</Button>
|
||||
<Divider />
|
||||
<Spacer />
|
||||
<Select options={options} />
|
||||
</Toolbar>
|
||||
</Container>
|
||||
))
|
||||
.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'
|
||||
])}
|
||||
disabled={boolean('Disabled', false)}
|
||||
onClick={action('button clicked')}
|
||||
>
|
||||
{text('Label', 'Hello Button')}
|
||||
</Button>
|
||||
<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'], 'center')}
|
||||
/>
|
||||
<Button
|
||||
title={text('Title', 'Hello Tooltip')}
|
||||
tooltipPosition={select('tooltipPosition', [
|
||||
'top',
|
||||
'bottom',
|
||||
'left',
|
||||
'right',
|
||||
'bottom-left',
|
||||
'bottom-right',
|
||||
'top-left',
|
||||
'top-right'
|
||||
])}
|
||||
disabled={boolean('Disabled', false)}
|
||||
onClick={action('button clicked')}
|
||||
>
|
||||
{text('Label', 'Hello Button')}
|
||||
</Button>
|
||||
</Toolbar>
|
||||
</Container>
|
||||
))
|
||||
.add('with slider', () => (
|
||||
<Container>
|
||||
<SliderContainer>
|
||||
<Toolbar noBorder fullHeight compact>
|
||||
<Button
|
||||
title={text('Title', 'Hello Tooltip')}
|
||||
tooltipPosition={
|
||||
select('tooltipPosition', ['top', 'bottom', 'left', 'right',
|
||||
'bottom-left', 'bottom-right', 'top-left', 'top-right'])
|
||||
}
|
||||
disabled={boolean('Disabled', false)}
|
||||
title={text('play title', 'Play')}
|
||||
tooltipPosition={select('tooltipPosition', [
|
||||
'top',
|
||||
'bottom',
|
||||
'left',
|
||||
'right',
|
||||
'bottom-left',
|
||||
'bottom-right',
|
||||
'top-left',
|
||||
'top-right'
|
||||
])}
|
||||
onClick={action('button clicked')}
|
||||
>
|
||||
{text('Label', 'Hello Button')}
|
||||
<PlayIcon />
|
||||
</Button>
|
||||
<Divider />
|
||||
<Button
|
||||
title={text('Title', 'Hello Tooltip')}
|
||||
tooltipPosition={
|
||||
select('tooltipPosition', ['top', 'bottom', 'left', 'right',
|
||||
'bottom-left', 'bottom-right', 'top-left', 'top-right'])
|
||||
}
|
||||
disabled={boolean('Disabled', false)}
|
||||
onClick={action('button clicked')}
|
||||
>
|
||||
<RecordIcon />
|
||||
</Button>
|
||||
<Divider />
|
||||
<Spacer />
|
||||
<Select options={options} />
|
||||
</Toolbar>
|
||||
</Container>
|
||||
)
|
||||
)
|
||||
.addWithInfo(
|
||||
'tabs',
|
||||
'',
|
||||
() => (
|
||||
<Container>
|
||||
<Toolbar>
|
||||
<Button
|
||||
title={text('Title', 'Hello Tooltip')}
|
||||
tooltipPosition={
|
||||
select('tooltipPosition', ['top', 'bottom', 'left', 'right',
|
||||
'bottom-left', 'bottom-right', 'top-left', 'top-right'])
|
||||
}
|
||||
disabled={boolean('Disabled', false)}
|
||||
onClick={action('button clicked')}
|
||||
>
|
||||
{text('Label', 'Hello Button')}
|
||||
</Button>
|
||||
<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'], 'center')}
|
||||
<Slider
|
||||
value={number('value', 80)}
|
||||
min={number('min', 0)}
|
||||
max={number('max', 100)}
|
||||
label={text('label', 'Slider label')}
|
||||
withValue={boolean('withValue', false)}
|
||||
onChange={action('slider changed')}
|
||||
/>
|
||||
<Button
|
||||
title={text('Title', 'Hello Tooltip')}
|
||||
tooltipPosition={
|
||||
select('tooltipPosition', ['top', 'bottom', 'left', 'right',
|
||||
'bottom-left', 'bottom-right', 'top-left', 'top-right'])
|
||||
}
|
||||
disabled={boolean('Disabled', false)}
|
||||
onClick={action('button clicked')}
|
||||
title="Previous state"
|
||||
tooltipPosition={select('tooltipPosition', [
|
||||
'top',
|
||||
'bottom',
|
||||
'left',
|
||||
'right',
|
||||
'bottom-left',
|
||||
'bottom-right',
|
||||
'top-left',
|
||||
'top-right'
|
||||
])}
|
||||
disabled
|
||||
onClick={action('previous state clicked')}
|
||||
>
|
||||
{text('Label', 'Hello Button')}
|
||||
<LeftIcon />
|
||||
</Button>
|
||||
<Button
|
||||
title="Next state"
|
||||
tooltipPosition={select('tooltipPosition', [
|
||||
'top',
|
||||
'bottom',
|
||||
'left',
|
||||
'right',
|
||||
'bottom-left',
|
||||
'bottom-right',
|
||||
'top-left',
|
||||
'top-right'
|
||||
])}
|
||||
onClick={action('next state clicked')}
|
||||
>
|
||||
<RightIcon />
|
||||
</Button>
|
||||
<SegmentedControl
|
||||
values={['live', '1x']}
|
||||
selected={select('selected', ['live', '1x'], 'live')}
|
||||
onClick={action('button selected')}
|
||||
/>
|
||||
</Toolbar>
|
||||
</Container>
|
||||
)
|
||||
)
|
||||
.addWithInfo(
|
||||
'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'])
|
||||
}
|
||||
onClick={action('button clicked')}
|
||||
>
|
||||
<PlayIcon />
|
||||
</Button>
|
||||
<Slider
|
||||
value={number('value', 80)}
|
||||
min={number('min', 0)}
|
||||
max={number('max', 100)}
|
||||
label={text('label', 'Slider label')}
|
||||
withValue={boolean('withValue', false)}
|
||||
onChange={action('slider changed')}
|
||||
/>
|
||||
<Button
|
||||
title="Previous state"
|
||||
tooltipPosition={
|
||||
select('tooltipPosition', ['top', 'bottom', 'left', 'right',
|
||||
'bottom-left', 'bottom-right', 'top-left', 'top-right'])
|
||||
}
|
||||
disabled
|
||||
onClick={action('previous state clicked')}
|
||||
>
|
||||
<LeftIcon />
|
||||
</Button>
|
||||
<Button
|
||||
title="Next state"
|
||||
tooltipPosition={
|
||||
select('tooltipPosition', ['top', 'bottom', 'left', 'right',
|
||||
'bottom-left', 'bottom-right', 'top-left', 'top-right'])
|
||||
}
|
||||
onClick={action('next state clicked')}
|
||||
>
|
||||
<RightIcon />
|
||||
</Button>
|
||||
<SegmentedControl
|
||||
values={['live', '1x']}
|
||||
selected={select('selected', ['live', '1x'], 'live')}
|
||||
onClick={action('button selected')}
|
||||
/>
|
||||
</Toolbar>
|
||||
</SliderContainer>
|
||||
</Container>
|
||||
)
|
||||
);
|
||||
</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 }) => {
|
||||
|
|
|
@ -3,7 +3,7 @@ import { render, mount } from 'enzyme';
|
|||
import { renderToJson } from 'enzyme-to-json';
|
||||
import { Button } from '../src';
|
||||
|
||||
describe('Button', function () {
|
||||
describe('Button', function() {
|
||||
it('renders correctly', () => {
|
||||
const wrapper = render(<Button>Text</Button>);
|
||||
expect(renderToJson(wrapper)).toMatchSnapshot();
|
||||
|
|
|
@ -3,10 +3,12 @@ import { render } from 'enzyme';
|
|||
import { renderToJson } from 'enzyme-to-json';
|
||||
import { Container } from '../src';
|
||||
|
||||
describe('Container', function () {
|
||||
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>
|
||||
);
|
||||
|
|
|
@ -4,29 +4,23 @@ import { renderToJson } from 'enzyme-to-json';
|
|||
import { ContextMenu } from '../src';
|
||||
import { items } from '../src/ContextMenu/stories/data';
|
||||
|
||||
describe('ContextMenu', function () {
|
||||
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();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -3,7 +3,7 @@ import { render, mount } from 'enzyme';
|
|||
import { renderToJson } from 'enzyme-to-json';
|
||||
import { Dialog } from '../src';
|
||||
|
||||
describe('Dialog', function () {
|
||||
describe('Dialog', function() {
|
||||
it('renders correctly', () => {
|
||||
const wrapper = render(<Dialog />);
|
||||
expect(renderToJson(wrapper)).toMatchSnapshot();
|
||||
|
@ -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();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4,10 +4,10 @@ import { mountToJson } from 'enzyme-to-json';
|
|||
import { Editor } from '../src';
|
||||
import 'codemirror/mode/javascript/javascript';
|
||||
|
||||
describe('Editor', function () {
|
||||
describe('Editor', function() {
|
||||
const getBoundingClientRect = jest.fn();
|
||||
const getClientRects = jest.fn();
|
||||
document.body.createTextRange = function () {
|
||||
document.body.createTextRange = function() {
|
||||
return {
|
||||
getBoundingClientRect() {
|
||||
getBoundingClientRect();
|
||||
|
|
|
@ -4,14 +4,11 @@ import { shallowToJson } from 'enzyme-to-json';
|
|||
import { Form } from '../src';
|
||||
import { schema, uiSchema, formData } from '../src/Form/stories/schema';
|
||||
|
||||
describe('Form', function () {
|
||||
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();
|
||||
});
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import { render, mount } from 'enzyme';
|
|||
import { renderToJson } from 'enzyme-to-json';
|
||||
import { Notification } from '../src';
|
||||
|
||||
describe('Notification', function () {
|
||||
describe('Notification', function() {
|
||||
it('renders correctly', () => {
|
||||
const wrapper = render(<Notification>Message</Notification>);
|
||||
expect(renderToJson(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();
|
||||
|
|
|
@ -3,7 +3,7 @@ import { render, mount } from 'enzyme';
|
|||
import { renderToJson } from 'enzyme-to-json';
|
||||
import { SegmentedControl } from '../src';
|
||||
|
||||
describe('SegmentedControl', function () {
|
||||
describe('SegmentedControl', function() {
|
||||
it('renders correctly', () => {
|
||||
const wrapper = render(
|
||||
<SegmentedControl
|
||||
|
@ -17,15 +17,19 @@ describe('SegmentedControl', function () {
|
|||
});
|
||||
it('should handle the click event', () => {
|
||||
const onClick = jest.fn();
|
||||
const wrapper = mount(<SegmentedControl
|
||||
values={['Button1', 'Button2', 'Button3']}
|
||||
selected="Button1"
|
||||
disabled={false}
|
||||
onClick={onClick}
|
||||
/>
|
||||
const wrapper = mount(
|
||||
<SegmentedControl
|
||||
values={['Button1', 'Button2', 'Button3']}
|
||||
selected="Button1"
|
||||
disabled={false}
|
||||
onClick={onClick}
|
||||
/>
|
||||
);
|
||||
|
||||
wrapper.find('button').first().simulate('click');
|
||||
wrapper
|
||||
.find('button')
|
||||
.first()
|
||||
.simulate('click');
|
||||
expect(onClick).toBeCalled();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4,7 +4,7 @@ import { renderToJson, mountToJson } from 'enzyme-to-json';
|
|||
import { Select } from '../src';
|
||||
import { options } from '../src/Select/stories/options';
|
||||
|
||||
describe('Select', function () {
|
||||
describe('Select', function() {
|
||||
it('renders correctly', () => {
|
||||
const wrapper = render(<Select options={options} onChange={() => {}} />);
|
||||
expect(renderToJson(wrapper)).toMatchSnapshot();
|
||||
|
|
|
@ -3,7 +3,7 @@ import { render, mount } from 'enzyme';
|
|||
import { renderToJson } from 'enzyme-to-json';
|
||||
import { Slider } from '../src';
|
||||
|
||||
describe('Slider', function () {
|
||||
describe('Slider', function() {
|
||||
it('renders correctly', () => {
|
||||
const wrapper = render(<Slider />);
|
||||
expect(renderToJson(wrapper)).toMatchSnapshot();
|
||||
|
|
|
@ -4,7 +4,7 @@ import { renderToJson } from 'enzyme-to-json';
|
|||
import { Tabs } from '../src';
|
||||
import { tabs, simple10Tabs } from '../src/Tabs/stories/data';
|
||||
|
||||
describe('Tabs', function () {
|
||||
describe('Tabs', function() {
|
||||
it('renders correctly', () => {
|
||||
const wrapper = render(<Tabs tabs={tabs} onClick={() => {}} />);
|
||||
expect(renderToJson(wrapper)).toMatchSnapshot();
|
||||
|
@ -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();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -3,7 +3,7 @@ import { render } from 'enzyme';
|
|||
import { renderToJson } from 'enzyme-to-json';
|
||||
import { Toolbar, Divider, Spacer, Button } from '../src';
|
||||
|
||||
describe('Toolbar', function () {
|
||||
describe('Toolbar', function() {
|
||||
it('renders correctly', () => {
|
||||
const wrapper = render(
|
||||
<Toolbar>
|
||||
|
@ -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>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user