├── .babelrc ├── .gitignore ├── .storybook ├── config.js └── webpack.config.js ├── CHANGELOG.md ├── LICENSE ├── README.md ├── fixtures ├── .gitignore ├── app-registry.js ├── index.html ├── package-lock.json ├── package.json ├── server.js └── src │ ├── Menu.js │ └── index.js ├── lerna.json ├── package.json ├── packages ├── activity-indicator │ ├── README.md │ ├── index.d.ts │ ├── index.js │ ├── package.json │ └── src │ │ └── ActivityIndicator.js ├── app-registry │ ├── README.md │ ├── index.d.ts │ ├── index.js │ ├── package.json │ └── src │ │ └── AppRegistry.js ├── async-loader │ ├── README.md │ ├── index.d.ts │ ├── index.js │ ├── package.json │ └── src │ │ └── AsyncLoader.js ├── box │ ├── README.md │ ├── index.d.ts │ ├── index.js │ ├── package.json │ └── src │ │ └── Box.js ├── button │ ├── README.md │ ├── index.d.ts │ ├── index.js │ ├── package.json │ └── src │ │ └── Button.js ├── components │ ├── README.md │ ├── index.d.ts │ ├── index.js │ ├── package.json │ └── src │ │ └── Components.js ├── file-picker │ ├── README.md │ ├── index.d.ts │ ├── index.js │ ├── package.json │ └── src │ │ └── FilePicker.js ├── fullscreen │ ├── index.d.ts │ ├── index.js │ ├── package.json │ └── src │ │ └── Fullscreen.js ├── grid │ ├── README.md │ ├── index.d.ts │ ├── index.js │ ├── package.json │ └── src │ │ └── Grid.js ├── image │ ├── README.md │ ├── index.d.ts │ ├── index.js │ ├── package.json │ └── src │ │ └── Image.js ├── menu │ ├── README.md │ ├── index.d.ts │ ├── index.js │ ├── package.json │ └── src │ │ └── Menu.js ├── platform │ ├── README.md │ ├── index.d.ts │ ├── index.js │ ├── package.json │ └── src │ │ └── Platform.js ├── popup │ ├── README.md │ ├── index.d.ts │ ├── index.js │ ├── package.json │ ├── src │ │ └── Popup.js │ └── tests │ │ └── Popup.js ├── promise-view │ ├── README.md │ ├── index.d.ts │ ├── index.js │ ├── package.json │ └── src │ │ └── PromiseView.js ├── scroll-view │ ├── README.md │ ├── index.d.ts │ ├── index.js │ ├── package.json │ └── src │ │ └── ScrollView.js ├── slider │ ├── README.md │ ├── index.d.ts │ ├── index.js │ ├── package.json │ └── src │ │ └── Slider.js ├── stylesheet │ ├── README.md │ ├── index.d.ts │ ├── index.js │ ├── package.json │ └── src │ │ └── StyleSheet.js ├── svg │ ├── index.d.ts │ ├── package.json │ └── src │ │ └── Svg.js ├── text-input │ ├── README.md │ ├── index.d.ts │ ├── index.js │ ├── package.json │ └── src │ │ └── TextInput.js ├── text │ ├── README.md │ ├── index.d.ts │ ├── index.js │ ├── package.json │ └── src │ │ └── Text.js ├── touchable │ ├── README.md │ ├── index.d.ts │ ├── index.js │ ├── package.json │ └── src │ │ └── TouchableOpacity.js ├── triangle-arrow │ ├── README.md │ ├── index.d.ts │ ├── index.js │ ├── package.json │ └── src │ │ └── TriangleArrow.js ├── utils │ ├── README.md │ ├── index.d.ts │ ├── index.js │ ├── package.json │ └── src │ │ ├── attr-accept.js │ │ └── data-url-to-blob.js ├── vendor │ ├── README.md │ ├── index.d.ts │ ├── index.js │ ├── package.json │ ├── src │ │ ├── Vendor.js │ │ └── index.js │ ├── webpack.dev.js │ └── webpack.prod.js ├── view │ ├── README.md │ ├── index.d.ts │ ├── index.js │ ├── package.json │ └── src │ │ └── View.js └── webpack │ ├── README.md │ ├── index.d.ts │ ├── index.js │ ├── package.json │ └── src │ ├── Webpack.js │ └── createWebpackConfig.js ├── scripts ├── glob-babel.js └── update-gh-pages.sh ├── stories └── index.stories.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | [ 4 | "transform-runtime", 5 | { 6 | "helpers": false, 7 | "polyfill": false, 8 | "regenerator": true, 9 | "moduleName": "babel-runtime" 10 | } 11 | ], 12 | "transform-class-properties" 13 | ], 14 | "presets": [ 15 | "react", 16 | "stage-0", 17 | "es2015" 18 | ] 19 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | /*.js 3 | # !src/*.js 4 | .DS_Store 5 | !*.config.js 6 | .idea 7 | stats.html 8 | umd/*.js 9 | storybook-static 10 | *.github.io 11 | dist 12 | *.log* -------------------------------------------------------------------------------- /.storybook/config.js: -------------------------------------------------------------------------------- 1 | import { configure } from '@storybook/react'; 2 | 3 | // automatically import all files ending in *.stories.js 4 | const req = require.context('../stories', true, /.stories.js$/); 5 | function loadStories() { 6 | req.keys().forEach((filename) => req(filename)); 7 | } 8 | 9 | configure(loadStories, module); 10 | -------------------------------------------------------------------------------- /.storybook/webpack.config.js: -------------------------------------------------------------------------------- 1 | // you can use this file to add your custom webpack plugins, loaders and anything you like. 2 | // This is just the basic way to add additional webpack configurations. 3 | // For more information refer the docs: https://storybook.js.org/configurations/custom-webpack-config 4 | 5 | // IMPORTANT 6 | // When you add this file, we won't add the default configurations which is similar 7 | // to "React Create App". This only has babel loader to load JavaScript. 8 | 9 | module.exports = { 10 | plugins: [ 11 | // your custom plugins 12 | ], 13 | module: { 14 | rules: [ 15 | // add your custom rules. 16 | ], 17 | }, 18 | }; 19 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [Unreleased] 2 |
3 | 4 | Changes that have landed in master but are not yet released. 5 | Click to see more. 6 | 7 |
8 | 9 | 10 | ## 0.0.11 (May 2, 2018) 11 | 12 | ### Components 13 | 14 | * Fix a bug in `` 15 | 16 | ## 0.0.10 (Apr 23, 2018) 17 | 18 | ### Vendors 19 | 20 | * Upgrade React version to 16.3.2. 21 | * Upgrade ReactDOM version to 16.3.2. 22 | 23 | ### Components 24 | 25 | * Fix a position bug in `Menu`. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Zejin Zhuang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-web 2 | React全家桶 3 | 4 | A rich collection of react vendors and components for silky web dev experience. 5 | 6 | 7 | ## Install 8 | 9 | #### Browser/Production 10 | 11 | ```html 12 | 13 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /fixtures/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-bucket-example", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "react-bucket": "0.0.1-placeholder.2" 14 | }, 15 | "devDependencies": { 16 | "babili-webpack-plugin": "^0.1.2", 17 | "compression": "^1.7.1", 18 | "cors": "^2.8.4", 19 | "express": "^4.16.2", 20 | "lodash": "^4.17.4", 21 | "mkdirp": "^0.5.1", 22 | "morgan": "^1.9.0", 23 | "stats-webpack-plugin": "^0.6.2", 24 | "uglifyjs-webpack-plugin": "^1.2.4", 25 | "webpack": "^3.10.0", 26 | "webpack-dev-middleware": "^2.0.4", 27 | "webpack-node-externals": "^1.6.0", 28 | "webpack-system-register": "^1.5.1", 29 | "webpack-visualizer-plugin": "^0.1.11" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /fixtures/server.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | const morgan = require('morgan') 3 | const fs = require('fs') 4 | const path = require('path') 5 | const webpackDevMiddleware = require('webpack-dev-middleware') 6 | const compression = require('compression') 7 | const cors = require('cors') 8 | const webpack = require('webpack') 9 | 10 | const createWebpackConfig = require('../scripts/createWebpackConfig') 11 | const packageFile = JSON.parse(fs.readFileSync('package.json', 'UTF-8')) 12 | 13 | const port = process.env.PORT || 8080 14 | 15 | const config = createWebpackConfig({ 16 | platform: 'web', 17 | outputDir: './umd', 18 | port, 19 | name: packageFile.name, 20 | compress: true, 21 | production: true, 22 | devEntry: './src/index.js', 23 | alias: [], 24 | externals: [ 25 | { 26 | "commonjs": "react-bucket", 27 | "commonjs2": "react-bucket", 28 | "root": "react-bucket", 29 | "amd": "react-bucket" 30 | }, 31 | ], 32 | version: packageFile.version, 33 | }) 34 | 35 | const compiler = webpack(config) 36 | 37 | const app = express() 38 | app.use(cors()) 39 | app.use(morgan('dev')) 40 | app.use(compression()) 41 | app.use(webpackDevMiddleware(compiler, { 42 | publicPath: config.output.publicPath, 43 | stats: { 44 | colors: true 45 | } 46 | })) 47 | 48 | app.use(express.static(path.resolve('./'))) 49 | app.use(express.static(path.resolve('../umd'))) 50 | 51 | app.listen(port, () => { 52 | console.log('dev server listening on port %s', port) 53 | }) 54 | 55 | module.exports = app 56 | -------------------------------------------------------------------------------- /fixtures/src/Menu.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { View } from 'react-bucket' 3 | import Popup from '../../src/Popup' 4 | import Menu from '../../src/Menu' 5 | 6 | class MenuExample extends Component { 7 | 8 | onClickItem = (e, item) => { 9 | console.log(item) 10 | } 11 | 12 | render() { 13 | return ( 14 | { 16 | const { portalStyle } = props 17 | return ( 18 | { 44 | return ( 45 |
{item.name}
46 | ) 47 | }} 48 | /> 49 | ) 50 | }} 51 | > 52 | 触发 53 | 54 | ) 55 | } 56 | } 57 | 58 | export default MenuExample -------------------------------------------------------------------------------- /fixtures/src/index.js: -------------------------------------------------------------------------------- 1 | import { React, AppRegistry, ReactRouter, StyleSheet, View } from 'react-bucket' 2 | import Menu from './Menu' 3 | const { Switch, Route, Link, withRouter } = ReactRouter 4 | 5 | const styles = StyleSheet.create({ 6 | btn: { 7 | color: '#FFF', 8 | padding: '6px 10px', 9 | backgroundColor: '#3344ee' 10 | } 11 | }) 12 | 13 | class App extends React.Component { 14 | static historyType = 'hash' 15 | 16 | render() { 17 | console.log(this.props) 18 | 19 | return ( 20 |
21 | 22 | 23 | 24 | 25 | 26 | a 27 | 28 | 29 | Menu 30 | 31 | 32 | 33 | 34 | 35 |
36 | 首页 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 |
not found
45 |
46 |
47 |
48 | ) 49 | } 50 | } 51 | 52 | AppRegistry.registerComponent('app', () => App, { 53 | mountPoint: document.getElementById('app'), 54 | }) -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "lerna": "2.11.0", 3 | "npmClient": "yarn", 4 | "useWorkspaces": true, 5 | "packages": [ 6 | "packages/*" 7 | ], 8 | "version": "0.2.7" 9 | } 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-web", 3 | "version": "0.0.11", 4 | "private": true, 5 | "description": "React全家桶:splash:", 6 | "main": "index.js", 7 | "browser": "umd/react-bucket.production.js", 8 | "scripts": { 9 | "storybook": "start-storybook -p 6006", 10 | "build-storybook": "build-storybook" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/heineiuo/react-bucket.git" 15 | }, 16 | "author": "", 17 | "license": "MIT", 18 | "bugs": { 19 | "url": "https://github.com/heineiuo/react-bucket/issues" 20 | }, 21 | "homepage": "https://github.com/heineiuo/react-bucket#readme", 22 | "workspaces": [ 23 | "packages/*" 24 | ], 25 | "devDependencies": { 26 | "babel-eslint": "^8.2.3", 27 | "lerna": "^2.11.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/activity-indicator/README.md: -------------------------------------------------------------------------------- 1 | # @react-web/activity-indicator 2 | 3 | ## Usage 4 | 5 | ```js 6 | import { ActivityIndicator } from '@react-web/components' 7 | 8 | ``` 9 | 10 | ## License 11 | [MIT↗](../../LICENSE) -------------------------------------------------------------------------------- /packages/activity-indicator/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for @react-web/activity-indicator 2 | // Project: react-web 3 | // Definitions by: heineiuo 4 | 5 | import * as React from 'react'; 6 | 7 | type P = any 8 | 9 | export default ActivityIndicator 10 | 11 | declare class ActivityIndicator extends React.Component<{ 12 | color?: string 13 | size?: number 14 | delay?: number 15 | animating?: boolean 16 | style?: any 17 | }, any>{} -------------------------------------------------------------------------------- /packages/activity-indicator/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = module.exports.default = require('./dist/ActivityIndicator').default; -------------------------------------------------------------------------------- /packages/activity-indicator/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-web/activity-indicator", 3 | "version": "0.2.6", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "prepublish": "babel src -d dist" 8 | }, 9 | "files": [ 10 | "dist", 11 | "index.js", 12 | "index.d.ts" 13 | ], 14 | "dependencies": { 15 | "@react-web/stylesheet": "^0.2.6", 16 | "@react-web/view": "^0.2.6" 17 | }, 18 | "peerDependencies": { 19 | "@react-web/vendor": "*" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/activity-indicator/src/ActivityIndicator.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import StyleSheet from '@react-web/stylesheet' 3 | import { Keyframes, Frame } from 'react-keyframes' 4 | import View from '@react-web/view' 5 | 6 | const bars = Array.from({ length: 12 }, v => 0) 7 | 8 | class ActivityIndicator extends Component { 9 | 10 | static defaultProps = { 11 | color: 'black', 12 | size: 60, 13 | delay: 0, 14 | animating: true, 15 | style: {} 16 | } 17 | 18 | 19 | renderStatic = ({ increment }) => { 20 | const { color } = this.props 21 | 22 | return bars.map((item, index) => { 23 | let remainder = (index + increment) % 11 24 | let opacity = remainder < 6 ? 0.12 : remainder / 11 25 | return ( 26 | 34 | ) 35 | }) 36 | } 37 | 38 | render() { 39 | const Static = this.renderStatic 40 | const { size, animating, style, delay } = this.props 41 | 42 | if (!animating) return null 43 | 44 | return ( 45 | 48 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | ) 62 | } 63 | } 64 | 65 | const styles = StyleSheet.create({ 66 | spinner: { 67 | position: 'relative', 68 | // transformOrigin: `60px 60px`, 69 | // transform: `rotate(${rotate}deg)`, 70 | // transition: 'all 0.8s linear', 71 | width: 120, 72 | height: 120, 73 | }, 74 | 75 | spinner__bar: { 76 | transformOrigin: '5px 60px', 77 | transition: 'all 0.12s linear', 78 | borderRadius: '5px', 79 | // backgroundColor: 'black', 80 | position: 'absolute', 81 | top: 0, 82 | left: 60, 83 | marginLeft: -5, 84 | width: 10, 85 | height: 30, 86 | } 87 | }) 88 | 89 | export default ActivityIndicator 90 | -------------------------------------------------------------------------------- /packages/app-registry/README.md: -------------------------------------------------------------------------------- 1 | # @react-web/app-registry 2 | 3 | ## Usage 4 | 5 | ```js 6 | import { AppRegistry } from '@react-web/components' 7 | 8 | const App = () => { 9 | return ( 10 | hello world! 11 | ) 12 | } 13 | 14 | AppRegistry.registerComponent('app', () => App, { 15 | mountPoint: document.getElementById('app') 16 | }) 17 | ``` 18 | 19 | ## License 20 | [MIT↗](../../LICENSE) -------------------------------------------------------------------------------- /packages/app-registry/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for @react-web/app-registry 2 | // Project: react-web 3 | // Definitions by: heineiuo 4 | 5 | import * as React from 'react'; 6 | 7 | type P = any 8 | 9 | export default AppRegistry 10 | 11 | declare namespace AppRegistry { 12 | 13 | function registerComponent ( 14 | appKey:string, 15 | componentProvider: () => React.Component, 16 | config: { 17 | systemConfig?: any, 18 | mountPoint: any 19 | } 20 | ) 21 | 22 | } -------------------------------------------------------------------------------- /packages/app-registry/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = module.exports.default = require('./dist/AppRegistry').default -------------------------------------------------------------------------------- /packages/app-registry/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-web/app-registry", 3 | "version": "0.2.6", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "files": [ 7 | "dist", 8 | "index.js", 9 | "index.d.ts" 10 | ], 11 | "scripts": { 12 | "prepublish": "babel src -d dist" 13 | }, 14 | "peerDependencies": { 15 | "@react-web/vendor": "*" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/app-registry/src/AppRegistry.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import { Provider } from 'react-redux' 4 | import { withRouter } from 'react-router-dom' 5 | import { createHashHistory, createBrowserHistory, createMemoryHistory } from 'history' 6 | import { createStore, applyMiddleware, combineReducers } from 'redux' 7 | import { routerReducer, routerMiddleware, ConnectedRouter } from 'react-router-redux' 8 | import ReduxThunk from 'redux-thunk' 9 | import SystemJS from 'systemjs' 10 | import warning from 'warning' 11 | 12 | const AppRegistry = { 13 | registerComponent: (appKey, componentProvider, config) => { 14 | if (config.systemConfig) { 15 | SystemJS.config(config.systemConfig) 16 | } 17 | const App = componentProvider() 18 | const { historyType } = App 19 | const AppWithRouter = withRouter(App) 20 | const history = historyType === 'hash' 21 | ? createHashHistory() : historyType === 'browser' 22 | ? createBrowserHistory() 23 | : createMemoryHistory() 24 | 25 | const loggerMiddleware = store => next => action => { 26 | if (process.env.NODE_ENV !== 'production') console.warn(action) 27 | return next(action) 28 | } 29 | 30 | const create = global.devToolsExtension ? global.devToolsExtension()(createStore) : createStore 31 | 32 | const createReducer = (asyncReducers) => combineReducers({ 33 | router: routerReducer, 34 | routing: routerReducer, 35 | ...asyncReducers 36 | }) 37 | 38 | const createStoreWithMiddleware = applyMiddleware( 39 | ReduxThunk, 40 | loggerMiddleware, 41 | routerMiddleware(history) 42 | )(create) 43 | 44 | const store = createStoreWithMiddleware(createReducer({}), {}) 45 | store.asyncReducers = {} 46 | 47 | const injectReducer = (name, asyncReducer, force = false) => { 48 | warning(!store.hasOwnProperty(name) || force, `${name} has been injected, if you want to replace it, use force=true argument`) 49 | store.asyncReducers[name] = asyncReducer 50 | store.replaceReducer(createReducer(store.asyncReducers)) 51 | } 52 | 53 | return ReactDOM.render( 54 | 55 | 56 | 57 | 58 | , 59 | config.mountPoint 60 | ) 61 | } 62 | } 63 | 64 | export default AppRegistry 65 | -------------------------------------------------------------------------------- /packages/async-loader/README.md: -------------------------------------------------------------------------------- 1 | # @react-web/async-loader 2 | 3 | 4 | ## Usage 5 | 6 | ```js 7 | import AsyncLoader from '@react-web/async-loader' 8 | 9 | ``` 10 | 11 | ## License 12 | [MIT↗](../../LICENSE) -------------------------------------------------------------------------------- /packages/async-loader/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for @react-web/async-loader 2 | // Project: @react-web 3 | // Definitions by: heineiuo 4 | 5 | import * as React from 'react'; 6 | 7 | type P = any 8 | 9 | export default AsyncLoader 10 | 11 | declare class AsyncLoader extends React.Component<{ 12 | loadKey: string 13 | load: () => React.Component 14 | renderLoading: () => React.ReactElement

, 15 | renderError: () => React.ReactElement

16 | }, any>{ 17 | 18 | } -------------------------------------------------------------------------------- /packages/async-loader/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = module.exports.default = require('./dist/AsyncLoader').default; -------------------------------------------------------------------------------- /packages/async-loader/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-web/async-loader", 3 | "version": "0.2.6", 4 | "main": "index.js", 5 | "files": [ 6 | "dist", 7 | "index.js", 8 | "index.d.ts" 9 | ], 10 | "scripts": { 11 | "prepublish": "babel src -d dist" 12 | }, 13 | "license": "MIT" 14 | } 15 | -------------------------------------------------------------------------------- /packages/async-loader/src/AsyncLoader.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react' 2 | import omit from 'lodash/omit' 3 | 4 | class AsyncLoader extends Component { 5 | static defaultProps = { 6 | loadKey: '', 7 | load: () => {}, 8 | renderLoading: () => { 9 | return ( 10 |

Loading...
11 | ) 12 | }, 13 | renderError: (err) => { 14 | console.error(err) 15 | return ( 16 |
17 |
18 |             {err.stack || err.message || err}
19 |           
20 |
21 | ) 22 | } 23 | 24 | } 25 | 26 | state = { 27 | loadState: 1, 28 | CurrentComponent: null, 29 | error: null 30 | } 31 | 32 | componentDidMount = () => { 33 | this.load(this.props) 34 | } 35 | 36 | componentDidUpdate = (prevProps) => { 37 | if (this.props.loadKey !== prevProps.loadKey) { 38 | this.load(this.props) 39 | } 40 | } 41 | 42 | load = (props) => { 43 | this.setState({ 44 | loadState: 1, 45 | CurrentComponent: null 46 | }) 47 | props.load((e, CurrentComponent) => { 48 | if (e) { 49 | return this.setState({ 50 | loadState: 3, 51 | error: e 52 | }) 53 | } 54 | this.setState({ 55 | loadState: 2, 56 | // handle both es module and commonjs 57 | CurrentComponent: CurrentComponent.default ? CurrentComponent.default : CurrentComponent 58 | }) 59 | }) 60 | } 61 | 62 | renderSuccess = (CurrentComponent) => { 63 | const pickedProps = omit(this.props, ['load', 'loadKey']) 64 | return ( 65 | 66 | ) 67 | } 68 | 69 | render () { 70 | const {renderLoading, renderError} = this.props 71 | const {loadState, CurrentComponent, error} = this.state 72 | 73 | if (typeof this.props.children === 'function') { 74 | return this.props.children(loadState, CurrentComponent, error) 75 | } 76 | 77 | const renderSuccess = this.props.renderSuccess || this.renderSuccess 78 | 79 | return loadState === 1 80 | ? renderLoading() 81 | : loadState === 2 82 | ? renderSuccess(CurrentComponent) 83 | : renderError(error) 84 | } 85 | } 86 | 87 | export default AsyncLoader 88 | -------------------------------------------------------------------------------- /packages/box/README.md: -------------------------------------------------------------------------------- 1 | # @react-web/box 2 | 3 | ## License 4 | [MIT↗](../../LICENSE) -------------------------------------------------------------------------------- /packages/box/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for @react-web/box 2 | // Project: @react-web/box 3 | // Definitions by: heineiuo 4 | 5 | import * as React from 'react'; 6 | 7 | type P = any 8 | 9 | export default Box 10 | 11 | declare class Box extends React.Component<{ 12 | 13 | 14 | }, any>{ 15 | 16 | } -------------------------------------------------------------------------------- /packages/box/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = module.exports.default = require('./dist/Box').default; -------------------------------------------------------------------------------- /packages/box/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-web/box", 3 | "version": "0.2.4", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "prepublish": "babel src -d dist" 8 | }, 9 | "files": [ 10 | "dist", 11 | "index.js", 12 | "index.d.ts" 13 | ], 14 | "peerDependencies": { 15 | "@react-web/stylesheet": "*", 16 | "@react-web/vendor": "*", 17 | "@react-web/view": "*" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/box/src/Box.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import StyleSheet from '@react-web/stylesheet' 3 | import PropTypes from 'prop-types' 4 | import View from '@react-web/view' 5 | 6 | class Box extends Component { 7 | 8 | static defaultProps = { 9 | renderOption: () => null 10 | } 11 | 12 | static propTypes = { 13 | label: PropTypes.string.isRequired, 14 | renderOption: PropTypes.func 15 | } 16 | 17 | scrollToEnd = () => { 18 | let lastEl = this.module.lastElementChild 19 | if (lastEl) { 20 | this.module.scrollTop = lastEl.offsetTop 21 | } 22 | } 23 | 24 | render() { 25 | const Option = this.props.renderOption 26 | return ( 27 | 28 | 29 | {this.props.label} 30 | 31 | 32 | 33 | 34 |
this.module = r} 36 | style={StyleSheet.assign([styles.card, styles.box__module])} 37 | >{this.props.children}
38 |
39 | ) 40 | } 41 | } 42 | 43 | const styles = StyleSheet.create({ 44 | card: { 45 | backgroundColor: '#fff', 46 | boxShadow: '0 0 0 1px rgba(200,215,225,0.5), 0 1px 2px #e9eff3' 47 | }, 48 | 49 | card_compact: { 50 | padding: '16px 24px', 51 | position: 'relative', 52 | }, 53 | 54 | box__header: { 55 | lineHeight: '28px', 56 | paddingtop: 11, 57 | paddingBottom: 11, 58 | display: 'flex', 59 | justifyContent: 'space-between', 60 | }, 61 | 62 | box__label: { 63 | color: '#2e4453', 64 | fontSize: 14 65 | } 66 | }) 67 | 68 | export default Box 69 | -------------------------------------------------------------------------------- /packages/button/README.md: -------------------------------------------------------------------------------- 1 | # @react-web/button 2 | 3 | 4 | ## Usage 5 | 6 | ```jsx 7 | import { Button } from "@react-web/components" 8 | // or: 9 | // import Button from "@react-web/button" 10 | 11 | render( 12 | 13 | ) 14 | ``` 15 | 16 | ## License 17 | 18 | [MIT↗](../../LICENSE) -------------------------------------------------------------------------------- /packages/button/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for @react-web/button 2 | // Project: @react-web/button 3 | // Definitions by: heineiuo 4 | 5 | import * as React from 'react'; 6 | 7 | type P = any 8 | 9 | export interface ButtonProps { 10 | autofocus?: boolean; 11 | cancelKeyboardEventOnSelection?: boolean; 12 | className?: string; 13 | // createFromSearch?(items: OptionValue[], search: string): OptionValue; 14 | // defaultValue?: OptionValue; 15 | delimiters?: [any]; 16 | color?: string; 17 | disabled?: boolean 18 | style?: any; 19 | renderIcon: () => React.ReactElement

20 | // ... 21 | } 22 | 23 | declare class Button extends React.Component { 24 | 25 | } 26 | 27 | export default Button -------------------------------------------------------------------------------- /packages/button/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = module.exports.default = require('./dist/Button').default -------------------------------------------------------------------------------- /packages/button/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-web/button", 3 | "version": "0.2.6", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "files": [ 7 | "dist", 8 | "index.js", 9 | "index.d.ts" 10 | ], 11 | "scripts": { 12 | "prepublish": "babel src -d dist" 13 | }, 14 | "dependencies": { 15 | "@react-web/stylesheet": "^0.2.6", 16 | "@react-web/touchable": "^0.2.6", 17 | "@react-web/view": "^0.2.6" 18 | }, 19 | "peerDependencies": { 20 | "@react-web/vendor": "*" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/button/src/Button.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { Link } from 'react-router-dom' 3 | import StyleSheet from '@react-web/stylesheet' 4 | import omit from 'lodash/omit' 5 | import View from '@react-web/view' 6 | import { TouchableOpacity } from '@react-web/touchable' 7 | 8 | class Button extends Component { 9 | 10 | static defaultProps = { 11 | color: '#1194f6', 12 | disabled: false, 13 | style: {}, 14 | renderIcon: () => null, 15 | } 16 | 17 | renderBackArrow = (props) => { 18 | const { width, height } = this.props 19 | return ( 20 | 21 | 22 | 23 | 24 | 25 | ) 26 | } 27 | 28 | render() { 29 | const { children, type, noBackground, level, style, color, } = this.props 30 | const BackArrow = this.renderBackArrow 31 | if (type === 'back-arrow') return 32 | const props = omit(this.props, [ 33 | 'state', 'dispatch', 'renderIcon', 'color', 'disabled', 'style' 34 | ]) 35 | 36 | const Icon = this.props.renderIcon 37 | return ( 38 | 46 | 47 | {children} 48 | 49 | ) 50 | } 51 | } 52 | 53 | const baseStyle = { 54 | cursor: "pointer", 55 | outline: 'none' 56 | } 57 | 58 | export const colors = { 59 | primary: "#537994", 60 | secondary: "#537994", 61 | warning: "#537994", 62 | danger: "#537994", 63 | } 64 | 65 | const styles = StyleSheet.create({ 66 | btn: { 67 | cursor: 'pointer', 68 | fontSize: 14, 69 | display: 'flex', 70 | textAlign: 'center', 71 | alignItems: 'center', 72 | justifyContent: 'center', 73 | flexDirection: 'row', 74 | height: 30, 75 | borderRadius: 3, 76 | marginBottom: 5, 77 | paddingLeft: 5, 78 | paddingRight: 5, 79 | borderWidth: 1, 80 | borderStyle: 'solid', 81 | }, 82 | 83 | btn_text: { 84 | // alignSelf: '', 85 | } 86 | }) 87 | 88 | export default Button 89 | -------------------------------------------------------------------------------- /packages/components/README.md: -------------------------------------------------------------------------------- 1 | # @react-web/components 2 | 3 | ## License 4 | [MIT↗](../../LICENSE) -------------------------------------------------------------------------------- /packages/components/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for @react-web/components 2 | // Project: react-web 3 | // Definitions by: heineiuo 4 | 5 | import * as React from 'react'; 6 | 7 | import Button from '@react-web/button'; 8 | import Image from '@react-web/image'; 9 | import View from '@react-web/view'; 10 | import PromiseView from '@react-web/promise-view'; 11 | import Popup from '@react-web/popup'; 12 | import FilePicker from '@react-web/file-picker'; 13 | import Text from '@react-web/text'; 14 | import TextInput from '@react-web/text-input'; 15 | import Menu from '@react-web/menu'; 16 | import ActivityIndicator from '@react-web/activity-indicator' 17 | import AppRegistry from '@react-web/app-registry' 18 | import AsyncLoader from '@react-web/async-loader' 19 | import StyleSheet from '@react-web/stylesheet' 20 | import Platform from '@react-web/platform' 21 | import { TouchableOpacity } from '@react-web/touchable' 22 | import * as Utils from '@react-web/utils' 23 | 24 | export { 25 | ActivityIndicator, 26 | AppRegistry, 27 | AsyncLoader, 28 | Button, 29 | Image, 30 | View, 31 | Platform, 32 | PromiseView, 33 | Popup, 34 | StyleSheet, 35 | FilePicker, 36 | Text, 37 | TextInput, 38 | TouchableOpacity, 39 | Menu, 40 | Utils, 41 | }; 42 | 43 | -------------------------------------------------------------------------------- /packages/components/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = module.exports.default = require('./dist/Components'); -------------------------------------------------------------------------------- /packages/components/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-web/components", 3 | "version": "0.2.7", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "files": [ 7 | "dist", 8 | "index.d.ts", 9 | "index.js" 10 | ], 11 | "scripts": { 12 | "prepublish": "babel src -d dist" 13 | }, 14 | "dependencies": { 15 | "@react-web/activity-indicator": "^0.2.6", 16 | "@react-web/box": "^0.2.4", 17 | "@react-web/button": "^0.2.6", 18 | "@react-web/file-picker": "^0.2.4", 19 | "@react-web/image": "^0.2.6", 20 | "@react-web/menu": "^0.2.6", 21 | "@react-web/popup": "^0.2.6", 22 | "@react-web/promise-view": "^0.2.4", 23 | "@react-web/scroll-view": "^0.2.4", 24 | "@react-web/slider": "^0.2.4", 25 | "@react-web/stylesheet": "^0.2.6", 26 | "@react-web/text": "^0.2.4", 27 | "@react-web/text-input": "^0.2.6", 28 | "@react-web/touchable": "^0.2.6", 29 | "@react-web/utils": "^0.2.4", 30 | "@react-web/view": "^0.2.6" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/components/src/Components.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import View from '@react-web/view' 3 | import Button from '@react-web/button' 4 | import ScrollView from '@react-web/scroll-view' 5 | import TextInput from '@react-web/text-input' 6 | import FilePicker from '@react-web/file-picker' 7 | import Box from '@react-web/box' 8 | import Menu from '@react-web/menu' 9 | import Popup from '@react-web/popup' 10 | import { TouchableOpacity } from '@react-web/touchable' 11 | import PromiseView from '@react-web/promise-view' 12 | import Text from '@react-web/text' 13 | import Image from '@react-web/image' 14 | import Slider from '@react-web/slider' 15 | import ActivityIndicator from '@react-web/activity-indicator' 16 | import * as Utils from '@react-web/utils' 17 | import StyleSheet from '@react-web/stylesheet' 18 | 19 | const Overlay = Popup 20 | const Style = (props) => 21 | 22 | export { 23 | ActivityIndicator, 24 | View, 25 | Button, 26 | Box, 27 | FilePicker, 28 | ScrollView, 29 | TextInput, 30 | Text, 31 | Image, 32 | Menu, 33 | Popup, 34 | Overlay, 35 | Slider, 36 | TouchableOpacity, 37 | PromiseView, 38 | Utils, 39 | Style, 40 | StyleSheet 41 | } 42 | -------------------------------------------------------------------------------- /packages/file-picker/README.md: -------------------------------------------------------------------------------- 1 | # @react-web/file-picker 2 | 3 | ## Usage 4 | 5 | ```js 6 | import { FilePicker } from '@react-web/components' 7 | // import FilePicker from '@react-web/file-picker' 8 | 9 | ``` 10 | 11 | ## License 12 | [MIT↗](../../LICENSE) -------------------------------------------------------------------------------- /packages/file-picker/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for @react-web/file-picker 2 | // Project: react-web 3 | // Definitions by: heineiuo 4 | 5 | import * as React from 'react'; 6 | 7 | declare class FilePicker extends React.Component<{ 8 | multiple?: boolean | true; 9 | accept?: string; 10 | tag?: string; 11 | className?: string; 12 | style?: object | object[]; 13 | disabled?: boolean | false; 14 | withObjectUrl?: boolean; 15 | onFileChange?: () => {}; 16 | }, any> { 17 | 18 | } 19 | 20 | export default FilePicker -------------------------------------------------------------------------------- /packages/file-picker/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = module.exports.default = require('./dist/FilePicker').default; -------------------------------------------------------------------------------- /packages/file-picker/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-web/file-picker", 3 | "version": "0.2.4", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "prepublish": "babel src -d dist" 8 | }, 9 | "files": [ 10 | "dist", 11 | "index.js", 12 | "index.d.ts" 13 | ], 14 | "dependencies": { 15 | "@react-web/utils": "^0.2.4" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/file-picker/src/FilePicker.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { attrAccept } from '@react-web/utils' 3 | 4 | /** 5 | * 仅负责选择本地文件,文件的处理和上传交给其他组件完成 6 | */ 7 | class FilePicker extends Component { 8 | 9 | static defaultProps = { 10 | multiple: true, 11 | accept: '', 12 | tag: 'div', 13 | className: '', 14 | style: {}, 15 | disabled: false, 16 | withObjectUrl: false, 17 | onFileChange: () => { } 18 | } 19 | 20 | handleClick = () => { 21 | if (!this.fileInputEl) return false 22 | this.fileInputEl.click() 23 | } 24 | 25 | handleFileChange = (e) => { 26 | const files = e.target.files 27 | this.handleFiles(Array.prototype.slice.call(files)) 28 | } 29 | 30 | handleFiles = (files) => { 31 | if (this.props.withObjectUrl) { 32 | files.forEach(file => { 33 | file.objectUrl = URL.createObjectURL(file) 34 | }) 35 | } 36 | this.props.onFileChange(files) 37 | } 38 | 39 | handleKeyDown = e => { 40 | if (e.key === 'Enter') { 41 | this.handleClick() 42 | } 43 | } 44 | 45 | handleFileDrop = e => { 46 | if (e.type === 'dragover') { 47 | e.preventDefault() 48 | return false 49 | } 50 | const files = Array.prototype.slice.call(e.dataTransfer.files).filter( 51 | file => attrAccept(file, this.props.accept) 52 | ) 53 | this.handleFiles(files) 54 | e.preventDefault() 55 | } 56 | 57 | 58 | render() { 59 | const { tag: Tag, className, disabled, style, multiple, accept, children } = this.props 60 | 61 | const events = disabled ? {} : { 62 | onClick: this.handleClick, 63 | onKeyDown: this.handleKeyDown, 64 | onDrop: this.handleFileDrop, 65 | onDragOver: this.handleFileDrop, 66 | } 67 | 68 | return ( 69 | 76 | this.fileInputEl = ref} 79 | style={{ display: 'none' }} 80 | accept={accept} 81 | multiple={multiple} 82 | onChange={this.handleFileChange} 83 | /> 84 | {children} 85 | 86 | ) 87 | } 88 | } 89 | 90 | export default FilePicker 91 | -------------------------------------------------------------------------------- /packages/fullscreen/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for @react-web/fullscreen 2 | // Project: react-web 3 | // Definitions by: heineiuo 4 | 5 | import * as React from 'react'; 6 | 7 | type P = any 8 | 9 | declare class Fullscreen extends React.Component<{ 10 | 11 | }, any> { 12 | 13 | } -------------------------------------------------------------------------------- /packages/fullscreen/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | module.exports = module.exports.default = require('./dist/Fullscreen').default; -------------------------------------------------------------------------------- /packages/fullscreen/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-web/fullscreen", 3 | "version": "0.2.6", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "prepublish": "babel src -d dist" 8 | }, 9 | "files": [ 10 | "dist", 11 | "index.d.ts", 12 | "index.js" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/fullscreen/src/Fullscreen.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | const { Provider, Consumer } = React.createContext({}) 4 | 5 | class Fullscreen extends Component { 6 | 7 | static Consumer = Consumer 8 | 9 | constructor(props) { 10 | super(props) 11 | 12 | this.state = { 13 | isFullscreen: this.isFullscreen(), 14 | open: this.open, 15 | close: this.close, 16 | toggle: this.toggle 17 | } 18 | } 19 | 20 | componentDidMount() { 21 | document.addEventListener('webkitfullscreenchange', this.handleChange, false) 22 | } 23 | 24 | componentWillUnmount() { 25 | document.removeEventListener('webkitfullscreenchange', this.handleChange, false) 26 | } 27 | 28 | handleChange = () => { 29 | this.setState({ 30 | isFullscreen: this.isFullscreen() 31 | }) 32 | } 33 | 34 | open() { 35 | if (this.state.isFullscreen) return; 36 | this.setState({ 37 | isFullscreen: true 38 | }, () => { 39 | document.documentElement.webkitRequestFullscreen() 40 | }) 41 | } 42 | 43 | toggle() { 44 | if (this.state.isFullscreen) return this.close(); 45 | this.open() 46 | } 47 | 48 | close() { 49 | if (!this.state.isFullscreen) return; 50 | this.setState({ 51 | isFullscreen: false 52 | }, () => { 53 | if (document.webkitExitFullscreen) { 54 | document.webkitExitFullscreen(); 55 | } 56 | }) 57 | } 58 | 59 | isFullscreen() { 60 | return document.webkitFullscreenElement != null 61 | } 62 | 63 | render() { 64 | 65 | {this.props.children} 66 | 67 | } 68 | } 69 | 70 | 71 | export default Fullscreen -------------------------------------------------------------------------------- /packages/grid/README.md: -------------------------------------------------------------------------------- 1 | # @react-web/grid 2 | 3 | ## Usage 4 | 5 | 6 | 7 | ## License 8 | [MIT↗](../../LICENSE) -------------------------------------------------------------------------------- /packages/grid/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for @react-web/grid 2 | // Project: react-web 3 | // Definitions by: heineiuo 4 | 5 | import * as React from 'react'; 6 | 7 | type P = any -------------------------------------------------------------------------------- /packages/grid/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = module.exports.default = require('./dist/Grid').default; -------------------------------------------------------------------------------- /packages/grid/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-web/grid", 3 | "version": "0.2.4", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "files": [ 7 | "dist", 8 | "index.js", 9 | "index.d.ts" 10 | ], 11 | "scripts": { 12 | "prepublish": "babel src -d dist" 13 | }, 14 | "peerDependencies": { 15 | "@react-web/vendor": "*" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/grid/src/Grid.js: -------------------------------------------------------------------------------- 1 | // @unstable 2 | 3 | export * from 'react-grid-system' -------------------------------------------------------------------------------- /packages/image/README.md: -------------------------------------------------------------------------------- 1 | # @react-web/image 2 | 3 | 4 | ## Usage 5 | 6 | ```jsx 7 | import { Image } from "@react-web/components" 8 | // or: 9 | // import Image from "@react-web/image" 10 | 11 | render( 12 | 15 | ) 16 | ``` 17 | 18 | ## License 19 | 20 | [MIT↗](../../LICENSE) -------------------------------------------------------------------------------- /packages/image/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for @react-web/image 2 | // Project: react-web 3 | // Definitions by: heineiuo 4 | 5 | 6 | import React from 'react'; 7 | 8 | declare class Image extends React.Component<{ 9 | style: any 10 | alt: string 11 | source: { 12 | uri: string 13 | }[] 14 | }, any> {} 15 | 16 | export default Image; -------------------------------------------------------------------------------- /packages/image/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = module.exports.default = require('./dist/Image').default; -------------------------------------------------------------------------------- /packages/image/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-web/image", 3 | "version": "0.2.6", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "files": [ 7 | "dist", 8 | "index.js", 9 | "index.d.ts" 10 | ], 11 | "scripts": { 12 | "prepublish": "babel src -d dist" 13 | }, 14 | "dependencies": { 15 | "@react-web/activity-indicator": "^0.2.6", 16 | "@react-web/promise-view": "^0.2.4", 17 | "@react-web/stylesheet": "^0.2.6", 18 | "@react-web/view": "^0.2.6", 19 | "is-base64": "^0.0.4" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/image/src/Image.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import PropTypes from 'prop-types' 3 | import StyleSheet from '@react-web/stylesheet' 4 | import PromiseView from '@react-web/promise-view' 5 | import View from '@react-web/view' 6 | import ActivityIndicator from '@react-web/activity-indicator' 7 | import isBase64 from 'is-base64' 8 | 9 | const cache = {} 10 | 11 | class Image extends Component { 12 | 13 | static propTypes = { 14 | style: PropTypes.object, 15 | alt: PropTypes.string, 16 | source: PropTypes.array.isRequired 17 | } 18 | 19 | state = { 20 | // fetchCache: 'only-if-cached' 21 | fetchCache: 'force-cache' 22 | } 23 | 24 | componentDidMount = () => { 25 | this.loadImage() 26 | } 27 | 28 | getTrueUrl = () => { 29 | const { source } = this.props 30 | return source[0].uri 31 | } 32 | 33 | loadImage = () => { 34 | this.setState({ 35 | promise: new Promise((resolve, reject) => { 36 | const url = this.getTrueUrl() 37 | if (!url) return reject(new Error('No Address')) 38 | 39 | if (cache[url]) { 40 | return resolve(cache[url]) 41 | } 42 | 43 | if (isBase64(url)) { 44 | return resolve(url) 45 | } 46 | 47 | // console.log(`: cache: ${this.state.fetchCache}`) 48 | fetch(url, { 49 | cache: this.state.fetchCache 50 | }).then((res) => { 51 | return res.blob() 52 | }).then((imgBlob) => { 53 | const objectURL = URL.createObjectURL(imgBlob) 54 | cache[url] = objectURL 55 | resolve(objectURL) 56 | }).catch((e) => { 57 | reject(e) 58 | }) 59 | }) 60 | }) 61 | } 62 | 63 | _renderLoading = (props) => { 64 | return ( 65 | 66 | 67 | 68 | ) 69 | } 70 | 71 | _renderFail = (props) => { 72 | return ( 73 | 图片加载失败 76 | ) 77 | } 78 | 79 | render() { 80 | const Loading = this.props.renderLoading || this._renderLoading 81 | const Fail = this.props.renderFail || this._renderFail 82 | 83 | return ( 84 | { 87 | if (status === 'resolved') { 88 | return ( 89 | {this.props.alt} 94 | ) 95 | } 96 | if (status === 'rejected') return 97 | if (status === 'pending') return 98 | return null 99 | }} 100 | /> 101 | ) 102 | } 103 | } 104 | 105 | 106 | const styles = StyleSheet.create({ 107 | img: { 108 | 109 | } 110 | }) 111 | 112 | export default Image -------------------------------------------------------------------------------- /packages/menu/README.md: -------------------------------------------------------------------------------- 1 | # @react-web/menu 2 | 3 | ## Usage 4 | 5 | ```js 6 | import { Menu } from '@react-web/components' 7 | // import Menu from '@react-web/menu' 8 | ``` 9 | 10 | ## LICENSE 11 | 12 | [MIT↗](../../LICENSE) -------------------------------------------------------------------------------- /packages/menu/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for @react-web/menu 2 | // Project: @react-web/menu 3 | // Definitions by: heineiuo 4 | 5 | import * as React from 'react'; 6 | 7 | type P = any 8 | 9 | export default Menu 10 | 11 | declare class Menu extends React.Component<{ 12 | isRoot?: boolean, 13 | getKey?: (item: any) => string, 14 | style?: any, 15 | itemStyle?: any, 16 | arrowStyle?: any, 17 | top?: number, 18 | left?: number, 19 | width?: number, 20 | parentRight?: number, 21 | parentWidth?: number, 22 | parentTop?: number, 23 | onClickItem?: React.EventHandler

