🚚 Post lerna init and import of packages
This commit is contained in:
parent
d73cd3512c
commit
921a757356
48 changed files with 14830 additions and 0 deletions
15
lerna.json
Normal file
15
lerna.json
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"version": "0.0.0",
|
||||
"npmClient": "npm",
|
||||
"command": {
|
||||
"publish": {
|
||||
"ignoreChanges": ["ignored-file", "*.md"],
|
||||
"message": "chore(release): publish"
|
||||
},
|
||||
"bootstrap": {
|
||||
"ignore": "component-*",
|
||||
"npmClientArgs": ["--no-package-lock"]
|
||||
}
|
||||
},
|
||||
"packages": ["packages/*"]
|
||||
}
|
7
package.json
Normal file
7
package.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name": "root",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"lerna": "^3.13.3"
|
||||
}
|
||||
}
|
13
packages/components/.editorconfig
Normal file
13
packages/components/.editorconfig
Normal file
|
@ -0,0 +1,13 @@
|
|||
# editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
66
packages/components/.gitignore
vendored
Normal file
66
packages/components/.gitignore
vendored
Normal file
|
@ -0,0 +1,66 @@
|
|||
# Compiled code
|
||||
dist
|
||||
tests/dist
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
coverage.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# TypeScript v1 declaration files
|
||||
typings/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
|
||||
# next.js build output
|
||||
.next
|
1
packages/components/.npmignore
Normal file
1
packages/components/.npmignore
Normal file
|
@ -0,0 +1 @@
|
|||
dist/
|
21
packages/components/LICENSE
Normal file
21
packages/components/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2019 freesewing
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
57
packages/components/README.md
Normal file
57
packages/components/README.md
Normal file
|
@ -0,0 +1,57 @@
|
|||
<p align="center">
|
||||
<a title="Go to freesewing.org" href="https://freesewing.org/"><img src="https://freesewing.org/img/logo/black.svg" align="center" width="150px" alt="Freesewing logo"/></a>
|
||||
</p>
|
||||
<h4 align="center"><em> <a title="Go to freesewing.org" href="https://freesewing.org/">freesewing</a></em>
|
||||
<br><sup>a library for made-to-measure sewing patterns</sup>
|
||||
</h4>
|
||||
<p align="center">
|
||||
<a href="https://www.npmjs.com/package/@freesewing/components"><img src="https://badgen.net/npm/v/@freesewing/components" alt="Version"></a>
|
||||
<a href="https://www.npmjs.com/package/@freesewing/components"><img src="https://badgen.net/npm/license/@freesewing/components" alt="License"></a>
|
||||
<a href="https://deepscan.io/dashboard#view=project&tid=2114&pid=4633&bid=37171"><img src="https://deepscan.io/api/teams/2114/projects/4633/branches/37171/badge/grade.svg" alt="DeepScan grade"></a>
|
||||
<a href="https://gitter.im/freesewing/freesewing"><img src="https://badgen.net/badge/chat/on%20Gitter/cyan" alt="Chat on Gitter"></a>
|
||||
<a href="https://freesewing.org/patrons/join"><img src="https://badgen.net/badge/become/a%20Patron/FF5B77" alt="Become a Patron"></a>
|
||||
</p>
|
||||
|
||||
# @freesewing/components
|
||||
|
||||
This is a [Material UI](https://material-ui.com) theme that's used by the freesewing web sites.
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
npm i --save @freesewing/components
|
||||
```
|
||||
|
||||
## Getting the theme
|
||||
|
||||
After installing [@freesewing/components](https://www.npmjs.com/package/@freesewing/components),
|
||||
import it:
|
||||
|
||||
```js
|
||||
import createTheme from "@freesewing/components";
|
||||
```
|
||||
|
||||
The default export (`createTheme` in our example above) is a method that
|
||||
calls [`createMuiTheme`](https://material-ui.com/customization/themes/#createmuitheme-options-theme) under the hood.
|
||||
It takes a single argument, the theme name:
|
||||
|
||||
```
|
||||
object createTheme(string themeName = "light")
|
||||
```
|
||||
|
||||
If the name you pass it is `dark` you'll get the dark theme.
|
||||
Anything else, and you'll get the light theme.
|
||||
|
||||
## Using the theme
|
||||
|
||||
To use this theme, you need to pass it as the `theme` prop to
|
||||
[`muiThemeProvider`](https://material-ui.com/customization/themes/#muithemeprovider):
|
||||
|
||||
```js
|
||||
<MuiThemeProvider theme={createTheme(true)}>
|
||||
// ... your app here
|
||||
</MuiThemeProvider>
|
||||
```
|
||||
|
||||
See [the Material-UI docs on themes](https://material-ui.com/customization/themes/) for more details.
|
70
packages/components/package.json
Normal file
70
packages/components/package.json
Normal file
|
@ -0,0 +1,70 @@
|
|||
{
|
||||
"name": "@freesewing/components",
|
||||
"version": "0.0.1",
|
||||
"description": "A collection of React components for freesewing web UIs",
|
||||
"author": "Joost De Cock <joost@decock.org> (https://github.com/joostdecock)",
|
||||
"homepage": "https://freesewing.org/",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/freesewing/components.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/freesewing/components/issues"
|
||||
},
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.mjs",
|
||||
"scripts": {
|
||||
"patch": "npm version patch -m ':bookmark: v%s' && npm run build",
|
||||
"minor": "npm version minor -m ':bookmark: v%s' && npm run build",
|
||||
"major": "npm version major -m ':bookmark: v%s' && npm run build",
|
||||
"precommit": "npm run pretty && lint-staged",
|
||||
"clean": "rimraf dist",
|
||||
"pretty": "npx prettier --write 'src/*.js'",
|
||||
"lint": "eslint --fix 'src/*.js'",
|
||||
"nodebuild": "rollup --silent -c -o dist/index.js -f cjs -e bezier-js,bin-pack",
|
||||
"modulebuild": "rollup --silent -c -o dist/index.mjs -f esm",
|
||||
"build": "npm run clean && npm run nodebuild && npm run modulebuild"
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "lint-staged"
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{js,json}": [
|
||||
"prettier --write",
|
||||
"git add"
|
||||
]
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.3.3",
|
||||
"@babel/plugin-proposal-object-rest-spread": "7.4.3",
|
||||
"@babel/preset-env": "7.3.1",
|
||||
"babel-eslint": "^8.2.6",
|
||||
"eslint": "5.14.0",
|
||||
"eslint-config-prettier": "^2.10.0",
|
||||
"eslint-config-standard": "12.0.0",
|
||||
"eslint-plugin-import": "2.15.0",
|
||||
"eslint-plugin-node": "8.0.1",
|
||||
"eslint-plugin-prettier": "2.7.0",
|
||||
"eslint-plugin-promise": "4.0.1",
|
||||
"eslint-plugin-standard": "4.0.0",
|
||||
"husky": "^0.14.3",
|
||||
"lint-staged": "^7.3.0",
|
||||
"prettier": "1.16.4",
|
||||
"rimraf": "2.6.3",
|
||||
"rollup": "0.63.4",
|
||||
"rollup-plugin-babel": "4.3.2",
|
||||
"rollup-plugin-commonjs": "9.2.0",
|
||||
"rollup-plugin-json": "^3.1.0",
|
||||
"rollup-plugin-node-resolve": "^3.4.0",
|
||||
"rollup-plugin-terser": "^1.0.1"
|
||||
},
|
||||
"files": [
|
||||
"dist/*",
|
||||
"README.md",
|
||||
"package.json"
|
||||
]
|
||||
}
|
27
packages/components/src/Emblem/index.js
Normal file
27
packages/components/src/Emblem/index.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
const Emblem = props => (
|
||||
<React.Fragment>
|
||||
<span className="emb" style={{color: props.c1}}>{props.t1}</span>
|
||||
<span className="lem" style={{color: props.c2}}>{props.t2}</span>
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
Emblem.propTypes = {
|
||||
size: PropTypes.number,
|
||||
c1: PropTypes.string,
|
||||
c2: PropTypes.string,
|
||||
t1: PropTypes.string,
|
||||
t2: PropTypes.string,
|
||||
};
|
||||
|
||||
Emblem.defaultProps = {
|
||||
size: 24,
|
||||
c1: "#111111",
|
||||
c2: "#111111",
|
||||
t1: "",
|
||||
t2: ""
|
||||
};
|
||||
|
||||
export default Emblem;
|
34
packages/components/src/Logo/index.js
Normal file
34
packages/components/src/Logo/index.js
Normal file
File diff suppressed because one or more lines are too long
12
packages/workbench/.babelrc
Normal file
12
packages/workbench/.babelrc
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"presets": [
|
||||
["env", {
|
||||
"modules": false
|
||||
}],
|
||||
"stage-0",
|
||||
"react"
|
||||
],
|
||||
"plugins": [
|
||||
["transform-object-rest-spread", { "useBuiltIns": true }]
|
||||
]
|
||||
}
|
9
packages/workbench/.editorconfig
Normal file
9
packages/workbench/.editorconfig
Normal file
|
@ -0,0 +1,9 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
23
packages/workbench/.eslintrc
Normal file
23
packages/workbench/.eslintrc
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"parser": "babel-eslint",
|
||||
"extends": [
|
||||
"standard",
|
||||
"standard-react"
|
||||
],
|
||||
"env": {
|
||||
"es6": true
|
||||
},
|
||||
"plugins": [
|
||||
"react"
|
||||
],
|
||||
"parserOptions": {
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
// don't force es6 functions to include space before paren
|
||||
"space-before-function-paren": 0,
|
||||
|
||||
// allow specifying true explicitly for boolean props
|
||||
"react/jsx-boolean-value": 0
|
||||
}
|
||||
}
|
22
packages/workbench/.gitignore
vendored
Normal file
22
packages/workbench/.gitignore
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
# See https://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
node_modules
|
||||
|
||||
# builds
|
||||
build
|
||||
dist
|
||||
.rpt2_cache
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
4
packages/workbench/.travis.yml
Normal file
4
packages/workbench/.travis.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- 9
|
||||
- 8
|
21
packages/workbench/LICENSE
Normal file
21
packages/workbench/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2019 freesewing
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
31
packages/workbench/README.md
Normal file
31
packages/workbench/README.md
Normal file
|
@ -0,0 +1,31 @@
|
|||
# workbench
|
||||
|
||||
> A React component to facilitate freesewing pattern design
|
||||
|
||||
[](https://www.npmjs.com/package/workbench) [](https://standardjs.com)
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npm install --save workbench
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```jsx
|
||||
import React, { Component } from 'react'
|
||||
|
||||
import MyComponent from 'workbench'
|
||||
|
||||
class Example extends Component {
|
||||
render () {
|
||||
return (
|
||||
<MyComponent />
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT © [freesewing](https://github.com/freesewing)
|
5
packages/workbench/example/.babelrc
Normal file
5
packages/workbench/example/.babelrc
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"plugins": [
|
||||
["transform-object-rest-spread", { "useBuiltIns": true }]
|
||||
]
|
||||
}
|
2164
packages/workbench/example/README.md
Normal file
2164
packages/workbench/example/README.md
Normal file
File diff suppressed because it is too large
Load diff
11122
packages/workbench/example/package-lock.json
generated
Normal file
11122
packages/workbench/example/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
25
packages/workbench/example/package.json
Normal file
25
packages/workbench/example/package.json
Normal file
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"name": "workbench-example",
|
||||
"homepage": "https://freesewing.github.io/workbench",
|
||||
"version": "0.0.0",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@freesewing/aaron": "0.14.0",
|
||||
"@freesewing/brian": "0.25.0",
|
||||
"@freesewing/plugin-bundle": "0.9.0",
|
||||
"freesewing": "0.31.0",
|
||||
"prop-types": "^15.6.2",
|
||||
"react": "^16.4.1",
|
||||
"react-dom": "^16.4.1",
|
||||
"react-scripts": "^1.1.4",
|
||||
"workbench": "file:.."
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test --env=jsdom",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"devDependencies": {}
|
||||
}
|
20
packages/workbench/example/public/index.html
Normal file
20
packages/workbench/example/public/index.html
Normal file
|
@ -0,0 +1,20 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="theme-color" content="#000000">
|
||||
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
||||
|
||||
<title>workbench</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript>
|
||||
You need to enable JavaScript to run this app.
|
||||
</noscript>
|
||||
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
8
packages/workbench/example/public/manifest.json
Normal file
8
packages/workbench/example/public/manifest.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"short_name": "workbench",
|
||||
"name": "workbench",
|
||||
"start_url": "./index.html",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
15
packages/workbench/example/src/App.js
Normal file
15
packages/workbench/example/src/App.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
import React from 'react'
|
||||
import Workbench from 'workbench'
|
||||
import freesewing from "freesewing";
|
||||
import Aaron from "@freesewing/aaron";
|
||||
import Brian from "@freesewing/brian";
|
||||
import bundle from "@freesewing/plugin-bundle";
|
||||
|
||||
export default props => <Workbench
|
||||
freesewing={freesewing}
|
||||
patterns={{
|
||||
Aaron,
|
||||
Brian
|
||||
}}
|
||||
plugins={{bundle}}
|
||||
/>
|
5
packages/workbench/example/src/index.js
Normal file
5
packages/workbench/example/src/index.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import App from './App'
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById('root'))
|
81
packages/workbench/package.json
Normal file
81
packages/workbench/package.json
Normal file
|
@ -0,0 +1,81 @@
|
|||
{
|
||||
"name": "@freesewing/workbench",
|
||||
"version": "0.0.1",
|
||||
"description": "A React component to facilitate freesewing pattern design",
|
||||
"author": "Joost De Cock <joost@decock.org> (https://github.com/joostdecock)",
|
||||
"homepage": "https://freesewing.org/",
|
||||
"license": "MIT",
|
||||
"repository": "freesewing/workbench",
|
||||
"bugs": {
|
||||
"url": "https://github.com/freesewing/workbench/issues"
|
||||
},
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.es.js",
|
||||
"jsnext:main": "dist/index.es.js",
|
||||
"engines": {
|
||||
"node": ">=8",
|
||||
"npm": ">=5"
|
||||
},
|
||||
"scripts": {
|
||||
"patch": "npm version patch -m ':bookmark: v%s' && npm run build",
|
||||
"minor": "npm version minor -m ':bookmark: v%s' && npm run build",
|
||||
"major": "npm version major -m ':bookmark: v%s' && npm run build",
|
||||
"test": "cross-env CI=1 react-scripts test --env=jsdom",
|
||||
"test:watch": "react-scripts test --env=jsdom",
|
||||
"build": "rollup -c",
|
||||
"start": "rollup -c -w",
|
||||
"prepare": "npm run build",
|
||||
"predeploy": "cd example && npm install && npm run build",
|
||||
"deploy": "gh-pages -d example/build"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"prop-types": "^15.5.4",
|
||||
"react": "^15.0.0 || ^16.0.0",
|
||||
"react-dom": "^15.0.0 || ^16.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@svgr/rollup": "^2.4.1",
|
||||
"babel-core": "^6.26.3",
|
||||
"babel-eslint": "^8.2.5",
|
||||
"babel-plugin-external-helpers": "^6.22.0",
|
||||
"babel-plugin-transform-object-rest-spread": "6.26.0",
|
||||
"babel-preset-env": "^1.7.0",
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"babel-preset-stage-0": "^6.24.1",
|
||||
"cross-env": "^5.1.4",
|
||||
"eslint": "^5.0.1",
|
||||
"eslint-config-standard": "^11.0.0",
|
||||
"eslint-config-standard-react": "^6.0.0",
|
||||
"eslint-plugin-import": "^2.13.0",
|
||||
"eslint-plugin-node": "^7.0.1",
|
||||
"eslint-plugin-promise": "^4.0.0",
|
||||
"eslint-plugin-react": "^7.10.0",
|
||||
"eslint-plugin-standard": "^3.1.0",
|
||||
"gh-pages": "^1.2.0",
|
||||
"react": "^16.4.1",
|
||||
"react-dom": "^16.4.1",
|
||||
"react-scripts": "^1.1.4",
|
||||
"rollup": "^0.64.1",
|
||||
"rollup-plugin-babel": "^3.0.7",
|
||||
"rollup-plugin-commonjs": "^9.1.3",
|
||||
"rollup-plugin-json": "4.0.0",
|
||||
"rollup-plugin-node-resolve": "^3.3.0",
|
||||
"rollup-plugin-peer-deps-external": "^2.2.0",
|
||||
"rollup-plugin-postcss": "^1.6.2",
|
||||
"rollup-plugin-url": "^1.4.0"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"dependencies": {
|
||||
"@freesewing/i18n": "0.11.3",
|
||||
"@freesewing/mui-theme": "0.1.2",
|
||||
"@freesewing/plugin-theme": "0.18.4",
|
||||
"@material-ui/core": "3.9.2",
|
||||
"@material-ui/icons": "3.0.2",
|
||||
"freesewing": "0.30.6",
|
||||
"material-icons": "0.3.1",
|
||||
"react-intl": "2.8.0",
|
||||
"typeface-roboto-condensed": "0.0.54"
|
||||
}
|
||||
}
|
41
packages/workbench/rollup.config.js
Normal file
41
packages/workbench/rollup.config.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
import babel from 'rollup-plugin-babel'
|
||||
import commonjs from 'rollup-plugin-commonjs'
|
||||
import external from 'rollup-plugin-peer-deps-external'
|
||||
import postcss from 'rollup-plugin-postcss'
|
||||
import resolve from 'rollup-plugin-node-resolve'
|
||||
import url from 'rollup-plugin-url'
|
||||
import svgr from '@svgr/rollup'
|
||||
import json from "rollup-plugin-json";
|
||||
|
||||
import pkg from './package.json'
|
||||
|
||||
export default {
|
||||
input: 'src/index.js',
|
||||
output: [
|
||||
{
|
||||
file: pkg.main,
|
||||
format: 'cjs',
|
||||
sourcemap: true
|
||||
},
|
||||
{
|
||||
file: pkg.module,
|
||||
format: 'es',
|
||||
sourcemap: true
|
||||
}
|
||||
],
|
||||
plugins: [
|
||||
external(),
|
||||
json(),
|
||||
postcss({
|
||||
modules: true
|
||||
}),
|
||||
url(),
|
||||
svgr(),
|
||||
babel({
|
||||
exclude: 'node_modules/**',
|
||||
plugins: [ 'external-helpers', 'transform-object-rest-spread' ]
|
||||
}),
|
||||
resolve({ browser: true }),
|
||||
commonjs()
|
||||
]
|
||||
}
|
5
packages/workbench/src/.eslintrc
Normal file
5
packages/workbench/src/.eslintrc
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"env": {
|
||||
"jest": true
|
||||
}
|
||||
}
|
40
packages/workbench/src/components/ButtonPicker.js
Normal file
40
packages/workbench/src/components/ButtonPicker.js
Normal file
|
@ -0,0 +1,40 @@
|
|||
import React from "react";
|
||||
import Logo from "./Logo";
|
||||
import Emblem from "./Emblem";
|
||||
import { i18n } from "@freesewing/i18n";
|
||||
import { version } from "../../package.json";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import css from "./css/ButtonPicker.css";
|
||||
|
||||
const ButtonPicker = props => (
|
||||
<section>
|
||||
<div className={css.box}>
|
||||
<Logo size={250}/>
|
||||
{ props.msgKey
|
||||
? <h1><FormattedMessage id={props.msgKey} /></h1>
|
||||
: <div><Emblem size={52} color1="#61dafb" color2="#ffffff" text1="Free" text2="Sewing"/></div>
|
||||
}
|
||||
<div className={css.buttons}>
|
||||
{props.keys.map((key) => (
|
||||
<button key={key} className={css.picker} onClick={() => props.setChoice(key)}>
|
||||
<Emblem size={21} color1="#ffffff" text1={props.values[key]} text2=""/>
|
||||
</button>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<footer className={css.picker}>
|
||||
Freesewing workbench v{version}
|
||||
<br />
|
||||
<a className={css.link} href="https://freesewing.org">
|
||||
<Emblem size={16} color1="#61dafb" color2="#ffffff" text1="freesewing" text2=".org"/>
|
||||
</a>
|
||||
|
|
||||
<a className={css.link} href="https://freesewing.dev">
|
||||
<Emblem size={16} color1="#61dafb" color2="#ffffff" text1="freesewing" text2=".dev"/>
|
||||
</a>
|
||||
</footer>
|
||||
</section>
|
||||
);
|
||||
|
||||
export default ButtonPicker;
|
47
packages/workbench/src/components/Emblem.js
Normal file
47
packages/workbench/src/components/Emblem.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
const Emblem = props => {
|
||||
const font = {
|
||||
fontFamily: "'Roboto Condensed', sans-serif",
|
||||
fontSize: props.size,
|
||||
fontWeight: 900,
|
||||
}
|
||||
const styles = {
|
||||
free: {
|
||||
...font,
|
||||
color: props.color1,
|
||||
letterSpacing: props.size/-40+"px",
|
||||
},
|
||||
sewing: {
|
||||
...font,
|
||||
color: props.color2,
|
||||
letterSpacing: props.size/-20+"px",
|
||||
},
|
||||
}
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<span style={styles.free}>{props.text1}</span>
|
||||
<span style={styles.sewing}>{props.text2}</span>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
Emblem.propTypes = {
|
||||
size: PropTypes.number,
|
||||
color1: PropTypes.string,
|
||||
color2: PropTypes.string,
|
||||
text1: PropTypes.string,
|
||||
text2: PropTypes.string,
|
||||
};
|
||||
|
||||
Emblem.defaultProps = {
|
||||
size: 24,
|
||||
color1: "#111111",
|
||||
color2: "#111111",
|
||||
text1: "",
|
||||
text2: ""
|
||||
};
|
||||
|
||||
export default Emblem;
|
32
packages/workbench/src/components/Logo.js
Normal file
32
packages/workbench/src/components/Logo.js
Normal file
File diff suppressed because one or more lines are too long
44
packages/workbench/src/components/NavBar.js
Normal file
44
packages/workbench/src/components/NavBar.js
Normal file
|
@ -0,0 +1,44 @@
|
|||
import React from "react";
|
||||
import Logo from "./Logo";
|
||||
import Emblem from "./Emblem";
|
||||
import css from "./css/NavBar.css";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
const NavBar = props => {
|
||||
const goToHelp = () =>
|
||||
window.location.href = "https://freesewing.dev/"+props.locale+"/workbench";
|
||||
|
||||
return (
|
||||
<header className={css.navbar}>
|
||||
{ props.empty
|
||||
? ""
|
||||
: <React.Fragment>
|
||||
<div className={css.logo}><Logo size={36} /></div>
|
||||
<a href="https://freesewing.org/" className={css.navbar}>
|
||||
<Emblem size={20} color1="#61dafb" color2="#ffffff" text1="Free" text2="Sewing"/>
|
||||
</a>
|
||||
<div className={css.right}>
|
||||
{ props.pattern ? (
|
||||
<React.Fragment>
|
||||
<button className={css.navbar} onClick={props.toggleSettings}>
|
||||
<Emblem size={16} text1={<FormattedMessage id="app.settings" />} color1="#fff" />
|
||||
</button>
|
||||
<button className={css.navbar} onClick={props.clearPattern}>
|
||||
<Emblem size={16} text1={props.pattern} color1="#fff" />
|
||||
</button>
|
||||
</React.Fragment>
|
||||
) : ""
|
||||
}
|
||||
<button className={css.navbar} onClick={props.clearLanguage}>
|
||||
<Emblem size={16} text1={props.language} color1="#fff" />
|
||||
</button>
|
||||
<button className={css.navbar} onClick={goToHelp}>
|
||||
<Emblem size={16} text1="?" color1="#fff" />
|
||||
</button>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
}
|
||||
</header>
|
||||
);
|
||||
}
|
||||
export default NavBar;
|
21
packages/workbench/src/components/Pattern.js
Normal file
21
packages/workbench/src/components/Pattern.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
const Pattern = props => {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<span style={styles.free}>{props.text1}</span>
|
||||
<span style={styles.sewing}>{props.text2}</span>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
Pattern.propTypes = {
|
||||
pattern: PropTypes.string,
|
||||
freesewing: PropTypes.object
|
||||
};
|
||||
|
||||
Pattern.defaultProps = {
|
||||
};
|
||||
|
||||
export default Pattern;
|
31
packages/workbench/src/components/css/ButtonPicker.css
Normal file
31
packages/workbench/src/components/css/ButtonPicker.css
Normal file
|
@ -0,0 +1,31 @@
|
|||
.box {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
padding: 1rem 2rem;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
button.picker {
|
||||
padding: 0.5rem 1rem;
|
||||
margin: 0.5rem 1rem;
|
||||
border: 1px solid transparent;
|
||||
border-bottom: 4px solid #fff6;
|
||||
background: transparent;
|
||||
}
|
||||
button.picker:hover {
|
||||
border-bottom: 4px solid #61dafb;
|
||||
}
|
||||
footer.picker {
|
||||
position: fixed;
|
||||
bottom: 2rem;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
.link {
|
||||
padding: 0.5rem;
|
||||
font-weight: normal;
|
||||
}
|
42
packages/workbench/src/components/css/Config.css
Normal file
42
packages/workbench/src/components/css/Config.css
Normal file
|
@ -0,0 +1,42 @@
|
|||
div.config {
|
||||
border: 1px solid #fffa;
|
||||
border-radius: 4px;
|
||||
padding: 1rem;
|
||||
margin: 0.5rem;
|
||||
}
|
||||
table.config {
|
||||
width: 300px;
|
||||
text-align: left;
|
||||
}
|
||||
table.config td {
|
||||
padding: 0.1rem 0.5rem;
|
||||
}
|
||||
td.option {
|
||||
padding-left: 1rem;
|
||||
}
|
||||
span.key,
|
||||
span.subkey {
|
||||
font-weight: bold;
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
span.true,
|
||||
span.false {
|
||||
font-family: 'Roboto Condensed', sans-serif;
|
||||
font-weight: bold;
|
||||
}
|
||||
span.true {
|
||||
color: #58fc58;
|
||||
}
|
||||
span.false {
|
||||
color: #f97070;
|
||||
}
|
||||
span.key {
|
||||
color: #61dafb;
|
||||
font-family: 'Roboto Condensed', sans-serif;
|
||||
}
|
||||
ul.config,
|
||||
ol.config {
|
||||
margin: 0.2rem 0;
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
31
packages/workbench/src/components/css/Help.css
Normal file
31
packages/workbench/src/components/css/Help.css
Normal file
|
@ -0,0 +1,31 @@
|
|||
.box {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
padding: 1rem 2rem;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
button.picker {
|
||||
padding: 0.5rem 1rem;
|
||||
margin: 0.5rem 1rem;
|
||||
border: 1px solid transparent;
|
||||
border-bottom: 4px solid #fff6;
|
||||
background: transparent;
|
||||
}
|
||||
button.picker:hover {
|
||||
border-bottom: 4px solid #61dafb;
|
||||
}
|
||||
footer.picker {
|
||||
position: fixed;
|
||||
bottom: 2rem;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
.link {
|
||||
padding: 0.5rem;
|
||||
font-weight: normal;
|
||||
}
|
43
packages/workbench/src/components/css/NavBar.css
Normal file
43
packages/workbench/src/components/css/NavBar.css
Normal file
|
@ -0,0 +1,43 @@
|
|||
header.navbar {
|
||||
height: 64px;
|
||||
background: #222;
|
||||
color: #fff;
|
||||
padding: 0 2rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
div.right {
|
||||
flex-grow: 1;
|
||||
text-align: right;
|
||||
}
|
||||
div.logo {
|
||||
line-height: 0
|
||||
}
|
||||
button.emblem {
|
||||
margin: 0;
|
||||
margin-left: 1rem;
|
||||
padding: 0 0.5rem;
|
||||
height: 64px;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-bottom: 4px solid transparent;
|
||||
transition: border 0.2s ease-out;
|
||||
}
|
||||
a.navbar,
|
||||
button.navbar {
|
||||
margin: 0;
|
||||
margin-left: 1rem;
|
||||
padding: 0 0.5rem;
|
||||
height: 64px;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-bottom: 4px solid transparent;
|
||||
transition: border 0.2s ease-out;
|
||||
}
|
||||
button.navbar:hover {
|
||||
border-bottom: 4px solid #61dafb;
|
||||
}
|
||||
a.navbar {
|
||||
line-height: 64px
|
||||
}
|
||||
|
4
packages/workbench/src/components/css/Settings.css
Normal file
4
packages/workbench/src/components/css/Settings.css
Normal file
|
@ -0,0 +1,4 @@
|
|||
div.wrapper {
|
||||
padding: 1rem;
|
||||
display: flex;
|
||||
}
|
73
packages/workbench/src/components/settings/Config.js
Normal file
73
packages/workbench/src/components/settings/Config.js
Normal file
|
@ -0,0 +1,73 @@
|
|||
import React from "react";
|
||||
import Emblem from "../Emblem";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import css from "../css/Config.css";
|
||||
|
||||
const Config = props => {
|
||||
console.log(props.pattern);
|
||||
const emblem = (t1, t2) =>
|
||||
<Emblem text1={t1} text2={t2} color1="#61dafb" color2="#fff" size={20}/>
|
||||
|
||||
const renderConfig = () => {
|
||||
let c = props.pattern.config;
|
||||
let rows = [];
|
||||
for (let key of ["name", "version"])
|
||||
rows.push(<tr><td>
|
||||
<span className={css.key}>{key}:</span>
|
||||
<span className={css.val}>{c[key]}</span>
|
||||
</td></tr>);
|
||||
for (let key of ["measurements", "parts", "hide"]) {
|
||||
let list = [];
|
||||
if (typeof c[key] !== "undefined") {
|
||||
for (let item of c[key]) list.push(<li><span className={css.val}>{item}</span></li>);
|
||||
rows.push(<tr><td>
|
||||
<span className={css.key}>{key}:</span>
|
||||
<ul className={css.config}>{list}</ul>
|
||||
</td></tr>);
|
||||
} else rows.push(<tr><td><span className={css.key}>{key}:</span></td></tr>);
|
||||
}
|
||||
for (let key of ["dependencies", "inject"]) {
|
||||
if (typeof c[key] !== "undefined") {
|
||||
let list = [];
|
||||
for (let item of Object.keys(c[key])) {
|
||||
let values = null;
|
||||
if (typeof c[key][item] === "string") {
|
||||
list.push(<li>
|
||||
<span className={css.subkey}>{item}
|
||||
{ key === "inject" ? " «" : ":"}
|
||||
</span>
|
||||
<span className={css.val}>{c[key][item]}</span>
|
||||
</li>);
|
||||
} else if (c[key][item].length > 0) {
|
||||
list.push(<li>
|
||||
<span className={css.subkey}>{item}:</span>
|
||||
<span className={css.val}>{c[key][item].map(v => v+" ")}</span>
|
||||
</li>);
|
||||
|
||||
}
|
||||
}
|
||||
rows.push(<tr><td>
|
||||
<span className={css.key}>{key}:</span>
|
||||
<ul className={css.config}>{list}</ul>
|
||||
</td></tr>);
|
||||
} else rows.push(<tr><td><span className={css.key}>{key}:</span></td></tr>);
|
||||
}
|
||||
return (
|
||||
<table className={css.config}>
|
||||
<thead>
|
||||
<tr><th>{emblem("config",".js")}</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{rows}
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={css.config}>
|
||||
{renderConfig()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default Config;
|
25
packages/workbench/src/components/settings/Measurements.js
Normal file
25
packages/workbench/src/components/settings/Measurements.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
import React from "react";
|
||||
import Emblem from "../Emblem";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import css from "../css/Config.css";
|
||||
|
||||
const Measurements = props => {
|
||||
const emblem = (t1, t2) =>
|
||||
<Emblem text1={t1} text2={t2} color1="#61dafb" color2="#fff" size={20}/>
|
||||
|
||||
return (
|
||||
<div className={css.config}>
|
||||
<table className={css.config}>
|
||||
<thead>
|
||||
<tr><th><FormattedMessage id="app.measurements" /></th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
<pre>
|
||||
{JSON.stringify(props, null, 2)}
|
||||
</pre>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default Measurements;
|
106
packages/workbench/src/components/settings/Options.js
Normal file
106
packages/workbench/src/components/settings/Options.js
Normal file
|
@ -0,0 +1,106 @@
|
|||
import React from "react";
|
||||
import Emblem from "../Emblem";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import css from "../css/Config.css";
|
||||
|
||||
const Options = props => {
|
||||
const emblem = (t1, t2) =>
|
||||
<Emblem text1={t1} text2={t2} color1="#61dafb" color2="#fff" size={20}/>
|
||||
|
||||
const renderOptions = () => {
|
||||
let c = props.pattern.config;
|
||||
let rows = [];
|
||||
if (typeof c.options !== "undefined") {
|
||||
let list = [];
|
||||
for (let item of Object.keys(c.options).sort()) {
|
||||
let values = null;
|
||||
if (typeof c.options[item] === "boolean") {
|
||||
rows.push(<tr><td>
|
||||
<span className={css.key}>{item}:</span>
|
||||
<span className={css.true}>{c.options[item] ? "TRUE" : "FALSE"}</span>
|
||||
</td></tr>);
|
||||
} else if (typeof c.options[item] !== "object") {
|
||||
rows.push(<tr><td>
|
||||
<span className={css.key}>{item}:</span>
|
||||
<span className={css.val}>{c.options[item]}</span>
|
||||
</td></tr>);
|
||||
} else {
|
||||
if (typeof c.options[item].pct !== "undefined") {
|
||||
rows.push(<tr><td>
|
||||
<span className={css.key}>{item}:</span>
|
||||
<span className={css.val}>
|
||||
{c.options[item].min}%
|
||||
{" / "}
|
||||
<b>{c.options[item].pct}%</b>
|
||||
{" / "}
|
||||
{c.options[item].max}%
|
||||
</span>
|
||||
</td></tr>);
|
||||
} else if (typeof c.options[item].deg !== "undefined") {
|
||||
rows.push(<tr><td>
|
||||
<span className={css.key}>{item}:</span>
|
||||
<span className={css.val}>
|
||||
{c.options[item].min}°
|
||||
{" / "}
|
||||
<b>{c.options[item].deg}°</b>
|
||||
{" / "}
|
||||
{c.options[item].max}°
|
||||
</span>
|
||||
</td></tr>);
|
||||
} else if (typeof c.options[item].mm !== "undefined") {
|
||||
rows.push(<tr><td>
|
||||
<span className={css.key}>{item}:</span>
|
||||
<span className={css.val}>
|
||||
{c.options[item].min}mm;
|
||||
{" / "}
|
||||
<b>{c.options[item].mm}mm</b>
|
||||
{" / "}
|
||||
{c.options[item].max}mm
|
||||
</span>
|
||||
</td></tr>);
|
||||
} else if (typeof c.options[item].bool !== "undefined") {
|
||||
rows.push(<tr><td>
|
||||
<span className={css.key}>{item}:</span>
|
||||
{c.options[item].bool
|
||||
? <React.Fragment><span className={css.true}>TRUE</span><span> / FALSE</span></React.Fragment>
|
||||
: <React.Fragment><span>TRUE / </span><span className={css.false}>FALSE</span></React.Fragment>
|
||||
}
|
||||
</td></tr>);
|
||||
} else if (typeof c.options[item].list !== "undefined") {
|
||||
let list = [];
|
||||
for (let opt of c.options[item].list) {
|
||||
if (opt === c.options[item].dflt) list.push(<li><b>{opt}</b> «</li>);
|
||||
else list.push(<li>{opt}</li>);
|
||||
}
|
||||
rows.push(<tr><td>
|
||||
<span className={css.key}>{item}:</span>
|
||||
<ul className={css.config}>{list}</ul>
|
||||
</td></tr>);
|
||||
} else {
|
||||
rows.push(<tr><td>
|
||||
<span className={css.key}>{item}:</span>
|
||||
<span className={css.val}>FIXME</span>
|
||||
</td></tr>);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else return null;
|
||||
return (
|
||||
<table className={css.config}>
|
||||
<thead>
|
||||
<tr><th>{emblem(c.name+".config",".options")}</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{rows}
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={css.config}>
|
||||
{renderOptions()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default Options;
|
65
packages/workbench/src/components/settings/ResolvedConfig.js
Normal file
65
packages/workbench/src/components/settings/ResolvedConfig.js
Normal file
|
@ -0,0 +1,65 @@
|
|||
import React from "react";
|
||||
import Emblem from "../Emblem";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import css from "../css/Config.css";
|
||||
|
||||
const ResolvedConfig = props => {
|
||||
const emblem = (t1, t2) =>
|
||||
<Emblem text1={t1} text2={t2} color1="#61dafb" color2="#fff" size={20}/>
|
||||
|
||||
const renderResolvedConfig = () => {
|
||||
let c = props.pattern.config;
|
||||
let rows = [];
|
||||
let list = [];
|
||||
if (typeof c.draftOrder !== "undefined") {
|
||||
for (let item of c.draftOrder) list.push(<li><span className={css.val}>{item}</span></li>);
|
||||
rows.push(<tr><td>
|
||||
<span className={css.key}>draftOrder:</span>
|
||||
<ol className={css.config}>{list}</ol>
|
||||
</td></tr>);
|
||||
} else rows.push(<tr><td><span className={css.key}>draftOrder:</span></td></tr>);
|
||||
for (let key of ["resolvedDependencies"]) {
|
||||
if (typeof c[key] !== "undefined") {
|
||||
let list = [];
|
||||
for (let item of Object.keys(c[key])) {
|
||||
let values = null;
|
||||
if (typeof c[key][item] === "string") {
|
||||
list.push(<li>
|
||||
<span className={css.subkey}>{item}
|
||||
{ key === "inject" ? " «" : ":"}
|
||||
</span>
|
||||
<span className={css.val}>{c[key][item]}</span>
|
||||
</li>);
|
||||
} else if (c[key][item].length > 0) {
|
||||
list.push(<li>
|
||||
<span className={css.subkey}>{item}:</span>
|
||||
<span className={css.val}>{c[key][item].map(v => v+" ")}</span>
|
||||
</li>);
|
||||
|
||||
}
|
||||
}
|
||||
rows.push(<tr><td>
|
||||
<span className={css.key}>{key}:</span>
|
||||
<ul className={css.config}>{list}</ul>
|
||||
</td></tr>);
|
||||
} else rows.push(<tr><td><span className={css.key}>{key}:</span></td></tr>);
|
||||
}
|
||||
return (
|
||||
<table className={css.config}>
|
||||
<thead>
|
||||
<tr><th>{emblem(c.name,".config")}</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{rows}
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={css.config}>
|
||||
{renderResolvedConfig()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default ResolvedConfig;
|
35
packages/workbench/src/components/settings/index.js
Normal file
35
packages/workbench/src/components/settings/index.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
import React from "react";
|
||||
import Emblem from "../Emblem";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import css from "../css/Settings.css";
|
||||
import Config from "./Config";
|
||||
import ResolvedConfig from "./ResolvedConfig";
|
||||
import Options from "./Options";
|
||||
import Measurements from "./Measurements";
|
||||
import Complete from "./options/draft-complete";
|
||||
|
||||
const Settings = props => {
|
||||
let pattern = new props.freesewing.patterns[props.pattern]();
|
||||
return (
|
||||
<section>
|
||||
<div className={css.wrapper}>
|
||||
<Options pattern={pattern} />
|
||||
<Measurements pattern={pattern} />
|
||||
<div>
|
||||
<Complete
|
||||
pattern={props.pattern}
|
||||
gist={{
|
||||
complete: false
|
||||
}}
|
||||
updateGist={props.updateGist}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
//<Config pattern={pattern} />
|
||||
//<ResolvedConfig pattern={pattern} />
|
||||
|
||||
export default Settings;
|
|
@ -0,0 +1,44 @@
|
|||
import React from "react";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import { strings } from "@freesewing/i18n";
|
||||
|
||||
const Complete = props => {
|
||||
let complete, incomplete;
|
||||
if (props.gist.complete) complete = "checked";
|
||||
else incomplete = "checked";
|
||||
return (
|
||||
<div className="option draft">
|
||||
<header>
|
||||
<h5 className="do-title"><FormattedMessage id="settings.complete.title" /></h5>
|
||||
<p className="do-description"><FormattedMessage id="settings.complete.description" /></p>
|
||||
</header>
|
||||
<ul className="radio">
|
||||
<li>
|
||||
<label>
|
||||
<input
|
||||
type="radio"
|
||||
name="complete"
|
||||
value={1}
|
||||
onChange={evt => props.updateGist("complete", true)}
|
||||
checked={props.gist.complete}
|
||||
/>
|
||||
<FormattedMessage id="app.yes" />
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label>
|
||||
<input
|
||||
type="radio"
|
||||
name="complete"
|
||||
value={0}
|
||||
onChange={evt => props.updateGist("complete", false)}
|
||||
checked={props.gist.complete}
|
||||
/>
|
||||
<FormattedMessage id="app.no" />
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default Complete;
|
155
packages/workbench/src/index.js
Normal file
155
packages/workbench/src/index.js
Normal file
|
@ -0,0 +1,155 @@
|
|||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import storage from "./utils/storage"
|
||||
import { i18n, strings } from "@freesewing/i18n";
|
||||
import "./style.css";
|
||||
import NavBar from "./components/NavBar";
|
||||
import ButtonPicker from "./components/ButtonPicker";
|
||||
import Settings from "./components/settings/";
|
||||
import { IntlProvider, addLocaleData } from "react-intl";
|
||||
import en from "react-intl/locale-data/en";
|
||||
import de from "react-intl/locale-data/de";
|
||||
import es from "react-intl/locale-data/es";
|
||||
import fr from "react-intl/locale-data/fr";
|
||||
import nl from "react-intl/locale-data/nl";
|
||||
import createTheme from "@freesewing/mui-theme";
|
||||
import MuiThemeProvider from '@material-ui/core/styles/MuiThemeProvider';
|
||||
import Button from "@material-ui/core/Button";
|
||||
require("typeface-roboto-condensed");
|
||||
require("@freesewing/css-theme");
|
||||
|
||||
addLocaleData([...en, ...de, ...es, ...fr, ...nl]);
|
||||
|
||||
export default class Workbench extends Component {
|
||||
static propTypes = {
|
||||
freesewing: PropTypes.object
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
language: this.getLanguage(),
|
||||
pattern: this.getPattern(),
|
||||
settings: false,
|
||||
gist: {},
|
||||
theme: "light"
|
||||
};
|
||||
}
|
||||
|
||||
Storage = new storage();
|
||||
|
||||
saveToStorage = key => {
|
||||
if (key === "language") this.Storage.set("language", this.state.language);
|
||||
else if (key === "pattern") this.Storage.set("pattern", this.state.pattern);
|
||||
else if (key === "gist") this.Storage.set(this.state.pattern, JSON.stringify(this.state.gist));
|
||||
else {
|
||||
this.Storage.set("language", this.state.language);
|
||||
this.Storage.set("pattern", this.state.pattern);
|
||||
this.Storage.set(this.state.pattern, JSON.stringify(this.state.gist));
|
||||
}
|
||||
}
|
||||
|
||||
getLanguage = () => {
|
||||
let lang = this.Storage.get("language");
|
||||
if (Object.keys(i18n).indexOf(lang) !== -1) return lang;
|
||||
return false;
|
||||
}
|
||||
setLanguage = language => this.setState({ language }, () => this.saveToStorage('language'));
|
||||
|
||||
getPattern = () => {
|
||||
let pattern = this.Storage.get("pattern");
|
||||
if (Object.keys(this.props.freesewing.patterns).indexOf(pattern) !== -1) return pattern;
|
||||
return false;
|
||||
}
|
||||
setPattern = pattern => this.setState({ pattern }, () => this.saveToStorage('pattern'));
|
||||
|
||||
getGist = () => {
|
||||
let gist = this.Storage.get(JSON.parse(this.state.pattern));
|
||||
if (typeof gist === "object") return gist;
|
||||
return false;
|
||||
}
|
||||
setGist = gist => this.setState({ gist }, () => this.saveToStorage('gist'));
|
||||
|
||||
toggleSettings = () => {
|
||||
let settings = !this.state.settings;
|
||||
this.setState({ settings });
|
||||
}
|
||||
|
||||
updateGist = (key, value) => {
|
||||
if (key.substring(0, 7) === "options.") return updateOption(key.substring(7), value);
|
||||
let gist = this.state.gist;
|
||||
gist[key] = value;
|
||||
this.setState({ gist }, () => this.saveToStorage('gist'));
|
||||
}
|
||||
|
||||
toggleDarkmode = () => {
|
||||
let theme = "light";
|
||||
if (this.state.theme === "light") theme = "dark";
|
||||
this.setState({ theme });
|
||||
}
|
||||
|
||||
render() {
|
||||
let main = null;
|
||||
let navbar = null;
|
||||
if (!this.state.language) {
|
||||
navbar = <NavBar empty={true} />
|
||||
let keys = Object.keys(i18n);
|
||||
let values = {};
|
||||
for (let lang of keys) values[lang] = i18n[lang][lang];
|
||||
main = <ButtonPicker
|
||||
setChoice={this.setLanguage}
|
||||
keys={keys}
|
||||
values={values}
|
||||
/>
|
||||
} else {
|
||||
if (!this.state.pattern) {
|
||||
navbar = <NavBar
|
||||
clearLanguage={() => this.setLanguage(false)}
|
||||
language={i18n[this.state.language][this.state.language]}
|
||||
locale={this.state.language}
|
||||
pattern={false}
|
||||
/>
|
||||
let keys = Object.keys(this.props.freesewing.patterns);
|
||||
let values = {};
|
||||
for (let pattern of keys) values[pattern] = pattern;
|
||||
main = <ButtonPicker
|
||||
setChoice={this.setPattern}
|
||||
keys={keys}
|
||||
values={values}
|
||||
msgKey="app.chooseAPattern"
|
||||
/>
|
||||
} else {
|
||||
navbar = <NavBar
|
||||
clearLanguage={() => this.setLanguage(false)}
|
||||
language={i18n[this.state.language][this.state.language]}
|
||||
locale={this.state.language}
|
||||
clearPattern={() => this.setPattern(false)}
|
||||
pattern={this.state.pattern}
|
||||
toggleSettings={this.toggleSettings}
|
||||
/>
|
||||
if (this.state.settings) main = <Settings
|
||||
pattern={this.state.pattern}
|
||||
gist={this.state.gist}
|
||||
freesewing={this.props.freesewing}
|
||||
updateGist={this.updateGist}
|
||||
/>
|
||||
else main = <div>Language is set<pre>{JSON.stringify(this.state, null, 2)}</pre></div>
|
||||
}
|
||||
}
|
||||
|
||||
return <IntlProvider
|
||||
locale={this.state.language || 'en'}
|
||||
messages={strings[this.state.language]}
|
||||
>
|
||||
<MuiThemeProvider theme={createTheme(true)}>
|
||||
<React.Fragment>
|
||||
{navbar}
|
||||
<Button variant="contained" color="primary">test</Button>
|
||||
{main}
|
||||
</React.Fragment>
|
||||
</MuiThemeProvider>
|
||||
</IntlProvider>
|
||||
}
|
||||
}
|
||||
|
||||
|
32
packages/workbench/src/style.css
Normal file
32
packages/workbench/src/style.css
Normal file
|
@ -0,0 +1,32 @@
|
|||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: #fff;
|
||||
font-feature-settings: "kern", "liga", "clig", "calt";
|
||||
word-wrap: break-word;
|
||||
font-kerning: normal;
|
||||
font-family: -apple-system,system-ui,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #61dafb;
|
||||
transition: color 0.2s ease-out;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
color: #f58fff;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
section {
|
||||
width: 100%;
|
||||
min-height: calc(100vh - 64px);
|
||||
display: flex;
|
||||
background: #222;
|
||||
color: #fff;
|
||||
}
|
||||
|
7
packages/workbench/src/test.js
Normal file
7
packages/workbench/src/test.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
import ExampleComponent from './'
|
||||
|
||||
describe('ExampleComponent', () => {
|
||||
it('is truthy', () => {
|
||||
expect(ExampleComponent).toBeTruthy()
|
||||
})
|
||||
})
|
29
packages/workbench/src/utils/storage.js
Normal file
29
packages/workbench/src/utils/storage.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
export default class Storage {
|
||||
set(key, value, isJson) {
|
||||
if (typeof localStorage === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
const _key = "fswb_" + key;
|
||||
|
||||
if (typeof value === "undefined" || value === null) {
|
||||
localStorage.removeItem(_key);
|
||||
} else {
|
||||
localStorage.setItem(_key, isJson ? JSON.stringify(value) : value);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
get(key, isJson) {
|
||||
if (typeof localStorage === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
const _key = "fswb_" + key;
|
||||
|
||||
const value = localStorage.getItem(_key);
|
||||
|
||||
return isJson ? JSON.parse(value) : value;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue