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 |
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 |
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 |
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 | ))
--------------------------------------------------------------------------------