, 24 | renderItem: (P) => React.ReactElement

25 | }, any > {} -------------------------------------------------------------------------------- /packages/menu/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = module.exports.default = require('./dist/Menu').default; -------------------------------------------------------------------------------- /packages/menu/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-web/menu", 3 | "version": "0.2.6", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "files": [ 7 | "dist", 8 | "index.js", 9 | "index.d.ts" 10 | ], 11 | "scripts": { 12 | "prepublish": "babel src -d dist" 13 | }, 14 | "dependencies": { 15 | "@react-web/stylesheet": "^0.2.6", 16 | "@react-web/view": "^0.2.6" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/menu/src/Menu.js: -------------------------------------------------------------------------------- 1 | import React, { Component, Fragment } from 'react' 2 | import ReactDOM from 'react-dom' 3 | import View from '@react-web/view' 4 | import StyleSheet from '@react-web/stylesheet' 5 | 6 | class Menu extends Component { 7 | 8 | static defaultProps = { 9 | isRoot: true, 10 | getKey: (item) => item.key, 11 | style: {}, 12 | itemStyle: {}, 13 | arrowStyle: {}, 14 | top: 0, 15 | left: 0, 16 | width: 200, 17 | parentRight: 0, 18 | parentWidth: 0, 19 | parentTop: 0, 20 | onClickItem: () => { }, 21 | renderItem: (props) => { 22 | return ( 23 |

{props.name}
24 | ) 25 | } 26 | } 27 | 28 | constructor(props) { 29 | super(props) 30 | this._mountPoint = document.createElement('div') 31 | this.getMountWrapper().appendChild(this._mountPoint) 32 | } 33 | 34 | state = { 35 | visible: false, 36 | refTop: 0, 37 | updateTimes: 0, 38 | visibleStyle: {} 39 | } 40 | 41 | getMountWrapper = () => { 42 | if (this.props.getMountWrapper) return this.props.getMountWrapper() 43 | if (this._mountWrapper) return this._mountWrapper 44 | const id = '__menu' 45 | this._mountWrapper = document.getElementById(id) 46 | if (!this._mountWrapper) { 47 | this._mountWrapper = document.createElement('div') 48 | this._mountWrapper.id = id 49 | document.body.appendChild(this._mountWrapper) 50 | return this._mountWrapper 51 | } 52 | return this._mountWrapper 53 | } 54 | 55 | componentDidMount = () => { 56 | this.checkPosition() 57 | } 58 | 59 | componentWillUnmount = () => { 60 | this._mountPoint.remove() 61 | } 62 | 63 | componentDidUpdate = () => { 64 | // this.checkPosition() 65 | } 66 | 67 | getRef = ref => this.refRoot = ReactDOM.findDOMNode(ref) 68 | 69 | checkPosition = () => { 70 | if (!this.state.visible && !!this.refRoot) { 71 | const { width, height, left, top } = this.refRoot.getBoundingClientRect() 72 | const visibleStyle = { 73 | width, 74 | height, 75 | left, 76 | top, 77 | } 78 | const { innerWidth, innerHeight } = window 79 | if (left + width > innerWidth) { 80 | visibleStyle.left -= (this.props.parentWidth || 0) 81 | visibleStyle.left -= width 82 | } 83 | if (top + height > innerHeight) { 84 | visibleStyle.top = innerHeight - height 85 | } 86 | 87 | this.setState((prevState) => { 88 | return { 89 | visible: true, 90 | visibleStyle, 91 | updateTimes: prevState.updateTimes++ 92 | } 93 | }) 94 | } 95 | } 96 | 97 | onMouseEnter = (e, refName) => { 98 | const top = e.target.getBoundingClientRect().top 99 | this.setState((prevState) => { 100 | // const isSame = prevState.hovered === refName 101 | const isSame = false 102 | return { 103 | hovered: isSame ? null : refName, 104 | refTop: isSame ? 0 : top, 105 | showHoverStyle: !isSame 106 | } 107 | }) 108 | } 109 | 110 | onMouseLeave = (e, refName) => { 111 | this.setState({ 112 | showHoverStyle: false 113 | }) 114 | } 115 | 116 | renderArrow = (props) => { 117 | const { arrowStyle } = this.props 118 | return ( 119 | 125 | 126 | 127 | ) 128 | } 129 | 130 | render() { 131 | const { 132 | getKey, 133 | isRoot, 134 | isBranch, 135 | renderItem, 136 | data, 137 | parentTop = 0, 138 | parentRight = 0, 139 | style, 140 | itemStyle, 141 | onClickItem 142 | } = this.props 143 | const Arrow = this.renderArrow 144 | 145 | const { 146 | refTop, 147 | visible, 148 | visibleStyle, 149 | showHoverStyle, 150 | hovered, 151 | } = this.state 152 | 153 | const mergedVisibleStyle = { 154 | visibility: visible ? 'visible' : 'hidden', 155 | left: (!isRoot && visible) ? visibleStyle.left : parentRight, 156 | top: (!isRoot && visible) ? visibleStyle.top : parentTop, 157 | } 158 | 159 | return ReactDOM.createPortal( 160 | 168 | {data.map((item, index) => { 169 | const refName = `ref${index}` 170 | const isHovered = hovered === refName 171 | const hasChildren = item.children && item.children.length > 0 172 | return ( 173 | this[refName] = ref} 177 | onMouseEnter={(e) => this.onMouseEnter(e, refName)} 178 | onMouseLeave={(e) => this.onMouseLeave(e, refName)} 179 | > 180 | 181 | onClickItem(e, item)} style={[styles.menuItemWrapper, itemStyle]}> 182 | {renderItem({ item })} 183 | {hasChildren ? : null} 184 | 185 | {(hasChildren && isHovered) ? 186 | : 198 | null 199 | } 200 | 201 | 202 | ) 203 | })} 204 | , 205 | this._mountPoint 206 | ) 207 | } 208 | } 209 | 210 | const styles = StyleSheet.create({ 211 | menu: { 212 | boxShadow: '0 0 14px 0 rgba(33, 33, 33, 0.4)', 213 | borderRadius: 4, 214 | padding: 4, 215 | backgroundColor: '#fafafa', 216 | position: 'absolute', 217 | }, 218 | 219 | menuItem: { 220 | whiteSpace: 'nowrap', 221 | cursor: 'default', 222 | marginLeft: -4, 223 | marginRight: -4, 224 | height: 24, 225 | lineHeight: '24px', 226 | fontSize: 14, 227 | color: '#333', 228 | backgroundColor: '#fafafa', 229 | ":hover": { 230 | backgroundColor: '#3E9AFF', 231 | color: '#FFF' 232 | } 233 | }, 234 | 235 | menuItemWrapper: { 236 | padding: '0 16px', 237 | display: 'flex', 238 | alignItems: 'center', 239 | justifyContent: 'space-between' 240 | } 241 | }) 242 | 243 | export default Menu -------------------------------------------------------------------------------- /packages/platform/README.md: -------------------------------------------------------------------------------- 1 | # @react-web/platform 2 | 3 | ## Usage 4 | 5 | 6 | 7 | ## License 8 | [MIT↗](../../LICENSE) -------------------------------------------------------------------------------- /packages/platform/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for @react-web/platform 2 | // Project: react-web 3 | // Definitions by: heineiuo 4 | 5 | import * as React from 'react'; 6 | 7 | type P = any 8 | 9 | export default Platform 10 | 11 | declare class Platform extends React.Component<{ 12 | rules: any, 13 | className: string, 14 | style: any 15 | }, any > { 16 | 17 | 18 | } -------------------------------------------------------------------------------- /packages/platform/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = module.exports.default = require('./dist/Platform').default; -------------------------------------------------------------------------------- /packages/platform/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-web/platform", 3 | "version": "0.2.4", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "files": [ 7 | "dist", 8 | "index.js", 9 | "index.d.ts" 10 | ], 11 | "scripts": { 12 | "prepublish": "babel src -d dist" 13 | }, 14 | "dependencies": { 15 | "ua-parser-js": "^0.7.18" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/platform/src/Platform.js: -------------------------------------------------------------------------------- 1 | // @unstable 2 | 3 | import React, { Component } from 'react' 4 | import UAParser from 'ua-parser-js' 5 | 6 | const parser = new UAParser() 7 | const result = parser.getResult() 8 | 9 | const OS = result.os.name 10 | const OSVersion = result.os.version 11 | const Browser = result.browser.name 12 | const BrowserVersion = result.browser.version 13 | const DeviceType = result.device.type 14 | const DeviceModel = result.device.model 15 | const DeviceVendor = result.device.vendor 16 | const Engine = result.engine.name 17 | const EngineVersion = result.engine.version 18 | const CPU = result.cpu.architecture 19 | const UA = result.ua 20 | 21 | const props = { 22 | OS, 23 | OSVersion, 24 | Browser, 25 | BrowserVersion, 26 | DeviceType, 27 | DeviceModel, 28 | DeviceVendor, 29 | Engine, 30 | EngineVersion, 31 | CPU, 32 | UA 33 | } 34 | 35 | class Platform extends Component { 36 | static OS = OS 37 | static OSVersion = OSVersion 38 | static Browser = Browser 39 | static BrowserVersion = BrowserVersion 40 | static DeviceType = DeviceType 41 | static DeviceModel = DeviceModel 42 | static DeviceVendor = DeviceVendor 43 | static Engine = Engine 44 | static EngineVersion = EngineVersion 45 | static CPU = CPU 46 | static UA = UA 47 | 48 | static defaultProps = { 49 | rules: {}, 50 | className: '', 51 | style: {} 52 | } 53 | 54 | static select = (selectMap) => { 55 | return Object.keys(selectMap).find(key => { 56 | return key === this.OS 57 | }) 58 | } 59 | 60 | render() { 61 | const { children, rules, className, style } = this.props 62 | if (typeof children === 'function') return children(props) 63 | const illegal = Object.keys(rules).find(key => props[key] !== rules[key]) 64 | if (illegal) return null; 65 | if (typeof children === 'string' || children instanceof Array) return React.createElement('div', { className, style }, children); 66 | return React.cloneElement(children) 67 | } 68 | } 69 | 70 | export default Platform -------------------------------------------------------------------------------- /packages/popup/README.md: -------------------------------------------------------------------------------- 1 | # @react-web/popup 2 | 3 | ## Usage 4 | 5 | ```js 6 | import { Popup } from '@react-web/components' 7 | // import Popup from '@react-web/popup' 8 | 9 | ``` 10 | 11 | ## License 12 | [MIT↗](../../LICENSE) 13 | 14 | -------------------------------------------------------------------------------- /packages/popup/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for @react-web/popup 2 | // Project: react-web 3 | // Definitions by: heineiuo 4 | 5 | 6 | import * as React from 'react'; 7 | 8 | type P = any 9 | 10 | declare class Popup extends React.Component<{ 11 | offsetTop?: number; 12 | offsetLeft?: number; 13 | onToggle?: () => {}; 14 | action?: string[]; 15 | renderOverlay: (overlayProps: { 16 | closePopup: () => {}, 17 | getMountWrapper: () => {}, 18 | portalStyle: any 19 | }) => React.ReactElement

; 20 | }, any> { } 21 | 22 | export default Popup -------------------------------------------------------------------------------- /packages/popup/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = module.exports.default = require('./dist/Popup').default; -------------------------------------------------------------------------------- /packages/popup/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-web/popup", 3 | "version": "0.2.6", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "files": [ 7 | "dist", 8 | "index.js", 9 | "index.d.ts" 10 | ], 11 | "scripts": { 12 | "prepublish": "babel src -d dist" 13 | }, 14 | "dependencies": { 15 | "@react-web/stylesheet": "^0.2.6", 16 | "@react-web/view": "^0.2.6" 17 | }, 18 | "peerDependencies": { 19 | "lodash": "^4.17.10" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/popup/src/Popup.js: -------------------------------------------------------------------------------- 1 | import React, { Component, Fragment } from 'react' 2 | import ReactDOM from 'react-dom' 3 | import PropTypes from 'prop-types' 4 | import View from '@react-web/view' 5 | import StyleSheet from '@react-web/stylesheet' 6 | import pick from 'lodash/pick' 7 | import isEqual from 'lodash/isEqual' 8 | 9 | const noop = () => { } 10 | 11 | const pickRect = (obj) => pick(obj, ['top', 'left', 'width', 'height']) 12 | 13 | const id = 'ReactBucketPopup' 14 | 15 | /** 16 | * @class Popup 17 | * @summary 弹出层 18 | * @description 19 | * IMPORTANT: React v16+ required 20 | */ 21 | class Popup extends Component { 22 | 23 | static defaultProps = { 24 | onClick: noop, 25 | onToggle: () => { }, 26 | offsetTop: 0, 27 | offsetLeft: 0, 28 | renderOverlay: () => null, 29 | className: '', 30 | component: 'div', 31 | action: ['click'] 32 | } 33 | 34 | constructor(props) { 35 | super(props) 36 | this.el = document.createElement('div') 37 | } 38 | 39 | state = { 40 | open: false 41 | } 42 | 43 | updatePosition = () => { 44 | const rect = pickRect(this.wrapper.getBoundingClientRect()) 45 | const prevState = pickRect(this.state) 46 | if (!isEqual(prevState, rect)) { 47 | this.setState(rect) 48 | } 49 | } 50 | 51 | getMountWrapper = () => { 52 | if (this._mountWrapper) return this._mountWrapper 53 | this._mountWrapper = document.getElementById(id) 54 | if (!this._mountWrapper) { 55 | this._mountWrapper = document.createElement('div') 56 | this._mountWrapper.id = id 57 | document.body.appendChild(this._mountWrapper) 58 | return this._mountWrapper 59 | } 60 | return this._mountWrapper 61 | } 62 | 63 | componentDidMount() { 64 | document.addEventListener('click', this.handleDocumentClick, false) 65 | document.addEventListener('mousemove', this.handleDocumentMouseMove, false) 66 | this.getMountWrapper().appendChild(this.el) 67 | this.updatePosition() 68 | } 69 | 70 | componentDidUpdate = () => { 71 | this.updatePosition() 72 | } 73 | 74 | componentWillUnmount() { 75 | document.removeEventListener('click', this.handleDocumentClick, false) 76 | document.removeEventListener('mousemove', this.handleDocumentMouseMove, false) 77 | this.el.remove() 78 | } 79 | 80 | getWrapperRef = ref => this.wrapper = ReactDOM.findDOMNode(ref) 81 | getPortalRef = ref => this.portal = ReactDOM.findDOMNode(ref) 82 | 83 | getOverlayMountWrapper = () => { 84 | return this.portal 85 | } 86 | 87 | handleDocumentClick = (e) => { 88 | if (!(this.portal.contains(e.target) || this.wrapper.contains(e.target)) && this.state.open) { 89 | this.handleCloseOverlay(e) 90 | } 91 | } 92 | 93 | handleClick = (e) => { 94 | this.setState({ open: !this.state.open }, () => { 95 | this.props.onToggle({ open: this.state.open }) 96 | }) 97 | this.props.onClick(e) 98 | } 99 | 100 | handleMouseEnter = (e) => { 101 | this.setState({ open: true }, () => { 102 | this.props.onToggle({ open: this.state.open }) 103 | }) 104 | } 105 | 106 | handleDocumentMouseMove = (e) => { 107 | if (!this.props.action.includes('hover')) return false 108 | const isOutWrapper = (() => { 109 | if (!this.wrapper) return true 110 | if (this.wrapper.contains(e.target)) return false 111 | return true 112 | })() 113 | 114 | const isOutPortal = (() => { 115 | if (!this.portal) return true 116 | if (this.portal.contains(e.target)) return false 117 | return true 118 | })() 119 | 120 | if (isOutWrapper && isOutPortal) { 121 | if (this.state.open) this.handleCloseOverlay(e) 122 | } 123 | } 124 | 125 | closeOverlay = () => { 126 | this.setState({ open: !this.state.open }, () => { 127 | this.props.onToggle({ open: this.state.open }) 128 | }) 129 | } 130 | 131 | handleCloseOverlay = (e) => { 132 | this.closeOverlay() 133 | } 134 | 135 | render() { 136 | const { className, style, renderOverlay, action } = this.props 137 | const { open } = this.state 138 | const WrapperComponent = this.props.component || View 139 | 140 | const wrapperEventProps = {} 141 | const portalEventProps = {} 142 | if (action.includes('click')) { 143 | wrapperEventProps.onClick = this.handleClick 144 | } 145 | if (action.includes('hover')) { 146 | wrapperEventProps.onMouseEnter = this.handleMouseEnter 147 | // wrapperEventProps.onMouseLeave = this.handleMouseOutWrapper 148 | // portalEventProps.onMouseLeave = this.handleMouseOutPortal 149 | } 150 | 151 | const overlayProps = { 152 | closePopup: this.closeOverlay, 153 | getMountWrapper: this.getOverlayMountWrapper, 154 | portalStyle: !open ? { display: 'none' } : { 155 | position: 'absolute', 156 | width: this.state.width, 157 | height: this.state.height, 158 | top: this.state.top + this.state.height + this.props.offsetTop, 159 | left: this.state.left + this.props.offsetLeft, 160 | } 161 | } 162 | 163 | return ( 164 | 165 | 170 | {this.props.children} 171 | 172 | {ReactDOM.createPortal( 173 | 177 | {!open ? null : renderOverlay(overlayProps)} 178 | , 179 | this.el 180 | )} 181 | 182 | ) 183 | } 184 | } 185 | 186 | export default Popup 187 | -------------------------------------------------------------------------------- /packages/popup/tests/Popup.js: -------------------------------------------------------------------------------- 1 | import Popup from '../src/Popup' -------------------------------------------------------------------------------- /packages/promise-view/README.md: -------------------------------------------------------------------------------- 1 | # @react-web/promise-view 2 | 3 | ## Usage 4 | 5 | ```js 6 | import PromiseView from '@react-web/promise-view' 7 | // or 8 | // import { PromiseView } from '@react-web/components' 9 | 10 | render( 11 | 12 | {(state, result) => { 13 | if (state === 'resolved') return

Data: {result}
14 | if (state === 'rejected') return
Error: {result.message}
15 | if (state === 'pending') return
Loading...
16 | return null 17 | }} 18 | 19 | ) 20 | ``` 21 | 22 | ## Reference 23 | 24 | [如何优雅地结合类 Redux 处理异步通信的中间状态? 25 | ](https://www.zhihu.com/question/66869266/answer/345948392) 26 | 27 | ## License 28 | 29 | [MIT↗](../../LICENSE) -------------------------------------------------------------------------------- /packages/promise-view/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for @react-web/promise-view 2 | // Project: react-web 3 | // Definitions by: heineiuo 4 | 5 | 6 | import * as React from 'react'; 7 | 8 | 9 | 10 | export interface PromiseViewProps { 11 | promise: Promise, 12 | onStateChange?: (status: string, result: any) => {}, 13 | render?: (status: string, result: any) => {}, 14 | } 15 | 16 | declare class PromiseView extends React.Component { 17 | 18 | } 19 | 20 | export default PromiseView -------------------------------------------------------------------------------- /packages/promise-view/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = module.exports.default = require('./dist/PromiseView').default; -------------------------------------------------------------------------------- /packages/promise-view/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-web/promise-view", 3 | "version": "0.2.4", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "prepublish": "babel src -d dist" 8 | }, 9 | "files": [ 10 | "dist", 11 | "index.js", 12 | "index.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/promise-view/src/PromiseView.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import EventEmitter from 'events' 3 | 4 | export const __unstable_P2E = (promise) => { 5 | const emitter = new EventEmitter() 6 | 7 | promise.then(res => { 8 | emitter.emit('change', 'resolved', res) 9 | }).catch(err => { 10 | emitter.emit('change', 'rejected', err) 11 | }) 12 | 13 | return emitter 14 | } 15 | 16 | class PromiseView extends Component { 17 | static defaultProps = { 18 | onStateChange: new Function() 19 | } 20 | 21 | state = {} 22 | 23 | componentDidMount = () => { 24 | this.initListener(this.props) 25 | } 26 | 27 | componentDidUpdate = (prevProps) => { 28 | if (this.props.promise != prevProps.promise) { 29 | this.initListener(this.props) 30 | } 31 | } 32 | 33 | initListener = (props) => { 34 | if (this.listener) this.listener.removeAllListeners() 35 | if (!(props.promise instanceof Promise)) { 36 | this.setState({ status: 'none' }) 37 | props.onStateChange('none') 38 | this.listener = null 39 | } else { 40 | this.setState({ status: 'pending' }) 41 | props.onStateChange('pending') 42 | this.listener = __unstable_P2E(props.promise) 43 | this.listener.on('change', (status, result) => { 44 | this.setState({ status, result }) 45 | props.onStateChange(status, result) 46 | }) 47 | } 48 | } 49 | 50 | componentWillUnmount = () => { 51 | if (this.listener) this.listener.removeAllListeners() 52 | } 53 | 54 | render() { 55 | const { render, children = null } = this.props 56 | if (typeof render === 'function') return render(this.state.status, this.state.result) 57 | if (typeof children === 'function') return children(this.state.status, this.state.result) 58 | return children 59 | } 60 | } 61 | 62 | export default PromiseView 63 | -------------------------------------------------------------------------------- /packages/scroll-view/README.md: -------------------------------------------------------------------------------- 1 | # @react-web/scroll-view 2 | 3 | 4 | ## Usage 5 | 6 | ```js 7 | import { ScrollView } from '@react-web/components' 8 | // import ScrollView from '@react-web/scroll-view' 9 | 10 | ``` 11 | 12 | ## License 13 | [MIT↗](../../LICENSE) -------------------------------------------------------------------------------- /packages/scroll-view/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for @react-web/scroll-view 2 | // Project: @react-web/scroll-view 3 | // Definitions by: heineiuo 4 | 5 | import * as React from 'react'; 6 | 7 | type P = any 8 | 9 | export default ScrollView 10 | 11 | declare class ScrollView extends React.Component<{ 12 | onEndReached: React.EventHandler

13 | }, any> { 14 | 15 | 16 | } -------------------------------------------------------------------------------- /packages/scroll-view/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = module.exports.default = require('./dist/ScrollView').default; -------------------------------------------------------------------------------- /packages/scroll-view/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-web/scroll-view", 3 | "version": "0.2.4", 4 | "main": "index.js", 5 | "files": [ 6 | "dist", 7 | "index.js", 8 | "index.d.ts" 9 | ], 10 | "scripts": { 11 | "prepublish": "babel src -d dist" 12 | }, 13 | "peerDependencies": { 14 | "lodash": "*" 15 | }, 16 | "license": "MIT" 17 | } 18 | -------------------------------------------------------------------------------- /packages/scroll-view/src/ScrollView.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import ReactDOM from 'react-dom' 3 | import throttle from 'lodash/throttle' 4 | 5 | class ScrollView extends Component { 6 | 7 | static defaultProps = { 8 | onEndReached: () => { } 9 | } 10 | 11 | onWheel = e => { 12 | if (this._tick) return false 13 | requestAnimationFrame(() => { 14 | this._tick = true 15 | this.update(e) 16 | }) 17 | } 18 | componentDidMount = () => { 19 | this.update() 20 | this.scrollTop = this.wrapper.scrollTop 21 | } 22 | 23 | update = (e) => { 24 | this._tick = false 25 | const scrollTop = this.wrapper.scrollTop 26 | const wrapperHeight = this.wrapper.offsetHeight 27 | const childHeight = ReactDOM.findDOMNode(this.child).offsetHeight 28 | if (this.scrollTop !== scrollTop && scrollTop + wrapperHeight > childHeight - 200) { 29 | this.props.onEndReached() 30 | } 31 | this.scrollTop = scrollTop 32 | } 33 | 34 | _tick = false 35 | 36 | refWrapper = ref => this.wrapper = ref 37 | refChild = ref => this.child = ref 38 | 39 | render() { 40 | const { style = {}, children, width } = this.props 41 | const clonedChildren = React.cloneElement(children({ 42 | width, 43 | scrollTop: this.scrollTop 44 | }), { ref: this.refChild }) 45 | return ( 46 |

{clonedChildren}
52 | ) 53 | } 54 | } 55 | 56 | export default ScrollView 57 | -------------------------------------------------------------------------------- /packages/slider/README.md: -------------------------------------------------------------------------------- 1 | # @react-web/slider 2 | 3 | 4 | ## Usage 5 | 6 | ```js 7 | import { Slider } from '@react-web/components' 8 | 9 | ``` 10 | 11 | ## License 12 | [MIT↗](../../LICENSE) -------------------------------------------------------------------------------- /packages/slider/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for @react-web/button 2 | // Project: @react-web/button 3 | // Definitions by: heineiuo 4 | 5 | import * as React from 'react'; 6 | 7 | type P = any 8 | 9 | export default Slider 10 | 11 | declare class Slider extends React.Component<{}, any>{ } -------------------------------------------------------------------------------- /packages/slider/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = module.exports.default = require('./dist/Slider').default; -------------------------------------------------------------------------------- /packages/slider/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-web/slider", 3 | "version": "0.2.4", 4 | "main": "index.js", 5 | "scripts": { 6 | "prepublish": "babel src -d dist" 7 | }, 8 | "files": [ 9 | "dist", 10 | "index.js", 11 | "index.d.ts" 12 | ], 13 | "license": "MIT" 14 | } 15 | -------------------------------------------------------------------------------- /packages/slider/src/Slider.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | class Slider extends Component { 4 | 5 | render() { 6 | const props = Object.assign({ 7 | min: 1, 8 | max: 10, 9 | step: '0.0.1', 10 | }, this.props) 11 | 12 | return ( 13 | 14 | ) 15 | } 16 | } 17 | 18 | export default Slider -------------------------------------------------------------------------------- /packages/stylesheet/README.md: -------------------------------------------------------------------------------- 1 | # @react-web/stylesheet 2 | 3 | ## Install 4 | 5 | ```sh 6 | → npm i @react-web/stylesheet 7 | ``` 8 | 9 | 10 | ## API 11 | 12 | * `StyleSheet.create(styleMap: Object) styles: object` 13 | * `StyleSheet.assign(styleList | styleMap) prefixedStyle: object` 14 | * `StyleSheet.flatten(nestedStyleList: Array): styleList: Array` 15 | 16 | Example: 17 | 18 | ```js 19 | import { StyleSheet, View } from 'react-bucket' 20 | 21 | const styles = StyleSheet.create({ 22 | btn: { 23 | height: 36, 24 | textAlign: 'center' 25 | }, 26 | btn_red: { 27 | backgroundColor: '#F33' 28 | } 29 | }) 30 | 31 | ReactDOM.render( 32 | Click Me! 33 | ) 34 | 35 | ``` 36 | 37 | ## LICENSE 38 | [MIT↗](../../LICENSE) -------------------------------------------------------------------------------- /packages/stylesheet/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for @react-web/stylesheet 2 | // Project: react-web 3 | // Definitions by: heineiuo 4 | 5 | import * as React from 'react'; 6 | 7 | type RegisteredStyle = number & { __registeredStyleBrand: T }; 8 | 9 | declare class StyleMap { 10 | [styleName: string]: CSSStyleDeclaration 11 | } 12 | 13 | declare namespace StyleSheet { 14 | 15 | type NamedStyles = { [P in keyof T]: StyleMap }; 16 | 17 | export function create>(styles: T): { [P in keyof T]: RegisteredStyle } 18 | 19 | export function flatten(style?: RegisteredStyle): T; 20 | 21 | export function assign(style?: RegisteredStyle): T; 22 | 23 | } 24 | 25 | export default StyleSheet 26 | -------------------------------------------------------------------------------- /packages/stylesheet/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = module.exports.default = require('./dist/StyleSheet').default -------------------------------------------------------------------------------- /packages/stylesheet/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-web/stylesheet", 3 | "version": "0.2.6", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "prepublish": "babel src -d dist" 8 | }, 9 | "files": [ 10 | "dist", 11 | "index.js", 12 | "index.d.ts" 13 | ], 14 | "keywords": [], 15 | "author": "", 16 | "license": "MIT", 17 | "dependencies": { 18 | "inline-style-prefixer": "^4.0.2" 19 | }, 20 | "devDependencies": { 21 | "lodash": "^4.17.10" 22 | }, 23 | "peerDependencies": { 24 | "lodash": "^4.17.10" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/stylesheet/src/StyleSheet.js: -------------------------------------------------------------------------------- 1 | import Prefixer from 'inline-style-prefixer' 2 | import isPlainObject from 'lodash/isPlainObject' 3 | import flatten from 'lodash/flatten' 4 | 5 | const prefixer = new Prefixer() 6 | 7 | /** 8 | * if itme has prop `_definition` then prefix it (for styles created by aphrodite) 9 | */ 10 | const _compatiblePrefix = (item) => { 11 | return item.hasOwnProperty('_definition') ? prefixer.prefix(item._definition) : item 12 | } 13 | 14 | const _assignFlattenStyles = (styleList) => { 15 | return styleList.reduce((left, right) => { 16 | Object.assign(left, isPlainObject(right) ? _compatiblePrefix(right) : {}) 17 | return left 18 | }, {}) 19 | } 20 | 21 | const flattenStyles = (styleList) => { 22 | return flatten(styleList).map(_compatiblePrefix) 23 | } 24 | 25 | const assignStyles = (params) => { 26 | return _assignFlattenStyles(flatten(params instanceof Array ? params : [params])) 27 | } 28 | 29 | const create = (rawStyleMap) => { 30 | return Object.entries(rawStyleMap).reduce((left, [key, value]) => { 31 | left[key] = prefixer.prefix(value) 32 | return left 33 | }, {}) 34 | } 35 | 36 | export default { 37 | create, 38 | flatten: flattenStyles, 39 | assign: assignStyles 40 | } 41 | -------------------------------------------------------------------------------- /packages/svg/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for @react-web/button 2 | // Project: @react-web/button 3 | // Definitions by: heineiuo 4 | 5 | import * as React from 'react'; 6 | 7 | type P = any -------------------------------------------------------------------------------- /packages/svg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-web/svg", 3 | "version": "0.2.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "files": [ 7 | "index.js", 8 | "index.d.ts", 9 | "dist" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/svg/src/Svg.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heineiuo/react-web/12a10e18ed7eb2b1dcc0d507d1e33113318d24c0/packages/svg/src/Svg.js -------------------------------------------------------------------------------- /packages/text-input/README.md: -------------------------------------------------------------------------------- 1 | # @react-web/text-input 2 | 3 | ## Usage 4 | 5 | ```js 6 | import { TextInput } from 'react-web/components' 7 | // import TextInput from 'react-web/text-input' 8 | 9 | render( 10 | 13 | ) 14 | ``` 15 | 16 | ## License 17 | [MIT↗](../../LICENSE) -------------------------------------------------------------------------------- /packages/text-input/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for @react-web/text-input 2 | // Project: react-web 3 | // Definitions by: heineiuo 4 | 5 | import * as React from 'react'; 6 | 7 | 8 | declare class TextInput extends React.Component<{ 9 | enableFocus?: boolean; 10 | focusStyle?: object | object[]; 11 | affix?: string; 12 | withAffix?: boolean; 13 | type?: string; 14 | dispatch?: () => {}; 15 | }, any> { 16 | 17 | } 18 | 19 | 20 | export default TextInput -------------------------------------------------------------------------------- /packages/text-input/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = module.exports.default = require('./dist/TextInput').default; -------------------------------------------------------------------------------- /packages/text-input/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-web/text-input", 3 | "version": "0.2.6", 4 | "main": "index.js", 5 | "files": [ 6 | "dist", 7 | "index.js", 8 | "index.d.ts" 9 | ], 10 | "license": "MIT", 11 | "scripts": { 12 | "prepublish": "babel src -d dist" 13 | }, 14 | "dependencies": { 15 | "@react-web/stylesheet": "^0.2.6", 16 | "@react-web/view": "^0.2.6" 17 | }, 18 | "peerDependencies": { 19 | "lodash": "*" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/text-input/src/TextInput.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import PropTypes from 'prop-types' 3 | import omit from 'lodash/omit' 4 | import StyleSheet from '@react-web/stylesheet' 5 | import View from '@react-web/view' 6 | 7 | class TextInput extends Component { 8 | 9 | state = { 10 | isFocused: false 11 | } 12 | 13 | static defaultProps = { 14 | type: 'normal', 15 | withAffix: false, 16 | enableFocus: true, 17 | affix: '' 18 | } 19 | 20 | static propTypes = { 21 | enableFocus: PropTypes.bool, 22 | focusStyle: PropTypes.any, 23 | affix: PropTypes.string, 24 | withAffix: PropTypes.bool, 25 | type: PropTypes.string, 26 | dispatch: PropTypes.func 27 | } 28 | 29 | _onfocus = (e) => { 30 | if (this.props.type === 'password') { 31 | this._input.removeAttribute('readonly') 32 | } 33 | this.setState({ isFocused: true }) 34 | this.props.onFocus && this.props.onFocus(e) 35 | } 36 | 37 | _onblur = (e) => { 38 | this.setState({ isFocused: false }) 39 | if (this.props.type === 'password') { 40 | this._input.setAttribute('readonly', true) 41 | } 42 | this.props.onBlur && this.props.onBlur(e) 43 | } 44 | 45 | focus = () => { 46 | this._input.focus() 47 | } 48 | 49 | blur = () => { 50 | this._input.blur() 51 | } 52 | 53 | getValue = () => { 54 | return this._input.value 55 | } 56 | 57 | renderWithAffix = (props) => { 58 | return ( 59 | 60 | {this.props.affix} 61 | this._input = ref} {...props.inputProps} /> 62 | 63 | ) 64 | } 65 | 66 | render() { 67 | const { isFocused } = this.state 68 | const { children, enableFocus, type, withAffix, style, focusStyle, color } = this.props 69 | const inputProps = omit(this.props, Object.keys(TextInput.propTypes).concat([])) 70 | 71 | inputProps.style = StyleSheet.assign([styles.input, style, isFocused && [styles.input_focus, focusStyle]]) 72 | inputProps.type = this.props.type 73 | 74 | if (withAffix) { 75 | return this.renderWithAffix({ inputProps }) 76 | } 77 | 78 | if (enableFocus) { 79 | Object.assign(inputProps, { 80 | onFocus: this._onfocus, 81 | onBlur: this._onblur 82 | }) 83 | } 84 | 85 | if (type === 'password') { 86 | inputProps.readOnly = true 87 | } 88 | 89 | return ( 90 | this._input = ref} 92 | {...inputProps} 93 | /> 94 | ) 95 | } 96 | } 97 | 98 | const styles = StyleSheet.create({ 99 | inputWrapper: { 100 | display: 'flex', 101 | }, 102 | inputWrapper_withAffix: { 103 | position: 'relative', 104 | background: '#f3f6f8', 105 | border: '1px solid #c8d7e1', 106 | color: '#4f748e', 107 | padding: '8px 14px', 108 | whiteSpace: 'nowrap', 109 | flex: 1, 110 | fontSize: 16, 111 | lineHeight: 1.5, 112 | }, 113 | input: { 114 | minHeight: 32, 115 | padding: 4, 116 | boxSizing: 'border-box', 117 | outline: 'none', 118 | fontSize: 14, 119 | borderWidth: 1, 120 | borderRadius: 3, 121 | borderColor: '#a0a0a0', 122 | display: 'block', 123 | width: '100%', 124 | borderStyle: 'solid' 125 | }, 126 | input_focus: { 127 | borderColor: '#505050' 128 | } 129 | }) 130 | 131 | export default TextInput 132 | -------------------------------------------------------------------------------- /packages/text/README.md: -------------------------------------------------------------------------------- 1 | # @react-web/text 2 | 3 | ## Usage 4 | 5 | ```js 6 | import { Text } from '@react-web/components' 7 | ``` 8 | 9 | ## License 10 | [MIT↗](../../LICENSE) -------------------------------------------------------------------------------- /packages/text/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for @react-web/text 2 | // Project: react-web 3 | // Definitions by: heineiuo 4 | 5 | import * as React from 'react'; 6 | 7 | type P = any 8 | 9 | export default Text 10 | 11 | declare class Text extends React.Component<{}, any> { 12 | 13 | } -------------------------------------------------------------------------------- /packages/text/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = module.exports.default = require('./dist/Text').default; -------------------------------------------------------------------------------- /packages/text/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-web/text", 3 | "version": "0.2.4", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "files": [ 7 | "dist", 8 | "index.js", 9 | "index.d.ts" 10 | ], 11 | "scripts": { 12 | "prepublish": "babel src -d dist" 13 | }, 14 | "peerDependencies": { 15 | "react": "*" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/text/src/Text.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const Text = (props) => {props.children} 4 | 5 | export default Text -------------------------------------------------------------------------------- /packages/touchable/README.md: -------------------------------------------------------------------------------- 1 | # @react-web/touchable 2 | 3 | ## Usage 4 | 5 | 6 | ## License 7 | [MIT↗](../../LICENSE) -------------------------------------------------------------------------------- /packages/touchable/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for @react-web/touchable 2 | // Project: react-web 3 | // Definitions by: heineiuo 4 | 5 | import * as React from 'react'; 6 | 7 | type P = any 8 | 9 | export { 10 | TouchableOpacity 11 | } 12 | 13 | declare class TouchableOpacity extends React.Component<{}, any>{} 14 | -------------------------------------------------------------------------------- /packages/touchable/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = module.exports.default = { 4 | TouchableOpacity: require('./dist/TouchableOpacity').default 5 | }; -------------------------------------------------------------------------------- /packages/touchable/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-web/touchable", 3 | "version": "0.2.6", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "files": [ 7 | "dist", 8 | "index.js", 9 | "index.d.ts" 10 | ], 11 | "scripts": { 12 | "prepublish": "babel src -d dist" 13 | }, 14 | "dependencies": { 15 | "@react-web/stylesheet": "^0.2.6", 16 | "@react-web/view": "^0.2.6" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/touchable/src/TouchableOpacity.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import View from '@react-web/view' 3 | import StyleSheet from '@react-web/stylesheet' 4 | 5 | class TouchableOpacity extends Component { 6 | 7 | static defaultProps = { 8 | onMouseDown: () => { }, 9 | onMouseUp: () => { }, 10 | onTouchStart: () => { }, 11 | onMouseLeave: () => { }, 12 | onTouchEnd: () => { }, 13 | } 14 | 15 | onMouseDown = (e) => { 16 | this.getRef().style.opacity = 0.5 17 | this.props.onMouseDown(e) 18 | } 19 | 20 | onMouseUp = (e) => { 21 | this.getRef().style.opacity = 1 22 | this.props.onMouseUp(e) 23 | } 24 | 25 | onMouseUp = (e) => { 26 | this.getRef().style.opacity = 1 27 | this.props.onMouseUp(e) 28 | } 29 | onMouseLeave = (e) => { 30 | this.getRef().style.opacity = 1 31 | this.props.onMouseLeave(e) 32 | } 33 | 34 | onTouchStart = (e) => { 35 | this.getRef().style.opacity = 0.5 36 | this.props.onTouchStart(e) 37 | } 38 | onTouchEnd = (e) => { 39 | this.getRef().style.opacity = 1 40 | this.props.onTouchEnd(e) 41 | } 42 | 43 | getRef = (ref) => { 44 | if (!ref) return this._ref.getRef() 45 | return this._ref = ref 46 | } 47 | 48 | render() { 49 | const { onMouseDown, onMouseUp, onTouchEnd, onMouseLeave, onTouchStart, } = this 50 | const props = Object.assign({}, this.props, { 51 | onMouseDown, 52 | onMouseUp, 53 | onTouchEnd, 54 | onTouchStart, 55 | onMouseLeave 56 | }) 57 | 58 | props.style = StyleSheet.assign([{ 59 | cursor: 'pointer', 60 | transition: 'opacity .15s ease' 61 | }, this.props.style]) 62 | 63 | return ( 64 | 68 | ) 69 | } 70 | } 71 | 72 | export default TouchableOpacity 73 | -------------------------------------------------------------------------------- /packages/triangle-arrow/README.md: -------------------------------------------------------------------------------- 1 | 2 | # @react-web/triangle-arrow 3 | 4 | 5 | ## Usage 6 | 7 | ```js 8 | import TriangleArrow from 'react-web/triangle-arrow' 9 | ``` 10 | 11 | 12 | 13 | ## License 14 | [MIT↗](../../LICENSE) -------------------------------------------------------------------------------- /packages/triangle-arrow/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for @react-web/button 2 | // Project: @react-web/button 3 | // Definitions by: heineiuo 4 | 5 | import * as React from 'react'; 6 | 7 | type P = any 8 | 9 | declare class TriangleArrow extends React.Component<{ 10 | wrapperStyle?: any, 11 | border?: string, 12 | width?: number, 13 | boxShadow?: string, 14 | }, any> {} -------------------------------------------------------------------------------- /packages/triangle-arrow/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = module.exports.default = require('./dist/TriangleArrow').default -------------------------------------------------------------------------------- /packages/triangle-arrow/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-web/triangle-arrow", 3 | "version": "0.2.6", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "files": [ 7 | "dist", 8 | "index.js", 9 | "index.d.ts" 10 | ], 11 | "scripts": { 12 | "prepublish": "babel src -d dist" 13 | }, 14 | "dependencies": { 15 | "@react-web/stylesheet": "^0.2.6" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/triangle-arrow/src/TriangleArrow.js: -------------------------------------------------------------------------------- 1 | // @unstable 2 | 3 | import React, { Component } from 'react' 4 | import View from '@react-web/view' 5 | import StyleSheet from '@react-web/stylesheet' 6 | 7 | class TriangleArrow extends Component { 8 | static defaultProps = { 9 | wrapperStyle: { 10 | position: 'absolute' 11 | }, 12 | border: '1px solid #e6e6e6', 13 | width: 14, 14 | boxShadow: '0 0 5px 1px rgba(0,0,0,.0975)', 15 | } 16 | 17 | render() { 18 | const { border, width, boxShadow, wrapperStyle } = this.props 19 | return ( 20 | 21 | 22 | 23 | 24 | ) 25 | } 26 | } 27 | 28 | const styles = StyleSheet.create({ 29 | shadow: { 30 | position: 'absolute', 31 | background: '#fff', 32 | border: '1px solid #e6e6e6', 33 | boxShadow: '0 0 5px 1px rgba(0,0,0,.0975)', 34 | height: '14px', 35 | left: '4px', 36 | top: '8px', 37 | transform: 'rotate(45deg)', 38 | width: '14px', 39 | zIndex: -1, 40 | }, 41 | mask: { 42 | position: 'absolute', 43 | borderColor: 'transparent transparent #fff', 44 | borderStyle: 'solid', 45 | borderWidth: '0 10px 10px', 46 | height: 0, 47 | top: '6px', 48 | left: '2px', 49 | width: 0, 50 | zIndex: 1, 51 | } 52 | }) 53 | 54 | export default TriangleArrow -------------------------------------------------------------------------------- /packages/utils/README.md: -------------------------------------------------------------------------------- 1 | 2 | # @react-web/utils 3 | 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { Utils } from 'react-web/components' 9 | // import Utils from 'react-web/utils' 10 | ``` 11 | 12 | ## API 13 | 14 | ### `Utils.flatten` 15 | 16 | 17 | ## License 18 | [MIT↗](../../LICENSE) -------------------------------------------------------------------------------- /packages/utils/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for @react-web/utils 2 | // Project: react-web 3 | // Definitions by: heineiuo 4 | 5 | import * as React from 'react'; 6 | 7 | type P = any 8 | 9 | export = ReactWebUtils 10 | 11 | declare namespace ReactWebUtils { 12 | 13 | function attrAccept(file: any, acceptedFiles: string[]) 14 | 15 | function dataURLToBlob(dataURL: string) 16 | 17 | } -------------------------------------------------------------------------------- /packages/utils/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = module.exports.default = { 4 | attrAccept: require('./dist/attr-accept').default, 5 | dataURLToBlob: require('./dist/data-url-to-blob').default 6 | }; -------------------------------------------------------------------------------- /packages/utils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-web/utils", 3 | "version": "0.2.4", 4 | "main": "index.js", 5 | "files": [ 6 | "dist", 7 | "index.js", 8 | "index.d.ts" 9 | ], 10 | "scripts": { 11 | "prepublish": "babel src -d dist" 12 | }, 13 | "license": "MIT" 14 | } 15 | -------------------------------------------------------------------------------- /packages/utils/src/attr-accept.js: -------------------------------------------------------------------------------- 1 | // https://github.com/okonet/attr-accept 2 | 3 | export default function attrAccept(file, acceptedFiles) { 4 | if (file && acceptedFiles) { 5 | const acceptedFilesArray = (Array.isArray(acceptedFiles) ? 6 | acceptedFiles : 7 | acceptedFiles.split(',')); 8 | const fileName = file.name || ''; 9 | const mimeType = file.type || ''; 10 | const baseMimeType = mimeType.replace(/\/.*$/, ''); 11 | 12 | return acceptedFilesArray.some(type => { 13 | const validType = type.trim(); 14 | if (validType.charAt(0) === '.') { 15 | return fileName.toLowerCase().endsWith(validType.toLowerCase()); 16 | } else if (/\/\*$/.test(validType)) { 17 | // This is something like a image/* mime type 18 | return baseMimeType === validType.replace(/\/.*$/, ''); 19 | } 20 | return mimeType === validType; 21 | }); 22 | } 23 | return true; 24 | } -------------------------------------------------------------------------------- /packages/utils/src/data-url-to-blob.js: -------------------------------------------------------------------------------- 1 | 2 | export default function dataURLToBlob(dataURL) { 3 | const BASE64_MARKER = ';base64,' 4 | 5 | if (dataURL.indexOf(BASE64_MARKER) == -1) { 6 | const parts = dataURL.split(',') 7 | const contentType = parts[0].split(':')[1] 8 | const raw = decodeURIComponent(parts[1]) 9 | return new Blob([raw], { type: contentType }) 10 | } 11 | 12 | const parts = dataURL.split(BASE64_MARKER) 13 | const contentType = parts[0].split(':')[1] 14 | const raw = window.atob(parts[1]) 15 | const rawLength = raw.length 16 | 17 | let uInt8Array = new Uint8Array(rawLength) 18 | 19 | for (let i = 0; i < rawLength; ++i) { 20 | uInt8Array[i] = raw.charCodeAt(i) 21 | } 22 | return new Blob([uInt8Array], { type: contentType }) 23 | } -------------------------------------------------------------------------------- /packages/vendor/README.md: -------------------------------------------------------------------------------- 1 | # @react-web/vendor 2 | 3 | 4 | ## Install 5 | 6 | ```html 7 | 8 | ``` 9 | 10 | ## License 11 | 12 | [MIT↗](../../LICENSE) -------------------------------------------------------------------------------- /packages/vendor/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for @react-web/vendor 2 | // Project: @react-web/vendor 3 | // Definitions by: heineiuo 4 | 5 | import React, { Component } from 'react' 6 | import ReactDOM from 'react-dom' 7 | import * as ReactRouter from 'react-router-dom' 8 | import * as ReactRouterRedux from 'react-router-redux' 9 | import Modal from 'react-modal' 10 | import System from 'systemjs' 11 | import * as Redux from 'redux' 12 | import * as ReactRedux from 'react-redux' 13 | import PropTypes from 'prop-types' 14 | import * as history from 'history' 15 | import ReduxThunk from 'redux-thunk' 16 | import { Adopt, adopt } from 'react-adopt' 17 | import { Motion, spring } from 'react-motion' 18 | import * as Keyframes from 'react-keyframes' 19 | 20 | export { 21 | Adopt, 22 | React, 23 | ReactDOM, 24 | ReactRouter, 25 | ReactRedux, 26 | ReactRouterRedux, 27 | PropTypes, 28 | Component, 29 | Modal, 30 | Motion, 31 | Redux, 32 | adopt, 33 | Keyframes, 34 | spring, 35 | } -------------------------------------------------------------------------------- /packages/vendor/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * @todo fetch polyfill will be removed in future 5 | */ 6 | require('whatwg-fetch'); 7 | 8 | module.exports = module.exports.default = require('./dist/Vendor'); 9 | -------------------------------------------------------------------------------- /packages/vendor/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-web/vendor", 3 | "version": "0.2.6", 4 | "description": "", 5 | "main": "index.js", 6 | "browser": "dist/vendor.production.js", 7 | "scripts": { 8 | "build:dev": "../../node_modules/.bin/webpack --config=webpack.dev.js", 9 | "build": "../../node_modules/.bin/webpack --config=webpack.prod.js", 10 | "prepublish": "babel src -d dist && npm run build:dev && npm run build" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "MIT", 15 | "files": [ 16 | "dist", 17 | "index.js", 18 | "index.d.ts" 19 | ], 20 | "devDependencies": { 21 | "@react-web/webpack": "^0.2.6" 22 | }, 23 | "dependencies": { 24 | "attr-accept": "^1.1.0", 25 | "babel-runtime": "^6.26.0", 26 | "history": "^4.7.2", 27 | "inline-style-prefixer": "^4.0.0", 28 | "is-base64": "0.0.4", 29 | "lodash": "^4.17.5", 30 | "prop-types": "^15.6.0", 31 | "react": "^16.3.2", 32 | "react-adopt": "^0.4.1", 33 | "react-dom": "^16.3.2", 34 | "react-grid-system": "^3.1.2", 35 | "react-keyframes": "^0.2.3", 36 | "react-modal": "^3.1.11", 37 | "react-motion": "^0.5.2", 38 | "react-redux": "^5.0.6", 39 | "react-router-dom": "^4.2.2", 40 | "react-router-redux": "^5.0.0-alpha.9", 41 | "redux": "^3.7.2", 42 | "redux-thunk": "^2.2.0", 43 | "systemjs": "^0.20.19", 44 | "warning": "^3.0.0", 45 | "whatwg-fetch": "^2.0.3" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /packages/vendor/src/Vendor.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import ReactDOM from 'react-dom' 3 | import * as ReactRouter from 'react-router-dom' 4 | import * as ReactRouterRedux from 'react-router-redux' 5 | import Modal from 'react-modal' 6 | import System from 'systemjs' 7 | import * as Redux from 'redux' 8 | import * as ReactRedux from 'react-redux' 9 | import PropTypes from 'prop-types' 10 | import * as history from 'history' 11 | import ReduxThunk from 'redux-thunk' 12 | import { Adopt, adopt } from 'react-adopt' 13 | import * as ReactMotion from 'react-motion' 14 | import * as Keyframes from 'react-keyframes' 15 | 16 | /** 17 | * Motion 18 | */ 19 | const { Motion, spring } = ReactMotion 20 | 21 | /** 22 | * redux 23 | */ 24 | const { connect } = ReactRedux 25 | const { bindActionCreators } = Redux 26 | 27 | /** 28 | * Router 29 | */ 30 | const { Route, Link, Switch: RouteSwitch } = ReactRouter 31 | 32 | /** 33 | * System registry 34 | */ 35 | const systemRegisties = [ 36 | { name: 'systemjs', default: System, aliasName: [] }, 37 | { name: 'react', default: React, aliasName: ['React'] }, 38 | { name: 'react-dom', default: ReactDOM, aliasName: ['ReactDOM'] }, 39 | { name: 'react-router-dom', default: ReactRouter, aliasName: ['ReactRouterDOM'] }, 40 | { name: 'react-redux', default: ReactRedux, aliasName: ['ReactRedux'] }, 41 | { name: 'react-router-redux', default: ReactRouterRedux, aliasName: ['ReactRouterRedux'] }, 42 | { name: 'redux', default: Redux, aliasName: ['Redux'] }, 43 | { name: 'react-modal', default: Modal, aliasName: ['ReactModal'] }, 44 | { name: 'react-motion', default: ReactMotion, aliasName: ['ReactMotion'] }, 45 | { name: 'redux-thunk', default: ReduxThunk, aliasName: ['ReduxThunk'] }, 46 | { name: 'prop-types', default: PropTypes, aliasName: ['PropTypes'] } 47 | ] 48 | 49 | 50 | systemRegisties.forEach(item => { 51 | global[item.name] = item.default 52 | item.aliasName.forEach(name => { 53 | global[name] = item.default 54 | }) 55 | System.registry.set( 56 | System.resolveSync(item.name), 57 | System.newModule(item.default) 58 | ) 59 | }) 60 | 61 | 62 | /** 63 | * Export Third-party Components 64 | */ 65 | export { 66 | Adopt, 67 | React, 68 | ReactDOM, 69 | ReactRouter, 70 | ReactRedux, 71 | ReactRouterRedux, 72 | PropTypes, 73 | Component, 74 | Modal, 75 | Motion, 76 | Redux, 77 | connect, 78 | adopt, 79 | Keyframes, 80 | bindActionCreators, 81 | spring, 82 | } 83 | 84 | -------------------------------------------------------------------------------- /packages/vendor/src/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = module.exports.default = require('./Vendor'); 4 | -------------------------------------------------------------------------------- /packages/vendor/webpack.dev.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | const { createWebpackConfig } = require('@react-web/webpack') 4 | 5 | const __DEV__ = process.env.NODE_ENV === 'development' 6 | 7 | module.exports = createWebpackConfig({ 8 | __DEV__: true, 9 | noServe: true, 10 | "publicPathPrefix": "https://cdn.jsdelivr.net/npm/", 11 | "context": "./", 12 | "outputDir": "./dist/", 13 | "entry": "./src/index.js", 14 | "nodeModulesDir": "../../node_modules/", 15 | "alias": [ 16 | { "commonjs": "systemjs", "path": "./systemjs/dist/system.js" }, 17 | ] 18 | }) 19 | -------------------------------------------------------------------------------- /packages/vendor/webpack.prod.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | const { createWebpackConfig } = require('@react-web/webpack') 4 | 5 | const __DEV__ = process.env.NODE_ENV === 'development' 6 | 7 | module.exports = createWebpackConfig({ 8 | __DEV__: false, 9 | "publicPathPrefix": "https://cdn.jsdelivr.net/npm/", 10 | "context": "./", 11 | "outputDir": "./dist/", 12 | "entry": "./src/index.js", 13 | "nodeModulesDir": "../../node_modules/", 14 | "alias": [ 15 | { "commonjs": "systemjs", "path": "./systemjs/dist/system.js" }, 16 | ] 17 | }) 18 | -------------------------------------------------------------------------------- /packages/view/README.md: -------------------------------------------------------------------------------- 1 | # @react-web/view 2 | 3 | ## Usage 4 | 5 | ```js 6 | import { View } from 'react-web/components' 7 | // import View from 'react-web/view' 8 | ``` 9 | 10 | ## License 11 | [MIT↗](../../LICENSE) -------------------------------------------------------------------------------- /packages/view/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for @react-web/view 2 | // Project: react-web 3 | // Definitions by: heineiuo 4 | 5 | 6 | import * as React from 'react'; 7 | 8 | export interface ViewProps { 9 | hoverStyle?: object | object[]; 10 | style?: object | object[]; 11 | enableHover?: boolean; 12 | } 13 | 14 | declare class View extends React.Component { 15 | 16 | } 17 | 18 | export default View -------------------------------------------------------------------------------- /packages/view/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = module.exports.default = require('./dist/View').default; -------------------------------------------------------------------------------- /packages/view/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-web/view", 3 | "version": "0.2.6", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "prepublish": "babel src -d dist" 8 | }, 9 | "files": [ 10 | "dist", 11 | "index.js", 12 | "index.d.ts" 13 | ], 14 | "dependencies": { 15 | "@react-web/stylesheet": "^0.2.6" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/view/src/View.js: -------------------------------------------------------------------------------- 1 | import React, { Component, createElement } from 'react' 2 | import omit from 'lodash/omit' 3 | import StyleSheet from '@react-web/stylesheet' 4 | 5 | class View extends Component { 6 | 7 | static defaultProps = { 8 | enableHover: false, 9 | inline: false 10 | } 11 | 12 | state = { 13 | isHovered: false 14 | } 15 | 16 | _mouseenter = (e) => { 17 | this.setState({ isHovered: true }) 18 | this.props.onStateChange && this.props.onStateChange({ isHovered: true }) 19 | this.props.onMouseEnter && this.props.onMouseEnter(e) 20 | } 21 | 22 | _mouseleave = (e) => { 23 | this.setState({ isHovered: false }) 24 | this.props.onStateChange && this.props.onStateChange({ isHovered: false }) 25 | this.props.onMouseLeave && this.props.onMouseLeave(e) 26 | } 27 | 28 | getRef = () => { 29 | return this._ref 30 | } 31 | 32 | render() { 33 | const { isHovered } = this.state 34 | const { children, enableHover, style, className, hoverStyle, inline } = this.props 35 | const el = typeof children === 'function' ? children({ 36 | isHovered 37 | }) : children 38 | 39 | let type = inline ? 'span' : 'div' 40 | 41 | const props = omit(this.props, ['enableHover', 'style', 'inline', 'hoverStyle']) 42 | props.style = StyleSheet.assign([style, isHovered && hoverStyle]) 43 | props.ref = ref => this._ref = ref 44 | 45 | if (enableHover) { 46 | Object.assign(props, { 47 | onMouseEnter: this._mouseenter, 48 | onMouseLeave: this._mouseleave 49 | }) 50 | } 51 | 52 | return createElement(type, props, el) 53 | } 54 | } 55 | 56 | export default View 57 | -------------------------------------------------------------------------------- /packages/webpack/README.md: -------------------------------------------------------------------------------- 1 | # @react-web/webpack 2 | 3 | A collection of helpers for webpack. 4 | 5 | ## License 6 | [MIT↗](../../LICENSE) -------------------------------------------------------------------------------- /packages/webpack/index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for @react-web/webpack 2 | // Project: @react-web/webpack 3 | // Definitions by: heineiuo 4 | 5 | type P = any 6 | 7 | export = WebpackHelper 8 | 9 | declare namespace WebpackHelper { 10 | 11 | function createWebpackConfig

(configProps: { 12 | __DEV__?: boolean, 13 | context?: string, 14 | noServe?: boolean, 15 | platform?: string, 16 | entry?: string, 17 | nodeModulesDir?: string, 18 | packageFile?: string, 19 | outputDir?: string, 20 | publicPathPrefix?: string, 21 | devPublicPathPrefix?: string, 22 | }) 23 | 24 | } 25 | -------------------------------------------------------------------------------- /packages/webpack/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | module.exports = module.exports.default = { 4 | createWebpackConfig: require('./dist/createWebpackConfig') 5 | } 6 | -------------------------------------------------------------------------------- /packages/webpack/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-web/webpack", 3 | "version": "0.2.6", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "prepublish": "babel src -d dist" 8 | }, 9 | "files": [ 10 | "dist", 11 | "index.js", 12 | "index.d.ts" 13 | ], 14 | "dependencies": { 15 | "babel-core": "^6.26.0", 16 | "babel-loader": "^7.1.2", 17 | "babel-plugin-transform-class-properties": "^6.24.1", 18 | "babel-plugin-transform-runtime": "^6.23.0", 19 | "babel-preset-es2015": "^6.24.1", 20 | "babel-preset-react": "^6.24.1", 21 | "babel-preset-stage-0": "^6.24.1", 22 | "mkdirp": "^0.5.1", 23 | "stats-webpack-plugin": "^0.6.2", 24 | "webpack": "^4.8.3", 25 | "webpack-cli": "^2.1.3", 26 | "webpack-node-externals": "^1.7.2", 27 | "webpack-system-register": "^1.5.1", 28 | "webpack-visualizer-plugin": "^0.1.11" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/webpack/src/Webpack.js: -------------------------------------------------------------------------------- 1 | const Webpack = { 2 | externals: [ 3 | { commonjs: 'react', root: 'React' } 4 | ] 5 | } 6 | 7 | export default Webpack -------------------------------------------------------------------------------- /packages/webpack/src/createWebpackConfig.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | const url = require('url') 4 | const nodeExternals = require('webpack-node-externals') 5 | const webpack = require('webpack') 6 | const mkdirp = require('mkdirp') 7 | const trimEnd = require('lodash/trimEnd') 8 | const defaults = require('lodash/defaults') 9 | 10 | const createWebpackConfig = (configFile) => { 11 | 12 | defaults(configFile, { 13 | __DEV__: process.env.NODE_ENV != 'production', 14 | context: process.cwd(), 15 | noServe: false, 16 | platform: 'web', 17 | entry: './src/index.js', 18 | nodeModulesDir: './node_modules', 19 | packageFile: './package.json', 20 | outputDir: './umd', 21 | publicPathPrefix: 'https://cdn.jsdelivr.net/npm', 22 | devPublicPathPrefix: 'http://localhost:8080' 23 | }) 24 | 25 | const { 26 | __DEV__, 27 | noServe, 28 | context, 29 | platform, 30 | nodeModulesDir, 31 | packageFile, 32 | outputDir, 33 | devPublicPathPrefix, 34 | publicPathPrefix, 35 | } = configFile 36 | 37 | console.log(`NODE_ENV: ${__DEV__ ? 'development' : 'production'}`) 38 | 39 | const packageJSON = JSON.parse( 40 | fs.readFileSync(path.resolve(context, packageFile), 'utf8') 41 | ) 42 | 43 | const nodeModulesPath = path.resolve(context, nodeModulesDir) + path.sep 44 | const outputPath = path.resolve(context, outputDir) + path.sep 45 | const publicPath = url.resolve(publicPathPrefix, '') + path.posix.resolve(`/${packageJSON.name}@${packageJSON.version}`, outputDir).substr(1) + '/' 46 | 47 | const devPublicPath = '/' 48 | const entryName = path.basename(packageJSON.name) 49 | 50 | const config = { 51 | context: path.resolve(__dirname, context), 52 | devtool: __DEV__ ? 'inline-source-map' : false, 53 | node: { 54 | fs: 'empty' 55 | }, 56 | entry: { 57 | [entryName]: [ 58 | path.resolve(context, configFile.entry) 59 | ] 60 | }, 61 | target: platform, 62 | output: { 63 | path: outputPath, 64 | publicPath: __DEV__ ? devPublicPath : publicPath, 65 | filename: `[name].${__DEV__ ? 'development' : 'production'}.js`, 66 | library: packageJSON.name, 67 | libraryTarget: platform === 'web' ? 'umd' : 'commonjs2', 68 | umdNamedDefine: platform === 'web' ? true : false 69 | }, 70 | externals: platform === 'node' ? [nodeExternals()] : {}, 71 | resolve: { 72 | alias: {}, 73 | extensions: ['.jsx', '.js', '.json'], 74 | modules: [ 75 | 'node_modules', 76 | path.resolve(context, `node_modules`), 77 | ] 78 | }, 79 | module: { 80 | rules: [ 81 | { 82 | test: /\.(png|jpg|jpeg|svg|gif)$/, 83 | loader: 'url-loader?limit=1024&name=images/[hash].[ext]' 84 | }, 85 | { 86 | test: /\.(json)$/, 87 | loader: 'json-loader' 88 | }, 89 | { 90 | test: /\.hash\.css$/, 91 | use: [ 92 | 'style-loader', 93 | 'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]' 94 | ] 95 | }, 96 | { 97 | test: /^((?!hash).)*\.css$/, 98 | use: [ 99 | 'style-loader', 100 | 'css-loader', 101 | ] 102 | }, 103 | { 104 | test: /(\.js|\.jsx)$/, 105 | exclude: /(node_modules)/, 106 | loader: 'babel-loader' 107 | } 108 | ] 109 | }, 110 | plugins: [], 111 | // mode: __DEV__ ? 'development' : 'production' 112 | } 113 | 114 | if (__DEV__ && !noServe) { 115 | config.serve = { 116 | content: __dirname, 117 | dev: { 118 | publicPath: '/', 119 | }, 120 | hot: true, 121 | } 122 | } 123 | 124 | if (configFile.externals) { 125 | configFile.externals.forEach(externalItem => { 126 | config.externals[externalItem.commonjs] = Object.assign({ 127 | root: externalItem.commonjs 128 | }, externalItem) 129 | }) 130 | } 131 | 132 | if (configFile.alias) { 133 | configFile.alias.forEach(aliasItem => { 134 | config.resolve.alias[aliasItem.commonjs] = path.resolve(nodeModulesPath, aliasItem.path) 135 | }) 136 | } 137 | 138 | if (__DEV__) { 139 | config.plugins.push(new webpack.DefinePlugin({ 140 | 'process.env.NODE_ENV': JSON.stringify('development') 141 | })) 142 | } else { 143 | config.plugins.push(new webpack.DefinePlugin({ 144 | 'process.env.NODE_ENV': JSON.stringify('production') 145 | })) 146 | } 147 | 148 | return config 149 | } 150 | 151 | module.exports = createWebpackConfig 152 | -------------------------------------------------------------------------------- /scripts/glob-babel.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heineiuo/react-web/12a10e18ed7eb2b1dcc0d507d1e33113318d24c0/scripts/glob-babel.js -------------------------------------------------------------------------------- /scripts/update-gh-pages.sh: -------------------------------------------------------------------------------- 1 | #! /usr/local/bash 2 | 3 | npm run build-storybook 4 | cd storybook-static 5 | ga . 6 | gc -m "update" 7 | gp 8 | -------------------------------------------------------------------------------- /stories/index.stories.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { storiesOf } from '@storybook/react'; 4 | import { action } from '@storybook/addon-actions'; 5 | import { linkTo } from '@storybook/addon-links'; 6 | 7 | import { View, Button, TextInput, Menu } from '@react-web/components'; 8 | 9 | storiesOf('Welcome', module) 10 | .add('to Storybook', () => { 11 | return ( 12 | 13 | Welcome 14 | 15 | ) 16 | }); 17 | 18 | storiesOf('Button', module) 19 | .add('with text', () => ( 20 | 23 | )) 24 | .add('with some emoji', () => ( 25 | 26 | )); 27 | 28 | 29 | 30 | storiesOf('TextInput', module) 31 | .add('with text', () => ( 32 | 33 | )) 34 | 35 | storiesOf('Menu', module) 36 | .add('basic', () => ( 37 | 38 |

39 |
40 | )) --------------------------------------------------------------------------------