Repository: gabrielbull/react-desktop
Branch: master
Commit: bba61374849d
Files: 249
Total size: 382.5 KB
Directory structure:
gitextract_6tgptjls/
├── .babelrc
├── .codeclimate.yml
├── .editorconfig
├── .eslintrc.yml
├── .github/
│ └── workflows/
│ └── npm-publish.yml
├── .gitignore
├── .npmignore
├── .travis.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── demo/
│ └── electron/
│ ├── .gitignore
│ ├── README.md
│ ├── babel.config.js
│ ├── index.html
│ ├── index.js
│ ├── package.json
│ ├── page_index.js
│ └── webpack.config.js
├── docs/
│ ├── README.md
│ ├── advanced-usage/
│ │ ├── electron-js.md
│ │ └── nw-js.md
│ ├── faq.md
│ ├── getting-started/
│ │ └── installation.md
│ ├── mac-os/
│ │ ├── box.md
│ │ ├── button.md
│ │ ├── checkbox.md
│ │ ├── dialog.md
│ │ ├── label.md
│ │ ├── link.md
│ │ ├── list-view.md
│ │ ├── pin.md
│ │ ├── progress-circle.md
│ │ ├── radio.md
│ │ ├── search-field.md
│ │ ├── segmented-control.md
│ │ ├── text-input.md
│ │ ├── text.md
│ │ ├── title-bar.md
│ │ ├── toolbar-nav.md
│ │ ├── toolbar.md
│ │ ├── view.md
│ │ └── window.md
│ ├── testing.md
│ └── windows/
│ ├── button.md
│ ├── checkbox.md
│ ├── label.md
│ ├── master-details-view.md
│ ├── nav-pane.md
│ ├── progress-circle.md
│ ├── radio.md
│ ├── text-input.md
│ ├── text.md
│ ├── title-bar.md
│ ├── view.md
│ └── window.md
├── examples/
│ ├── macOs/
│ │ ├── advanced/
│ │ │ └── pinDialog.js
│ │ └── components/
│ │ ├── box.js
│ │ ├── button.js
│ │ ├── checkbox.js
│ │ ├── dialog.js
│ │ ├── label.js
│ │ ├── link.js
│ │ ├── listView.js
│ │ ├── pin.js
│ │ ├── progressCircle.js
│ │ ├── radio.js
│ │ ├── searchField.js
│ │ ├── segmentedControl.js
│ │ ├── text.js
│ │ ├── textArea.js
│ │ ├── textInput.js
│ │ ├── titleBar.js
│ │ ├── toolbar.js
│ │ ├── toolbarNav.js
│ │ ├── view.js
│ │ └── window.js
│ └── windows/
│ └── components/
│ ├── button.js
│ ├── checkbox.js
│ ├── label.js
│ ├── masterDetailsView.js
│ ├── navPane.js
│ ├── progressCircle.js
│ ├── radio.js
│ ├── text.js
│ ├── textArea.js
│ ├── textInput.js
│ ├── titleBar.js
│ ├── view.js
│ └── window.js
├── index.js
├── macOs.js
├── package.json
├── playground/
│ ├── assets/
│ │ └── icons.js
│ ├── examplesLoader.js
│ ├── index.js
│ ├── playground.js
│ ├── ui/
│ │ ├── examples/
│ │ │ └── examples.js
│ │ └── sidebar/
│ │ ├── logo.js
│ │ └── sidebar.js
│ └── webpack.config.js
├── src/
│ ├── Box/
│ │ └── macOs/
│ │ ├── index.js
│ │ └── styles/
│ │ └── 10.11.js
│ ├── Button/
│ │ ├── macOs/
│ │ │ ├── index.js
│ │ │ └── styles/
│ │ │ └── 10.11.js
│ │ └── windows/
│ │ ├── index.js
│ │ └── styles/
│ │ └── windows10.js
│ ├── Checkbox/
│ │ ├── macOs/
│ │ │ ├── Checkmark.js
│ │ │ ├── index.js
│ │ │ └── styles/
│ │ │ └── 10.11.js
│ │ └── windows/
│ │ ├── index.js
│ │ └── styles/
│ │ └── windows10.js
│ ├── Dialog/
│ │ └── macOs/
│ │ ├── index.js
│ │ └── style/
│ │ └── 10.11.js
│ ├── Label/
│ │ ├── macOs/
│ │ │ └── index.js
│ │ └── windows/
│ │ └── index.js
│ ├── Link/
│ │ └── macOs/
│ │ └── index.js
│ ├── ListView/
│ │ └── macOs/
│ │ ├── Footer/
│ │ │ ├── index.js
│ │ │ └── style/
│ │ │ └── 10.11.js
│ │ ├── Header/
│ │ │ ├── index.js
│ │ │ └── style/
│ │ │ └── 10.11.js
│ │ ├── Row/
│ │ │ ├── index.js
│ │ │ └── style/
│ │ │ └── 10.11.js
│ │ ├── Section/
│ │ │ ├── Header/
│ │ │ │ ├── index.js
│ │ │ │ └── style/
│ │ │ │ └── 10.11.js
│ │ │ ├── index.js
│ │ │ └── style/
│ │ │ └── 10.11.js
│ │ ├── Separator/
│ │ │ ├── index.js
│ │ │ └── style/
│ │ │ └── 10.11.js
│ │ ├── index.js
│ │ └── style/
│ │ └── 10.11.js
│ ├── MasterDetailsView/
│ │ └── windows/
│ │ ├── Details/
│ │ │ └── index.js
│ │ ├── Item/
│ │ │ └── index.js
│ │ ├── Master/
│ │ │ └── index.js
│ │ ├── Pane.js
│ │ └── index.js
│ ├── NavPane/
│ │ └── windows/
│ │ ├── Item/
│ │ │ ├── Content/
│ │ │ │ └── index.js
│ │ │ ├── Title/
│ │ │ │ └── index.js
│ │ │ └── index.js
│ │ ├── Pane/
│ │ │ ├── Button/
│ │ │ │ └── index.js
│ │ │ ├── Item/
│ │ │ │ └── index.js
│ │ │ ├── index.js
│ │ │ └── style/
│ │ │ └── windows10.js
│ │ ├── index.js
│ │ └── style/
│ │ └── windows10.js
│ ├── Pin/
│ │ └── macOs/
│ │ ├── index.js
│ │ └── style/
│ │ └── 10.11.js
│ ├── ProgressCircle/
│ │ ├── macOs/
│ │ │ ├── index.js
│ │ │ ├── progressCircleAnimation.js
│ │ │ └── styles/
│ │ │ └── 10.11.js
│ │ └── windows/
│ │ ├── index.js
│ │ ├── progressCircleAnimation.js
│ │ └── styles/
│ │ └── windows10.js
│ ├── Radio/
│ │ ├── macOs/
│ │ │ ├── Circle.js
│ │ │ ├── index.js
│ │ │ └── styles/
│ │ │ └── 10.11.js
│ │ └── windows/
│ │ ├── index.js
│ │ └── styles/
│ │ └── windows.js
│ ├── SearchField/
│ │ └── macOs/
│ │ ├── cancelAnimation.js
│ │ ├── icons.js
│ │ ├── index.js
│ │ └── styles/
│ │ └── 10.11.js
│ ├── SegmentedControl/
│ │ └── macOs/
│ │ ├── Item/
│ │ │ └── index.js
│ │ ├── Tabs/
│ │ │ ├── Tab.js
│ │ │ └── index.js
│ │ ├── index.js
│ │ └── style/
│ │ └── 10.11.js
│ ├── Text/
│ │ ├── macOs/
│ │ │ ├── index.js
│ │ │ └── styles/
│ │ │ └── 10.11.js
│ │ └── windows/
│ │ ├── index.js
│ │ └── styles/
│ │ └── windows10.js
│ ├── TextArea/
│ │ ├── macOs/
│ │ │ ├── centerPlaceholderAnimation.js
│ │ │ ├── focusRingAnimation.js
│ │ │ ├── index.js
│ │ │ └── styles/
│ │ │ └── 10.11.js
│ │ └── windows/
│ │ ├── index.js
│ │ └── styles/
│ │ └── windows10.js
│ ├── TextInput/
│ │ ├── macOs/
│ │ │ ├── centerPlaceholderAnimation.js
│ │ │ ├── focusRingAnimation.js
│ │ │ ├── index.js
│ │ │ └── styles/
│ │ │ └── 10.11.js
│ │ └── windows/
│ │ ├── index.js
│ │ └── styles/
│ │ └── windows10.js
│ ├── TitleBar/
│ │ ├── macOs/
│ │ │ ├── Controls/
│ │ │ │ ├── Close.js
│ │ │ │ ├── Minimize.js
│ │ │ │ ├── Resize.js
│ │ │ │ ├── index.js
│ │ │ │ └── styles/
│ │ │ │ └── 10.11.js
│ │ │ ├── index.js
│ │ │ └── styles/
│ │ │ └── 10.11.js
│ │ └── windows/
│ │ ├── Controls/
│ │ │ ├── Close.js
│ │ │ ├── Maximize.js
│ │ │ ├── Minimize.js
│ │ │ └── index.js
│ │ ├── index.js
│ │ └── styles/
│ │ └── windows10.js
│ ├── Toolbar/
│ │ └── macOs/
│ │ ├── Nav/
│ │ │ ├── Item/
│ │ │ │ └── index.js
│ │ │ └── index.js
│ │ └── index.js
│ ├── ValueRef.js
│ ├── View/
│ │ ├── macOs/
│ │ │ └── index.js
│ │ └── windows/
│ │ └── index.js
│ ├── Window/
│ │ ├── macOs/
│ │ │ ├── index.js
│ │ │ └── styles/
│ │ │ └── 10.11.js
│ │ └── windows/
│ │ ├── index.js
│ │ └── styles/
│ │ └── windows10.js
│ ├── animation/
│ │ └── bezierEasing.js
│ ├── color.js
│ ├── monitor.js
│ ├── os.js
│ ├── placeholderStyle.js
│ ├── style/
│ │ ├── alignment.js
│ │ ├── background/
│ │ │ ├── macOs.js
│ │ │ └── windows.js
│ │ ├── color/
│ │ │ └── windows.js
│ │ ├── dimension.js
│ │ ├── fontSize.js
│ │ ├── hidden.js
│ │ ├── margin.js
│ │ ├── padding.js
│ │ ├── textAlign.js
│ │ ├── theme/
│ │ │ └── windows.js
│ │ └── width.js
│ ├── styleHelper.js
│ ├── utils/
│ │ └── mapStyles.js
│ └── windowFocus.js
├── test/
│ ├── mocha.opts
│ ├── setup.js
│ └── tests/
│ ├── box.js
│ ├── button.js
│ ├── checkbox.js
│ ├── color.js
│ ├── dialog.js
│ ├── index.js
│ ├── label.js
│ ├── link.js
│ ├── listView.js
│ ├── macOs.js
│ ├── pin.js
│ ├── progressCircle.js
│ ├── searchField.js
│ ├── text.js
│ ├── textArea.js
│ ├── textInput.js
│ ├── toolbar.js
│ ├── toolbarNav.js
│ └── windows.js
└── windows.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .babelrc
================================================
{
"presets": [
"es2015",
"stage-0",
"react"
],
"plugins": [
"transform-decorators-legacy"
]
}
================================================
FILE: .codeclimate.yml
================================================
languages:
JavaScript: true
exclude_paths:
- "test/*"
- "lib/*"
================================================
FILE: .editorconfig
================================================
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# http://editorconfig.org
root = true
[*]
# Change these settings to your own preference
indent_style = space
indent_size = 2
# We recommend you to keep these unchanged
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
================================================
FILE: .eslintrc.yml
================================================
parser: babel-eslint
extends:
- plugin:import/errors
- plugin:import/warnings
plugins:
- react
env:
browser: true
node: true
es6: true
mocha: true
rules:
# Strict mode
strict: [2, never]
# Code style
indent: [2, 2]
quotes: [2, single]
no-unused-vars: 1
no-undef: 1
object-curly-spacing: [2, always]
# JSX
jsx-quotes: 1
# React
react/display-name: 0
react/jsx-boolean-value: 1
react/jsx-closing-bracket-location: 1
react/jsx-curly-spacing: 1
react/jsx-max-props-per-line: 0
react/jsx-indent-props: 0
react/jsx-no-duplicate-props: 1
react/jsx-no-undef: 1
react/jsx-sort-prop-types: 0
react/jsx-sort-props: 0
react/jsx-uses-react: 1
react/jsx-uses-vars: 1
react/no-danger: 0
react/no-set-state: 0
react/no-did-mount-set-state: 1
react/no-did-update-set-state: 1
react/no-multi-comp: 0
react/no-unknown-property: 1
react/self-closing-comp: 1
react/jsx-wrap-multilines: 1
================================================
FILE: .github/workflows/npm-publish.yml
================================================
# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
# For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages
name: Node.js Package
on:
release:
types: [created]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 12
- run: npm ci
- run: npm test
publish-npm:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 12
registry-url: https://registry.npmjs.org/
- run: npm ci
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
publish-gpr:
needs: build
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 12
registry-url: https://npm.pkg.github.com/
- run: npm ci
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
================================================
FILE: .gitignore
================================================
# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
/.idea
ehthumbs.db
Thumbs.db
# Node
/node_modules
yarn.lock
# react-desktop #
########
/lib
/build
# Logs
logs
*.log
npm-debug.log*
package-lock.json
================================================
FILE: .npmignore
================================================
/build
/docs
/examples
/lib
/node_modules
/playground
/test
/.idea
/.babelrc
/.codeclimate.yml
/.editorconfig
/.eslintrc
/.npmignore
/.travis.yml
/CONTRIBUTING.md
/npm-debug.log
================================================
FILE: .travis.yml
================================================
language: node_js
node_js:
- '8'
- '7'
- '6'
================================================
FILE: CHANGELOG.md
================================================
# CHANGELOG
## 0.3.10 (July 28th, 2019)
- Add the Electron framework demo
## 0.3.7 (July 25th, 2018)
- Add ability to disable individual titlebar controls (#125)
- Allow end-user to force `isWindowFocused` prop (#126)
- Allow defaultChecked to be string as well as boolean (#123) (Fixes #90)
## 0.3.6 (July 25th, 2018)
- This release was published incorrectly. Use 0.3.7 instead.
## 0.3.5 (April 6th, 2018)
- Fixed issue with case sensitivity
## 0.3.4 (April 4th, 2018)
- Added TextArea component
- Several minor fixes
## 0.3.3 (November 21st, 2017)
- Updated dependencies
- Fixed title props
## 0.3.2 (October 17th, 2017)
- Updated dependencies
- Fixed unit tests
- Fixed unit playground
- Add public `focus` and `blur` methods to TextInput
- Prop title of TitleBar now supports element node
## 0.3.1 (June 21th, 2017)
- Updated dependencies
## 0.3.0 (April 17th, 2017)
- Added prop-types dependency to avoid deprecation in React 16
## 0.2.19 (March 14th, 2017)
- Removed rubber band effect from list view
## 0.2.18 (March 14th, 2017)
- Fixed an issue with OS detection
## 0.2.17 (January 9th, 2017)
- Fixed issue with windows window background color
- Added ref value for input elements
- CheckBoxes and Radios now changes style when window is unfocused
- Can now import components based on OS from 'react-desktop'
## 0.2.16 (January 9th, 2017)
- Custom styles for Windows text field's label
- Default color for Windows text field's label changes based on theme
## 0.2.15 (January 9th, 2017)
- Fixed bug with macOs text field’s placeholder
## 0.2.14 (September 19th, 2016)
- Fixed duplicate onChange events on the windows textInput
## 0.2.13 (August 25th, 2016)
- Improve macOS title bar control icons
## 0.2.12 (August 17th, 2016)
- Fixed some styling issues with the list view
- Fixed some styling issues with the windows
## 0.2.11 (August 12th, 2016)
- Added macOS list view component
## 0.2.10 (August 11th, 2016)
- Quick fix for the macOS text input component border issue
## 0.2.9 (August 11th, 2016)
- Added macOS search field component
- Added centerPlaceholder, focusRing, icon and onEnter properties to the macOS text input component
## 0.2.8 (August 8th, 2016)
- Added macOS toolbar nav component
- Added inset property to macOS title bar component
- Added dimension and alignment properties to macOS toolbar component
## 0.2.7 (July 28th, 2016)
- Added macOS dialog component
- Added bold property to macOS text
- Added onEnter and disabled properties to macOS button
- Fixed issues with margin on pin component for macOS
## 0.2.6 (July 27th, 2016)
- Added macOS pin component
- Added size, padding and margin properties to macOS buttons
- Fixed issues with text input for macOS
- Added rounded corners and size properties to text input for macOS
## 0.2.5 (July 18th, 2016)
- Fixed some issues with View alignment
## 0.2.4 (July 17th, 2016)
- Removed all unknown props from components
- Intial window focus is now the real window focus instead of being always true
## 0.2.3 (June 24th, 2016)
- Fixed bug with title bar in macOS
## 0.2.2 (June 24th, 2016)
- Added Link component for macOS
- Added size to Text component
- Added transparent option to titlebar for macOS
- Fixed title bar size for macOS
## 0.2.1 (June 14th, 2016)
- Added support for React 15.1.0
## 0.2.0 (May 16th, 2016)
- Beta 1 release
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing Guidelines
We are open to, and grateful for, any contributions made by the community.
## Reporting Issues and Asking Questions
Before opening an issue, please search the [issue tracker](https://github.com/gabrielbull/react-desktop/issues)
to make sure your issue hasn’t already been reported.
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright © 2017 Gabriel Bull
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.
================================================
FILE: README.md
================================================
# 
[](https://travis-ci.org/gabrielbull/react-desktop)
[](https://codeclimate.com/github/gabrielbull/react-desktop)
[](https://github.com/gabrielbull/react-desktop/blob/master/LICENSE)
[](https://github.com/gabrielbull/react-desktop/stargazers)
[](https://www.npmjs.org/package/react-desktop)
[](https://www.npmjs.org/package/react-desktop)
[](https://gitter.im/gabrielbull/react-desktop?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
React UI Components for macOS High Sierra and Windows 10.
```npm
npm install react-desktop --save
```

## Help wanted!
I am looking for developers to help me develop this project. Please submit some ideas in the issues section or some PRs to get this project going. If you are interested, you can become a collaborator on the project. Thanks.
## Contributing
This library has been created to bring a native desktop experience to the web. It works extremely well with tools such as [node-webkit](http://nwjs.io) or [Electron.js](http://electron.atom.io)!
Everyone is welcome to contribute and add more components/documentation whilst following the [contributing guidelines](/CONTRIBUTING.md).
## Documentation
Guides on installation, components and advanced usage are found in the [documentation](http://reactdesktop.js.org).
## Contributors
================================================
FILE: demo/electron/.gitignore
================================================
node_modules/
dist/
================================================
FILE: demo/electron/README.md
================================================
# React desktop Electron demo

## How to use
First, enter the folder:
```cd demo/electron```
Install the libraries:
```npm i``` or ```yarn``` (if you have been installed it)
Build once:
```npm run build```
Then start the server:
```npm run watch```
Open another console at the same folder, and run this command to start the Electron process:
```npm start```
That's it!
================================================
FILE: demo/electron/babel.config.js
================================================
module.exports = function (api) {
api.cache(false);
const presets = [
[
'@babel/preset-env',
{
'modules': 'commonjs',
'targets': {
'node': 'current'
}
}
],
[
'@babel/preset-react'
]
];
const plugins = [
[
'@babel/plugin-proposal-decorators',
{
'legacy': true
}
],
[
'@babel/plugin-proposal-class-properties',
{
'loose': true
}
]
];
return {
presets,
plugins
};
}
================================================
FILE: demo/electron/index.html
================================================
DEMO
================================================
FILE: demo/electron/index.js
================================================
const electron = require('electron');
const { app, BrowserWindow, Menu } = electron;
let mainWnd = null;
function createMainWnd() {
mainWnd = new BrowserWindow({
width:800,
height:600,
minWidth:800,
maxWidth: 800,
minHeight: 600,
maxHeight: 600,
useContentSize: true,
show: false,
frame: false,
titleBarStyle: 'hidden',
webPreferences: {
nodeIntegration: true
}
});
mainWnd.loadURL('http://127.0.0.1:16000/index.html');
mainWnd.on('ready-to-show', ()=>{
Menu.setApplicationMenu(null);
mainWnd.show();
// mainWnd.webContents.openDevTools({ detach:true });
});
mainWnd.on('closed', () => {
mainWnd = null;
process.exit();
});
}
app.on('ready', ()=>{
createMainWnd();
});
app.on('window-all-closed', () => {
app.quit();
});
================================================
FILE: demo/electron/package.json
================================================
{
"name": "react-desktop-electron-demo",
"version": "0.1.0",
"description": "",
"private": true,
"scripts": {
"start": "electron ./index.js",
"watch": "webpack-dev-server --config ./webpack.config.js --colors --inline --port 16000",
"build": "webpack --config ./webpack.config.js",
"package": "electron-packager ./ ReactDesktop --all --overwrite --out=./packaged/",
"package:windows": "electron-packager ./ ReactDesktop --platform=win32 --overwrite --out=./packaged/",
"package:mac": "electron-builder build --mac --config electron-builder.json --publish never",
"test": "jest --watch"
},
"author": "langyo",
"license": "MIT",
"dependencies": {
"@babel/cli": "^7.5.5",
"@babel/core": "^7.5.5",
"@babel/plugin-proposal-class-properties": "^7.5.5",
"@babel/plugin-proposal-decorators": "^7.4.4",
"@babel/plugin-transform-flow-strip-types": "^7.4.4",
"@babel/preset-env": "^7.5.5",
"@babel/preset-react": "^7.0.0",
"@material-ui/core": "^4.3.0",
"babel-jest": "^24.8.0",
"babel-loader": "^8.0.6",
"classnames": "^2.2.6",
"prop-types": "^15.7.2",
"react": "^16.8.6",
"react-desktop": "^0.3.9",
"react-dom": "^16.8.6"
},
"keywords": [],
"devDependencies": {
"electron": "^9.1.0",
"electron-builder": "^21.1.5",
"electron-packager": "^14.0.3",
"jest": "^24.8.0",
"webpack": "^4.38.0",
"webpack-cli": "^3.3.6",
"webpack-dev-server": "^3.7.2"
}
}
================================================
FILE: demo/electron/page_index.js
================================================
import React from 'react';
import ReactDOM from 'react-dom';
import { Window, TitleBar } from 'react-desktop/windows';
import Button from '@material-ui/core/Button';
ReactDOM.render(
process.exit()}/>
{'Hello world!'}
, document.querySelector('#content'));
================================================
FILE: demo/electron/webpack.config.js
================================================
var path = require('path');
module.exports = {
mode: 'development',
entry: './page_index.js',
output: {
filename: 'bundle.js'
},
devtool: 'source-map',
// resolve: {
// alias: {
// 'react-desktop': path.join(__dirname, '..', '..')
// }
// },
module: {
rules: [
{
test: /\.(js)$/,
exclude: /node_modules/,
use: 'babel-loader'
}
]
}
};
================================================
FILE: docs/README.md
================================================
# Documentation
**react-desktop** is a JavaScript library built on top of [Facebook's React](https://facebook.github.io/react/) library,
which aims to bring a native desktop experience to the web, featuring many macOS High Sierra and Windows 10 components.
**react-desktop** works perfectly with [NW.js](http://nwjs.io) and [Electron.js](http://electron.atom.io), but
can be used in any JavaScript powered project!
## Table of Contents
1. Getting Started
* [Installation](/docs/getting-started/installation.md)
2. macOS
* [Box](/docs/mac-os/box.md)
* [Button](/docs/mac-os/button.md)
* [Checkbox](/docs/mac-os/checkbox.md)
* [Dialog](/docs/mac-os/dialog.md)
* [Label](/docs/mac-os/label.md)
* [Link](/docs/mac-os/link.md)
* [List View](/docs/mac-os/list-view.md)
* [Pin](/docs/mac-os/pin.md)
* [Progress Circle](/docs/mac-os/progress-circle.md)
* [Radio](/docs/mac-os/radio.md)
* [Search Field](/docs/mac-os/search-field.md)
* [Segmented Control](/docs/mac-os/segmented-control.md)
* [Text](/docs/mac-os/text.md)
* [Text Input](/docs/mac-os/text-input.md)
* [Title Bar](/docs/mac-os/title-bar.md)
* [Toolbar](/docs/mac-os/toolbar.md)
* [Toolbar Nav](/docs/mac-os/toolbar-nav.md)
* [View](/docs/mac-os/view.md)
* [Window](/docs/mac-os/window.md)
3. Windows 10
* [Button](/docs/windows/button.md)
* [Checkbox](/docs/windows/checkbox.md)
* [Label](/docs/windows/label.md)
* [Master/Details View](/docs/windows/master-details-view.md)
* [Nav Pane](/docs/windows/nav-pane.md)
* [Progress Circle](/docs/windows/progress-circle.md)
* [Radio](/docs/windows/radio.md)
* [Text](/docs/windows/text.md)
* [Text Input](/docs/windows/text-input.md)
* [Title Bar](/docs/windows/title-bar.md)
* [View](/docs/windows/view.md)
* [Window](/docs/windows/window.md)
4. [Contributing](/CONTRIBUTING.md)
5. [Change Log](/CHANGELOG.md)
================================================
FILE: docs/advanced-usage/electron-js.md
================================================
# Electron.js
Documentation is coming soon.
================================================
FILE: docs/advanced-usage/nw-js.md
================================================
# NW.js
Documentation is coming soon.
================================================
FILE: docs/faq.md
================================================
# Frequently Asked Questions
Documentation is coming soon.
================================================
FILE: docs/getting-started/installation.md
================================================
# Installation
**To install the stable version:**
## [NPM](https://www.npmjs.com/)
`npm install react-desktop --save`
## [Yarn](https://yarnpkg.com)
`yarn add react-desktop`
================================================
FILE: docs/mac-os/box.md
================================================
# Box
### Properties
Property | Type | Description
:------------------ | :-------------:| :----------
background | string | Sets the background color of a component.
height | number | Sets the height of a component.
hidden | bool | Sets the visibility of a component.
horizontalAlignment | string | Sets the horizontal alignment of the component's content __Property value__ _"left"_, _"center"_, _"right"_
label | string | Adds a label to the box.
margin | string, number | Sets the outer margin of a component. __E.G.__ _"30px 20px"_
marginBottom | string, number | Sets the outer margin bottom of a component.
marginLeft | string, number | Sets the outer margin left of a component.
marginRight | string, number | Sets the outer margin right of a component.
marginTop | string, number | Sets the outer margin top of a component.
padding | string, number | Sets the padding inside a component. __E.G.__ _"30px 20px"_
paddingBottom | string, number | Sets the padding bottom inside a component.
paddingLeft | string, number | Sets the padding left inside a component.
paddingRight | string, number | Sets the padding right inside a component.
paddingTop | string, number | Sets the padding top inside a component.
verticalAlignment | string | Sets the vertical alignment of the component's content. __Property value__ _"top"_, _"center"_, _"bottom"_
width | number | Sets the width of a component.
### Examples
```jsx
import React, { Component } from 'react';
import { Box, Text } from 'react-desktop/macOs';
export default class extends Component {
render() {
return (
Some text...
);
}
}
```
================================================
FILE: docs/mac-os/button.md
================================================
# Button
### Properties
Property | Type | Description
:------------------ | :-------------:| :----------
color | string | Sets the color of the button __Property value__ _null_ _"blue"_.
hidden | bool | Sets the visibility of a component.
margin | string, number | Sets the outer margin of a component. __E.G.__ _"30px 20px"_
marginBottom | string, number | Sets the outer margin bottom of a component.
marginLeft | string, number | Sets the outer margin left of a component.
marginRight | string, number | Sets the outer margin right of a component.
marginTop | string, number | Sets the outer margin top of a component.
onClick | function | Callback function when the button is pressed.
onEnter | function | Callback function when the the enter key is pressed.
padding | string, number | Sets the padding inside a component. __E.G.__ _"30px 20px"_
paddingBottom | string, number | Sets the padding bottom inside a component.
paddingLeft | string, number | Sets the padding left inside a component.
paddingRight | string, number | Sets the padding right inside a component.
paddingTop | string, number | Sets the padding top inside a component.
size | string, number | Sets the font size of a component.
type | string | Sets the type of the button __Property value__ _"button"_ _"submit"_. Default value _"button"_.
### Examples
```jsx
import React, { Component } from 'react';
import { Button } from 'react-desktop/macOs';
export default class extends Component {
render() {
return (
console.log('Clicked!')}>
Press me!
);
}
}
```
================================================
FILE: docs/mac-os/checkbox.md
================================================
# Checkbox
### Properties
Property | Type | Description
:------------------ | :-----------:| :----------
defaultValue | string | Sets the default value of the input.
defaultChecked | string | If true, the checkbox is checked by default.
hidden | bool | Sets the visibility of a component.
label | string | Adds a label to the checkbox.
onChange | function | Callback function when the checkbox has changed.
### Examples
```jsx
import React, { Component } from 'react';
import { Checkbox } from 'react-desktop/macOs';
export default class extends Component {
render() {
return (
console.log(e.target.value)}
defaultValue="I got checked!"
defaultChecked
/>
);
}
}
```
================================================
FILE: docs/mac-os/dialog.md
================================================
# Dialog
### Properties
Property | Type | Description
:------------------ | :-------------:| :----------
buttons | array | Sets the buttons of the component.
horizontalAlignment | string | Sets the horizontal alignment of the component's content __Property value__ _"left"_, _"center"_, _"right"_
icon | element | Sets the icon element of the component.
margin | string, number | Sets the outer margin of a component. __E.G.__ _"30px 20px"_
marginBottom | string, number | Sets the outer margin bottom of a component.
marginLeft | string, number | Sets the outer margin left of a component.
marginRight | string, number | Sets the outer margin right of a component.
marginTop | string, number | Sets the outer margin top of a component.
message | string | Sets the message of the component.
title | string | Sets the title of the component.
verticalAlignment | string | Sets the vertical alignment of the component's content. __Property value__ _"top"_, _"center"_, _"bottom"_
### Examples
```jsx
import React, { Component } from 'react';
import { Dialog, Button } from 'react-desktop/macOs';
export default class extends Component {
render() {
return (
console.log('close this dialog')}>Cancel,
console.log('submit this dialog')}>Submit ,
]}
/>
);
}
renderIcon() {
return (
);
}
}
```
================================================
FILE: docs/mac-os/label.md
================================================
# Label
### Properties
Property | Type | Description
:------------------ | :-------------:| :----------
color | string | Sets the color of the text.
height | number | Sets the height of a component.
hidden | bool | Sets the visibility of a component.
horizontalAlignment | string | Sets the horizontal alignment of the component's content __Property value__ _"left"_, _"center"_, _"right"_
margin | string, number | Sets the outer margin of a component. __E.G.__ _"30px 20px"_
marginBottom | string, number | Sets the outer margin bottom of a component.
marginLeft | string, number | Sets the outer margin left of a component.
marginRight | string, number | Sets the outer margin right of a component.
marginTop | string, number | Sets the outer margin top of a component.
padding | string, number | Sets the padding inside a component. __E.G.__ _"30px 20px"_
paddingBottom | string, number | Sets the padding bottom inside a component.
paddingLeft | string, number | Sets the padding left inside a component.
paddingRight | string, number | Sets the padding right inside a component.
paddingTop | string, number | Sets the padding top inside a component.
verticalAlignment | string | Sets the vertical alignment of the component's content. __Property value__ _"top"_, _"center"_, _"bottom"_
width | number | Sets the width of a component.
### Examples
```jsx
import React, { Component } from 'react';
import { Label } from 'react-desktop/macOs';
export default class extends Component {
render() {
return (
My Label
);
}
}
```
================================================
FILE: docs/mac-os/link.md
================================================
# Link
### Properties
Property | Type | Description
:------------------ | :-------------:| :----------
color | string | Sets the color of the text.
height | string, number | Sets the height of a component.
hidden | bool | Sets the visibility of a component.
margin | string, number | Sets the outer margin of a component. __E.G.__ _"30px 20px"_
marginBottom | string, number | Sets the outer margin bottom of a component.
marginLeft | string, number | Sets the outer margin left of a component.
marginRight | string, number | Sets the outer margin right of a component.
marginTop | string, number | Sets the outer margin top of a component.
padding | string, number | Sets the padding inside a component. __E.G.__ _"30px 20px"_
paddingBottom | string, number | Sets the padding bottom inside a component.
paddingLeft | string, number | Sets the padding left inside a component.
paddingRight | string, number | Sets the padding right inside a component.
paddingTop | string, number | Sets the padding top inside a component.
size | string, number | Sets the font size of a component.
textAlign | string | Sets the text alignment of the component's content. __Property value__ _"left"_, _"center"_, _"right"_
width | string, number | Sets the width of a component.
### Examples
```jsx
import React, { Component } from 'react';
import { View, Link } from 'react-desktop/macOs';
export default class extends Component {
render() {
return (
This is a link
This is another link
);
}
}
```
================================================
FILE: docs/mac-os/list-view.md
================================================
# ListView
## ListView
### Properties
Property | Type | Description
:------------------ | :-------------:| :----------
background | string | Sets the background color of a component.
height | number | Sets the height of a component.
hidden | bool | Sets the visibility of a component.
margin | string, number | Sets the outer margin of a component. __E.G.__ _"30px 20px"_
marginBottom | string, number | Sets the outer margin bottom of a component.
marginLeft | string, number | Sets the outer margin left of a component.
marginRight | string, number | Sets the outer margin right of a component.
marginTop | string, number | Sets the outer margin top of a component.
padding | string, number | Sets the padding inside a component. __E.G.__ _"30px 20px"_
paddingBottom | string, number | Sets the padding bottom inside a component.
paddingLeft | string, number | Sets the padding left inside a component.
paddingRight | string, number | Sets the padding right inside a component.
paddingTop | string, number | Sets the padding top inside a component.
width | number | Sets the width of a component.
## ListViewFooter
### Properties
Property | Type | Description
:------------------ | :-------------:| :----------
background | string | Sets the background color of a component.
height | number | Sets the height of a component.
padding | string, number | Sets the padding inside a component. __E.G.__ _"30px 20px"_
paddingBottom | string, number | Sets the padding bottom inside a component.
paddingLeft | string, number | Sets the padding left inside a component.
paddingRight | string, number | Sets the padding right inside a component.
paddingTop | string, number | Sets the padding top inside a component.
width | number | Sets the width of a component.
## ListViewHeader
### Properties
Property | Type | Description
:------------------ | :-------------:| :----------
background | string | Sets the background color of a component.
height | number | Sets the height of a component.
padding | string, number | Sets the padding inside a component. __E.G.__ _"30px 20px"_
paddingBottom | string, number | Sets the padding bottom inside a component.
paddingLeft | string, number | Sets the padding left inside a component.
paddingRight | string, number | Sets the padding right inside a component.
paddingTop | string, number | Sets the padding top inside a component.
width | number | Sets the width of a component.
## ListViewRow
### Properties
Property | Type | Description
:------------------ | :-------------:| :----------
background | string | Sets the background color of a component.
height | number | Sets the height of a component.
hidden | bool | Sets the visibility of a component.
horizontalAlignment | string | Sets the horizontal alignment of the component's content __Property value__ _"left"_, _"center"_, _"right"_
layout | string | Sets the direction of the content. __Property value__ _"horizontal"_, _"vertical"_
margin | string, number | Sets the outer margin of a component. __E.G.__ _"30px 20px"_
marginBottom | string, number | Sets the outer margin bottom of a component.
marginLeft | string, number | Sets the outer margin left of a component.
marginRight | string, number | Sets the outer margin right of a component.
marginTop | string, number | Sets the outer margin top of a component.
padding | string, number | Sets the padding inside a component. __E.G.__ _"30px 20px"_
paddingBottom | string, number | Sets the padding bottom inside a component.
paddingLeft | string, number | Sets the padding left inside a component.
paddingRight | string, number | Sets the padding right inside a component.
paddingTop | string, number | Sets the padding top inside a component.
verticalAlignment | string | Sets the vertical alignment of the component's content. __Property value__ _"top"_, _"center"_, _"bottom"_
width | number | Sets the width of a component.
## ListViewSection
### Properties
Property | Type | Description
:------------------ | :---------------------:| :----------
header | string, element, array | Sets the header or header element of the component.
## ListViewSectionHeader
### Properties
Property | Type | Description
:------------------ | :-------------------:| :----------
bold | bool, number, string | Sets the bold value of a component.
color | string | Sets the color of the text.
margin | string, number | Sets the outer margin of a component. __E.G.__ _"30px 20px"_
marginBottom | string, number | Sets the outer margin bottom of a component.
marginLeft | string, number | Sets the outer margin left of a component.
marginRight | string, number | Sets the outer margin right of a component.
marginTop | string, number | Sets the outer margin top of a component.
padding | string, number | Sets the padding inside a component. __E.G.__ _"30px 20px"_
paddingBottom | string, number | Sets the padding bottom inside a component.
paddingLeft | string, number | Sets the padding left inside a component.
paddingRight | string, number | Sets the padding right inside a component.
paddingTop | string, number | Sets the padding top inside a component.
size | string, number | Sets the font size of a component.
## ListViewSeparator
### Properties
Property | Type | Description
:------------------ | :-------------------:| :----------
color | string | Sets the color of the separator.
height | number | Sets the height of a component.
hidden | bool | Sets the visibility of a component.
margin | string, number | Sets the outer margin of a component. __E.G.__ _"30px 20px"_
marginBottom | string, number | Sets the outer margin bottom of a component.
marginLeft | string, number | Sets the outer margin left of a component.
marginRight | string, number | Sets the outer margin right of a component.
marginTop | string, number | Sets the outer margin top of a component.
padding | string, number | Sets the padding inside a component. __E.G.__ _"30px 20px"_
paddingBottom | string, number | Sets the padding bottom inside a component.
paddingLeft | string, number | Sets the padding left inside a component.
paddingRight | string, number | Sets the padding right inside a component.
paddingTop | string, number | Sets the padding top inside a component.
width | number | Sets the width of a component.
### Examples
```jsx
import React, { Component } from 'react';
import {
ListView,
ListViewHeader,
ListViewFooter,
ListViewSection,
ListViewSectionHeader,
ListViewRow,
ListViewSeparator,
Text
} from 'react-desktop/macOs';
export default class extends Component {
constructor() {
super();
this.state = { selected: null };
}
render() {
return (
Order by name
{this.renderItem('Item 1', 'This is the first item.')}
{this.renderItem('Item 2', 'This is the second item.')}
{this.renderItem('Item 3', 'This is the third item.')}
{this.renderItem('Item 4', 'This is the fourth item.')}
{this.renderItem('Item 5', 'This is the fifth item.')}
{this.renderItem('Item 6', 'This is the sixth item.')}
Status
);
}
renderSectionHeader(title) {
return (
{title}
);
}
renderItem(title, info) {
return (
this.setState({ selected: title })}
background={this.state.selected === title ? '#d8dadc' : null}
>
{info}
);
}
}
```
================================================
FILE: docs/mac-os/pin.md
================================================
# Pin
### Properties
Property | Type | Description
:------------------ | :-------------:| :----------
hidden | bool | Sets the visibility of a component.
length | number | Sets the length of the pin.
margin | string, number | Sets the outer margin of a component. __E.G.__ _"30px 20px"_
marginBottom | string, number | Sets the outer margin bottom of a component.
marginLeft | string, number | Sets the outer margin left of a component.
marginRight | string, number | Sets the outer margin right of a component.
marginTop | string, number | Sets the outer margin top of a component.
onChange | function | Callback function when the input changes.
reveal | bool | Reveals the characters in the pin.
### Examples
```jsx
import React, { Component } from 'react';
import { Pin, View } from 'react-desktop/macOs';
export default class extends Component {
render() {
return (
console.log(value)}
length={4}
reveal
/>
);
}
}
```
================================================
FILE: docs/mac-os/progress-circle.md
================================================
# Progress Circle
### Properties
Property | Type | Description
:------------------ | :-----------:| :----------
color | string | Sets the color of the progress circle.
hidden | bool | Sets the visibility of a component.
size | number | Sets the size of the progress circle.
### Examples
```jsx
import React, { Component } from 'react';
import { ProgressCircle } from 'react-desktop/macOs';
export default class extends Component {
render() {
return (
);
}
}
```
================================================
FILE: docs/mac-os/radio.md
================================================
# Radio
### Properties
Property | Type | Description
:------------------ | :-----------:| :----------
defaultValue | string | Sets the default value of the input.
defaultChecked | string | If true, the radio is checked by default.
hidden | bool | Sets the visibility of a component.
label | string | Adds a label to the checkbox.
name | string | Name of the input.
onChange | function | Callback function when the checkbox has changed.
### Examples
```jsx
import React, { Component } from 'react';
import { View, Radio } from 'react-desktop/macOs';
export default class extends Component {
render() {
return (
console.log(e.target.value)}
defaultValue="I got checked!"
defaultChecked
/>
console.log(e.target.value)}
defaultValue="I got checked!"
/>
);
}
}
```
================================================
FILE: docs/mac-os/search-field.md
================================================
# SearchField
### Properties
Property | Type | Description
:------------------ | :-------------------:| :----------
cancel | bool | Sets whether the cancel button is visible.
centerPlaceholder | bool | Sets whether the placeholder is animated and centered when the input is not focused.
defaultValue | string | Sets the default value of the input.
focusRing | bool | Sets the visibility of the focus ring around the input.
hidden | bool | Sets the visibility of a component.
icon | element, array | Adds an icon to the input.
label | string | Adds a label to the input.
margin | string, number | Sets the outer margin of a component. __E.G.__ _"30px 20px"_
marginBottom | string, number | Sets the outer margin bottom of a component.
marginLeft | string, number | Sets the outer margin left of a component.
marginRight | string, number | Sets the outer margin right of a component.
marginTop | string, number | Sets the outer margin top of a component.
onCancel | function | Callback function when the user press the cancel button.
onChange | function | Callback function when the input changes.
onEnter | function | Callback function when the enter key is pressed.
placeholder | string | Adds a placeholder to the input.
rounded | bool, number, string | Sets the roundness of the input border
size | string, number | Sets the font size of a component.
value | string | Sets the value of the input.
width | number | Sets the width of a component.
### Examples
```jsx
import React, { Component } from 'react';
import { TitleBar, Toolbar, SearchField } from 'react-desktop/macOs';
export default class extends Component {
handleChange = e => console.log(e.target.value);
render() {
return (
);
}
}
```
================================================
FILE: docs/mac-os/segmented-control.md
================================================
# Segmented Control
## SegmentedControl
### Properties
Property | Type | Description
:------------------ | :-------------:| :----------
box | bool | Sets whether the item is in a box or not.
height | number | Sets the height of a component.
hidden | bool | Sets the visibility of a component.
margin | string, number | Sets the outer margin of a component. __E.G.__ _"30px 20px"_
marginBottom | string, number | Sets the outer margin bottom of a component.
marginLeft | string, number | Sets the outer margin left of a component.
marginRight | string, number | Sets the outer margin right of a component.
marginTop | string, number | Sets the outer margin top of a component.
width | number | Sets the width of a component.
## SegmentedControlItem
### Properties
Property | Type | Description
:------------------ | :-------:| :----------
title | string | Sets the title of the item.
onSelect | function | Callback function when selecting an item.
selected | bool | Sets whether the item is selected or not.
### Examples
```jsx
import React, { Component } from 'react';
import { SegmentedControl, SegmentedControlItem, Text } from 'react-desktop/macOs';
export default class extends Component {
constructor() {
super();
this.state = { selected: 1 }
}
render() {
return (
{this.renderItems()}
);
}
renderItems() {
return [
this.renderItem(1, 'Tab 1', Content 1 ),
this.renderItem(2, 'Tab 2', Content 2 ),
this.renderItem(3, 'Tab 3', Content 3 )
];
}
renderItem(key, title, content) {
return (
this.setState({ selected: key })}
>
{content}
);
}
}
```
================================================
FILE: docs/mac-os/text-input.md
================================================
# TextInput
### Properties
Property | Type | Description
:------------------ | :-------------------:| :----------
centerPlaceholder | bool | Sets whether the placeholder is animated and centered when the input is not focused.
defaultValue | string | Sets the default value of the input.
focusRing | bool | Sets the visibility of the focus ring around the input.
hidden | bool | Sets the visibility of a component.
icon | element, array | Adds an icon to the input.
label | string | Adds a label to the input.
margin | string, number | Sets the outer margin of a component. __E.G.__ _"30px 20px"_
marginBottom | string, number | Sets the outer margin bottom of a component.
marginLeft | string, number | Sets the outer margin left of a component.
marginRight | string, number | Sets the outer margin right of a component.
marginTop | string, number | Sets the outer margin top of a component.
onChange | function | Callback function when the input changes.
onEnter | function | Callback function when the enter key is pressed.
placeholder | string | Adds a placeholder to the input.
rounded | bool, number, string | Sets the roundness of the input border
size | string, number | Sets the font size of a component.
value | string | Sets the value of the input.
width | number | Sets the width of a component.
password | bool | Sets the input type to password.
### Methods
Method | Type | Description
:------------------ | :-------------:| :----------
focus | function | Focus text input programmatically
blur | function | Remove focus from text input programmatically
### Examples
```jsx
import React, { Component } from 'react';
import { TextInput } from 'react-desktop/macOs';
export default class extends Component {
handleChange = e => console.log(e.target.value);
render() {
return (
);
}
}
```
================================================
FILE: docs/mac-os/text.md
================================================
# Text
### Properties
Property | Type | Description
:------------------ | :-------------------:| :----------
background | string | Sets the background color of a component.
bold | bool, number, string | Sets the bold value of a component.
color | string | Sets the color of the text.
height | string, number | Sets the height of a component.
hidden | bool | Sets the visibility of a component.
margin | string, number | Sets the outer margin of a component. __E.G.__ _"30px 20px"_
marginBottom | string, number | Sets the outer margin bottom of a component.
marginLeft | string, number | Sets the outer margin left of a component.
marginRight | string, number | Sets the outer margin right of a component.
marginTop | string, number | Sets the outer margin top of a component.
padding | string, number | Sets the padding inside a component. __E.G.__ _"30px 20px"_
paddingBottom | string, number | Sets the padding bottom inside a component.
paddingLeft | string, number | Sets the padding left inside a component.
paddingRight | string, number | Sets the padding right inside a component.
paddingTop | string, number | Sets the padding top inside a component.
size | string, number | Sets the font size of a component.
textAlign | string | Sets the text alignment of the component's content. __Property value__ _"left"_, _"center"_, _"right"_
width | string, number | Sets the width of a component.
### Examples
```jsx
import React, { Component } from 'react';
import { Text } from 'react-desktop/macOs';
export default class extends Component {
render() {
return (
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam justo urna, posuere vitae est et, accumsan
bibendum sapien. Suspendisse lobortis mollis finibus. Nunc tincidunt enim est, efficitur semper dolor luctus
eget. Donec faucibus dolor id leo tincidunt, condimentum mattis augue finibus. Etiam hendrerit ipsum nisi,
vel semper dolor malesuada a. Pellentesque a scelerisque sapien, quis interdum odio. Nulla posuere, velit sit
amet lacinia pharetra, sapien arcu convallis dolor, id congue erat lectus nec sem. Praesent pretium a nisi et
elementum. Cras lacinia sollicitudin suscipit. Phasellus accumsan felis odio. Pellentesque habitant morbi
tristique senectus et netus et malesuada fames ac turpis egestas.
);
}
}
```
================================================
FILE: docs/mac-os/title-bar.md
================================================
# TitleBar
### Properties
Property | Type | Description
:------------------ | :-----------:| :----------
controls | bool | Sets the visibility of the controls of the title bar.
inset | bool | Sets the controls of the title bar state to be inset.
isFullscreen | bool | Sets the title bar state to fullscreen.
onCloseClick | function | Callback function of the close button.
onMaximizeClick | function | Callback function of the maximize button
onMinimizeClick | function | Callback function of the minimize button
onResizeClick | function | Callback function of the resize button
title | string | Sets the title of the title bar.
transparent | bool | Make the title bar background transparent.
disableClose | bool | Disable the close button.
disableMinimize | bool | Disable the minimize button.
disableResize | bool | Disable the resize button.
disableFullscreen | bool | Disable fullscreen, will show the '+' maximize icon instead.
### Examples
```jsx
import React, { Component } from 'react';
import { View, TitleBar } from 'react-desktop/macOs';
export default class extends Component {
constructor() {
super();
this.state = { isFullscreen: false };
}
render() {
return (
console.log('Close window')}
onMinimizeClick={() => console.log('Minimize window')}
onMaximizeClick={() => console.log('Mazimize window')}
onResizeClick={() => this.setState({ isFullscreen: !this.state.isFullscreen })}
/>
);
}
}
```
================================================
FILE: docs/mac-os/toolbar-nav.md
================================================
# Toolbar Nav
## ToolbarNav
### Properties
Property | Type | Description
:------------------ | :-----------:| :----------
height | number | Sets the height of a component.
width | number | Sets the width of a component.
## ToolbarNavItem
### Properties
Property | Type | Description
:------------------ | :---------------------:| :----------
icon | element, array | Sets the icon element of the item.
onClick | function | Callback function when the item is pressed.
selected | bool | Sets whether the item is selected or not.
title | string | Sets the title of the item.
### Examples
```jsx
import React, { Component } from 'react';
import { TitleBar, Toolbar, ToolbarNav, ToolbarNavItem } from 'react-desktop/macOs';
const circle = (
);
const star = (
);
const polygon = (
);
export default class extends Component {
constructor() {
super();
this.state = { selected: 1 };
}
render() {
return (
this.setState({ selected: 1 })}
/>
this.setState({ selected: 2 })}
/>
this.setState({ selected: 3 })}
/>
);
}
}
```
================================================
FILE: docs/mac-os/toolbar.md
================================================
# Toolbar
### Properties
Property | Type | Description
:------------------ | :-----------:| :----------
height | number | Sets the height of a component.
horizontalAlignment | string | Sets the horizontal alignment of the component's content __Property value__ _"left"_, _"center"_, _"right"_
verticalAlignment | string | Sets the vertical alignment of the component's content. __Property value__ _"top"_, _"center"_, _"bottom"_
width | number | Sets the width of a component.
### Examples
```jsx
import React, { Component } from 'react';
import { TitleBar, Toolbar, Text } from 'react-desktop/macOs';
export default class extends Component {
render() {
return (
);
}
}
```
================================================
FILE: docs/mac-os/view.md
================================================
# View
### Properties
Property | Type | Description
:------------------ | :-------------:| :----------
background | string | Sets the background color of a component.
height | number | Sets the height of a component.
hidden | bool | Sets the visibility of a component.
horizontalAlignment | string | Sets the horizontal alignment of the component's content __Property value__ _"left"_, _"center"_, _"right"_
layout | string | Sets the direction of the content. __Property value__ _"horizontal"_, _"vertical"_
margin | string, number | Sets the outer margin of a component. __E.G.__ _"30px 20px"_
marginBottom | string, number | Sets the outer margin bottom of a component.
marginLeft | string, number | Sets the outer margin left of a component.
marginRight | string, number | Sets the outer margin right of a component.
marginTop | string, number | Sets the outer margin top of a component.
padding | string, number | Sets the padding inside a component. __E.G.__ _"30px 20px"_
paddingBottom | string, number | Sets the padding bottom inside a component.
paddingLeft | string, number | Sets the padding left inside a component.
paddingRight | string, number | Sets the padding right inside a component.
paddingTop | string, number | Sets the padding top inside a component.
verticalAlignment | string | Sets the vertical alignment of the component's content. __Property value__ _"top"_, _"center"_, _"bottom"_
width | number | Sets the width of a component.
### Examples
```jsx
import React, { Component } from 'react';
import { View, Text } from 'react-desktop/macOs';
export default class extends Component {
render() {
return (
Hello World
);
}
}
```
================================================
FILE: docs/mac-os/window.md
================================================
# Window
### Properties
Property | Type | Description
:------------------ | :-------------:| :----------
background | string | Sets the background color of a component.
chrome | bool | Sets the chrome of the window.
height | number | Sets the height of a component.
hidden | bool | Sets the visibility of a component.
horizontalAlignment | string | Sets the horizontal alignment of the component's content __Property value__ _"left"_, _"center"_, _"right"_
padding | string, number | Sets the padding inside a component. __E.G.__ _"30px 20px"_
paddingBottom | string, number | Sets the padding bottom inside a component.
paddingLeft | string, number | Sets the padding left inside a component.
paddingRight | string, number | Sets the padding right inside a component.
paddingTop | string, number | Sets the padding top inside a component.
verticalAlignment | string | Sets the vertical alignment of the component's content. __Property value__ _"top"_, _"center"_, _"bottom"_
width | number | Sets the width of a component.
### Examples
```jsx
import React, { Component } from 'react';
import { Window, TitleBar, Text } from 'react-desktop/macOs';
export default class extends Component {
render() {
return (
Hello World
);
}
}
```
================================================
FILE: docs/testing.md
================================================
# Testing
Documentation is coming soon.
================================================
FILE: docs/windows/button.md
================================================
# Button
### Properties
Property | Type | Description
:------------------ | :-----------:| :----------
color | string, bool | Sets whether the button is colored (bool) or sets the color of the button (string).
hidden | bool | Sets the visibility of a component.
onClick | function | Callback function when the button is pressed.
push | bool | Display push animation when pressing the button.
theme | string | Sets the UI theme that is used by this component and its children elements. __Property value__ _"light"_, _"dark"_
type | string | Sets the type of the button __Property value__ _"button"_ _"submit"_. Default value _"button"_.
### Examples
```jsx
import React, { Component } from 'react';
import { Button } from 'react-desktop/windows';
export default class extends Component {
static defaultProps = {
color: '#cc7f29'
};
render() {
return (
console.log('Clicked!')}>
Press me!
);
}
}
```
================================================
FILE: docs/windows/checkbox.md
================================================
# Checkbox
### Properties
Property | Type | Description
:------------------ | :-----------:| :----------
color | string | Sets the color of the checkbox.
defaultValue | string | Sets the default value of the input.
defaultChecked | string | If true, the checkbox is checked by default.
hidden | bool | Sets the visibility of a component.
label | string | Adds a label to the checkbox.
onChange | function | Callback function when the checkbox has changed.
theme | string | Sets the UI theme that is used by this component and its children elements. __Property value__ _"light"_, _"dark"_
### Examples
```jsx
import React, { Component } from 'react';
import { Checkbox } from 'react-desktop/windows';
export default class extends Component {
static defaultProps = {
color: '#cc7f29',
theme: 'light'
};
render() {
return (
console.log(e.target.value)}
defaultValue="I got checked!"
defaultChecked
/>
);
}
}
```
================================================
FILE: docs/windows/label.md
================================================
# Label
### Properties
Property | Type | Description
:------------------ | :-----------:| :----------
background | string, bool | Sets whether the background is colored (bool) or sets the color of the background (string).
color | string, bool | Sets whether the text is colored (bool) or sets the color of the text (string).
height | number | Sets the height of a component.
hidden | bool | Sets the visibility of a component.
horizontalAlignment | string | Sets the horizontal alignment of the component's content __Property value__ _"left"_, _"center"_, _"right"_
margin | string | Sets the outer margin of a component. __E.G.__ _"30px 20px"_
padding | string | Sets the padding inside a component. __E.G.__ _"30px 20px"_
theme | string | Sets the UI theme that is used by this component and its children elements. __Property value__ _"light"_, _"dark"_
verticalAlignment | string | Sets the vertical alignment of the component's content. __Property value__ _"top"_, _"center"_, _"bottom"_
width | number | Sets the width of a component.
### Examples
```jsx
import React, { Component } from 'react';
import { Label } from 'react-desktop/windows';
export default class extends Component {
render() {
return (
My Label
);
}
}
```
================================================
FILE: docs/windows/master-details-view.md
================================================
# MasterDetailsView
## MasterDetailsView
### Properties
Property | Type | Description
:------------------ | :-----:| :----------
color | string | Sets the main color of a component.
theme | string | Sets the UI theme that is used by this component and its children elements. __Property value__ _"light"_, _"dark"_
## MasterDetailsViewItem
### Properties
Property | Type | Description
:------------------ | :-----:| :----------
color | string | Sets the main color of a component.
theme | string | Sets the UI theme that is used by this component and its children elements. __Property value__ _"light"_, _"dark"_
## MasterDetailsViewItemMaster
### Properties
Property | Type | Description
:------------------ | :-----:| :----------
color | string | Sets the main color of a component.
push | bool | Display push animation when selecting an item.
selected | bool | Master is selected.
theme | string | Sets the UI theme that is used by this component and its children elements. __Property value__ _"light"_, _"dark"_
width | number | Sets the width of a component.
## MasterDetailsViewItemDetails
### Properties
Property | Type | Description
:------------------ | :-----------:| :----------
background | string, bool | Sets the background color of a component, if bool, the color will be used as the background color.
color | string | Sets the main color of a component.
theme | string | Sets the UI theme that is used by this component and its children elements. __Property value__ _"light"_, _"dark"_
### Examples
```jsx
import React, { Component } from 'react';
import {
MasterDetailsView,
MasterDetailsViewItem,
MasterDetailsViewItemMaster,
MasterDetailsViewItemDetails,
Text
} from 'react-desktop/windows';
export default class extends Component {
static defaultProps = {
color: '#cc7f29',
theme: 'light'
};
render() {
return (
{this.renderItem('Item 1', 'Content 1')}
{this.renderItem('Item 2', 'Content 2')}
{this.renderItem('Item 3', 'Content 3')}
);
}
renderItem(master, details) {
return (
{master}
{details}
);
}
}
```
================================================
FILE: docs/windows/nav-pane.md
================================================
# NavPane
## NavPane
### Properties
Property | Type | Description
:-------------------- | :-------------:| :----------
canPaneToggle | bool | Sets whether the pane can be compacted. Default value _"true"_.
color | string | Sets the main color of a component.
defaultIsPaneExpanded | string | Sets whether the pane is expanded by default. Default value _"true"_.
onPaneToggle | function | Callback function when the pane is expanded or compacted.
paneCompactedLength | string, number | Sets the length of the pane when compacted. Default value _"48px"_.
paneExpandedLength | string, number | Sets the length of the pane when expanded. Default value _"200px"_
theme | string | Sets the UI theme that is used by this component and its children elements. __Property value__ _"light"_, _"dark"_
## NavPaneItem
### Properties
Property | Type | Description
:------------------- | :---------------------:| :----------
background | string, bool | Sets the background color of a component, if bool, the color will be used as the background color.
color | string | Sets the main color of a component.
horizontalAlignment | string | Sets the horizontal alignment of the component's content __Property value__ _"left"_, _"center"_, _"right"_
icon | string, element, array | Sets the icon element of the item.
margin | string | Sets the outer margin of a component. __E.G.__ _"30px 20px"_
onSelect | function | Callback function when an item is selected.
padding | string | Sets the padding inside a component. __E.G.__ _"30px 20px"_
push | bool | Display push animation when pressing the button.
selected | bool | Sets whether the item is selected or not.
title | string, element, array | Sets the title of the element.
theme | string | Sets the UI theme that is used by this component and its children elements. __Property value__ _"light"_, _"dark"_
verticalAlignment | string | Sets the vertical alignment of the component's content. __Property value__ _"top"_, _"center"_, _"bottom"_
### Examples
```jsx
import React, { Component } from 'react';
import { NavPane, NavPaneItem, Text } from 'react-desktop/windows';
export default class extends Component {
static defaultProps = {
color: '#cc7f29',
theme: 'light'
};
constructor() {
super();
this.state = {
selected: 'Item 1'
}
}
render() {
return (
{this.renderItem('Item 1', 'Content 1')}
{this.renderItem('Item 2', 'Content 2')}
{this.renderItem('Item 3', 'Content 3')}
);
}
renderItem(title, content) {
return (
this.setState({ selected: title })}
padding="10px 20px"
push
>
{content}
);
}
renderIcon(name) {
const fill = this.props.theme === 'dark' ? '#ffffff' : '#000000';
switch(name) {
case 'Item 1':
return (
);
case 'Item 2':
return (
);
case 'Item 3':
return (
);
}
}
}
```
================================================
FILE: docs/windows/progress-circle.md
================================================
# Progress Circle
### Properties
Property | Type | Description
:------------------ | :-----------:| :----------
color | string | Sets the color of the progress circle.
hidden | bool | Sets the visibility of a component.
size | number | Sets the size of the progress circle.
### Examples
```jsx
import React, { Component } from 'react';
import { ProgressCircle } from 'react-desktop/windows';
export default class extends Component {
static defaultProps = {
color: '#cc7f29'
};
render() {
return (
);
}
}
```
================================================
FILE: docs/windows/radio.md
================================================
# Radio
### Properties
Property | Type | Description
:------------------ | :-----------:| :----------
color | string | Sets the color of the radio.
defaultValue | string | Sets the default value of the input.
defaultChecked | string | If true, the radio is checked by default.
hidden | bool | Sets the visibility of a component.
label | string | Adds a label to the checkbox.
name | string | Name of the input.
onChange | function | Callback function when the checkbox has changed.
theme | string | Sets the UI theme that is used by this component and its children elements. __Property value__ _"light"_, _"dark"_
### Examples
```jsx
import React, { Component } from 'react';
import { View, Radio } from 'react-desktop/windows';
export default class extends Component {
static defaultProps = {
color: '#cc7f29',
theme: 'light'
};
render() {
return (
console.log(e.target.value)}
defaultValue="I got checked!"
defaultChecked
/>
console.log(e.target.value)}
defaultValue="I got checked!"
/>
);
}
}
```
================================================
FILE: docs/windows/text-input.md
================================================
# TextInput
### Properties
Property | Type | Description
:------------------ | :-----------:| :----------
background | string, bool | Sets the background color of a component, if bool, the color will be used as the background color.
color | string | Sets the main color of a component and it's children.
defaultValue | string | Sets the default value of the input.
hidden | bool | Sets the visibility of a component.
label | string | Adds a label to the input.
labelColor | string, bool | Sets whether the label text is colored (bool) or sets the color of the label text (string).
labelStyle | object | Custom styles for the label.
margin | string | Sets the outer margin of a component. __E.G.__ _"30px 20px"_
onChange | function | Callback function when the input changes.
placeholder | function | Adds a placeholder to the input.
theme | string | Sets the UI theme that is used by this component and its children elements. __Property value__ _"light"_, _"dark"_
value | string | Sets the value of the input.
width | number | Sets the width of a component.
password | bool | Sets the input type to password.
### Examples
```jsx
import React, { Component } from 'react';
import { TextInput } from 'react-desktop/windows';
export default class extends Component {
static defaultProps = {
color: '#cc7f29',
theme: 'light'
};
handleChange = e => console.log(e.target.value);
render() {
return (
);
}
}
```
================================================
FILE: docs/windows/text.md
================================================
# Text
### Properties
Property | Type | Description
:------------------ | :-----------:| :----------
background | string, bool | Sets whether the background is colored (bool) or sets the color of the background (string).
color | string, bool | Sets whether the text is colored (bool) or sets the color of the text (string).
height | number | Sets the height of a component.
hidden | bool | Sets the visibility of a component.
horizontalAlignment | string | Sets the horizontal alignment of the component's content __Property value__ _"left"_, _"center"_, _"right"_
margin | string | Sets the outer margin of a component. __E.G.__ _"30px 20px"_
padding | string | Sets the padding inside a component. __E.G.__ _"30px 20px"_
theme | string | Sets the UI theme that is used by this component and its children elements. __Property value__ _"light"_, _"dark"_
verticalAlignment | string | Sets the vertical alignment of the component's content. __Property value__ _"top"_, _"center"_, _"bottom"_
width | number | Sets the width of a component.
### Examples
```jsx
import React, { Component } from 'react';
import { Text } from 'react-desktop/windows';
export default class extends Component {
static defaultProps = {
color: '#cc7f29',
theme: 'light'
};
render() {
return (
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam justo urna, posuere vitae est et, accumsan
bibendum sapien. Suspendisse lobortis mollis finibus. Nunc tincidunt enim est, efficitur semper dolor luctus
eget. Donec faucibus dolor id leo tincidunt, condimentum mattis augue finibus. Etiam hendrerit ipsum nisi,
vel semper dolor malesuada a. Pellentesque a scelerisque sapien, quis interdum odio. Nulla posuere, velit sit
amet lacinia pharetra, sapien arcu convallis dolor, id congue erat lectus nec sem. Praesent pretium a nisi et
elementum. Cras lacinia sollicitudin suscipit. Phasellus accumsan felis odio. Pellentesque habitant morbi
tristique senectus et netus et malesuada fames ac turpis egestas.
);
}
}
```
================================================
FILE: docs/windows/title-bar.md
================================================
# TitleBar
### Properties
Property | Type | Description
:------------------ | :-----------:| :----------
background | string, bool | Sets the background color of a component, if bool, the color will be used as the background color.
controls | bool | Sets the visibility of the controls of the title bar.
color | string | Sets the main color of a component and it's children.
isMaximized | bool | Sets the title bar state to maximized.
onCloseClick | function | Callback function of the close button.
onMaximizeClick | function | Callback function of the maximize button
onMinimizeClick | function | Callback function of the minimize button
onRestoreDownClick | function | Callback function of the restore down button
title | string | Sets the title of the title bar.
theme | string | Sets the UI theme that is used by this component and its children elements. __Property value__ _"light"_, _"dark"_
### Examples
```jsx
import React, { Component } from 'react';
import { TitleBar } from 'react-desktop/windows';
export default class extends Component {
static defaultProps = {
color: '#cc7f29',
theme: 'light'
};
constructor(props) {
super(props);
this.state = { isMaximized: true };
}
close = () => console.log('close');
minimize = () => console.log('minimize');
toggleMaximize = () => this.setState({ isMaximized: !this.state.isMaximized });
render() {
return (
);
}
}
```
================================================
FILE: docs/windows/view.md
================================================
# View
### Properties
Property | Type | Description
:------------------ | :-----------:| :----------
background | string, bool | Sets the background color of a component, if bool, the color will be used as the background color.
color | string | Sets the main color of a component and it's children.
height | number | Sets the height of a component.
hidden | bool | Sets the visibility of a component.
horizontalAlignment | string | Sets the horizontal alignment of the component's content __Property value__ _"left"_, _"center"_, _"right"_
layout | string | Sets the direction of the content. __Property value__ _"horizontal"_, _"vertical"_
margin | string | Sets the outer margin of a component. __E.G.__ _"30px 20px"_
padding | string | Sets the padding inside a component. __E.G.__ _"30px 20px"_
theme | string | Sets the UI theme that is used by this component and its children elements. __Property value__ _"light"_, _"dark"_
verticalAlignment | string | Sets the vertical alignment of the component's content. __Property value__ _"top"_, _"center"_, _"bottom"_
width | number | Sets the width of a component.
### Examples
```jsx
import React, { Component } from 'react';
import { View, Text } from 'react-desktop/windows';
export default class extends Component {
static defaultProps = {
color: '#cc7f29',
theme: 'light'
};
render() {
return (
Hello World
);
}
}
```
================================================
FILE: docs/windows/window.md
================================================
# Window
### Properties
Property | Type | Description
:------------------ | :-----------:| :----------
background | string, bool | Sets the background color of a component, if bool, the color will be used as the background color.
chrome | bool | Sets the chrome of the window.
color | string | Sets the main color of a component and it's children.
height | number | Sets the height of a component.
hidden | bool | Sets the visibility of a component.
horizontalAlignment | string | Sets the horizontal alignment of the component's content __Property value__ _"left"_, _"center"_, _"right"_
padding | string | Sets the padding inside a component. __E.G.__ _"30px 20px"_
theme | string | Sets the UI theme that is used by this component and its children elements. __Property value__ _"light"_, _"dark"_
verticalAlignment | string | Sets the vertical alignment of the component's content. __Property value__ _"top"_, _"center"_, _"bottom"_
width | number | Sets the width of a component.
### Examples
```jsx
import React, { Component } from 'react';
import { Window, TitleBar, Text } from 'react-desktop/windows';
export default class extends Component {
static defaultProps = {
color: '#cc7f29',
theme: 'light'
};
render() {
return (
Hello World
);
}
}
```
================================================
FILE: examples/macOs/advanced/pinDialog.js
================================================
import React, { Component } from 'react';
import { View, Dialog, Pin, Button, Text, ProgressCircle } from 'react-desktop/macOs';
class PinDialog extends Component {
constructor() {
super();
this.state = {
pin: '',
error: null,
loading: false
};
}
submit = () => {
this.setState({ loading: true });
setTimeout(() => {
this.setState({ loading: false, error: 'The confirmation code you entered is incorrect.' });
}, 1500);
};
render() {
let error;
if (this.state.error) {
error = {this.state.error} ;
}
return (
Cancel
,
Submit
]}
horizontalAlignment="center"
>
{error}
this.setState({ pin })}/>
Enter the four digit security code
);
}
renderIcon() {
return (
);
}
}
export default PinDialog;
================================================
FILE: examples/macOs/components/box.js
================================================
import React, { Component } from 'react';
import { Box, Text } from 'react-desktop/macOs';
export default class extends Component {
render() {
return (
Some text...
);
}
}
================================================
FILE: examples/macOs/components/button.js
================================================
import React, { Component } from 'react';
import { Button } from 'react-desktop/macOs';
export default class extends Component {
render() {
return (
console.log('Clicked!')}>
Press me!
);
}
}
================================================
FILE: examples/macOs/components/checkbox.js
================================================
import React, { Component } from 'react';
import { Checkbox } from 'react-desktop/macOs';
export default class extends Component {
render() {
return (
console.log(e.target.value)}
defaultValue="I got checked!"
defaultChecked
/>
);
}
}
================================================
FILE: examples/macOs/components/dialog.js
================================================
import React, { Component } from 'react';
import { Dialog, Button } from 'react-desktop/macOs';
export default class extends Component {
render() {
return (
console.log('close this dialog')}>Cancel,
console.log('submit this dialog')}>Submit ,
]}
/>
);
}
renderIcon() {
return (
);
}
}
================================================
FILE: examples/macOs/components/label.js
================================================
import React, { Component } from 'react';
import { Label } from 'react-desktop/macOs';
export default class extends Component {
render() {
return (
My Label
);
}
}
================================================
FILE: examples/macOs/components/link.js
================================================
import React, { Component } from 'react';
import { View, Link } from 'react-desktop/macOs';
export default class extends Component {
render() {
return (
This is a link
This is another link
);
}
}
================================================
FILE: examples/macOs/components/listView.js
================================================
import React, { Component } from 'react';
import {
ListView,
ListViewHeader,
ListViewFooter,
ListViewSection,
ListViewSectionHeader,
ListViewRow,
ListViewSeparator,
Text
} from 'react-desktop/macOs';
export default class extends Component {
constructor() {
super();
this.state = { selected: null };
}
render() {
return (
Order by name
{this.renderItem('Item 1', 'This is the first item.')}
{this.renderItem('Item 2', 'This is the second item.')}
{this.renderItem('Item 3', 'This is the third item.')}
{this.renderItem('Item 4', 'This is the fourth item.')}
{this.renderItem('Item 5', 'This is the fifth item.')}
{this.renderItem('Item 6', 'This is the sixth item.')}
Status
);
}
renderSectionHeader(title) {
return (
{title}
);
}
renderItem(title, info) {
return (
this.setState({ selected: title })}
background={this.state.selected === title ? '#d8dadc' : null}
>
{info}
);
}
}
================================================
FILE: examples/macOs/components/pin.js
================================================
import React, { Component } from 'react';
import { Pin, View } from 'react-desktop/macOs';
export default class extends Component {
render() {
return (
console.log(value)}
length={4}
reveal
/>
);
}
}
================================================
FILE: examples/macOs/components/progressCircle.js
================================================
import React, { Component } from 'react';
import { ProgressCircle } from 'react-desktop/macOs';
export default class extends Component {
render() {
return (
);
}
}
================================================
FILE: examples/macOs/components/radio.js
================================================
import React, { Component } from 'react';
import { View, Radio } from 'react-desktop/macOs';
export default class extends Component {
render() {
return (
console.log(e.target.value)}
defaultValue="I got checked!"
defaultChecked
/>
console.log(e.target.value)}
defaultValue="I got checked!"
/>
);
}
}
================================================
FILE: examples/macOs/components/searchField.js
================================================
import React, { Component } from 'react';
import { TitleBar, Toolbar, SearchField } from 'react-desktop/macOs';
export default class extends Component {
handleChange = e => console.log(e.target.value);
render() {
return (
);
}
}
================================================
FILE: examples/macOs/components/segmentedControl.js
================================================
import React, { Component } from 'react';
import { SegmentedControl, SegmentedControlItem, Text } from 'react-desktop/macOs';
export default class extends Component {
constructor() {
super();
this.state = { selected: 1 }
}
render() {
return (
{this.renderItems()}
);
}
renderItems() {
return [
this.renderItem(1, 'Tab 1', Content 1 ),
this.renderItem(2, 'Tab 2', Content 2 ),
this.renderItem(3, 'Tab 3', Content 3 )
];
}
renderItem(key, title, content) {
return (
this.setState({ selected: key })}
>
{content}
);
}
}
================================================
FILE: examples/macOs/components/text.js
================================================
import React, { Component } from 'react';
import { Text } from 'react-desktop/macOs';
export default class extends Component {
render() {
return (
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam justo urna, posuere vitae est et, accumsan
bibendum sapien. Suspendisse lobortis mollis finibus. Nunc tincidunt enim est, efficitur semper dolor luctus
eget. Donec faucibus dolor id leo tincidunt, condimentum mattis augue finibus. Etiam hendrerit ipsum nisi,
vel semper dolor malesuada a. Pellentesque a scelerisque sapien, quis interdum odio. Nulla posuere, velit sit
amet lacinia pharetra, sapien arcu convallis dolor, id congue erat lectus nec sem. Praesent pretium a nisi et
elementum. Cras lacinia sollicitudin suscipit. Phasellus accumsan felis odio. Pellentesque habitant morbi
tristique senectus et netus et malesuada fames ac turpis egestas.
);
}
}
================================================
FILE: examples/macOs/components/textArea.js
================================================
import React, { Component } from 'react';
import { TextArea } from 'react-desktop/macOs';
export default class extends Component {
handleChange = e => console.log(e.target.value);
render() {
return (
);
}
}
================================================
FILE: examples/macOs/components/textInput.js
================================================
import React, { Component } from 'react';
import { TextInput } from 'react-desktop/macOs';
export default class extends Component {
handleChange = e => console.log(e.target.value);
render() {
return (
);
}
}
================================================
FILE: examples/macOs/components/titleBar.js
================================================
import React, { Component } from 'react';
import { View, TitleBar } from 'react-desktop/macOs';
export default class extends Component {
constructor() {
super();
this.state = { isFullscreen: false };
}
render() {
return (
console.log('Close window')}
onMinimizeClick={() => console.log('Minimize window')}
onMaximizeClick={() => console.log('Mazimize window')}
onResizeClick={() => this.setState({ isFullscreen: !this.state.isFullscreen })}
/>
);
}
}
================================================
FILE: examples/macOs/components/toolbar.js
================================================
import React, { Component } from 'react';
import { TitleBar, Toolbar, Text } from 'react-desktop/macOs';
export default class extends Component {
render() {
return (
);
}
}
================================================
FILE: examples/macOs/components/toolbarNav.js
================================================
import React, { Component } from 'react';
import { TitleBar, Toolbar, ToolbarNav, ToolbarNavItem } from 'react-desktop/macOs';
const circle = (
);
const star = (
);
const polygon = (
);
export default class extends Component {
constructor() {
super();
this.state = { selected: 1 };
}
render() {
return (
this.setState({ selected: 1 })}
/>
this.setState({ selected: 2 })}
/>
this.setState({ selected: 3 })}
/>
);
}
}
================================================
FILE: examples/macOs/components/view.js
================================================
import React, { Component } from 'react';
import { View, Text } from 'react-desktop/macOs';
export default class extends Component {
render() {
return (
Hello World
);
}
}
================================================
FILE: examples/macOs/components/window.js
================================================
import React, { Component } from 'react';
import { Window, TitleBar, Text } from 'react-desktop/macOs';
export default class extends Component {
render() {
return (
Hello World
);
}
}
================================================
FILE: examples/windows/components/button.js
================================================
import React, { Component } from 'react';
import { Button } from 'react-desktop/windows';
export default class extends Component {
static defaultProps = {
color: '#cc7f29'
};
render() {
return (
console.log('Clicked!')}>
Press me!
);
}
}
================================================
FILE: examples/windows/components/checkbox.js
================================================
import React, { Component } from 'react';
import { Checkbox } from 'react-desktop/windows';
export default class extends Component {
static defaultProps = {
color: '#cc7f29',
theme: 'light'
};
render() {
return (
console.log(e.target.value)}
defaultValue="I got checked!"
defaultChecked
/>
);
}
}
================================================
FILE: examples/windows/components/label.js
================================================
import React, { Component } from 'react';
import { Label } from 'react-desktop/windows';
export default class extends Component {
render() {
return (
My Label
);
}
}
================================================
FILE: examples/windows/components/masterDetailsView.js
================================================
import React, { Component } from 'react';
import {
MasterDetailsView,
MasterDetailsViewItem,
MasterDetailsViewItemMaster,
MasterDetailsViewItemDetails,
Text
} from 'react-desktop/windows';
export default class extends Component {
static defaultProps = {
color: '#cc7f29',
theme: 'light'
};
render() {
return (
{this.renderItem('Item 1', 'Content 1')}
{this.renderItem('Item 2', 'Content 2')}
{this.renderItem('Item 3', 'Content 3')}
);
}
renderItem(master, details) {
return (
{master}
{details}
);
}
}
================================================
FILE: examples/windows/components/navPane.js
================================================
import React, { Component } from 'react';
import { NavPane, NavPaneItem, Text } from 'react-desktop/windows';
export default class extends Component {
static defaultProps = {
color: '#cc7f29',
theme: 'light'
};
constructor() {
super();
this.state = {
selected: 'Item 1'
}
}
render() {
return (
{this.renderItem('Item 1', 'Content 1')}
{this.renderItem('Item 2', 'Content 2')}
{this.renderItem('Item 3', 'Content 3')}
);
}
renderItem(title, content) {
return (
this.setState({ selected: title })}
padding="10px 20px"
push
>
{content}
);
}
renderIcon(name) {
const fill = this.props.theme === 'dark' ? '#ffffff' : '#000000';
switch(name) {
case 'Item 1':
return (
);
case 'Item 2':
return (
);
case 'Item 3':
return (
);
}
}
}
================================================
FILE: examples/windows/components/progressCircle.js
================================================
import React, { Component } from 'react';
import { ProgressCircle } from 'react-desktop/windows';
export default class extends Component {
static defaultProps = {
color: '#cc7f29'
};
render() {
return (
);
}
}
================================================
FILE: examples/windows/components/radio.js
================================================
import React, { Component } from 'react';
import { View, Radio } from 'react-desktop/windows';
export default class extends Component {
static defaultProps = {
color: '#cc7f29',
theme: 'light'
};
render() {
return (
console.log(e.target.value)}
defaultValue="I got checked!"
defaultChecked
/>
console.log(e.target.value)}
defaultValue="I got checked!"
/>
);
}
}
================================================
FILE: examples/windows/components/text.js
================================================
import React, { Component } from 'react';
import { Text } from 'react-desktop/windows';
export default class extends Component {
static defaultProps = {
color: '#cc7f29',
theme: 'light'
};
render() {
return (
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam justo urna, posuere vitae est et, accumsan
bibendum sapien. Suspendisse lobortis mollis finibus. Nunc tincidunt enim est, efficitur semper dolor luctus
eget. Donec faucibus dolor id leo tincidunt, condimentum mattis augue finibus. Etiam hendrerit ipsum nisi,
vel semper dolor malesuada a. Pellentesque a scelerisque sapien, quis interdum odio. Nulla posuere, velit sit
amet lacinia pharetra, sapien arcu convallis dolor, id congue erat lectus nec sem. Praesent pretium a nisi et
elementum. Cras lacinia sollicitudin suscipit. Phasellus accumsan felis odio. Pellentesque habitant morbi
tristique senectus et netus et malesuada fames ac turpis egestas.
);
}
}
================================================
FILE: examples/windows/components/textArea.js
================================================
import React, { Component } from 'react';
import { TextArea } from 'react-desktop/windows';
export default class extends Component {
static defaultProps = {
color: '#cc7f29',
theme: 'light'
};
handleChange = e => console.log(e.target.value);
render() {
return (
);
}
}
================================================
FILE: examples/windows/components/textInput.js
================================================
import React, { Component } from 'react';
import { TextInput } from 'react-desktop/windows';
export default class extends Component {
static defaultProps = {
color: '#cc7f29',
theme: 'light'
};
handleChange = e => console.log(e.target.value);
render() {
return (
);
}
}
================================================
FILE: examples/windows/components/titleBar.js
================================================
import React, { Component } from 'react';
import { TitleBar } from 'react-desktop/windows';
export default class extends Component {
static defaultProps = {
color: '#cc7f29',
theme: 'light'
};
constructor(props) {
super(props);
this.state = { isMaximized: true };
}
close = () => console.log('close');
minimize = () => console.log('minimize');
toggleMaximize = () => this.setState({ isMaximized: !this.state.isMaximized });
render() {
return (
);
}
}
================================================
FILE: examples/windows/components/view.js
================================================
import React, { Component } from 'react';
import { View, Text } from 'react-desktop/windows';
export default class extends Component {
static defaultProps = {
color: '#cc7f29',
theme: 'light'
};
render() {
return (
Hello World
);
}
}
================================================
FILE: examples/windows/components/window.js
================================================
import React, { Component } from 'react';
import { Window, TitleBar, Text } from 'react-desktop/windows';
export default class extends Component {
static defaultProps = {
color: '#cc7f29',
theme: 'light'
};
render() {
return (
Hello World
);
}
}
================================================
FILE: index.js
================================================
import { default as whichOs, MACOS } from './src/os';
import * as windows from './windows';
import * as macOs from './macOs';
const os = whichOs();
const select = (macOs, windows) => os === MACOS ? macOs : windows;
export { default as os } from './src/os';
export const Box = macOs.Box;
export const Button = select(macOs.Button, windows.Button);
export const Checkbox = select(macOs.Checkbox, windows.Checkbox);
export const Dialog = macOs.Dialog;
export const Label = select(macOs.Label, windows.Label);
export const Link = macOs.Link;
export const ListView = macOs.ListView;
export const ListViewFooter = macOs.ListViewFooter;
export const ListViewHeader = macOs.ListViewHeader;
export const ListViewRow = macOs.ListViewRow;
export const ListViewSection = macOs.ListViewSection;
export const ListViewSectionHeader = macOs.ListViewSectionHeader;
export const ListViewSeparator = macOs.ListViewSeparator;
export const MasterDetailsView = windows.MasterDetailsView;
export const MasterDetailsViewItem = windows.MasterDetailsViewItem;
export const MasterDetailsViewItemMaster = windows.MasterDetailsViewItemMaster;
export const MasterDetailsViewItemDetails = windows.MasterDetailsViewItemDetails;
export const NavPane = windows.NavPane;
export const NavPaneItem = windows.NavPaneItem;
export const Pin = macOs.Pin;
export const ProgressCircle = select(macOs.ProgressCircle, windows.ProgressCircle);
export const Radio = select(macOs.Radio, windows.Radio);
export const SearchField = macOs.SearchField;
export const SegmentedControl = macOs.SegmentedControl;
export const SegmentedControlItem = macOs.SegmentedControlItem;
export const Text = select(macOs.Text, windows.Text);
export const TextInput = select(macOs.TextInput, windows.TextInput);
export const TitleBar = select(macOs.TitleBar, windows.TitleBar);
export const Toolbar = macOs.Toolbar;
export const ToolbarNav = macOs.ToolbarNav;
export const ToolbarNavItem = macOs.ToolbarNavItem;
export const View = select(macOs.View, windows.View);
export const Window = select(macOs.Window, windows.Window);
================================================
FILE: macOs.js
================================================
export { default as Box } from './src/Box/macOs';
export { default as Button } from './src/Button/macOs';
export { default as Checkbox } from './src/Checkbox/macOs';
export { default as Dialog } from './src/Dialog/macOs';
export { default as Label } from './src/Label/macOs';
export { default as Link } from './src/Link/macOs';
export { default as ListView } from './src/ListView/macOs';
export { default as ListViewFooter } from './src/ListView/macOs/Footer';
export { default as ListViewHeader } from './src/ListView/macOs/Header';
export { default as ListViewRow } from './src/ListView/macOs/Row';
export { default as ListViewSection } from './src/ListView/macOs/Section';
export { default as ListViewSectionHeader } from './src/ListView/macOs/Header';
export { default as ListViewSeparator } from './src/ListView/macOs/Separator';
export { default as Pin } from './src/Pin/macOs';
export { default as ProgressCircle } from './src/ProgressCircle/macOs';
export { default as Radio } from './src/Radio/macOs';
export { default as SearchField } from './src/SearchField/macOs';
export { default as SegmentedControl } from './src/SegmentedControl/macOs';
export {
default as SegmentedControlItem
} from './src/SegmentedControl/macOs/Item';
export { default as Text } from './src/Text/macOs';
export { default as TextInput } from './src/TextInput/macOs';
export { default as TextArea } from './src/TextArea/macOs';
export { default as TitleBar } from './src/TitleBar/macOs';
export { default as Toolbar } from './src/Toolbar/macOs';
export { default as ToolbarNav } from './src/Toolbar/macOs/Nav';
export { default as ToolbarNavItem } from './src/Toolbar/macOs/Nav/Item';
export { default as View } from './src/View/macOs';
export { default as Window } from './src/Window/macOs';
================================================
FILE: package.json
================================================
{
"name": "react-desktop",
"author": "Gabriel Bull",
"version": "0.3.9",
"description": "React UI Components for macOS High Sierra and Windows 10",
"main": "./index.js",
"keywords": [
"react",
"react-component",
"electron",
"node-webkit",
"native",
"desktop",
"ui",
"user",
"interface",
"component",
"os x",
"macOS",
"mac",
"windows"
],
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/gabrielbull/react-desktop.git"
},
"scripts": {
"test": "./node_modules/.bin/mocha test",
"eslint": "./node_modules/.bin/eslint ./src ./test",
"prebuild": "rsync -av -delete . build --exclude build --exclude .git --exclude .idea && npm run eslint && npm run test",
"build": "./node_modules/.bin/babel ./build/src --out-dir ./build/src && ./node_modules/.bin/babel ./build/index.js --out-file ./build/index.js && ./node_modules/.bin/babel ./build/macOs.js --out-file ./build/osx.js && ./node_modules/.bin/babel ./build/macOs.js --out-file ./build/macOs.js && ./node_modules/.bin/babel ./build/windows.js --out-file ./build/windows.js",
"playground": "./node_modules/.bin/webpack-dev-server --config ./playground/webpack.config.js --colors --inline --port 3001",
"build-publish": "npm run build && npm publish ./build"
},
"dependencies": {
"radium": "=0.19.6"
},
"peerDependencies": {
"prop-types": "^15.0 || ^16.0",
"react": "^15.0 || ^16.0",
"react-dom": "^15.0 || ^16.0"
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-core": "^6.26.0",
"babel-eslint": "^8.2.2",
"babel-loader": "^7.1.4",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"chai": "^4.1.2",
"eslint": "^4.19.1",
"eslint-plugin-import": "^2.10.0",
"eslint-plugin-react": "^7.7.0",
"html-webpack-plugin": "^3.1.0",
"jsdom": "^11.7.0",
"mocha": "^5.0.5",
"prop-types": "^15.6.1",
"react": "^16.3.0",
"react-addons-test-utils": "^15.6.2",
"react-color": "^2.14.0",
"react-dom": "^16.3.0",
"react-hot-loader": "^4.0.1",
"webpack": "^4.4.1",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.1"
}
}
================================================
FILE: playground/assets/icons.js
================================================
import * as React from 'react';
export const home = (
);
export const form = (
);
export const progress = (
);
export const listView = (
);
================================================
FILE: playground/examplesLoader.js
================================================
var fs = require('fs');
var path = require('path');
function scanDir(dir) {
var files = fs.readdirSync(dir);
var filepath;
var subFiles;
var returnValue = [];
for (var i = 0, len = files.length; i < len; ++i) {
if (files[i].charAt(0) !== '.') {
filepath = path.resolve(path.join(dir, files[i]));
if (fs.lstatSync(filepath).isDirectory()) {
subFiles = scanDir(path.join(dir, files[i]));
returnValue.push.apply(returnValue, subFiles);
} else {
returnValue.push({
file: path.join(dir, files[i]),
filepath: filepath
});
}
}
}
return returnValue;
}
module.exports = function(source) {
var dirname = path.join(__dirname, '..');
var files = scanDir(path.join(dirname, 'examples'));
var file;
source = 'let data = {};\n';
for (var i = 0, len = files.length; i < len; ++i) {
file = files[i];
var filename = file.file.replace(dirname, '').replace(/\.js$/, '');
var key = filename.replace(/[\/\-]/g, '_');
source += 'import ' + key + ' from \'.' + filename + '\';\n';
source += 'data[\'' + filename + '\'] = ' + key + ';\n';
}
source += 'export default data;';
return source;
};
================================================
FILE: playground/index.js
================================================
import * as React from 'react';
import { render } from 'react-dom';
import Playground from './playground';
document.title = 'React Desktop Playground';
document.documentElement.style.width = '100%';
document.documentElement.style.height = '100%';
document.body.style.background = 'white';
document.body.style.backgroundImage = 'url(assets/background.jpg)';
document.body.style.backgroundSize = 'cover';
document.body.style.margin = '0';
document.body.style.padding = '0';
document.body.style.width = '100%';
document.body.style.height = '100%';
document.body.style.overflow = 'hidden';
document.body.innerHTML = `
`;
render( , document.getElementById('main'));
================================================
FILE: playground/playground.js
================================================
import * as React from 'react';
import * as PropTypes from 'prop-types';
import examples from 'examples-loader!examples';
import Sidebar from './ui/sidebar/sidebar';
const styles = {
container: {
width: '100%',
height: '100%',
display: 'flex'
},
sidebar: {
width: '200px'
},
example: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
width: '800px',
height: '100%',
margin: '0 auto'
}
};
class Playground extends React.Component {
static childContextTypes = {
playground: PropTypes.object
};
constructor() {
super();
this.state = {
color: '#cc7f29',
theme: 'light',
example: null
};
this.loadState(false);
}
loadState(mounted = true) {
try {
const state = JSON.parse(localStorage['playground']);
if (mounted) this.setState(state);
else this.state = { ...this.state, ...state };
} catch (err) {}
}
persistState() {
localStorage['playground'] = JSON.stringify(this.state);
}
getChildContext() {
return {
playground: this
};
}
componentDidUpdate() {
this.persistState();
}
showExample = (example) => {
this.setState({ example: example });
};
changeColor = (color) => {
this.setState({ color: color });
this.persistState();
};
changeTheme = (theme) => {
this.setState({ theme: theme });
this.persistState();
};
render() {
let example;
if (this.state.example) {
const Example = examples['/examples/' + this.state.example];
if (Example) {
example = ;
}
}
return (
);
}
}
export default Playground;
================================================
FILE: playground/ui/examples/examples.js
================================================
import * as React from 'react';
import * as PropTypes from 'prop-types';
const styles = {
list: {
margin: '0px',
padding: '0px',
listStyle: 'none'
},
title: {
display: 'block',
color: 'white',
fontFamily: 'sans-serif',
fontSize: '18px',
lineHeight: '1.4em',
fontWeight: 'normal',
margin: '20px 10px 10px',
padding: '0px 0px 10px',
borderBottom: '1px solid rgba(255, 255, 255, .2)'
},
subtitle: {
fontSize: '15px',
borderBottom: 'none',
padding: '0px',
margin: '20px 10px 10px',
},
item: {
display: 'block',
color: 'white',
fontFamily: 'sans-serif',
fontSize: '12px',
lineHeight: '1.2em',
fontWeight: 'normal',
margin: 0,
padding: '2px 10px',
cursor: 'pointer'
},
itemSelect: {
color: '#6FFFFD',
fontWeight: 'bold'
}
};
class Examples extends React.Component {
static contextTypes = {
playground: PropTypes.object
};
static propTypes = {
defaultExample: PropTypes.string,
list: PropTypes.object
};
constructor(props, ...args) {
super(props, ...args);
this.state = {
selected: props.defaultExample
}
};
click = (category, key) => {
key = (category + '/' + key).replace(/^\//, '');
this.context.playground.showExample(key);
this.setState({ selected: key });
};
render() {
return (
{this.renderItem(this.props.list)}
);
}
renderItem(item, path = '', subtitle = false) {
let finalChildren = [];
for (let prop in item) {
if (item.hasOwnProperty(prop)) {
if (typeof item[prop] === 'object') {
let children = this.renderItem(item[prop], path ? path + '/' + prop : prop, true);
if (children[0] && children[0].type === 'ul') {
finalChildren.push(
);
} else {
finalChildren.push(
);
}
} else {
const selected = path + '/' + prop === this.state.selected;
finalChildren.push(
this.click(path, prop)}
>
{prop}
);
}
}
}
return finalChildren;
}
}
export default Examples;
================================================
FILE: playground/ui/sidebar/logo.js
================================================
import * as React from 'react';
class Logo extends React.Component {
render() {
return (
);
}
}
export default Logo;
================================================
FILE: playground/ui/sidebar/sidebar.js
================================================
import * as React from 'react';
import ColorPicker from 'react-color';
import examples from 'examples-loader!examples';
import Examples from '../examples/examples';
import Logo from './logo';
const styles = {
sidebar: {
backgroundColor: 'rgba(0,0,0,.8)',
height: '100vh',
overflow: 'scroll',
userSelect: 'none',
WebkitUserSelect: 'none',
cursor: 'default'
}
};
class Sidebar extends React.Component {
constructor(...args) {
super(...args);
this.state = {
example: null,
color: this.props.color,
displayColorPicker: false,
theme: this.props.theme
};
}
handleClick = () => {
this.setState({ displayColorPicker: !this.state.displayColorPicker });
};
changeColor = (color) => {
this.setState({ color: color.hex });
this.props.onColorChange(color.hex);
};
changeTheme = () => {
this.state.theme = this.state.theme === 'light' ? 'dark' : 'light';
this.props.onThemeChange(this.state.theme);
};
render() {
const isChecked = this.state.theme === 'dark';
let colorPicker;
if (this.state.displayColorPicker) {
console.log(this.state.color);
colorPicker = (
)
}
return (
);
}
renderExamples() {
let list = {};
for (var prop in examples) {
if (examples.hasOwnProperty(prop)) {
let path = prop.replace(/^\/examples\//, '').split('/');
let currentList = list;
path.forEach((item, index) => {
if (index === path.length - 1) currentList[item] = examples[prop];
else if (typeof currentList[item] === 'undefined') currentList[item] = {};
currentList = currentList[item];
});
}
}
return ;
}
}
export default Sidebar;
================================================
FILE: playground/webpack.config.js
================================================
var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: path.join(__dirname, 'index.js'),
output: {
path: path.join(__dirname),
filename: 'bundle.js',
publicPath: '/'
},
devServer: {
filename: 'index.js',
contentBase: './playground'
},
devtool: 'source-map',
resolveLoader: {
alias: {
'examples-loader': path.join(__dirname, 'examplesLoader')
}
},
resolve: {
alias: {
'react-desktop': path.join(__dirname, '..'),
'examples': path.join(__dirname, '..', 'index.js'),
}
},
module: {
rules: [
{
test: /\.(js)$/,
exclude: /node_modules/,
use: 'babel-loader'
}
]
},
plugins: [
new HtmlWebpackPlugin()
]
};
================================================
FILE: src/Box/macOs/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styles from './styles/10.11';
import Dimension, { dimensionPropTypes } from '../../style/dimension';
import Margin, { marginPropTypes } from '../../style/margin';
import Padding, { paddingPropTypes } from '../../style/padding';
import Alignment, { alignmentPropTypes } from '../../style/alignment';
import Hidden, { hiddenPropTypes } from '../../style/hidden';
import { backgroundPropTypes } from '../../style/background/macOs';
import { convertColor, darkenColor } from '../../color';
import Text from '../../Text/macOs';
@Dimension()
@Margin()
@Padding()
@Alignment()
@Hidden()
class Box extends Component {
static propTypes = {
...backgroundPropTypes,
...dimensionPropTypes,
...marginPropTypes,
...paddingPropTypes,
...alignmentPropTypes,
...hiddenPropTypes,
label: PropTypes.string
};
static styleRefs = {
padding: 'box',
dimension: 'box'
};
render() {
let { children, style, background, label, ...props } = this.props;
const hasSegmentedControls = false;
let componentStyle = { ...styles.box, ...style };
if (hasSegmentedControls) {
componentStyle = { ...styles.segmentedControls };
}
if (background) {
background = convertColor(background);
componentStyle = {
...componentStyle,
backgroundColor: background,
borderTopColor: darkenColor(background, 0.3),
borderLeftColor: darkenColor(background, 0.24),
borderRightColor: darkenColor(background, 0.24),
borderBottomColor: darkenColor(background, 0.19)
};
}
if (label) {
return (
);
}
componentStyle = { ...styles.wrapper, ...componentStyle };
return (
{children}
);
}
}
export default Box;
================================================
FILE: src/Box/macOs/styles/10.11.js
================================================
export default {
wrapper: {
WebkitUserSelect: 'none',
userSelect: 'none',
cursor: 'default',
flex: '1'
},
box: {
backgroundColor: 'rgba(0, 0, 0, .04)',
borderWidth: '1px',
borderStyle: 'solid',
borderTopColor: 'rgba(0, 0, 0, .07)',
borderLeftColor: 'rgba(0, 0, 0, .037)',
borderRightColor: 'rgba(0, 0, 0, .037)',
borderBottomColor: 'rgba(0, 0, 0, .026)',
borderRadius: '4px',
position: 'relative',
padding: '23px 18px 22px 18px'
},
segmentedControls: {
marginTop: '10px',
paddingTop: '33px'
}
};
================================================
FILE: src/Button/macOs/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import WindowFocus from '../../windowFocus';
import Hidden, { hiddenPropTypes } from '../../style/hidden';
import FontSize, { fontSizePropTypes } from '../../style/fontSize';
import Padding, { paddingPropTypes, removeDuplicatePaddingProps } from '../../style/padding';
import Margin, { marginPropTypes } from '../../style/margin';
import styles from './styles/10.11';
import Radium from 'radium';
@WindowFocus()
@Padding()
@Margin()
@Hidden()
@FontSize()
@Radium
class Button extends Component {
static propTypes = {
...hiddenPropTypes,
...fontSizePropTypes,
...paddingPropTypes,
...marginPropTypes,
type: PropTypes.string,
color: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
onClick: PropTypes.func,
onEnter: PropTypes.func,
disabled: PropTypes.bool
};
componentDidMount() {
if (window && this.props.onEnter) {
window.addEventListener('keyup', this.handleKeyUp);
}
}
componentWillUnmount() {
if (window && this.props.onEnter) {
window.removeEventListener('keyup', this.handleKeyUp);
}
}
handleKeyUp = e => {
if (e.keyCode === 13) {
if (this.props.onEnter && !this.props.disabled) this.props.onEnter(e);
}
};
render() {
let { style, type, children, color, onClick, isWindowFocused, disabled, ...props } = this.props;
delete props.onEnter;
let componentStyle = { ...styles.button };
if (!disabled && color === 'blue' && isWindowFocused) {
componentStyle = { ...componentStyle, ...styles.blue };
} else if (disabled) {
componentStyle = { ...componentStyle, opacity: '.5' };
}
componentStyle = { ...componentStyle, ...style };
return (
{children}
);
}
}
export default Button;
================================================
FILE: src/Button/macOs/styles/10.11.js
================================================
export default {
button: {
WebkitUserSelect: 'none',
userSelect: 'none',
cursor: 'default',
backgroundColor: '#ffffff',
outline: 'none',
borderWidth: '1px',
borderStyle: 'solid',
borderRadius: '5px',
borderTopColor: '#c8c8c8',
borderBottomColor: '#acacac',
borderLeftColor: '#c2c2c2',
borderRightColor: '#c2c2c2',
boxShadow: '0 1px rgba(0, 0, 0, .039)',
paddingTop: 0,
paddingBottom: 0,
paddingLeft: '13px',
paddingRight: '13px',
lineHeight: '19px',
fontFamily: '-apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif',
fontSize: '13px',
':active': {
backgroundImage: '-webkit-linear-gradient(top, #4c98fe 0%, #0564e3 100%)',
borderTopColor: '#247fff',
borderBottomColor: '#003ddb',
borderLeftColor: '#125eed',
borderRightColor: '#125eed',
color: 'rgba(255, 255, 255, .9 )'
}
},
blue: {
backgroundImage: '-webkit-linear-gradient(top, #6cb3fa 0%, #087eff 100%)',
borderTopColor: '#4ca2f9',
borderBottomColor: '#015cff',
borderLeftColor: '#267ffc',
borderRightColor: '#267ffc',
color: 'rgba(255, 255, 255, .9)',
':active': {
backgroundImage: '-webkit-linear-gradient(top, #4c98fe 0%, #0564e3 100%)',
borderTopColor: '#247fff',
borderBottomColor: '#003ddb',
borderLeftColor: '#125eed',
borderRightColor: '#125eed',
color: 'rgba(255, 255, 255, .9 )'
}
}
};
================================================
FILE: src/Button/windows/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { colorPropTypes, colorContextTypes } from '../../style/color/windows';
import { ThemeContext, themePropTypes } from '../../style/theme/windows';
import Hidden, { hiddenPropTypes } from '../../style/hidden';
import Radium from 'radium';
import { darkenColor } from '../../color';
import styles from './styles/windows10';
@Hidden()
@ThemeContext()
@Radium
class Button extends Component {
static propTypes = {
...hiddenPropTypes,
...colorPropTypes,
...themePropTypes,
type: PropTypes.string,
push: PropTypes.bool,
onClick: PropTypes.func
};
static contextTypes = {
...colorContextTypes
};
render() {
let { style, type, children, color, push, onClick, ...props } = this.props;
let componentStyle = { ...styles.button, ...style };
if (color) {
color = color === true ? this.context.color : color;
styles.colorButton = {
...styles.colorButton,
borderColor: color,
backgroundColor: color,
':hover': {
...styles.colorButton[':hover'],
borderColor: darkenColor(color, .35)
},
':active': {
...styles.colorButton[':active'],
borderColor: darkenColor(color, .35),
backgroundColor: darkenColor(color, .35)
}
};
componentStyle = { ...componentStyle, ...styles.colorButton };
}
if (push) {
componentStyle[':active'] = { ...componentStyle[':active'], ...styles.pushTransform };
}
return (
{children}
);
}
}
export default Button;
================================================
FILE: src/Button/windows/styles/windows10.js
================================================
export default {
button: {
WebkitUserSelect: 'none',
userSelect: 'none',
cursor: 'default',
backgroundColor: '#cccccc',
outline: 'none',
borderWidth: '2px',
borderStyle: 'solid',
borderColor: '#cccccc',
paddingTop: 0,
paddingBottom: 0,
paddingLeft: '32px',
paddingRight: '32px',
lineHeight: '28px',
fontFamily: '"Segoe UI", Frutiger, "Frutiger Linotype", "Dejavu Sans", "Helvetica Neue", Arial, sans-serif',
fontSize: '15px',
color: '#000000',
':hover': {
color: '#000000',
borderColor: '#7a7a7a'
},
':active': {
color: '#000000',
borderColor: '#999999',
backgroundColor: '#999999'
}
},
colorButton: {
color: '#ffffff',
borderColor: '#0078d7',
backgroundColor: '#0078d7',
':hover': {
borderColor: '#004e8c'
},
':active': {
borderColor: '#004e8c',
backgroundColor: '#004e8c'
}
},
pushTransform: {
transform: 'scale(0.97)',
transition: 'transform .1s ease-in'
}
};
================================================
FILE: src/Checkbox/macOs/Checkmark.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Radium from 'radium';
import styles from './styles/10.11';
@Radium
class Checkmark extends Component {
static propTypes = {
show: PropTypes.bool,
color: PropTypes.string,
shadowColor: PropTypes.string
};
static defaultProps = {
color: '#FFFFFF'
};
render() {
const { color, shadowColor } = this.props;
let style = { ...styles.checkmark };
style.opacity = '0';
style.transform = 'scale(0)';
style.transition = 'all 0.5s';
if (this.props.show) {
style.opacity = '1';
style.transform = 'scale(1)';
}
return (
);
}
}
export default Checkmark;
================================================
FILE: src/Checkbox/macOs/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import WindowFocus from '../../windowFocus';
import Hidden, { hiddenPropTypes } from '../../style/hidden';
import Radium, { getState } from 'radium';
import styles from './styles/10.11';
import Checkmark from './Checkmark';
import Text from '../../Text/macOs';
import ValueRef from '../../ValueRef';
@ValueRef()
@WindowFocus()
@Hidden()
@Radium
class Checkbox extends Component {
static propTypes = {
...hiddenPropTypes,
label: PropTypes.string,
onChange: PropTypes.func
};
constructor(props) {
super();
this.state = {
checked: !!props.defaultChecked === true,
transition: true
};
}
componentWillReceiveProps(nextProps) {
if (nextProps.isWindowFocused !== this.props.isWindowFocused) {
this.setState({ transition: false });
}
}
componentDidUpdate() {
if (!this.state.transition) {
setTimeout(() => this.setState({ transition: true }), 0);
}
}
onChange = event => {
this.setState({ checked: event.target.checked });
if (this.props.onChange) {
this.props.onChange(event);
}
};
render() {
let { style, label, isWindowFocused, ...props } = this.props;
const { transition } = this.state;
let componentStyle = { ...styles.checkbox, ...style };
let labelStyle = styles.label;
let checkMarkColor = '#FFFFFF';
let shadowColor = '#0050a5';
if (this.state.checked) {
if (isWindowFocused) {
componentStyle = {
...componentStyle,
...styles['checkbox:checked']
};
if (!transition) componentStyle.transition = 'none';
} else {
componentStyle = {
...componentStyle,
...styles['checkbox:checked:unfocused']
};
checkMarkColor = '#404040';
shadowColor = '#FFFFFF';
}
}
if (getState(this.state, null, ':active')) {
if (this.state.checked) {
componentStyle = {
...componentStyle,
...styles['checkbox:checked:active']
};
shadowColor = '#001d99';
} else {
componentStyle = {
...componentStyle,
...styles['checkbox:active']
};
}
}
return (
);
}
}
export default Checkbox;
================================================
FILE: src/Checkbox/macOs/styles/10.11.js
================================================
export default {
container: {
display: 'flex'
},
label: {
display: 'flex',
height: '20px',
position: 'relative',
':hover': {},
':active': {}
},
inputWrapper: {
position: 'relative',
marginRight: '3px',
paddingTop: '1px'
},
checkbox: {
WebkitUserSelect: 'none',
userSelect: 'none',
WebkitAppearance: 'none',
appearance: 'none',
borderWidth: '1px',
borderStyle: 'solid',
borderColor: '#b8b8b8',
borderRadius: '3px',
backgroundColor: '#ffffff',
padding: '6px',
margin: '0 1px',
boxShadow: 'inset 0 1px 0 0 rgba(224, 224, 224, .4)',
transition: 'all 0.4s',
':focus': {
outline: 'none'
}
},
'checkbox:active': {
borderColor: '#a4a4a4',
backgroundColor: '#f0f0f0',
boxShadow: 'inset 0 0 0 1px rgba(117, 117, 117, .35)',
transition: 'all 0.4s'
},
'checkbox:checked': {
backgroundColor: '#3b99fc',
boxShadow: 'none',
borderColor: '#2c91fc',
transition: 'all 0.4s'
},
'checkbox:checked:unfocused': {
backgroundColor: '#ffffff',
boxShadow: 'none',
borderColor: '#b8b8b8',
transition: 'none'
},
'checkbox:checked:active': {
backgroundColor: '#0080f6',
borderColor: '#006adc',
boxShadow: 'inset 0 0 0 1px rgba(19, 68, 119, .22)',
transition: 'all 0.4s'
},
checkmark: {
position: 'absolute',
top: '4px',
left: '4px',
width: '8px',
height: '8px'
},
svg: {
zIndex: '2',
position: 'absolute',
top: '0px',
left: '0px',
height: '8px'
},
svgShadow: {
zIndex: '1',
position: 'absolute',
top: '1.5px',
left: '0px',
opacity: '.37',
height: '8px',
filter: 'blur(.5px)'
}
};
================================================
FILE: src/Checkbox/windows/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { ColorContext, colorPropTypes, colorContextTypes } from '../../style/color/windows';
import { ThemeContext, themePropTypes, themeContextTypes } from '../../style/theme/windows';
import Hidden, { hiddenPropTypes } from '../../style/hidden';
import Radium, { getState } from 'radium';
import styles from './styles/windows10';
import ValueRef from '../../ValueRef';
@ValueRef()
@Hidden()
@ColorContext()
@ThemeContext()
@Radium
class Checkbox extends Component {
static propTypes = {
...hiddenPropTypes,
...colorPropTypes,
...themePropTypes,
label: PropTypes.string,
onChange: PropTypes.func
};
static contextTypes = {
...colorContextTypes,
...themeContextTypes
};
constructor(props) {
super();
this.state = {
checked: !!props.defaultChecked === true
};
}
handleChange = event => {
this.setState({ checked: event.target.checked });
if (this.props.onChange) {
this.props.onChange(event);
}
};
render() {
let { style, label, color, ...props } = this.props;
let componentStyle = { ...styles.checkbox };
let checkedStyle = { display: 'none' };
let textStyle = { ...styles.text };
if (this.context.theme === 'dark') {
componentStyle = { ...componentStyle, ...styles.checkboxDark };
textStyle = { ...textStyle, ...styles.textDark };
}
if (this.state.checked) {
checkedStyle = styles.svg;
componentStyle = {
...componentStyle,
...(this.context.theme === 'dark' ? styles['checkboxDark:checked'] : styles['checkbox:checked'])
};
color = color ? color : this.context.color;
componentStyle = {
...componentStyle,
backgroundColor: color,
borderColor: color
};
}
if (getState(this.state, null, ':active')) {
componentStyle = {
...componentStyle,
...(this.context.theme === 'dark' ? styles['checkboxDark:active'] : styles['checkbox:active'])
};
} else if (getState(this.state, null, ':hover')) {
componentStyle = {
...componentStyle,
...(this.context.theme === 'dark' ? styles['checkboxDark:hover'] : styles['checkbox:hover'])
};
}
return (
);
}
}
export default Checkbox;
================================================
FILE: src/Checkbox/windows/styles/windows10.js
================================================
export default {
container: {
display: 'flex',
marginBottom: '22px'
},
label: {
display: 'flex',
alignItems: 'center',
position: 'relative',
':hover': {},
':active': {}
},
text: {
WebkitUserSelect: 'none',
userSelect: 'none',
fontFamily: '"Segoe UI", Frutiger, "Frutiger Linotype", "Dejavu Sans", "Helvetica Neue", Arial, sans-serif',
fontSize: '15px',
marginTop: '1px',
color: '#000000'
},
textDark: {
color: '#ffffff'
},
inputWrapper: {
position: 'relative',
marginRight: '3px',
paddingTop: '1px'
},
checkbox: {
WebkitUserSelect: 'none',
userSelect: 'none',
WebkitAppearance: 'none',
appearance: 'none',
outline: 'none',
borderWidth: '2px',
borderStyle: 'solid',
borderColor: 'rgba(0, 0, 0, .8)',
padding: '8px',
color: '#fff',
verticalAlign: 'bottom',
marginRight: '6px',
':focus': {
outline: 'none'
}
},
checkboxDark: {
borderColor: 'rgba(255, 255, 255, .82)',
},
'checkbox:active': {
borderColor: 'rgba(0, 0, 0, 0)',
backgroundColor: 'rgba(0, 0, 0, .57)'
},
'checkbox:hover': {
borderColor: 'rgba(0, 0, 0, 1)'
},
'checkbox:checked': {
backgroundColor: '#007CD1',
borderColor: '#007CD1'
},
'checkboxDark:active': {
borderColor: 'rgba(255, 255, 255, 0)',
backgroundColor: 'rgba(255, 255, 255, .63)'
},
'checkboxDark:hover': {
borderColor: 'rgba(255, 255, 255, 1)'
},
'checkboxDark:checked': {
backgroundColor: '#007CD1',
borderColor: '#007CD1'
},
svg: {
position: 'absolute',
top: '6px',
left: '5px',
color: '#fff',
height: '16px'
}
};
================================================
FILE: src/Dialog/macOs/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Margin, { marginPropTypes } from '../../style/margin';
import Alignment, {
alignmentPropTypes,
removeAlignmentProps
} from '../../style/alignment';
import Text from '../../Text/macOs';
import styles from './style/10.11';
@Margin({
marginTop: '17px',
marginBottom: '19px',
marginLeft: '20px',
marginRight: '20px'
})
class Dialog extends Component {
static propTypes = {
...marginPropTypes,
...alignmentPropTypes,
icon: PropTypes.element,
title: PropTypes.string,
message: PropTypes.string,
children: PropTypes.oneOfType([PropTypes.element, PropTypes.array]),
buttons: PropTypes.array
};
isLast(...next) {
let isLast = false;
for (let i = 0, len = next.length; i < len; ++i) {
if (next[i]) isLast = false;
}
return isLast;
}
render() {
let {
icon,
style,
title,
message,
children,
buttons,
...props
} = this.props;
props = removeAlignmentProps(props);
return (
{this.renderIcon(icon)}
{this.renderTitle(title, this.isLast(message, children, buttons))}
{this.renderMessage(message, this.isLast(children, buttons))}
{this.renderChildren(children, this.isLast(buttons))}
{this.renderButtons(buttons)}
);
}
renderIcon(icon) {
if (icon) {
return (
e.preventDefault()}>
{icon}
);
}
return null;
}
renderTitle(title, isLast) {
const style = styles.title;
if (isLast) delete style.marginBottom;
if (title)
return (
{title}
);
return null;
}
renderMessage(message, isLast) {
const style = styles.message;
if (isLast) delete style.marginBottom;
if (message) return {message} ;
return null;
}
renderChildren(children, isLast) {
const style = styles.content;
if (isLast) delete style.marginBottom;
if (children)
return Alignment({children}
, {
...this.props,
layout: 'vertical'
});
return null;
}
renderButtons(buttons) {
if (buttons) {
return (
{buttons.map((button, index) => (
{button}
))}
);
}
return null;
}
}
export default Dialog;
================================================
FILE: src/Dialog/macOs/style/10.11.js
================================================
export default {
container: {
MozUserSelect: 'none',
WebkitUserSelect: 'none',
MsUserSelect: 'none',
userSelect: 'none',
WebkitUserDrag: 'none',
userDrag: 'none',
WebkitTouchCallout: 'none',
display: 'flex',
position: 'relative'
},
icon: {
width: '67px',
marginRight: '20px',
display: 'flex',
justifyContent: 'center',
},
contentContainer: {
flex: 1
},
title: {
marginBottom: '5px'
},
message: {
marginBottom: '16px'
},
content: {
display: 'flex',
flexDirection: 'column',
marginBottom: '16px',
position: 'relative'
},
buttons: {
display: 'flex',
justifyContent: 'flex-end'
},
buttonContainer: {
marginLeft: '14px'
}
};
================================================
FILE: src/Label/macOs/index.js
================================================
import Label from '../../Text/macOs';
export default Label;
================================================
FILE: src/Label/windows/index.js
================================================
import Label from '../../Text/windows';
export default Label;
================================================
FILE: src/Link/macOs/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Margin, { marginPropTypes } from '../../style/margin';
import Padding, { paddingPropTypes } from '../../style/padding';
import FontSize, { fontSizePropTypes } from '../../style/fontSize';
import Dimension, { dimensionPropTypes } from '../../style/dimension';
import TextAlign, { textAlignPropTypes } from '../../style/textAlign';
import Hidden, { hiddenPropTypes } from '../../style/hidden';
const componentStyle = {
display: 'inline-block',
WebkitUserSelect: 'none',
userSelect: 'none',
cursor: 'default',
fontFamily: '-apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif',
fontSize: '11px',
textDecoration: 'none'
};
@Margin()
@Padding()
@FontSize()
@Dimension()
@TextAlign()
@Hidden()
class Link extends Component {
static propTypes = {
...marginPropTypes,
...paddingPropTypes,
...fontSizePropTypes,
...dimensionPropTypes,
...textAlignPropTypes,
...hiddenPropTypes,
color: PropTypes.string
};
static defaultProps = {
color: '#009df0'
};
render() {
const { color, children, style, ...props } = this.props;
return (
{children}
);
}
}
export default Link;
================================================
FILE: src/ListView/macOs/Footer/index.js
================================================
import React, { Component } from 'react';
import Background, { backgroundPropTypes } from '../../../style/background/macOs';
import Dimension, { dimensionPropTypes } from '../../../style/dimension';
import Padding, { paddingPropTypes } from '../../../style/padding';
import styles from './style/10.11';
@Background({ background: '#f0f0f0' })
@Dimension()
@Padding({ paddingLeft: '10px', paddingRight: '10px', paddingTop: '2px', paddingBottom: '2px' })
class Footer extends Component {
static propTypes = {
...backgroundPropTypes,
...dimensionPropTypes,
...paddingPropTypes
};
render() {
const { children, style, ...props } = this.props;
return (
);
}
}
export default Footer;
================================================
FILE: src/ListView/macOs/Footer/style/10.11.js
================================================
export default {
header: {
top: '0px',
left: '0px',
width: '100%',
borderTopWidth: '1px',
borderTopStyle: 'solid',
borderTopColor: '#c9c9c9',
boxSizing: 'border-box'
}
};
================================================
FILE: src/ListView/macOs/Header/index.js
================================================
import React, { Component } from 'react';
import Background, { backgroundPropTypes } from '../../../style/background/macOs';
import Dimension, { dimensionPropTypes } from '../../../style/dimension';
import Padding, { paddingPropTypes } from '../../../style/padding';
import styles from './style/10.11';
@Background({ background: '#f0f0f0' })
@Dimension()
@Padding({ paddingLeft: '10px', paddingRight: '10px', paddingTop: '2px', paddingBottom: '2px' })
class Header extends Component {
static propTypes = {
...backgroundPropTypes,
...dimensionPropTypes,
...paddingPropTypes
};
render() {
const { children, style, ...props } = this.props;
return (
);
}
}
export default Header;
================================================
FILE: src/ListView/macOs/Header/style/10.11.js
================================================
export default {
header: {
top: '0px',
left: '0px',
width: '100%',
borderBottomWidth: '1px',
borderBottomStyle: 'solid',
borderBottomColor: '#c9c9c9',
boxSizing: 'border-box'
}
};
================================================
FILE: src/ListView/macOs/Row/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Background, { backgroundPropTypes } from '../../../style/background/macOs';
import Alignment, { alignmentPropTypes } from '../../../style/alignment';
import Dimension, { dimensionPropTypes } from '../../../style/dimension';
import Hidden, { hiddenPropTypes } from '../../../style/hidden';
import Margin, { marginPropTypes } from '../../../style/margin';
import Padding, { paddingPropTypes } from '../../../style/padding';
import styles from './style/10.11';
@Background()
@Alignment()
@Dimension()
@Hidden()
@Margin({ marginTop: '4px', marginBottom: '4px' })
@Padding({ paddingLeft: '18px', paddingRight: '18px', paddingTop: '5px', paddingBottom: '5px' })
class Row extends Component {
static propTypes = {
...backgroundPropTypes,
...alignmentPropTypes,
...dimensionPropTypes,
...hiddenPropTypes,
...marginPropTypes,
...paddingPropTypes,
layout: PropTypes.string
};
static defaultProps = {
layout: 'horizontal'
};
render() {
const { horizontalAlignment, children, style, layout, ...props } = this.props;
let componentStyle = { ...styles.row };
if (layout === 'vertical') {
componentStyle.flexDirection = 'column';
if (horizontalAlignment) {
switch(horizontalAlignment) {
case 'center': componentStyle.alignItems = 'center'; break;
case 'left': componentStyle.alignItems = 'flex-start'; break;
case 'right': componentStyle.alignItems = 'flex-end'; break;
}
}
} else {
if (horizontalAlignment) {
switch(horizontalAlignment) {
case 'center': componentStyle.justifyContent = 'center'; break;
case 'left': componentStyle.justifyContent = 'flex-start'; break;
case 'right': componentStyle.justifyContent = 'flex-end'; break;
}
}
}
return (
{children}
);
}
}
export default Row;
================================================
FILE: src/ListView/macOs/Row/style/10.11.js
================================================
export default {
row: {
WebkitUserSelect: 'none',
userSelect: 'none',
cursor: 'default',
display: 'flex',
position: 'relative'
}
};
================================================
FILE: src/ListView/macOs/Section/Header/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styles from './style/10.11';
import Text from '../../../../Text/macOs';
import Margin, {
marginPropTypes,
removeMarginProps
} from '../../../../style/margin';
import Padding, {
paddingPropTypes,
removePaddingProps
} from '../../../../style/padding';
import { fontSizePropTypes } from '../../../../style/fontSize';
import mapStyles from '../../../../utils/mapStyles';
class Header extends Component {
static propTypes = {
...marginPropTypes,
...paddingPropTypes,
...fontSizePropTypes,
color: PropTypes.string,
bold: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.number,
PropTypes.string
])
};
static defaultProps = {
color: '#5a5b5c',
bold: true,
size: '10'
};
static mapStyles = {
text: ['color', 'fontSize', 'fontWeight', 'lineHeight', 'fontFamily']
};
render() {
let { color, bold, size, children, style, ...props } = this.props;
props = removePaddingProps(removeMarginProps(props));
let [headerStyle, textStyle] = mapStyles(style, Header.mapStyles);
return (
{Padding(
Margin(
{children}
,
this.props
),
this.props
)}
);
}
}
export default Header;
================================================
FILE: src/ListView/macOs/Section/Header/style/10.11.js
================================================
export default {
title: {
margin: '9px 0px',
padding: '0px 10px',
fontWeight: 'normal'
}
};
================================================
FILE: src/ListView/macOs/Section/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Header from './Header';
import styles from './style/10.11';
class Section extends Component {
static propTypes = {
header: PropTypes.oneOfType([
PropTypes.string,
PropTypes.element,
PropTypes.array
])
};
render() {
let { children, header, ...props } = this.props;
if (typeof header === 'string') {
header = ;
}
return (
);
}
}
export default Section;
================================================
FILE: src/ListView/macOs/Section/style/10.11.js
================================================
export default {
list: {
listStyle: 'none',
padding: '0px',
margin: '0px'
}
};
================================================
FILE: src/ListView/macOs/Separator/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Dimension, { dimensionPropTypes } from '../../../style/dimension';
import Hidden, { hiddenPropTypes } from '../../../style/hidden';
import Margin, { marginPropTypes } from '../../../style/margin';
import Padding, { paddingPropTypes } from '../../../style/padding';
import styles from './style/10.11';
@Dimension()
@Hidden()
@Margin({ marginLeft: '10px', marginRight: '10px', marginTop: '4px', marginBottom: '4px' })
@Padding()
class Separator extends Component {
static propTypes = {
...dimensionPropTypes,
...hiddenPropTypes,
...marginPropTypes,
...paddingPropTypes,
color: PropTypes.string,
};
static defaultProps = {
color: '#e5e5e5'
};
render() {
const { style, ...props } = this.props;
return (
);
}
}
export default Separator;
================================================
FILE: src/ListView/macOs/Separator/style/10.11.js
================================================
export default {
separator: {
height: '1px',
margin: '0px',
padding: '0px',
border: 'none'
}
};
================================================
FILE: src/ListView/macOs/index.js
================================================
import React, { Component, Children } from 'react';
import styles from './style/10.11';
import Background, { backgroundPropTypes } from '../../style/background/macOs';
import Dimension, { dimensionPropTypes } from '../../style/dimension';
import Hidden, { hiddenPropTypes } from '../../style/hidden';
import Margin, { marginPropTypes } from '../../style/margin';
import Padding, { paddingPropTypes } from '../../style/padding';
import Header from './Header';
import Footer from './Footer';
import Row from './Row';
@Background()
@Dimension()
@Hidden()
@Margin()
@Padding()
class ListView extends Component {
static propTypes = {
...backgroundPropTypes,
...dimensionPropTypes,
...hiddenPropTypes,
...marginPropTypes,
...paddingPropTypes
};
mapChildren(children) {
let hasDirectRows = false;
let header = null,
items = null,
footer = null;
Children.map(children, child => {
const HeaderEl = ;
const FooterEl = ;
const RowEl =
;
if (child.type === HeaderEl.type) return (header = child);
else if (child.type === FooterEl.type) return (footer = child);
else if (child.type === RowEl.type) hasDirectRows = true;
if (!items) items = [];
items.push(child);
});
if (hasDirectRows) {
items = ;
}
return { header, items, footer };
}
render() {
const { children, style, ...props } = this.props;
const { header, items, footer } = this.mapChildren(children);
return (
{header}
{items}
{footer}
);
}
}
export default ListView;
================================================
FILE: src/ListView/macOs/style/10.11.js
================================================
export default {
container: {
position: 'relative',
display: 'flex',
flex: 1,
height: '100%',
flexDirection: 'column'
},
scrollable: {
overflow: 'scroll',
width: '100%',
display: 'flex',
flex: 1,
flexDirection: 'column'
},
list: {
listStyle: 'none',
padding: '0px',
margin: '0px',
}
};
================================================
FILE: src/MasterDetailsView/windows/Details/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { convertColor } from '../../../color';
import { ColorContext, colorPropTypes, colorContextTypes } from '../../../style/color/windows';
import { ThemeContext, themePropTypes } from '../../../style/theme/windows';
const styles = {
details: {
display: 'flex',
flexWrap: 'nowrap',
position: 'relative',
flex: '1'
}
};
@ColorContext()
@ThemeContext()
class Details extends Component {
static propTypes = {
...colorPropTypes,
...themePropTypes,
background: PropTypes.oneOfType([PropTypes.string, PropTypes.bool])
};
static childContextTypes = {
background: PropTypes.string
};
static contextTypes = {
...colorContextTypes
};
getChildContext() {
return {
background: typeof this.props.background === 'string' ? this.props.background : this.context.color
};
}
render() {
const { children, style, background, ...props } = this.props;
delete props.index;
let componentStyle = { ...styles.details, ...style };
if (background === true) {
componentStyle.backgroundColor = convertColor(this.context.color);
} else if (typeof background === 'string') {
componentStyle.backgroundColor = convertColor(background);
}
return (
{children}
);
}
}
export default Details;
================================================
FILE: src/MasterDetailsView/windows/Item/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Master from '../Master';
import Details from '../Details';
import { ColorContext, colorPropTypes } from '../../../style/color/windows';
import { ThemeContext, themePropTypes } from '../../../style/theme/windows';
const styles = {
display: 'flex',
flexWrap: 'nowrap',
position: 'relative',
flex: '1'
};
let warnOnceMaster = false;
let warnOnceDetails = false;
function applyChildenClasses() {
return function(ComposedComponent) {
const nextMaster = Master;
ComposedComponent.prototype.Master = ComposedComponent.Master = function(
...args
) {
if (!warnOnceMaster) {
warnOnceMaster = true;
console.warn(
'React Desktop: Using MasterDetailsView.Item.Master is deprecated, import MasterDetailsViewItemMaster instead.'
);
}
return new nextMaster(...args);
};
const nextDetails = Details;
ComposedComponent.prototype.Details = ComposedComponent.Details = function(
...args
) {
if (!warnOnceDetails) {
warnOnceDetails = true;
console.warn(
'React Desktop: Using MasterDetailsView.Item.Details is deprecated, import MasterDetailsViewItemDetails instead.'
);
}
return new nextDetails(...args);
};
return ComposedComponent;
};
}
@applyChildenClasses()
@ColorContext()
@ThemeContext()
class Item extends Component {
static propTypes = {
...colorPropTypes,
...themePropTypes,
selected: PropTypes.bool
};
constructor(props, context, updater) {
super(props, context, updater);
this.state = {
selected: props.selected ? props.selected : false
};
}
render() {
const { children, style, ...props } = this.props;
return (
{children}
);
}
}
export default Item;
================================================
FILE: src/MasterDetailsView/windows/Master/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { parseDimension } from '../../../styleHelper';
import { convertColor, hexToRgb } from '../../../color';
import { ColorContext, colorPropTypes, colorContextTypes } from '../../../style/color/windows';
import { ThemeContext, themePropTypes, themeContextTypes } from '../../../style/theme/windows';
import Radium from 'radium';
const styles = {
master: {
display: 'flex',
flexWrap: 'nowrap',
position: 'relative',
width: '320px',
boxSizing: 'border-box',
WebkitUserSelect: 'none',
userSelect: 'none',
':hover': {
backgroundColor: 'rgba(0, 0, 0, .1)'
},
':active': {
backgroundColor: 'rgba(0, 0, 0, .2)'
}
},
masterDark: {
':hover': {
backgroundColor: 'rgba(255, 255, 255, .1)'
},
':active': {
backgroundColor: 'rgba(255, 255, 255, .2)'
}
},
masterSpan: {
padding: '0 12px',
lineHeight: '50px',
fontFamily: '"Segoe UI", Frutiger, "Frutiger Linotype", "Dejavu Sans", "Helvetica Neue", Arial, sans-serif',
fontSize: '18px',
color: '#000000',
width: '320px',
boxSizing: 'border-box',
transition: 'transform .1s ease-in',
':hover': {
transition: 'transform .1s ease-in'
}
},
masterSpanDark: {
color: 'white'
},
masterSpanWithPush: {
':active': {
transform: 'scale(0.97)',
transition: 'transform 0s ease-in'
}
}
};
@ColorContext()
@ThemeContext()
@Radium
class Master extends Component {
static propTypes = {
...colorPropTypes,
...themePropTypes,
selected: PropTypes.bool,
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
push: PropTypes.bool
};
static contextTypes = {
...colorContextTypes,
...themeContextTypes,
id: PropTypes.string,
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
push: PropTypes.bool,
masterDetails: PropTypes.object
};
select = () => {
this.context.masterDetails.select(this.props.index);
};
render() {
const { children, style, selected, push, ...props } = this.props;
delete props.index;
let componentStyle = { ...styles.master, ...style };
let spanStyle = { ...styles.masterSpan };
if (this.context.theme === 'dark') {
componentStyle = { ...componentStyle, ...styles.masterDark };
spanStyle = { ...spanStyle, ...styles.masterSpanDark };
}
if (this.props.width) {
componentStyle.width = parseDimension(this.props.width);
spanStyle.width = parseDimension(this.props.width);
}
if (push) {
spanStyle[':active'] = {
...spanStyle[':active'],
...styles.masterSpanWithPush[':active']
}
}
if (selected) {
const c = hexToRgb(convertColor(this.context.color));
componentStyle = {
...componentStyle,
backgroundColor: `rgba(${c.r}, ${c.g}, ${c.b}, .4)`,
':hover': {
...componentStyle[':hover'],
backgroundColor: `rgba(${c.r}, ${c.g}, ${c.b}, .6)`
},
':active': {
...componentStyle[':active'],
backgroundColor: `rgba(${c.r}, ${c.g}, ${c.b}, .7)`
}
};
}
return (
{children}
);
}
}
export default Master;
================================================
FILE: src/MasterDetailsView/windows/Pane.js
================================================
import React, { Component } from 'react';
import { parseDimension } from '../../styleHelper';
import { ThemeContext, themeContextTypes } from '../../style/theme/windows';
const styles = {
pane: {
display: 'flex',
flexDirection: 'column',
flexWrap: 'nowrap',
position: 'relative',
flex: '0 0 320px',
width: '320px'
},
paneDark: {
}
};
@ThemeContext()
class Pane extends Component {
static contextTypes = {
...themeContextTypes
};
render() {
const { children, style, ...props } = this.props;
let componentStyle = { ...styles.pane, ...style };
if (this.props.width) {
componentStyle.width = parseDimension(this.props.width);
componentStyle.flex = '0 0 ' + parseDimension(this.props.width);
}
if (this.context.theme === 'dark') {
componentStyle = { ...componentStyle, ...styles.paneDark };
}
return (
{children}
);
}
}
export default Pane;
================================================
FILE: src/MasterDetailsView/windows/index.js
================================================
import React, { Component, Children, cloneElement } from 'react';
import PropTypes from 'prop-types';
import Master from './Master';
import Details from './Details';
import Pane from './Pane';
import Item from './Item';
import { ColorContext, colorPropTypes } from '../../style/color/windows';
import {
ThemeContext,
themePropTypes,
themeContextTypes
} from '../../style/theme/windows';
const styles = {
container: {
display: 'flex',
flexWrap: 'nowrap',
position: 'relative',
flex: '1',
background: 'white',
WebkitUserSelect: 'none',
userSelect: 'none',
cursor: 'default'
},
containerDark: {
background: '#171717'
}
};
let warnOnce = false;
function applyChildenClasses() {
return function(ComposedComponent) {
const nextItem = Item;
const item = function(...args) {
if (!warnOnce) {
warnOnce = true;
console.warn(
'React Desktop: Using MasterDetailsView.Item is deprecated, import MasterDetailsViewItem instead.'
);
}
return new nextItem(...args);
};
item.prototype.Master = item.Master = Master;
item.prototype.Details = item.Details = Details;
ComposedComponent.prototype.Item = ComposedComponent.Item = item;
return ComposedComponent;
};
}
@applyChildenClasses()
@ColorContext()
@ThemeContext()
class MasterDetailsView extends Component {
static propTypes = {
...colorPropTypes,
...themePropTypes
};
static childContextTypes = {
masterDetails: PropTypes.object
};
static contextTypes = {
...themeContextTypes
};
masters = [];
details = [];
maxWidth;
constructor(props, context, updater) {
super(props, context, updater);
this.state = {
selected: 0
};
this.filterChildren(props.children);
}
getChildContext() {
return {
masterDetails: this
};
}
select(index) {
this.setState({ selected: index });
}
filterChildren(children) {
this.maxWidth = null;
Children.map(children, (item, key) => {
Children.map(item.props.children, child => {
const MasterEl = ;
const DetailsEl = ;
if (child.type === MasterEl.type) {
if (
child.props.width !== undefined &&
child.props.width > this.maxWidth
) {
this.maxWidth = child.props.width;
}
this.masters = [
...this.masters,
cloneElement(child, { key: key, index: key })
];
} else if (child.type === DetailsEl.type) {
this.details = [
...this.details,
cloneElement(child, { key: key, index: key })
];
}
});
});
}
render() {
const { style, ...props } = this.props;
let componentStyle = { ...styles.container, ...style };
if (this.context.theme === 'dark') {
componentStyle = { ...componentStyle, ...styles.containerDark, ...style };
}
return (
{this.renderMasters()}
{this.renderDetail()}
);
}
renderMasters() {
let children = [];
this.masters.forEach((item, index) => {
children.push(
index === this.state.selected
? cloneElement(item, { selected: true })
: item
);
});
return children;
}
renderDetail() {
let children = null;
this.details.forEach((item, index) => {
if (index === this.state.selected) children = item;
});
return children;
}
}
export default MasterDetailsView;
================================================
FILE: src/NavPane/windows/Item/Content/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Padding, { paddingPropTypes } from '../../../../style/padding';
import Margin, { marginPropTypes } from '../../../../style/margin';
import Background, { backgroundPropTypes } from '../../../../style/background/windows';
import Alignment, { alignmentPropTypes } from '../../../../style/alignment';
import styles from '../../style/windows10';
@Padding()
@Margin()
@Background()
@Alignment()
class Content extends Component {
static propTypes = {
...paddingPropTypes,
...marginPropTypes,
...backgroundPropTypes,
...alignmentPropTypes,
content: PropTypes.oneOfType([PropTypes.string, PropTypes.element, PropTypes.array])
};
render() {
const { content, style, ...props } = this.props;
return (
{content}
);
}
}
export default Content;
================================================
FILE: src/NavPane/windows/Item/Title/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Radium, { keyframes } from 'radium';
import styles from '../../style/windows10';
var appear = keyframes({
'0%': {
opacity: 0
},
'29%': {
opacity: 0,
transform: 'translateY(9px)'
},
'30%': {
opacity: .35,
transform: 'translateY(9px)'
},
'100%': {
opacity: 1,
transform: 'translateY(0)'
}
}, 'Title');
var fadeOut = keyframes({
'0%': {
opacity: 1
},
'100%': {
opacity: 0
}
}, 'span');
styles.titleAnimation = {
animation: 'x 300ms forwards',
animationName: appear
};
styles.fadeSpanStyle = {
position: 'absolute',
top: '0px',
left: '0px',
animation: 'x 100ms forwards',
animationName: fadeOut
};
@Radium
class Title extends Component {
static propTypes = {
theme: PropTypes.string,
title: PropTypes.oneOfType([PropTypes.string, PropTypes.element, PropTypes.array])
};
render() {
const { title, prevTitle } = this.props;
let componentStyle = { ...styles.title };
let fadeSpanStyle = { ...styles.title };
let titleStyle = {};
if (this.props.theme === 'dark') {
componentStyle = { ...componentStyle, ...styles.titleDark };
fadeSpanStyle = { ...fadeSpanStyle, ...styles.titleDark };
}
if (prevTitle && prevTitle !== title) {
fadeSpanStyle = { ...fadeSpanStyle, ...styles.fadeSpanStyle };
titleStyle = { ...titleStyle, opacity: 0, ...styles.titleAnimation }
}
let fadeSpan;
if (prevTitle) {
fadeSpan = (
{prevTitle}
);
}
return (
{fadeSpan}
{title}
);
}
}
export default Title;
================================================
FILE: src/NavPane/windows/Item/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Padding, { paddingPropTypes } from '../../../style/padding';
import Margin, { marginPropTypes } from '../../../style/margin';
import Background, {
backgroundPropTypes
} from '../../../style/background/windows';
import Alignment, { alignmentPropTypes } from '../../../style/alignment';
import Title from './Title';
import Content from './Content';
import styles from '../style/windows10';
import { StyleRoot } from 'radium';
import { ColorContext, colorPropTypes } from '../../../style/color/windows';
import { ThemeContext, themePropTypes } from '../../../style/theme/windows';
@Padding()
@Margin()
@Background()
@Alignment()
@ColorContext()
@ThemeContext()
class Item extends Component {
static propTypes = {
...colorPropTypes,
...themePropTypes,
...paddingPropTypes,
...marginPropTypes,
...backgroundPropTypes,
...alignmentPropTypes,
title: PropTypes.oneOfType([
PropTypes.string,
PropTypes.element,
PropTypes.array
]),
icon: PropTypes.oneOfType([
PropTypes.string,
PropTypes.element,
PropTypes.array
]),
push: PropTypes.bool,
onSelect: PropTypes.func,
selected: PropTypes.bool,
paneTheme: PropTypes.string
};
constructor() {
super();
this.state = {
prevTitle: null
};
}
componentWillReceiveProps(nextProps) {
if (this.props.title !== nextProps.title) {
this.setState({ prevTitle: this.props.title });
}
}
render() {
const { children, title, paneTheme, ...props } = this.props;
delete props.icon;
delete props.push;
delete props.onSelect;
delete props.selected;
return (
);
}
}
export default Item;
================================================
FILE: src/NavPane/windows/Pane/Button/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Radium, { getState } from 'radium';
import { transparentize } from '../../../../color';
import { ColorContext, colorContextTypes } from '../../../../style/color/windows';
import { ThemeContext, themeContextTypes } from '../../../../style/theme/windows';
const styles = {
svg: {
':hover': {},
':active': {}
}
};
@ColorContext()
@ThemeContext()
@Radium
class Button extends Component {
static propTypes = {
onClick: PropTypes.func
};
static contextTypes = {
...colorContextTypes,
...themeContextTypes
};
render() {
let fill = this.context.theme === 'dark' ? '#ffffff' : '#000000';
if (getState(this.state, null, ':active')) {
fill = transparentize(this.context.color, .1);
} else if (getState(this.state, null, ':hover')) {
fill = transparentize(this.context.color, .2);
}
return (
);
}
}
export default Button;
================================================
FILE: src/NavPane/windows/Pane/Item/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styles from '../style/windows10';
import { transparentize } from '../../../../color';
import { ColorContext, colorContextTypes } from '../../../../style/color/windows';
import { ThemeContext, themeContextTypes } from '../../../../style/theme/windows';
import Radium from 'radium';
@ColorContext()
@ThemeContext()
@Radium
class Item extends Component {
static propTypes = {
isPaneExpanded: PropTypes.bool.isRequired,
title: PropTypes.oneOfType([PropTypes.string, PropTypes.element, PropTypes.array]),
icon: PropTypes.oneOfType([PropTypes.string, PropTypes.element, PropTypes.array]),
push: PropTypes.bool,
onSelect: PropTypes.func,
selected: PropTypes.bool
};
static contextTypes = {
...colorContextTypes,
...themeContextTypes
};
render() {
const { title, icon, selected, onSelect, push, isPaneExpanded } = this.props;
let componentStyle = styles.anchor;
let spanStyle = styles.span;
if (this.context.theme === 'dark') {
componentStyle = { ...componentStyle, ...styles.anchorDark };
spanStyle = { ...spanStyle, ...styles.spanDark };
}
if (selected) {
componentStyle = {
...componentStyle,
backgroundColor: transparentize(this.context.color, .4),
':hover': {
...componentStyle[':hover'],
backgroundColor: transparentize(this.context.color, .2)
},
':active': {
...componentStyle[':active'],
backgroundColor: transparentize(this.context.color, .1)
}
};
}
if (push) {
spanStyle[':hover'] = {
...spanStyle[':hover'],
...styles.pushTransformHover
};
spanStyle[':active'] = {
...spanStyle[':active'],
...styles.pushTransformActive
};
}
return (
{icon ? {icon} : null}
{isPaneExpanded ? {title} : null}
);
}
}
export default Item;
================================================
FILE: src/NavPane/windows/Pane/index.js
================================================
import React, { Component, Children } from 'react';
import PropTypes from 'prop-types';
import Item from './Item';
import Button from './Button';
import styles from './style/windows10';
class Pane extends Component {
static Item = Item;
static propTypes = {
items: PropTypes.oneOfType([
PropTypes.string,
PropTypes.element,
PropTypes.array
]),
canPaneToggle: PropTypes.bool,
onPaneToggle: PropTypes.func,
defaultIsPaneExpanded: PropTypes.bool,
paneCompactedLength: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
]),
paneExpandedLength: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
])
};
static defaultProps = {
canPaneToggle: true,
defaultIsPaneExpanded: true,
paneCompactedLength: '48px',
paneExpandedLength: '200px'
};
constructor(props, ...args) {
super(props, ...args);
this.state = {
isPaneExpanded: props.defaultIsPaneExpanded
};
}
toggleOpen = () => {
if (this.props.onPaneToggle)
this.props.onPaneToggle(!this.state.isPaneExpanded);
this.setState({ isPaneExpanded: !this.state.isPaneExpanded });
};
render() {
const {
canPaneToggle,
paneCompactedLength,
paneExpandedLength
} = this.props;
const button = !canPaneToggle ? null : (
);
let componentStyle = { ...styles.pane };
if (canPaneToggle) {
if (this.state.isPaneExpanded) componentStyle.width = paneExpandedLength;
else componentStyle.width = paneCompactedLength;
} else {
componentStyle.width = paneExpandedLength;
}
return (
{button}
{this.renderItems()}
);
}
renderItems() {
return Children.map(this.props.items, (item, index) => (
));
}
}
export default Pane;
================================================
FILE: src/NavPane/windows/Pane/style/windows10.js
================================================
export default {
pane: {
cursor: 'default',
WebkitUserSelect: 'none',
userSelect: 'none',
display: 'flex',
position: 'relative',
flexGrow: '0',
flexShrink: '0',
flexDirection: 'column',
overflow: 'hidden'
},
padding: {
height: '48px'
},
buttonStyle: {
position: 'absolute',
padding: '8px 10px',
top: '7px',
left: '4px',
width: '20px',
height: '20px',
boxSizing: 'content-box'
},
anchor: {
display: 'flex',
alignItems: 'center',
height: '44px',
':hover': {
backgroundColor: 'rgba(0, 0, 0, .1)',
},
':active': {
backgroundColor: 'rgba(0, 0, 0, .2)',
}
},
anchorDark: {
':hover': {
backgroundColor: 'rgba(255, 255, 255, .1)',
},
':active': {
backgroundColor: 'rgba(255, 255, 255, .2)',
}
},
anchorTitle: {
},
anchorIcon: {
marginRight: '8px',
height: '44px',
display: 'flex',
alignItems: 'center'
},
span: {
display: 'flex',
alignItems: 'center',
color: '#000000',
fontFamily: '"Segoe UI", Frutiger, "Frutiger Linotype", "Dejavu Sans", "Helvetica Neue", Arial, sans-serif',
fontSize: '15px',
letterSpacing: '0.4pt',
padding: '0 16px',
transition: 'transform .1s ease-in',
userSelect: 'none'
},
spanDark: {
color: '#ffffff',
},
pushTransformHover: {
transition: 'transform .1s ease-in'
},
pushTransformActive: {
transform: 'scale(0.97)',
transition: 'transform 0s ease-in'
}
};
================================================
FILE: src/NavPane/windows/index.js
================================================
import React, { Component, Children, cloneElement } from 'react';
import PropTypes from 'prop-types';
import Pane from './Pane';
import Item from './Item';
import styles from './style/windows10';
import { ColorContext, colorPropTypes } from '../../style/color/windows';
import {
ThemeContext,
themePropTypes,
themeContextTypes
} from '../../style/theme/windows';
let warnOnce = false;
function applyChildenClasses() {
return function(ComposedComponent) {
const nextItem = Item;
ComposedComponent.prototype.Item = ComposedComponent.Item = function(
...args
) {
if (!warnOnce) {
warnOnce = true;
console.warn(
'React Desktop: Using NavPane.Item is deprecated, import NavPaneItem instead.'
);
}
return new nextItem(...args);
};
return ComposedComponent;
};
}
@applyChildenClasses()
@ColorContext()
@ThemeContext()
class NavPane extends Component {
static propTypes = {
...colorPropTypes,
...themePropTypes,
canPaneToggle: PropTypes.bool,
onPaneToggle: PropTypes.func,
defaultIsPaneExpanded: PropTypes.bool,
paneCompactedLength: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
]),
paneExpandedLength: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
])
};
static contextTypes = {
...themeContextTypes
};
render() {
return (
);
}
renderContent() {
let content = null;
Children.map(this.props.children, child => {
if (child.props.selected) content = child;
});
return content
? cloneElement(content, {
...content.props,
paneTheme: this.context.theme
})
: null;
}
}
export default NavPane;
================================================
FILE: src/NavPane/windows/style/windows10.js
================================================
export default {
navPane: {
display: 'flex',
flexWrap: 'nowrap',
position: 'relative',
flex: '1'
},
navPaneItem: {
position: 'relative',
flexGrow: '1',
flexShrink: '0',
display: 'flex'
},
contentWrapper: {
display: 'flex',
flex: '1',
flexDirection: 'column'
},
content: {
display: 'flex',
flex: '1',
flexDirection: 'column'
},
title: {
position: 'relative',
color: '#000000',
height: '48px',
display: 'flex',
alignItems: 'center',
fontFamily: '"Segoe UI", Frutiger, "Frutiger Linotype", "Dejavu Sans", "Helvetica Neue", Arial, sans-serif',
fontSize: '15px',
textTransform: 'uppercase',
padding: '0 24px',
overflow: 'hidden',
cursor: 'default',
userSelect: 'none'
},
titleDark: {
color: '#ffffff'
}
};
================================================
FILE: src/Pin/macOs/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
import TextInput from '../../TextInput/macOs';
import Hidden, { hiddenPropTypes } from '../../style/hidden';
import Margin, { marginPropTypes, removeMarginProps } from '../../style/margin';
@Hidden()
@Margin()
class Pin extends Component {
static propTypes = {
...hiddenPropTypes,
...marginPropTypes,
reveal: PropTypes.bool,
length: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
.isRequired,
onChange: PropTypes.func
};
constructor(props, ...args) {
super(props, ...args);
const lenght = parseInt(props.length);
this.state = {
current: 0,
pin: new Array(lenght)
};
}
componentDidMount() {
this.handleBlur();
}
handleBlur = (e, index) => {
if (e && index === this.state.current) {
e.preventDefault();
e.stopPropagation();
}
if (this.state.current !== null) {
this.selectInput(this.state.current);
}
};
selectInput = index => {
if (this.refs[index]) {
const el = ReactDOM.findDOMNode(this.refs[index]).getElementsByTagName(
'INPUT'
)[0];
el.focus();
}
};
setValue = (index, value) => {
if (this.refs[index]) {
const el = ReactDOM.findDOMNode(this.refs[index]).getElementsByTagName(
'INPUT'
)[0];
// Use execCommand instead of direct assignment to keep the browser's undo stack
// This currently only handles delete, add conditions if use for other purposes
el.focus();
document.execCommand('delete', false);
const pin = [
...this.state.pin.slice(0, index),
value,
...this.state.pin.slice(index + 1)
];
this.setState({ pin });
if (this.props.onChange) this.props.onChange(pin.join(''));
}
};
handleChange = (e, index) => {
if (e.target.value || this.state.current === index + 1) {
// In case of undoing insert, switch back to previous pin
let nextIndex = (index === this.props.length - 1 || !e.target.value) ? index : index + 1;
const pin = [
...this.state.pin.slice(0, index),
e.target.value,
...this.state.pin.slice(index + 1)
];
this.setState({ current: nextIndex, pin });
setTimeout(() => this.selectInput(nextIndex));
if (this.props.onChange) this.props.onChange(pin.join(''));
}
};
handleKeyDown = e => {
if (e.keyCode === 8) {
if (e.target.value) {
this.setValue(this.state.current, '');
} else {
const nextIndex = this.state.current - 1;
this.setState({ current: nextIndex });
setTimeout(() => {
this.selectInput(nextIndex);
this.setValue(nextIndex, '');
});
}
}
};
handleKeyPress = e => {
if (e.charCode >= 48 && e.charCode <= 57) {
return true;
}
e.preventDefault();
e.stopPropagation();
};
render() {
const { length, reveal, style, ...props } = this.props;
delete props.onChange;
const children = [];
for (let i = 0, len = parseInt(length); i < len; ++i) {
children.push(
this.handleChange(e, i)}
onBlur={e => this.handleBlur(e, i)}
onKeyDown={this.handleKeyDown}
onKeyPress={this.handleKeyPress}
style={{
fontSize: '32px',
lineHeight: '32px',
textAlign: 'center',
paddingTop: '3px',
paddingBottom: '4px',
color: '#464646'
}}
{...removeMarginProps(props)}
/>
);
}
return {children}
;
}
}
export default Pin;
================================================
FILE: src/Pin/macOs/style/10.11.js
================================================
================================================
FILE: src/ProgressCircle/macOs/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { hiddenPropTypes } from '../../style/hidden';
import styles from './styles/10.11';
import { startAnimation, stopAnimation } from './progressCircleAnimation';
class ProgressCircle extends Component {
static propTypes = {
...hiddenPropTypes,
absolute: PropTypes.bool,
color: PropTypes.string,
size: PropTypes.number
};
componentDidMount() {
let elements = [];
for (let prop in this.refs) {
if (this.refs.hasOwnProperty(prop) && prop.match(/\d/g)) elements.push(this.refs[prop]);
}
this.animation = startAnimation(...elements);
}
componentWillUnmount() {
stopAnimation(this.animation);
}
render() {
const { size, color, style, absolute, hidden, ...props } = this.props;
let containerStyle = { ...styles.container };
let componentStyle = {
...styles.progress,
...style,
visibility: !hidden ? 'visible' : 'hidden',
display: !hidden ? 'block' : 'none'
};
if (absolute) {
componentStyle = { ...componentStyle, ...styles.absolute };
}
let componentColor = color;
if (!componentColor) {
componentColor = '#000000';
}
if (size) {
componentStyle = {
...componentStyle,
width: size + 'px',
height: size + 'px'
};
containerStyle = {
...containerStyle,
height: size + 'px'
};
}
const svg = (
);
let content = svg;
if (absolute) {
content = (
{svg}
);
}
return content;
}
}
export default ProgressCircle;
================================================
FILE: src/ProgressCircle/macOs/progressCircleAnimation.js
================================================
let ids = [];
let animations = {};
const framerate = 60;
const duration = 1900;
function animate(elements) {
this.currentStep = 0;
this.steps = duration / framerate;
this.increment = 1 / this.steps;
animateStep.apply(this, [elements]);
animations[this.id] = setInterval(() => animateStep.apply(this, [elements]), 1000 / framerate);
}
function animateStep(elements) {
this.currentStep++;
if (this.currentStep > this.steps) {
this.currentStep = 1;
}
for (let i = 0, len = 12; i < len; ++i) {
elements[11-i].style.opacity = this.increment * findStep.apply(this, [i]);
}
}
function findStep(index) {
let step = this.currentStep + (this.steps / 12 * index);
if (step > this.steps) {
step = -this.steps + step;
}
return this.steps - step;
}
export function startAnimation(...elements) {
let id = 0;
if (ids.length) id = ids[ids.length - 1] + 1;
ids.push(id);
animate.apply({ id }, [elements]);
return id;
}
export function stopAnimation(animation) {
window.clearInterval(animations[animation]);
}
================================================
FILE: src/ProgressCircle/macOs/styles/10.11.js
================================================
export default {
progress: {
width: '16px',
height: '16px'
},
container: {
position: 'relative',
height: '16px'
},
absolute: {
position: 'absolute',
top: 0,
left: 0
}
};
================================================
FILE: src/ProgressCircle/windows/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { hiddenPropTypes } from '../../style/hidden';
import { ColorContext, colorPropTypes, colorContextTypes } from '../../style/color/windows';
import { startAnimation, stopAnimation } from './progressCircleAnimation';
import styles from './styles/windows10';
@ColorContext()
class ProgressCircle extends Component {
static propTypes = {
...hiddenPropTypes,
...colorPropTypes,
absolute: PropTypes.bool,
size: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
};
static contextTypes = {
...colorContextTypes
};
componentDidMount() {
this.animation = startAnimation(
this.refs[0],
this.refs[1],
this.refs[2],
this.refs[3],
this.refs[4],
this.refs[5]
);
}
componentWillUnmount() {
stopAnimation(this.animation);
}
render() {
const { size, style, absolute, hidden, ...props } = this.props;
let containerStyle = { ...styles.container };
let componentStyle = {
...styles.progress,
...style,
visibility: !hidden ? 'visible' : 'hidden',
display: !hidden ? 'block' : 'none'
};
if (absolute) {
componentStyle = { ...componentStyle, ...styles.absolute };
}
let componentColor = this.context.color;
if (size) {
componentStyle = {
...componentStyle,
width: size + 'px',
height: size + 'px'
};
containerStyle = {
...containerStyle,
height: size + 'px'
};
}
const svg = (
);
let content = svg;
if (absolute) {
content = (
{svg}
);
}
return content;
}
}
export default ProgressCircle;
================================================
FILE: src/ProgressCircle/windows/progressCircleAnimation.js
================================================
import BezierEasing from '../../animation/bezierEasing';
let requestAnimationFrame;
if (typeof window !== 'undefined') {
requestAnimationFrame = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame;
}
const totalIterations = 95;
const circlesInterval = 14;
const restartInterval = 250;
const stopRotationAt = totalIterations * 2 / 1.02;
const easing = BezierEasing(0, 0.47, 0.9, .25);
const bounding = 68;
let ids = [];
let animations = {};
function rotateCircle(circles) {
let lastFrame = false;
for (var i = 0, len = circles.length; i < len; ++i) {
if (this.iteration >= circlesInterval * i) {
let iteration = this.iteration - circlesInterval * i;
const revolution = Math.floor(iteration / totalIterations);
iteration = iteration - (revolution * totalIterations);
if (iteration < 0) {
iteration = totalIterations - iteration;
} else if (iteration > totalIterations) {
iteration = iteration - totalIterations;
}
if (iteration + (revolution * totalIterations) > stopRotationAt) {
circles[i].setAttributeNS('', 'fill-opacity', '0');
if (i === circles.length-1) {
lastFrame = true;
}
} else {
const value = easing.get(1 / totalIterations * iteration) * 2 * Math.PI * -1;
circles[i].setAttributeNS('', 'fill-opacity', '1');
circles[i].setAttributeNS('', 'cx', 75 + (bounding * Math.sin(value)) + '');
circles[i].setAttributeNS('', 'cy', 75 + (bounding * Math.cos(value)) + '');
}
}
}
this.iteration++;
if (!lastFrame) {
animations[this.id] = ['animationFrame', requestAnimationFrame(rotateCircle.bind(this, circles))];
} else {
animations[this.id] = ['timeout', window.setTimeout(startAnimation.bind(null, ...circles), restartInterval)];
}
}
export function startAnimation(...elements) {
let id = 0;
if (ids.length) id = ids[ids.length - 1] + 1;
ids.push(id);
if (requestAnimationFrame) {
rotateCircle.apply({ iteration: 0, currentIteration: 0, id }, [elements]);
}
return id;
}
export function stopAnimation(animation) {
if (animations[animation][0] === 'timeout') {
window.clearTimeout(animations[animation][1]);
} else {
window.cancelAnimationFrame(animations[animation][1]);
}
}
================================================
FILE: src/ProgressCircle/windows/styles/windows10.js
================================================
export default {
progress: {
width: '20px',
height: '20px',
position: 'relative'
},
container: {
position: 'relative',
height: '20px'
},
absolute: {
position: 'absolute',
top: 0,
left: 0
}
};
================================================
FILE: src/Radio/macOs/Circle.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Radium from 'radium';
import styles from './styles/10.11';
@Radium
class Circle extends Component {
static propTypes = {
show: PropTypes.bool,
color: PropTypes.string,
shadowColor: PropTypes.string
};
static defaultProps = {
color: '#FFFFFF'
};
render() {
const { color, shadowColor } = this.props;
let style = { ...styles.checkmark };
style.opacity = '0';
style.transform = 'scale(2)';
style.transition = 'opacity 0s, transform 0.2s';
if (this.props.show) {
style.opacity = '1';
style.transform = 'scale(1)';
}
return (
);
}
}
export default Circle;
================================================
FILE: src/Radio/macOs/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Hidden, { hiddenPropTypes } from '../../style/hidden';
import Radium, { getState } from 'radium';
import styles from './styles/10.11';
import Text from '../../Text/macOs';
import Circle from './Circle';
import ValueRef from '../../ValueRef';
import WindowFocus from '../../windowFocus';
@ValueRef()
@WindowFocus()
@Hidden()
@Radium
class Radio extends Component {
static propTypes = {
...hiddenPropTypes,
label: PropTypes.string,
onChange: PropTypes.func
};
constructor(props) {
super();
this.state = {
checked: !!props.defaultChecked === true,
transition: true
};
}
componentDidMount() {
document.addEventListener('change', this.onSiblingChange);
}
componentWillUnmount() {
document.removeEventListener('change', this.onSiblingChange);
}
componentWillReceiveProps(nextProps) {
if (nextProps.isWindowFocused !== this.props.isWindowFocused) {
this.setState({ transition: false });
}
}
componentDidUpdate() {
if (!this.state.transition) {
setTimeout(() => this.setState({ transition: true }), 0);
}
}
onSiblingChange = () => {
if (this.refs.element.checked !== this.state.checked) {
this.setState({ checked: this.refs.element.checked });
}
};
handleChange = event => {
this.setState({ checked: event.target.checked });
if (this.props.onChange) {
this.props.onChange(event);
}
};
render() {
let { style, label, isWindowFocused, ...props } = this.props;
const { transition } = this.state;
let componentStyle = { ...styles.radio, ...style };
let labelStyle = styles.label;
let circleColor = '#FFFFFF';
let shadowColor = '#0050a5';
if (this.state.checked) {
if (isWindowFocused) {
componentStyle = {
...componentStyle,
...styles['radio:checked']
};
if (!transition) componentStyle.transition = 'none';
} else {
componentStyle = {
...componentStyle,
...styles['radio:checked:unfocused']
};
circleColor = '#404040';
shadowColor = '#FFFFFF';
}
}
if (getState(this.state, null, ':active')) {
if (this.state.checked) {
componentStyle = {
...componentStyle,
...styles['radio:checked:active']
};
shadowColor = '#001d99';
} else {
componentStyle = {
...componentStyle,
...styles['radio:active']
};
}
}
return (
);
}
}
export default Radio;
================================================
FILE: src/Radio/macOs/styles/10.11.js
================================================
export default {
container: {
display: 'flex'
},
label: {
display: 'flex',
height: '20px',
position: 'relative',
':hover': {},
':active': {}
},
inputWrapper: {
position: 'relative',
marginRight: '3px',
paddingTop: '2px'
},
radio: {
WebkitUserSelect: 'none',
userSelect: 'none',
WebkitAppearance: 'none',
appearance: 'none',
borderWidth: '1px',
borderStyle: 'solid',
borderColor: '#b8b8b8',
borderRadius: '50%',
backgroundColor: '#ffffff',
padding: '7px',
margin: '0px',
boxShadow: 'inset 0 1px 0 0 rgba(224, 224, 224, .4)',
transition: 'all 0.4s',
':focus': {
outline: 'none'
}
},
'radio:active': {
borderColor: '#a4a4a4',
backgroundColor: '#f0f0f0',
boxShadow: 'inset 0 0 0 1px rgba(117, 117, 117, .35)',
transition: 'all 0.4s'
},
'radio:checked': {
backgroundColor: '#3b99fc',
boxShadow: 'none',
borderColor: '#2c91fc',
transition: 'all 0s'
},
'radio:checked:unfocused': {
backgroundColor: '#FFFFFF',
boxShadow: 'none',
borderColor: '#b8b8b8',
transition: 'none'
},
'radio:checked:active': {
backgroundColor: '#0080f6',
borderColor: '#006adc',
boxShadow: 'inset 0 0 0 1px rgba(19, 68, 119, .22)',
transition: 'all 0.4s'
},
checkmark: {
position: 'absolute',
top: '7px',
left: '5px',
width: '6px',
height: '6px'
},
svg: {
zIndex: '2',
position: 'absolute',
top: '0px',
left: '0px',
height: '6px'
},
svgShadow: {
zIndex: '1',
position: 'absolute',
top: '1.5px',
left: '0px',
opacity: '.37',
height: '6px',
filter: 'blur(.5px)'
}
};
================================================
FILE: src/Radio/windows/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Radium, { getState } from 'radium';
import styles from './styles/windows';
import Text from '../../Text/windows';
import {
ThemeContext,
themePropTypes,
themeContextTypes
} from '../../style/theme/windows';
import Hidden, { hiddenPropTypes } from '../../style/hidden';
import {
ColorContext,
colorPropTypes,
colorContextTypes
} from '../../style/color/windows';
import ValueRef from '../../ValueRef';
@ValueRef()
@Hidden()
@ColorContext()
@ThemeContext()
@Radium
class Radio extends Component {
static propTypes = {
...hiddenPropTypes,
...colorPropTypes,
...themePropTypes,
label: PropTypes.string,
onChange: PropTypes.func
};
static contextTypes = {
...themeContextTypes,
...colorContextTypes
};
constructor(props) {
super();
this.state = {
checked: !!props.defaultChecked === true
};
}
componentDidMount() {
document.addEventListener('change', this.onSiblingChange);
}
componentWillUnmount() {
document.removeEventListener('change', this.onSiblingChange);
}
onSiblingChange = () => {
if (this.refs.element.checked !== this.state.checked) {
this.setState({ checked: this.refs.element.checked });
}
};
handleChange = event => {
this.setState({ checked: event.target.checked });
if (this.props.onChange) {
this.props.onChange(event);
}
};
render() {
let { style, label, color, ...props } = this.props;
let componentStyle = {
...styles.radio,
...(this.context.theme === 'dark' ? styles['radioDark'] : {})
};
let labelStyle = styles.label;
let circleStyle = {
...styles.circle,
...(this.context.theme === 'dark' ? styles['circleDark'] : {})
};
if (this.state.checked) {
componentStyle = {
...componentStyle,
borderColor: color || this.context.color
};
}
if (getState(this.state, null, ':active')) {
if (this.state.checked) {
componentStyle = {
...componentStyle,
...styles['radio:checked:active'],
...(this.context.theme === 'dark'
? styles['radioDark:checked:active']
: {})
};
circleStyle = {
...circleStyle,
...styles['circle:active'],
...(this.context.theme === 'dark' ? styles['circleDark:active'] : {})
};
} else {
componentStyle = {
...componentStyle,
...styles['radio:active'],
...(this.context.theme === 'dark' ? styles['radioDark:active'] : {})
};
}
} else if (getState(this.state, null, ':hover')) {
if (this.state.checked) {
circleStyle = {
...circleStyle,
...styles['circle:hover'],
...(this.context.theme === 'dark' ? styles['circleDark:hover'] : {})
};
} else {
componentStyle = {
...componentStyle,
...styles['radio:hover'],
...(this.context.theme === 'dark' ? styles['radioDark:hover'] : {})
};
}
}
componentStyle = { ...componentStyle, ...style };
return (
{this.state.checked ?
: null}
{label}
);
}
}
export default Radio;
================================================
FILE: src/Radio/windows/styles/windows.js
================================================
export default {
container: {
display: 'flex',
marginBottom: '21px'
},
label: {
display: 'flex',
position: 'relative',
':hover': {},
':active': {}
},
text: {
fontFamily: '"Segoe UI", Frutiger, "Frutiger Linotype", "Dejavu Sans", "Helvetica Neue", Arial, sans-serif',
fontSize: '15px',
color: '#000000',
display: 'inline'
},
textDark: {
color: '#ffffff'
},
inputWrapper: {
position: 'relative',
marginRight: '7px',
paddingTop: '2px'
},
radio: {
WebkitUserSelect: 'none',
userSelect: 'none',
WebkitAppearance: 'none',
appearance: 'none',
borderWidth: '2px',
borderStyle: 'solid',
borderColor: '#333333',
borderRadius: '50%',
backgroundColor: 'transparent',
padding: '8px',
margin: '0px',
':focus': {
outline: 'none'
}
},
'radio:hover': {
borderColor: '#000000'
},
'radio:active': {
borderColor: '#666666'
},
'radio:checked:active': {
borderColor: '#666666'
},
radioDark: {
borderColor: '#cccccc'
},
'radioDark:hover': {
borderColor: '#ffffff'
},
'radioDark:active': {
borderColor: '#999999'
},
'radioDark:checked:active': {
borderColor: '#999999'
},
circle: {
position: 'absolute',
top: '7px',
left: '5px',
width: '10px',
height: '10px',
borderRadius: '50%',
background: '#333333'
},
'circle:hover': {
background: '#000000'
},
'circle:active': {
background: '#666666'
},
circleDark: {
background: '#cccccc'
},
'circleDark:hover': {
background: '#ffffff'
},
'circleDark:active': {
background: '#999999'
}
};
================================================
FILE: src/SearchField/macOs/cancelAnimation.js
================================================
let requestAnimationFrame;
if (typeof window !== 'undefined') {
requestAnimationFrame = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame;
}
let startTimestamp;
const duration = 150;
function animateCancelIcon(timestamp, element) {
if (!startTimestamp) startTimestamp = timestamp;
let progress = (timestamp - startTimestamp) / duration;
if (progress > 1) progress = 1;
element.style.height = (14 * progress) + 'px';
element.style.width = (14 * progress) + 'px';
element.style.opacity = progress;
if (progress !== 1) {
requestAnimationFrame(timestamp => animateCancelIcon(timestamp, element));
}
}
export default function(element) {
if (requestAnimationFrame) {
startTimestamp = null;
const icon = element.getElementsByTagName('svg')[0];
requestAnimationFrame(timestamp => animateCancelIcon(timestamp, icon));
}
}
================================================
FILE: src/SearchField/macOs/icons.js
================================================
import React from 'react';
export const searchIcon1x = (
);
export const searchIcon2x = (
);
export const cancelIcon1x = (
);
export const cancelIcon2x = (
);
================================================
FILE: src/SearchField/macOs/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
import TextInput from '../../TextInput/macOs';
import * as icon from './icons';
import styles from './styles/10.11';
import cancelAnimation from './cancelAnimation';
import ValueRef from '../../ValueRef';
@ValueRef()
class SearchInput extends Component {
static propTypes = {
onCancel: PropTypes.func,
cancel: PropTypes.bool
};
static defaultProps = {
cancel: true
};
constructor() {
super();
this.state = {
showCancel: false
};
}
get searchIcon() {
return window && window.devicePixelRatio > 1.5
? icon.searchIcon2x
: icon.searchIcon1x;
}
get cancelIcon() {
return window && window.devicePixelRatio > 1.5
? icon.cancelIcon2x
: icon.cancelIcon1x;
}
handleCancelMouseDown = e => {
e.preventDefault();
e.stopPropagation();
};
handleCancelClick = () => {
const element = ReactDOM.findDOMNode(this.refs.input).getElementsByTagName(
'INPUT'
)[0];
element.setSelectionRange(0, element.value.length);
setTimeout(() => {
element.value = '';
let event = document.createEvent('HTMLEvents');
event.initEvent('change', false, true);
element.dispatchEvent(event);
event = new Event('input', { bubbles: true });
element.dispatchEvent(event);
element.blur();
if (this.props.onCancel) {
this.props.onCancel();
}
}, 200);
};
handleChange = e => {
if (this.props.cancel) {
if (e.target.value && !this.state.showCancel) {
this.setState({ showCancel: true });
} else if (!e.target.value && this.state.showCancel) {
this.setState({ showCancel: false });
}
}
if (typeof this.props.onChange === 'function') this.props.onChange(e);
};
handleKeyDown = e => {
if (e.keyCode === 27) {
const element = ReactDOM.findDOMNode(
this.refs.input
).getElementsByTagName('INPUT')[0];
element.value = '';
let event = document.createEvent('HTMLEvents');
event.initEvent('change', false, true);
element.dispatchEvent(event);
event = new Event('input', { bubbles: true });
element.dispatchEvent(event);
setTimeout(() => element.blur(), 10);
}
if (typeof this.props.onKeyDown === 'function') this.props.onKeyDown(e);
};
componentDidUpdate(prevProps, prevState) {
if (!prevState.showCancel && this.state.showCancel) {
cancelAnimation(ReactDOM.findDOMNode(this.refs.cancel));
}
}
render() {
const { cancel, ...props } = this.props;
delete props.onCancel;
return (
);
}
}
export default SearchInput;
================================================
FILE: src/SearchField/macOs/styles/10.11.js
================================================
export default {
container: {
position: 'relative'
},
cancel: {
position: 'absolute',
zIndex: 4,
top: '0px',
right: '0px',
width: '14px',
height: '100%',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
marginRight: '4px',
marginLeft: '4px'
}
};
================================================
FILE: src/SegmentedControl/macOs/Item/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
class Item extends Component {
static propTypes = {
title: PropTypes.string,
selected: PropTypes.bool,
onSelect: PropTypes.func
};
render() {
let { children, ...props } = this.props;
delete props.title;
delete props.selected;
delete props.onSelect;
return (
{children}
);
}
}
export default Item;
================================================
FILE: src/SegmentedControl/macOs/Tabs/Tab.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styles from '../style/10.11';
import WindowFocus from '../../../windowFocus';
import Radium from 'radium';
@WindowFocus()
@Radium
class Tab extends Component {
static propTypes = {
selected: PropTypes.bool,
prevSelected: PropTypes.bool,
afterSelected: PropTypes.bool,
firstChild: PropTypes.bool,
lastChild: PropTypes.bool,
onSelect: PropTypes.func
};
render() {
let { children, style, onSelect, afterSelected, prevSelected, lastChild, firstChild, isWindowFocused } = this.props;
let componentStyle = { ...styles.tab, ...style };
if (firstChild) componentStyle = { ...componentStyle, ...styles.firstChild };
if (lastChild) componentStyle = { ...componentStyle, ...styles.lastChild };
if (prevSelected) componentStyle = { ...componentStyle, ...styles.prevSelected };
if (afterSelected) componentStyle = { ...componentStyle, ...styles.afterSelected };
if (this.props.selected) {
componentStyle = { ...componentStyle, ...styles.selected };
if (!isWindowFocused) componentStyle = { ...componentStyle, ...styles.selectedUnfocused };
if (firstChild) componentStyle = { ...componentStyle, ...styles.firstChildSelected };
if (lastChild) componentStyle = { ...componentStyle, ...styles.lastChildSelected };
}
return (
{children}
);
}
}
export default Tab;
================================================
FILE: src/SegmentedControl/macOs/Tabs/index.js
================================================
import React, { Component } from 'react';
import Tab from './Tab';
import styles from '../style/10.11';
class Tabs extends Component {
select(item) {
this.refs[item.props.tabId].setState({ selected: true });
}
unselect(item) {
this.refs[item.props.tabId].setState({ selected: false });
}
render() {
const { style } = this.props;
let children;
// todo: use Children.map
if (!this.props.children) {
return null;
} else if (
Object.prototype.toString.call(this.props.children) !== '[object Array]'
) {
children = [this.props.children];
} else {
children = [...this.props.children];
}
let tabs = [];
let hasSelected = false;
for (let i = 0, len = children.length; i < len; ++i) {
let props = children[i].props;
if (props.selected) hasSelected = true;
if (i === 0) props = { ...props, firstChild: true };
if (i === len - 1) props = { ...props, lastChild: true };
if (
children[i + 1] &&
children[i + 1].props &&
children[i + 1].props.selected
) {
props = { ...props, nextSelected: true };
}
tabs = [...tabs, props];
}
if (!hasSelected && tabs[0]) tabs[0].selected = true;
let prevSelectedIndex = null;
let afterSelected = false;
for (let i = 0, len = tabs.length; i < len; ++i) {
if (afterSelected) {
tabs[i] = { ...tabs[i], afterSelected: true };
afterSelected = false;
}
if (tabs[i].selected) {
afterSelected = true;
prevSelectedIndex = i - 1;
}
}
if (prevSelectedIndex >= 0 && tabs[prevSelectedIndex])
tabs[prevSelectedIndex] = {
...tabs[prevSelectedIndex],
prevSelected: true
};
return (
{this.renderTabs(tabs)}
);
}
renderTabs(tabs) {
const children = [];
for (let i = 0, len = tabs.length; i < len; ++i) {
children.push(
{tabs[i].title}
);
}
return children;
}
}
export default Tabs;
================================================
FILE: src/SegmentedControl/macOs/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Dimension, { dimensionPropTypes } from '../../style/dimension';
import Margin, { marginPropTypes } from '../../style/margin';
import Hidden, { hiddenPropTypes } from '../../style/hidden';
import Item from './Item';
import Tabs from './Tabs';
import styles from './style/10.11';
import Box from '../../Box/macOs';
let warnOnce = false;
function applyItem() {
return function(ComposedComponent) {
const nextItem = Item;
ComposedComponent.prototype.Item = ComposedComponent.Item = function(
...args
) {
if (!warnOnce) {
warnOnce = true;
console.warn(
'React Desktop: Using SegmentedControl.Item is deprecated, import SegmentedControlItem instead.'
);
}
return new nextItem(...args);
};
return ComposedComponent;
};
}
@applyItem()
@Dimension()
@Margin()
@Hidden()
class SegmentedControl extends Component {
static propTypes = {
...dimensionPropTypes,
...marginPropTypes,
...hiddenPropTypes,
box: PropTypes.bool
};
select(item) {
this.refs.tabs.select(item);
}
unselect(item) {
this.refs.tabs.unselect(item);
}
render() {
let { children, box, ...props } = this.props;
let content;
if (box) {
content = (
{this.renderItem()}
);
} else {
content = {this.renderItem()}
;
}
return (
{children}
{content}
);
}
renderItem() {
let child = null;
let children;
// todo: use Children.map
if (!this.props.children) {
return null;
} else if (
Object.prototype.toString.call(this.props.children) !== '[object Array]'
) {
children = [this.props.children];
} else {
children = [...this.props.children];
}
for (let i = 0, len = children.length; i < len; ++i) {
if (children[i].props.selected) child = children[i];
}
return child;
}
}
export default SegmentedControl;
================================================
FILE: src/SegmentedControl/macOs/style/10.11.js
================================================
export default {
sergmentedControl: {
WebkitUserSelect: 'none',
userSelect: 'none',
cursor: 'default',
flex: '1'
},
tabs: {
WebkitUserSelect: 'none',
userSelect: 'none',
cursor: 'default',
width: '100%',
display: 'flex',
justifyContent: 'center'
},
tab: {
WebkitUserSelect: 'none',
userSelect: 'none',
cursor: 'default',
background: '#ffffff',
borderTopWidth: '1px',
borderTopStyle: 'solid',
borderTopColor: '#c7c7c7',
borderBottomWidth: '1px',
borderBottomStyle: 'solid',
borderBottomColor: '#a6a6a6',
borderRightWidth: '1px',
borderRightStyle: 'solid',
borderRightColor: '#d8d8d8',
paddingTop: '1px',
paddingBottom: '2px',
paddingLeft: '12px',
paddingRight: '12px',
lineHeight: '16px',
fontFamily: '-apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif',
fontSize: '13px',
boxShadow: '0 1px rgba(0, 0, 0, .039), 0 0 .5px rgba(0, 0, 0, .1)',
':active': {
background: '#f0f0f0'
}
},
firstChild: {
borderLeftWidth: '1px',
borderLeftStyle: 'solid',
borderLeftColor: '#b8b8b8',
borderTopLeftRadius: '4px',
borderBottomLeftRadius: '4px'
},
lastChild: {
borderRightColor: '#b8b8b8',
borderTopRightRadius: '4px',
borderBottomRightRadius: '4px'
},
selected: {
background: '-webkit-linear-gradient(top, #5ab2f6 0%, #0082fa 100%)',
borderTopColor: '#30a0f5',
borderBottomColor: '#0060fa',
borderLeftColor: '#0080f7',
borderRightColor: '#0080f7',
color: 'white',
borderRightWidth: '0px',
paddingRight: '13px',
paddingLeft: '13px',
':active': {
background: '-webkit-linear-gradient(top, #3397f9 0%, #0068df 100%)',
borderTopColor: '#007ff9',
borderBottomColor: '#0040d8',
borderLeftColor: '#0061e9',
borderRightColor: '#0061e9',
color: 'white'
}
},
firstChildSelected: {
paddingLeft: '12px'
},
lastChildSelected: {
borderRightWidth: '1px',
paddingRight: '12px'
},
prevSelected: {
borderRightWidth: '0px',
paddingRight: '12px'
},
afterSelected: {
},
selectedUnfocused: {
background: '#e5e5e5',
borderTopColor: '#c7c7c7',
borderBottomColor: '#a6a6a6',
borderLeftColor: '#b7b7b7',
borderRightColor: '#b7b7b7',
color: '#000000'
}
};
================================================
FILE: src/Text/macOs/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Margin, { marginPropTypes } from '../../style/margin';
import Padding, { paddingPropTypes } from '../../style/padding';
import FontSize, { fontSizePropTypes } from '../../style/fontSize';
import Dimension, { dimensionPropTypes } from '../../style/dimension';
import TextAlign, { textAlignPropTypes } from '../../style/textAlign';
import Hidden, { hiddenPropTypes } from '../../style/hidden';
import Alignment, { alignmentPropTypes } from '../../style/alignment';
import Background, { backgroundPropTypes } from '../../style/background/macOs';
import styles from './styles/10.11';
@Background()
@Alignment()
@Margin()
@Padding()
@FontSize()
@Dimension()
@TextAlign()
@Hidden()
class Text extends Component {
static propTypes = {
...paddingPropTypes,
...alignmentPropTypes,
...backgroundPropTypes,
...hiddenPropTypes,
...textAlignPropTypes,
...marginPropTypes,
...fontSizePropTypes,
...dimensionPropTypes,
color: PropTypes.string,
bold: PropTypes.oneOfType([PropTypes.bool, PropTypes.number, PropTypes.string]),
};
static defaultProps = {
color: '#000000'
};
render() {
const { color, children, style, bold, ...props } = this.props;
let componentStyle = { ...styles.text, color };
if (bold && bold === true) {
componentStyle = { ...componentStyle, fontWeight: 'bold' };
} else if (bold) {
componentStyle = { ...componentStyle, fontWeight: bold };
}
return (
{children}
);
}
}
export default Text;
================================================
FILE: src/Text/macOs/styles/10.11.js
================================================
export default {
text: {
display: 'block',
WebkitUserSelect: 'none',
userSelect: 'none',
cursor: 'default',
fontFamily: '-apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif',
fontSize: '13px'
}
};
================================================
FILE: src/Text/windows/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Margin, { marginPropTypes } from '../../style/margin';
import Padding, { paddingPropTypes } from '../../style/padding';
import Alignment, { alignmentPropTypes } from '../../style/alignment';
import Hidden, { hiddenPropTypes } from '../../style/hidden';
import Background, { backgroundPropTypes } from '../../style/background/windows';
import Dimension, { dimensionPropTypes } from '../../style/dimension';
import { colorContextTypes } from '../../style/color/windows';
import { ThemeContext, themePropTypes, themeContextTypes } from '../../style/theme/windows';
import styles from './styles/windows10';
@Margin()
@Padding()
@Alignment()
@Hidden()
@Background()
@Dimension()
@ThemeContext()
class Text extends Component {
static propTypes = {
...themePropTypes,
...marginPropTypes,
...paddingPropTypes,
...alignmentPropTypes,
...hiddenPropTypes,
...backgroundPropTypes,
...dimensionPropTypes,
color: PropTypes.oneOfType([PropTypes.string, PropTypes.bool])
};
static contextTypes = {
...colorContextTypes,
...themeContextTypes
};
render() {
let { children, style, color, ...props } = this.props;
let componentStyle = { ...styles.text };
color = color === true ? this.context.color : color ? color : '#000000';
if (color) componentStyle = { ...componentStyle, color: color };
else if (this.context.theme === 'dark') componentStyle = { ...componentStyle, color: '#ffffff' };
if (props.horizontalAlignment) {
componentStyle.textAlign = props.horizontalAlignment;
}
componentStyle = { ...componentStyle, ...style };
return (
{children}
);
}
}
export default Text;
================================================
FILE: src/Text/windows/styles/windows10.js
================================================
export default {
text: {
WebkitUserSelect: 'none',
userSelect: 'none',
cursor: 'default',
lineHeight: '25.96px',
fontFamily: '"Segoe UI", Frutiger, "Frutiger Linotype", "Dejavu Sans", "Helvetica Neue", Arial, sans-serif',
fontSize: '14px',
display: 'flex'
}
};
================================================
FILE: src/TextArea/macOs/centerPlaceholderAnimation.js
================================================
import BezierEasing from '../../animation/bezierEasing';
let requestAnimationFrame;
if (typeof window !== 'undefined') {
requestAnimationFrame = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame;
}
let startTimestamp;
const duration = 350;
const easing = BezierEasing(.3,.14,0,1);
function moveLabel(timestamp, label, start, current, end, cb) {
if (start === end) return null;
if (!startTimestamp) startTimestamp = timestamp;
let progress = 1 - (timestamp - startTimestamp) / duration;
if (progress < 0) progress = 0;
progress = 1 - (easing.get(1 - progress));
if (start > end) {
current = progress * start;
} else {
current = (1 - progress) * end + start;
}
label.style.left = current + 'px';
if (start > end && current > end || start < end && current < end) {
requestAnimationFrame(timestamp => moveLabel(timestamp, label, start, current, end));
} else {
label.style.left = end + 'px';
if (cb) cb();
}
}
function animateLabel(label, start, end) {
return new Promise(resolve => {
if (requestAnimationFrame) {
requestAnimationFrame(timestamp => moveLabel(timestamp, label, start, start, end, resolve));
}
});
}
export function pullLeft(input, label) {
startTimestamp = null;
const start = label.offsetLeft;
input.style.color = 'transparent';
label.style.position = 'absolute';
setTimeout(() => {
animateLabel(label, start, 2);
setTimeout(() => input.style.color = null, 300);
}, 10);
}
export function pushCenter(input, label) {
startTimestamp = null;
label.style.position = 'relative';
const end = label.offsetLeft;
label.style.position = 'absolute';
setTimeout(() => {
animateLabel(label, 2, end)
.then(() => label.style.position = 'relative');
}, 10);
}
================================================
FILE: src/TextArea/macOs/focusRingAnimation.js
================================================
import { keyframes } from 'radium';
export default function (borderRadius) {
return keyframes(
{
'0%': {
opacity: '0',
borderWidth: '34px',
top: '-34px',
left: '-34px'
},
'32%': {
opacity: '0',
borderRadius: '10px',
borderWidth: '30px',
top: '-30px',
left: '-30px'
},
'50%': {
opacity: '.2',
borderWidth: '15px',
top: '-15px',
left: '-15px'
},
'80%': {
opacity: '.4',
borderWidth: '9px',
top: '-9px',
left: '-9px'
},
'90%': {
opacity: '.9',
borderWidth: '6px',
top: '-6px',
left: '-6px'
},
'100%': {
opacity: '1',
...(
borderRadius ? {
top: '-2px',
left: '-2px',
borderRadius: (parseInt(borderRadius) + 2) + 'px',
borderWidth: '2px',
boxShadow: '0 0 1px 0px rgba(125, 195, 242, .7)'
} : {
top: '-3px',
left: '-3px',
borderRadius: '4px',
borderWidth: '3px'
}
)
}
},
'text-input-focus'
);
}
================================================
FILE: src/TextArea/macOs/index.js
================================================
import React, { Component, cloneElement } from 'react';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
import Radium, { StyleRoot } from 'radium';
import styles from './styles/10.11';
import Text from '../../Text/macOs';
import Label from '../../Label/macOs';
import Hidden, { hiddenPropTypes, removeHiddenProps } from '../../style/hidden';
import Margin, { marginPropTypes, removeMarginProps } from '../../style/margin';
import Dimension, {
dimensionPropTypes,
removeDimensionProps
} from '../../style/dimension';
import FontSize, {
fontSizePropTypes,
removeFontSizeProps
} from '../../style/fontSize';
import PlaceholderStyle from '../../placeholderStyle';
import mapStyles from '../../utils/mapStyles';
import { parseDimension } from '../../styleHelper';
import focusRingAnimation from './focusRingAnimation';
import { pullLeft, pushCenter } from './centerPlaceholderAnimation';
import ValueRef from '../../ValueRef';
@ValueRef()
@Hidden()
@Dimension()
@Radium
class TextAreaOSX extends Component {
static propTypes = {
...hiddenPropTypes,
...marginPropTypes,
...dimensionPropTypes,
...fontSizePropTypes,
label: PropTypes.string,
rounded: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.number,
PropTypes.string
]),
rows: PropTypes.number,
cols: PropTypes.number,
focusRing: PropTypes.bool,
onEnter: PropTypes.func,
centerPlaceholder: PropTypes.bool,
icon: PropTypes.oneOfType([PropTypes.element, PropTypes.array]),
placeholder: PropTypes.string
};
static defaultProps = {
focusRing: true
};
static mapStyles = {
container: ['margin', 'width', 'height', 'display']
};
static contextTypes = {
titlebarChild: PropTypes.bool
};
constructor() {
super();
this.state = {
isFocused: false,
showPlaceholder: true,
iconPadding: null
};
}
componentDidMount() {
const el = ReactDOM.findDOMNode(this).getElementsByTagName('TEXTAREA')[0];
el.addEventListener('blur', this.handleBlur);
el.addEventListener('focus', this.handleFocus);
el.addEventListener('keypress', this.handleKeypress);
el.addEventListener('keydown', this.handleKeydown);
el.addEventListener('keyup', this.handleChange);
el.addEventListener('change', this.handleChange);
if (this.props.icon) {
setTimeout(() =>
this.setState({
iconPadding: ReactDOM.findDOMNode(
this.refs.icon
).getBoundingClientRect().width
})
);
}
}
componentWillUnmount() {
const el = ReactDOM.findDOMNode(this).getElementsByTagName('TEXTAREA')[0];
el.removeEventListener('blur', this.handleBlur);
el.removeEventListener('focus', this.handleFocus);
el.removeEventListener('keypress', this.handleKeypress);
el.removeEventListener('keydown', this.handleKeydown);
el.removeEventListener('keyup', this.handleChange);
el.removeEventListener('change', this.handleChange);
}
handleKeydown = e => {
if (e.keyCode === 8 && e.target.value.length === 1) {
this.setState({ showPlaceholder: true });
}
};
handleKeypress = e => {
const noEffect = [0, 13];
if (e.which === 13 && this.props.onEnter) {
this.props.onEnter(e);
}
if (!e.which || noEffect.indexOf(e.which) !== -1) return null;
if (String.fromCharCode(e.which)) {
if (this.state.showPlaceholder) {
this.setState({ showPlaceholder: false });
}
}
};
handleChange = e => {
if (e.target.value && this.state.showPlaceholder) {
this.setState({ showPlaceholder: false });
} else if (!e.target.value && !this.state.showPlaceholder) {
this.setState({ showPlaceholder: true });
}
};
handleBlur = e => {
if (this.props.centerPlaceholder) {
if (!e.target.value) {
pushCenter(e.target, ReactDOM.findDOMNode(this.refs.label));
}
}
this.setState({ isFocused: false });
};
handleFocus = e => {
if (this.props.centerPlaceholder) {
if (!e.target.value) {
pullLeft(e.target, ReactDOM.findDOMNode(this.refs.label));
}
}
setTimeout(() => this.setState({ isFocused: true }));
};
/**
* Remove the focus programmatically
* @public
* */
blur() {
const inputEl = ReactDOM.findDOMNode(this.refs.element);
inputEl.blur();
}
/**
* Focus the input programmatically
* @public
*/
focus() {
const inputEl = ReactDOM.findDOMNode(this.refs.element);
inputEl.focus();
}
render() {
let {
style,
label,
size,
rounded,
focusRing,
placeholder,
centerPlaceholder,
icon,
...props
} = this.props;
delete props.onEnter;
let [inputStyle, containerStyle] = mapStyles(style, TextAreaOSX.mapStyles);
let componentStyle = { ...styles.textField };
if (rounded) rounded = rounded === true ? '4px' : parseDimension(rounded);
let focusElement;
if (this.state.isFocused && focusRing) {
componentStyle = {
...componentStyle,
...(rounded ? styles.textFieldRoundedFocus : styles.textFieldFocus)
};
let focusElementStyle = {
...styles.focusElement,
animation: 'x .25s linear forwards',
animationName: focusRingAnimation(rounded)
};
focusElement =
;
}
let labelComponent = label ? (
{label}
) : null;
props = removeFontSizeProps(
removeDimensionProps(removeMarginProps(removeHiddenProps(props)))
);
if (rounded) {
componentStyle.borderRadius = parseDimension(rounded);
}
if (size && parseInt(size) !== 13) {
const ratio = size / 13;
componentStyle.lineHeight = parseDimension(size * 1.4);
componentStyle.paddingLeft = parseDimension(3.5 * ratio);
componentStyle.paddingRight = parseDimension(3.5 * ratio);
}
let input = FontSize(
,
this.props
);
if (this.state.iconPadding) {
inputStyle.paddingLeft = parseDimension(this.state.iconPadding + 12);
}
if (this.context.titlebarChild) {
inputStyle = { ...inputStyle, ...styles.titleBarTextArea };
if (this.state.isFocused && focusRing) {
inputStyle = { ...inputStyle, ...styles.titleBarTextAreaFocus };
}
}
input = cloneElement(input, {
...input.props,
style: { ...input.props.style, ...inputStyle }
});
let placeholderElement;
if (centerPlaceholder) {
placeholderElement = (
{icon}
{this.state.showPlaceholder ? (
{placeholder}
) : null}
);
} else if (placeholder) {
input = (
{cloneElement(input, {
...input.props,
style: { ...input.props.style, ...inputStyle },
placeholder
})}
);
}
return Margin(
{labelComponent}
{focusElement}
{placeholderElement}
{input}
,
this.props
);
}
}
export default TextAreaOSX;
================================================
FILE: src/TextArea/macOs/styles/10.11.js
================================================
export default {
container: {
position: 'relative',
zIndex: '2'
},
containerFocus: {
zIndex: '3'
},
wrapper: {
position: 'relative'
},
textField: {
position: 'relative',
zIndex: '2',
WebkitUserSelect: 'none',
userSelect: 'none',
borderWidth: '2px',
borderStyle: 'solid',
borderTopColor: '#bebfbf',
borderLeftColor: '#bebfbf',
borderRightColor: '#bebfbf',
borderBottomColor: '#bebfbf',
borderBottomWidth: '0',
boxShadow: 'inset 0 0 0 0 #f0f0f0',
paddingTop: '4px',
paddingBottom: '0px',
paddingLeft: '3.5px',
paddingRight: '3.5px',
lineHeight: '15px',
fontFamily: '-apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif',
fontSize: '13px',
letterSpacing: '0.4px',
width: '100%',
boxSizing: 'border-box',
outline: 'none',
':placeholder': {
color: '#c0c0c0'
}
},
textFieldFocus: {
borderTopColor: '#64abda',
borderLeftColor: '#64abda',
borderRightColor: '#64abda',
borderBottomColor: '#64abda',
transition: 'border-color .22s ease-out'
},
textFieldRoundedFocus: {
borderTopColor: '#64abda',
borderLeftColor: '#64abda',
borderRightColor: '#64abda',
borderBottomColor: '#64abda',
boxShadow: 'inset 0 0 0 0 rgba(125, 195, 242, .7)',
transition: 'all .22s ease-out'
},
titleBarTextArea: {
backgroundImage: '-webkit-linear-gradient(top, #ffffff 0%, #f1f1f1 100%)',
boxShadow: 'none',
borderTopColor: '#d0d0d0',
borderLeftColor: '#cacaca',
borderRightColor: '#cacaca',
borderBottomColor: '#afafaf'
},
titleBarTextAreaFocus: {
borderTopColor: '#6daed9',
borderLeftColor: '#70aed4',
borderRightColor: '#70aed4',
borderBottomColor: '#6199bc'
},
focusElement: {
position: 'absolute',
zIndex: '1',
width: '100%',
height: '100%',
top: '-2px',
left: '-3px',
background: '#7dc3f2',
border: '3px solid #7dc3f2',
opacity: '0',
borderRadius: '4px'
},
label: {
position: 'absolute',
zIndex: '4',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
width: '100%',
height: '100%',
paddingRight: '18px',
boxSizing: 'border-box',
pointerEvents: 'none'
},
icon: {
marginLeft: '6px',
marginRight: '6px',
paddingTop: '2px'
},
labelContent: {
display: 'flex',
alignItems: 'center',
paddingTop: '2px'
}
};
================================================
FILE: src/TextArea/windows/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
import Text from '../../Text/windows';
import Hidden, { hiddenPropTypes } from '../../style/hidden';
import Dimension, { dimensionPropTypes } from '../../style/dimension';
import Margin, { marginPropTypes } from '../../style/margin';
import ValueRef from '../../ValueRef';
import Background, {
backgroundPropTypes,
removeBackgroundProps
} from '../../style/background/windows';
import {
ThemeContext,
themePropTypes,
themeContextTypes
} from '../../style/theme/windows';
import { ColorContext, colorContextTypes } from '../../style/color/windows';
import styles from './styles/windows10';
import PlaceholderStyle from '../../placeholderStyle';
import Radium from 'radium';
@ValueRef()
@Hidden()
@Dimension()
@Margin()
@ColorContext()
@ThemeContext()
@Radium
class TextArea extends Component {
static propTypes = {
...themePropTypes,
...hiddenPropTypes,
...dimensionPropTypes,
...marginPropTypes,
...backgroundPropTypes,
label: PropTypes.string,
labelColor: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
labelStyle: PropTypes.object
};
static contextTypes = {
...themeContextTypes,
...colorContextTypes
};
get placeholderStyle() {
return this.context.theme === 'dark'
? styles[':placeholderDarkTheme']
: styles[':placeholder'];
}
/**
* Remove the focus programmatically
* @public
* */
blur() {
const inputEl = ReactDOM.findDOMNode(this.refs.element);
inputEl.blur();
}
/**
* Focus the input programmatically
* @public
*/
focus() {
const inputEl = ReactDOM.findDOMNode(this.refs.element);
inputEl.focus();
}
render() {
let {
label,
labelColor,
labelStyle,
style,
...props
} = this.props;
let componentStyle = { ...styles.textBox, ...style };
if (this.context.theme === 'dark') {
labelStyle = { ...styles.labalDarkTheme, ...labelStyle };
componentStyle = { ...componentStyle, ...styles.textBoxDarkTheme };
}
labelColor =
labelColor === true
? this.context.color
: labelColor
? labelColor
: this.context.theme === 'dark' ? '#FFFFFF' : null;
if (labelColor) labelStyle = { color: labelColor, ...labelStyle };
componentStyle[':focus'] = {
...componentStyle[':focus'],
borderColor: this.context.color
};
props = removeBackgroundProps(props);
const input = (
{Background(
,
this.props
)}
);
if (label) {
return (
{label}
{input}
);
}
return input;
}
}
export default TextArea;
================================================
FILE: src/TextArea/windows/styles/windows10.js
================================================
export default {
textBox: {
WebkitUserSelect: 'none',
userSelect: 'none',
borderWidth: '2px',
borderStyle: 'solid',
borderColor: 'rgba(148, 148, 148, 1)',
padding: '2px 10px 3px 10px',
lineHeight: '23px',
fontFamily: '"Segoe UI", Frutiger, "Frutiger Linotype", "Dejavu Sans", "Helvetica Neue", Arial, sans-serif',
fontSize: '15px',
fontWeight: '100',
color: '#000000',
marginBottom: '-4px',
background: 'rgba(255, 255, 255, .35)',
':hover': {
borderColor: 'rgba(100, 100, 100, 1)',
background: 'rgba(255, 255, 255, .5)'
},
':focus': {
outline: 'none',
borderColor: 'rgba(0, 120, 215, 1)',
background: 'rgba(255, 255, 255, 1)'
}
},
textBoxDarkTheme: {
borderColor: 'rgba(255, 255, 255, .41)',
background: 'rgba(0, 0, 0, .4)',
color: '#ffffff',
':hover': {
borderColor: 'rgba(255, 255, 255, .94)',
background: 'rgba(0, 0, 0, .6)'
},
':focus': {
outline: 'none',
borderColor: 'rgba(0, 120, 215, 1)',
background: 'rgba(255, 255, 255, 1)',
color: '#000000'
}
},
':placeholder': {
color: '#636363'
},
':placeholderDarkTheme': {
color: 'rgba(255, 255, 255, .64)',
':focus': {
color: 'rgba(0, 0, 0, .41)'
}
},
labalDarkTheme: {
}
};
================================================
FILE: src/TextInput/macOs/centerPlaceholderAnimation.js
================================================
import BezierEasing from '../../animation/bezierEasing';
let requestAnimationFrame;
if (typeof window !== 'undefined') {
requestAnimationFrame = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame;
}
let startTimestamp;
const duration = 350;
const easing = BezierEasing(.3,.14,0,1);
function moveLabel(timestamp, label, start, current, end, cb) {
if (start === end) return null;
if (!startTimestamp) startTimestamp = timestamp;
let progress = 1 - (timestamp - startTimestamp) / duration;
if (progress < 0) progress = 0;
progress = 1 - (easing.get(1 - progress));
if (start > end) {
current = progress * start;
} else {
current = (1 - progress) * end + start;
}
label.style.left = current + 'px';
if (start > end && current > end || start < end && current < end) {
requestAnimationFrame(timestamp => moveLabel(timestamp, label, start, current, end));
} else {
label.style.left = end + 'px';
if (cb) cb();
}
}
function animateLabel(label, start, end) {
return new Promise(resolve => {
if (requestAnimationFrame) {
requestAnimationFrame(timestamp => moveLabel(timestamp, label, start, start, end, resolve));
}
});
}
export function pullLeft(input, label) {
startTimestamp = null;
const start = label.offsetLeft;
input.style.color = 'transparent';
label.style.position = 'absolute';
setTimeout(() => {
animateLabel(label, start, 2);
setTimeout(() => input.style.color = null, 300);
}, 10);
}
export function pushCenter(input, label) {
startTimestamp = null;
label.style.position = 'relative';
const end = label.offsetLeft;
label.style.position = 'absolute';
setTimeout(() => {
animateLabel(label, 2, end)
.then(() => label.style.position = 'relative');
}, 10);
}
================================================
FILE: src/TextInput/macOs/focusRingAnimation.js
================================================
import { keyframes } from 'radium';
export default function (borderRadius) {
return keyframes(
{
'0%': {
opacity: '0',
borderWidth: '34px',
top: '-34px',
left: '-34px'
},
'32%': {
opacity: '0',
borderRadius: '10px',
borderWidth: '30px',
top: '-30px',
left: '-30px'
},
'50%': {
opacity: '.2',
borderWidth: '15px',
top: '-15px',
left: '-15px'
},
'80%': {
opacity: '.4',
borderWidth: '9px',
top: '-9px',
left: '-9px'
},
'90%': {
opacity: '.9',
borderWidth: '6px',
top: '-6px',
left: '-6px'
},
'100%': {
opacity: '1',
...(
borderRadius ? {
top: '-2px',
left: '-2px',
borderRadius: (parseInt(borderRadius) + 2) + 'px',
borderWidth: '2px',
boxShadow: '0 0 1px 0px rgba(125, 195, 242, .7)'
} : {
top: '-3px',
left: '-3px',
borderRadius: '4px',
borderWidth: '3px'
}
)
}
},
'text-input-focus'
);
}
================================================
FILE: src/TextInput/macOs/index.js
================================================
import React, { Component, cloneElement } from 'react';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
import Radium, { StyleRoot } from 'radium';
import styles from './styles/10.11';
import Text from '../../Text/macOs';
import Label from '../../Label/macOs';
import Hidden, { hiddenPropTypes, removeHiddenProps } from '../../style/hidden';
import Margin, { marginPropTypes, removeMarginProps } from '../../style/margin';
import Dimension, {
dimensionPropTypes,
removeDimensionProps
} from '../../style/dimension';
import FontSize, {
fontSizePropTypes,
removeFontSizeProps
} from '../../style/fontSize';
import PlaceholderStyle from '../../placeholderStyle';
import mapStyles from '../../utils/mapStyles';
import { parseDimension } from '../../styleHelper';
import focusRingAnimation from './focusRingAnimation';
import { pullLeft, pushCenter } from './centerPlaceholderAnimation';
import ValueRef from '../../ValueRef';
@ValueRef()
@Hidden()
@Dimension()
@Radium
class TextFieldOSX extends Component {
static propTypes = {
...hiddenPropTypes,
...marginPropTypes,
...dimensionPropTypes,
...fontSizePropTypes,
label: PropTypes.string,
rounded: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.number,
PropTypes.string
]),
focusRing: PropTypes.bool,
onEnter: PropTypes.func,
centerPlaceholder: PropTypes.bool,
icon: PropTypes.oneOfType([PropTypes.element, PropTypes.array]),
placeholder: PropTypes.string,
password: PropTypes.bool
};
static defaultProps = {
focusRing: true
};
static mapStyles = {
container: ['margin', 'width', 'height', 'display']
};
static contextTypes = {
titlebarChild: PropTypes.bool
};
constructor() {
super();
this.state = {
isFocused: false,
showPlaceholder: true,
iconPadding: null
};
}
componentDidMount() {
const el = ReactDOM.findDOMNode(this).getElementsByTagName('INPUT')[0];
el.addEventListener('blur', this.handleBlur);
el.addEventListener('focus', this.handleFocus);
el.addEventListener('keypress', this.handleKeypress);
el.addEventListener('keydown', this.handleKeydown);
el.addEventListener('keyup', this.handleChange);
el.addEventListener('change', this.handleChange);
if (this.props.icon) {
setTimeout(() =>
this.setState({
iconPadding: ReactDOM.findDOMNode(
this.refs.icon
).getBoundingClientRect().width
})
);
}
}
componentWillUnmount() {
const el = ReactDOM.findDOMNode(this).getElementsByTagName('INPUT')[0];
el.removeEventListener('blur', this.handleBlur);
el.removeEventListener('focus', this.handleFocus);
el.removeEventListener('keypress', this.handleKeypress);
el.removeEventListener('keydown', this.handleKeydown);
el.removeEventListener('keyup', this.handleChange);
el.removeEventListener('change', this.handleChange);
}
handleKeydown = e => {
if (e.keyCode === 8 && e.target.value.length === 1) {
this.setState({ showPlaceholder: true });
}
};
handleKeypress = e => {
const noEffect = [0, 13];
if (e.which === 13 && this.props.onEnter) {
this.props.onEnter(e);
}
if (!e.which || noEffect.indexOf(e.which) !== -1) return null;
if (String.fromCharCode(e.which)) {
if (this.state.showPlaceholder) {
this.setState({ showPlaceholder: false });
}
}
};
handleChange = e => {
if (e.target.value && this.state.showPlaceholder) {
this.setState({ showPlaceholder: false });
} else if (!e.target.value && !this.state.showPlaceholder) {
this.setState({ showPlaceholder: true });
}
};
handleBlur = e => {
if (this.props.centerPlaceholder) {
if (!e.target.value) {
pushCenter(e.target, ReactDOM.findDOMNode(this.refs.label));
}
}
this.setState({ isFocused: false });
};
handleFocus = e => {
if (this.props.centerPlaceholder) {
if (!e.target.value) {
pullLeft(e.target, ReactDOM.findDOMNode(this.refs.label));
}
}
setTimeout(() => this.setState({ isFocused: true }));
};
/**
* Remove the focus programmatically
* @public
* */
blur() {
const inputEl = ReactDOM.findDOMNode(this.refs.element);
inputEl.blur();
}
/**
* Focus the input programmatically
* @public
*/
focus() {
const inputEl = ReactDOM.findDOMNode(this.refs.element);
inputEl.focus();
}
render() {
let {
style,
label,
size,
rounded,
focusRing,
placeholder,
centerPlaceholder,
icon,
password,
...props
} = this.props;
delete props.onEnter;
let [inputStyle, containerStyle] = mapStyles(style, TextFieldOSX.mapStyles);
let componentStyle = { ...styles.textField };
if (rounded) rounded = rounded === true ? '4px' : parseDimension(rounded);
let focusElement;
if (this.state.isFocused && focusRing) {
componentStyle = {
...componentStyle,
...(rounded ? styles.textFieldRoundedFocus : styles.textFieldFocus)
};
let focusElementStyle = {
...styles.focusElement,
animation: 'x .25s linear forwards',
animationName: focusRingAnimation(rounded)
};
focusElement =
;
}
let labelComponent = label ? (
{label}
) : null;
props = removeFontSizeProps(
removeDimensionProps(removeMarginProps(removeHiddenProps(props)))
);
if (rounded) {
componentStyle.borderRadius = parseDimension(rounded);
}
if (size && parseInt(size) !== 13) {
const ratio = size / 13;
componentStyle.lineHeight = parseDimension(size * 1.4);
componentStyle.paddingLeft = parseDimension(3.5 * ratio);
componentStyle.paddingRight = parseDimension(3.5 * ratio);
}
let input = FontSize(
,
this.props
);
if (this.state.iconPadding) {
inputStyle.paddingLeft = parseDimension(this.state.iconPadding + 12);
}
if (this.context.titlebarChild) {
inputStyle = { ...inputStyle, ...styles.titleBarTextField };
if (this.state.isFocused && focusRing) {
inputStyle = { ...inputStyle, ...styles.titleBarTextFieldFocus };
}
}
input = cloneElement(input, {
...input.props,
style: { ...input.props.style, ...inputStyle }
});
let placeholderElement;
if (centerPlaceholder) {
placeholderElement = (
{icon}
{this.state.showPlaceholder ? (
{placeholder}
) : null}
);
} else if (placeholder) {
input = (
{cloneElement(input, {
...input.props,
style: { ...input.props.style, ...inputStyle },
placeholder
})}
);
}
return Margin(
{labelComponent}
{focusElement}
{placeholderElement}
{input}
,
this.props
);
}
}
export default TextFieldOSX;
================================================
FILE: src/TextInput/macOs/styles/10.11.js
================================================
export default {
container: {
position: 'relative',
zIndex: '2'
},
containerFocus: {
zIndex: '3'
},
wrapper: {
position: 'relative'
},
textField: {
position: 'relative',
zIndex: '2',
WebkitUserSelect: 'none',
userSelect: 'none',
borderWidth: '1px',
borderStyle: 'solid',
borderTopColor: '#bebfbf',
borderLeftColor: '#bebfbf',
borderRightColor: '#bebfbf',
borderBottomColor: '#bebfbf',
boxShadow: 'inset 0 0 0 1px #f0f0f0',
paddingTop: '4px',
paddingBottom: '3px',
paddingLeft: '3.5px',
paddingRight: '3.5px',
lineHeight: '15px',
fontFamily: '-apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif',
fontSize: '13px',
letterSpacing: '0.4px',
width: '100%',
boxSizing: 'border-box',
outline: 'none',
':placeholder': {
color: '#c0c0c0'
}
},
textFieldFocus: {
borderTopColor: '#64abda',
borderLeftColor: '#64abda',
borderRightColor: '#64abda',
borderBottomColor: '#64abda',
transition: 'border-color .22s ease-out'
},
textFieldRoundedFocus: {
borderTopColor: '#64abda',
borderLeftColor: '#64abda',
borderRightColor: '#64abda',
borderBottomColor: '#64abda',
boxShadow: 'inset 0 0 0 1px rgba(125, 195, 242, .7)',
transition: 'all .22s ease-out'
},
titleBarTextField: {
backgroundImage: '-webkit-linear-gradient(top, #ffffff 0%, #f1f1f1 100%)',
boxShadow: 'none',
borderTopColor: '#d0d0d0',
borderLeftColor: '#cacaca',
borderRightColor: '#cacaca',
borderBottomColor: '#afafaf'
},
titleBarTextFieldFocus: {
borderTopColor: '#6daed9',
borderLeftColor: '#70aed4',
borderRightColor: '#70aed4',
borderBottomColor: '#6199bc'
},
focusElement: {
position: 'absolute',
zIndex: '1',
width: '100%',
height: '100%',
top: '-3px',
left: '-3px',
background: '#7dc3f2',
border: '3px solid #7dc3f2',
opacity: '0',
borderRadius: '4px'
},
label: {
position: 'absolute',
zIndex: '4',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
width: '100%',
height: '100%',
paddingRight: '18px',
boxSizing: 'border-box',
pointerEvents: 'none'
},
icon: {
marginLeft: '6px',
marginRight: '6px',
paddingTop: '2px'
},
labelContent: {
display: 'flex',
alignItems: 'center',
paddingTop: '2px'
}
};
================================================
FILE: src/TextInput/windows/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
import Text from '../../Text/windows';
import Hidden, { hiddenPropTypes } from '../../style/hidden';
import Dimension, { dimensionPropTypes } from '../../style/dimension';
import Margin, { marginPropTypes } from '../../style/margin';
import ValueRef from '../../ValueRef';
import Background, {
backgroundPropTypes,
removeBackgroundProps
} from '../../style/background/windows';
import {
ThemeContext,
themePropTypes,
themeContextTypes
} from '../../style/theme/windows';
import { ColorContext, colorContextTypes } from '../../style/color/windows';
import styles from './styles/windows10';
import PlaceholderStyle from '../../placeholderStyle';
import Radium from 'radium';
@ValueRef()
@Hidden()
@Dimension()
@Margin()
@ColorContext()
@ThemeContext()
@Radium
class TextInput extends Component {
static propTypes = {
...themePropTypes,
...hiddenPropTypes,
...dimensionPropTypes,
...marginPropTypes,
...backgroundPropTypes,
label: PropTypes.string,
labelColor: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
labelStyle: PropTypes.object,
password: PropTypes.bool
};
static contextTypes = {
...themeContextTypes,
...colorContextTypes
};
get placeholderStyle() {
return this.context.theme === 'dark'
? styles[':placeholderDarkTheme']
: styles[':placeholder'];
}
/**
* Remove the focus programmatically
* @public
* */
blur() {
const inputEl = ReactDOM.findDOMNode(this.refs.element);
inputEl.blur();
}
/**
* Focus the input programmatically
* @public
*/
focus() {
const inputEl = ReactDOM.findDOMNode(this.refs.element);
inputEl.focus();
}
render() {
let {
label,
labelColor,
labelStyle,
style,
password,
...props
} = this.props;
let componentStyle = { ...styles.textBox, ...style };
if (this.context.theme === 'dark') {
labelStyle = { ...styles.labalDarkTheme, ...labelStyle };
componentStyle = { ...componentStyle, ...styles.textBoxDarkTheme };
}
labelColor =
labelColor === true
? this.context.color
: labelColor
? labelColor
: this.context.theme === 'dark' ? '#FFFFFF' : null;
if (labelColor) labelStyle = { color: labelColor, ...labelStyle };
componentStyle[':focus'] = {
...componentStyle[':focus'],
borderColor: this.context.color
};
props = removeBackgroundProps(props);
const input = (
{Background(
,
this.props
)}
);
if (label) {
return (
{label}
{input}
);
}
return input;
}
}
export default TextInput;
================================================
FILE: src/TextInput/windows/styles/windows10.js
================================================
export default {
textBox: {
WebkitUserSelect: 'none',
userSelect: 'none',
borderWidth: '2px',
borderStyle: 'solid',
borderColor: 'rgba(148, 148, 148, 1)',
padding: '2px 10px 3px 10px',
lineHeight: '23px',
fontFamily: '"Segoe UI", Frutiger, "Frutiger Linotype", "Dejavu Sans", "Helvetica Neue", Arial, sans-serif',
fontSize: '15px',
fontWeight: '100',
color: '#000000',
marginBottom: '18px',
background: 'rgba(255, 255, 255, .35)',
':hover': {
borderColor: 'rgba(100, 100, 100, 1)',
background: 'rgba(255, 255, 255, .5)'
},
':focus': {
outline: 'none',
borderColor: 'rgba(0, 120, 215, 1)',
background: 'rgba(255, 255, 255, 1)'
}
},
textBoxDarkTheme: {
borderColor: 'rgba(255, 255, 255, .41)',
background: 'rgba(0, 0, 0, .4)',
color: '#ffffff',
':hover': {
borderColor: 'rgba(255, 255, 255, .94)',
background: 'rgba(0, 0, 0, .6)'
},
':focus': {
outline: 'none',
borderColor: 'rgba(0, 120, 215, 1)',
background: 'rgba(255, 255, 255, 1)',
color: '#000000'
}
},
':placeholder': {
color: '#636363'
},
':placeholderDarkTheme': {
color: 'rgba(255, 255, 255, .64)',
':focus': {
color: 'rgba(0, 0, 0, .41)'
}
},
labalDarkTheme: {
}
};
================================================
FILE: src/TitleBar/macOs/Controls/Close.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import WindowFocus from '../../../windowFocus';
import styles from './styles/10.11';
import Radium from 'radium';
@WindowFocus()
@Radium
class Close extends Component {
static propTypes = {
style: PropTypes.object,
showIcon: PropTypes.bool,
disabled: PropTypes.bool
};
render() {
const { style, isWindowFocused, showIcon, disabled, ...props } = this.props;
delete props.isFullscreen;
const iconStyle = {
...styles.close.icon,
opacity: showIcon && !disabled ? 1 : 0
};
let componentStyle = { ...styles.close.button, ...style };
if (!isWindowFocused && !showIcon) {
componentStyle = { ...componentStyle, ...styles.close.unfocused };
}
if (disabled) {
componentStyle = { ...componentStyle, ...styles.close.disabled };
}
return (
{window && window.devicePixelRatio > 1.5 ? (
) : (
)}
);
}
}
export default Close;
================================================
FILE: src/TitleBar/macOs/Controls/Minimize.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import WindowFocus from '../../../windowFocus';
import styles from './styles/10.11';
import Radium from 'radium';
@WindowFocus()
@Radium
class Minimize extends Component {
static propTypes = {
style: PropTypes.object,
showIcon: PropTypes.bool,
disabled: PropTypes.bool
};
render() {
const { style, isWindowFocused, showIcon, disabled, ...props } = this.props;
delete props.isFullscreen;
const iconStyle = {
...styles.minimize.icon,
opacity: showIcon && !disabled ? 1 : 0
};
let componentStyle = { ...styles.minimize.button, ...style };
if (!isWindowFocused && !showIcon) {
componentStyle = { ...componentStyle, ...styles.minimize.unfocused };
}
if (disabled) {
componentStyle = { ...componentStyle, ...styles.minimize.disabled };
}
return (
{window && window.devicePixelRatio > 1.5 ? (
) : (
)}
);
}
}
export default Minimize;
================================================
FILE: src/TitleBar/macOs/Controls/Resize.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import WindowFocus from '../../../windowFocus';
import styles from './styles/10.11';
import Radium from 'radium';
@WindowFocus()
@Radium
class Resize extends Component {
static propTypes = {
isFullscreen: PropTypes.bool,
showIcon: PropTypes.bool,
disabled: PropTypes.bool,
disableFullscreen: PropTypes.bool,
};
componentDidMount() {
document.addEventListener('keydown', this.handleKeydown);
document.addEventListener('keyup', this.handleKeyup);
}
handleKeydown = e => {
if (e.altKey) this.setState({ altKey: true });
};
handleKeyup = () => {
if (this.state.altKey) this.setState({ altKey: false });
};
render() {
let {
style,
onClick,
onMaximizeClick,
isWindowFocused,
showIcon,
disabled,
disableFullscreen,
...props
} = this.props;
delete props.isFullscreen;
let iconStyle = {
...styles.resize.icon,
opacity: showIcon && !disabled ? 1 : 0
};
let componentStyle = { ...styles.resize.button, ...style };
if (!isWindowFocused && !showIcon) {
componentStyle = { ...componentStyle, ...styles.resize.unfocused };
}
if (disabled) {
componentStyle = { ...componentStyle, ...styles.resize.disabled };
}
let icon;
if (this.props.isFullscreen && !disableFullscreen) {
icon = window && window.devicePixelRatio > 1.5 ? (
) : (
);
} else if (this.state.altKey || disableFullscreen) {
onClick = onMaximizeClick;
icon = window && window.devicePixelRatio > 1.5 ? (
) : (
);
} else {
icon = window && window.devicePixelRatio > 1.5 ? (
) : (
);
}
return (
{icon}
);
}
}
export default Resize;
================================================
FILE: src/TitleBar/macOs/Controls/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Close from './Close';
import Minimize from './Minimize';
import Resize from './Resize';
var styles = {
controls: {
WebkitUserSelect: 'none',
userSelect: 'none',
cursor: 'default',
display: 'flex',
width: '61px'
},
inset: {
marginLeft: '5px'
}
};
class Controls extends Component {
static propTypes = {
inset: PropTypes.bool,
isFullscreen: PropTypes.bool,
onCloseClick: PropTypes.func,
onMinimizeClick: PropTypes.func,
onMaximizeClick: PropTypes.func,
onResizeClick: PropTypes.func,
disableClose: PropTypes.bool,
disableMinimize: PropTypes.bool,
disableResize: PropTypes.bool,
disableFullscreen: PropTypes.bool
};
constructor() {
super();
this.state = {
isOver: false
};
}
render() {
return (
this.setState({ isOver: true })}
onMouseLeave={() => this.setState({ isOver: false })}
>
);
}
}
export default Controls;
================================================
FILE: src/TitleBar/macOs/Controls/styles/10.11.js
================================================
export default {
close: {
button: {
WebkitUserSelect: 'none',
userSelect: 'none',
WebkitAppRegion: 'no-drag',
cursor: 'default',
boxSizing: 'border-box',
width: '12px',
height: '12px',
borderWidth: '1px',
borderStyle: 'solid',
borderRadius: '50%',
marginTop: '1px',
marginLeft: '5px',
marginRight: '4px',
lineHeight: 0,
backgroundColor: '#ff5f57',
borderColor: '#e2463f',
':active': {
backgroundColor: '#bf4943',
borderColor: '#ad3934'
}
},
unfocused: {
backgroundColor: '#dddddd',
borderColor: '#d0d0d0',
},
disabled: {
backgroundColor: '#dddddd',
borderColor: '#d0d0d0',
':active': {
backgroundColor: '#dddddd',
borderColor: '#d0d0d0'
}
},
icon: {
width: '10px',
height: '10px'
}
},
minimize: {
button: {
WebkitUserSelect: 'none',
userSelect: 'none',
WebkitAppRegion: 'no-drag',
cursor: 'default',
boxSizing: 'border-box',
width: '12px',
height: '12px',
borderWidth: '1px',
borderStyle: 'solid',
borderRadius: '50%',
marginTop: '1px',
marginLeft: '4px',
marginRight: '4px',
lineHeight: 0,
backgroundColor: '#ffbd2e',
borderColor: '#e1a116',
':active': {
backgroundColor: '#bf9123',
borderColor: '#ad7d15'
}
},
unfocused: {
backgroundColor: '#dddddd',
borderColor: '#d0d0d0',
},
disabled: {
backgroundColor: '#dddddd',
borderColor: '#d0d0d0',
':active': {
backgroundColor: '#dddddd',
borderColor: '#d0d0d0'
}
},
icon: {
width: '10px',
height: '10px'
}
},
resize: {
button: {
WebkitUserSelect: 'none',
userSelect: 'none',
WebkitAppRegion: 'no-drag',
cursor: 'default',
width: '12px',
height: '12px',
boxSizing: 'border-box',
borderWidth: '1px',
borderStyle: 'solid',
borderRadius: '50%',
marginTop: '1px',
marginLeft: '4px',
marginRight: '4px',
lineHeight: 0,
backgroundColor: '#28c940',
borderColor: '#12ac28',
':active': {
backgroundColor: '#1f9a31',
borderColor: '#128622'
}
},
unfocused: {
backgroundColor: '#dddddd',
borderColor: '#d0d0d0'
},
disabled: {
backgroundColor: '#dddddd',
borderColor: '#d0d0d0',
':active': {
backgroundColor: '#dddddd',
borderColor: '#d0d0d0'
}
},
icon: {
width: '10px',
height: '10px'
}
}
};
================================================
FILE: src/TitleBar/macOs/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Controls from './Controls';
import styles from './styles/10.11';
import WindowFocus from '../../windowFocus';
import Dimension, { dimensionPropTypes } from '../../style/dimension';
@Dimension({ width: '100%' })
@WindowFocus()
class TitleBar extends Component {
static propTypes = {
...dimensionPropTypes,
title: PropTypes.node,
inset: PropTypes.bool,
controls: PropTypes.bool,
transparent: PropTypes.bool,
isFullscreen: PropTypes.bool,
onCloseClick: PropTypes.func,
onMinimizeClick: PropTypes.func,
onMaximizeClick: PropTypes.func,
onResizeClick: PropTypes.func,
disableClose: PropTypes.bool,
disableMinimize: PropTypes.bool,
disableResize: PropTypes.bool,
disableFullscreen: PropTypes.bool
};
static childContextTypes = {
titlebarChild: PropTypes.bool
};
getChildContext() {
return {
titlebarChild: true
};
}
componentDidMount() {
window.addEventListener('resize', this.resize);
this.resize();
}
componentWillUnmount() {
window.removeEventListener('resize', this.resize);
}
componentDidUpdate() {
this.resize();
}
resize = () => {
if (this.refs.title) {
const barRect = this.refs.element.getBoundingClientRect();
this.refs.title.style.overflow = 'visible';
this.refs.title.style.paddingRight = 0;
this.refs.title.style.flexGrow = 0;
const titleRect = this.refs.title.getBoundingClientRect();
this.refs.title.style.overflow = 'hidden';
this.refs.title.style.flexGrow = 1;
const barWidth = barRect.width - 6;
const contentWidth = titleRect.width + (this.props.controls ? 60 : 0);
let padding = barWidth - contentWidth;
if (padding > 60) padding = 60;
this.refs.title.style.paddingRight = padding + 'px';
}
};
render() {
let {
children,
inset,
controls,
title,
transparent,
isWindowFocused,
style,
...props
} = this.props;
delete props.isFullscreen;
delete props.onCloseClick;
delete props.onMinimizeClick;
delete props.onMaximizeClick;
delete props.onResizeClick;
delete props.disableClose;
delete props.disableMinimize;
delete props.disableResize;
delete props.disableFullscreen;
let componentStyle = { ...styles.titleBar };
let titleStyle = styles.title;
if (inset) {
componentStyle = { ...componentStyle, ...styles.titleBarInset };
}
if (!isWindowFocused) {
componentStyle = { ...componentStyle, ...styles.unfocusedTitleBar };
titleStyle = { ...titleStyle, ...styles.unfocusedTitle };
}
controls = !controls || (
);
title = !title || (
{title}
);
if (transparent) {
delete componentStyle.backgroundImage;
delete componentStyle.borderBottomWidth;
delete componentStyle.borderBottomStyle;
delete componentStyle.borderBottomColor;
delete componentStyle.borderTopWidth;
delete componentStyle.borderTopStyle;
delete componentStyle.borderTopColor;
delete componentStyle.borderTopLeftRadius;
delete componentStyle.borderTopRightRadius;
}
return (
{controls}
{title}
{children}
);
}
}
export default TitleBar;
================================================
FILE: src/TitleBar/macOs/styles/10.11.js
================================================
export default {
titleBar: {
WebkitUserSelect: 'none',
userSelect: 'none',
WebkitAppRegion: 'drag',
cursor: 'default',
width: '100%',
boxSizing: 'border-box',
display: 'flex',
alignItems: 'center',
minHeight: '22px',
backgroundImage:
'-webkit-linear-gradient(top, #ededed 0, #ededed 1px, #e7e7e7 2px, #d1d1d1 100%)',
borderBottomWidth: '1px',
borderBottomStyle: 'solid',
borderBottomColor: '#afafaf',
borderTopWidth: '1px',
borderTopStyle: 'solid',
borderTopColor: '#f6f6f6',
borderTopLeftRadius: '5px',
borderTopRightRadius: '5px',
paddingLeft: '3px',
paddingRight: '3px'
},
titleBarInset: {
paddingTop: '11px',
paddingBottom: '11px',
paddingLeft: '8px',
paddingRight: '8px'
},
unfocusedTitleBar: {
backgroundImage:
'-webkit-linear-gradient(top, #fafafa 0px, #f6f6f6 2px, #f6f6f6 100%)',
borderBottomColor: '#d1d1d1'
},
title: {
WebkitUserSelect: 'none',
userSelect: 'none',
cursor: 'default',
fontFamily:
'-apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif',
fontSize: '13px',
letterSpacing: '0px',
color: '#4d4d4d',
flexGrow: '1',
flexShrink: '1',
textAlign: 'center',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis'
},
unfocusedTitle: {
color: '#d3d3d3'
}
};
================================================
FILE: src/TitleBar/windows/Controls/Close.js
================================================
import React, { Component } from 'react';
import Radium, { getState } from 'radium';
import WindowFocus from '../../../windowFocus';
import { themeContextTypes } from '../../../style/theme/windows';
import { backgroundContextTypes } from '../../../style/background/windows';
import { isDarkColor } from '../../../color';
const styles = {
button: {
WebkitUserSelect: 'none',
userSelect: 'none',
WebkitAppRegion: 'no-drag',
cursor: 'default',
width: '46px',
height: '100%',
lineHeight: 0,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
':hover': {
transition: 'background-color 0.1s',
backgroundColor: '#e81123',
},
':active': {
backgroundColor: '#f1707a',
}
},
icon: {
width: '10px',
height: '10px'
}
};
@WindowFocus()
@Radium
class Close extends Component {
static contextTypes = {
...themeContextTypes,
...backgroundContextTypes
};
render() {
const { style, isWindowFocused, ...props } = this.props;
let svgFill = '#000000';
if (!isWindowFocused && this.context.theme !== 'dark') {
svgFill = 'rgba(0, 0, 0, .4)';
}
let componentStyle = { ...styles.button, ...style };
if (this.context.theme === 'dark' || this.context.background && isDarkColor(this.context.background)) {
svgFill = '#ffffff';
componentStyle = { ...componentStyle, ...styles.buttonColorBackground };
}
if (getState(this.state, null, ':active')) {
svgFill = '#000000';
} else if (getState(this.state, null, ':hover')) {
svgFill = '#ffffff';
}
return (
);
}
}
export default Close;
================================================
FILE: src/TitleBar/windows/Controls/Maximize.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import WindowFocus from '../../../windowFocus';
import { themeContextTypes } from '../../../style/theme/windows';
import { backgroundContextTypes } from '../../../style/background/windows';
import { isDarkColor } from '../../../color';
import Radium from 'radium'
var styles = {
button: {
WebkitUserSelect: 'none',
userSelect: 'none',
WebkitAppRegion: 'no-drag',
cursor: 'default',
width: '46px',
height: '100%',
lineHeight: 0,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
':hover': {
transition: 'background-color 0.1s',
backgroundColor: '#e5e5e5'
},
':active': {
backgroundColor: '#cccccc'
}
},
buttonColorBackground: {
':hover': {
transition: 'background-color 0.1s',
backgroundColor: 'rgba(255, 255, 255, .13)'
},
':active': {
backgroundColor: 'rgba(255, 255, 255, .23)'
}
},
icon: {
width: '10px',
height: '10px'
}
};
@WindowFocus()
@Radium
class Maximize extends Component {
static contextTypes = {
...themeContextTypes,
...backgroundContextTypes,
isMaximized: PropTypes.bool
};
render() {
const { style, isWindowFocused, ...props } = this.props;
delete props.onMaximizeClick;
delete props.onRestoreDownClick;
let svgFill = '#000000';
if (!isWindowFocused && this.context.theme !== 'dark') {
svgFill = 'rgba(0, 0, 0, .4)';
}
let componentStyle = { ...styles.button, ...style };
if (this.context.theme === 'dark' || this.context.background && isDarkColor(this.context.background)) {
svgFill = '#ffffff';
componentStyle = { ...componentStyle, ...styles.buttonColorBackground };
}
let title = 'Maximize';
let icon = (
);
let onClick = this.props.onMaximizeClick;
if (this.context.isMaximized) {
title = 'Restore Down';
icon = (
);
onClick = this.props.onRestoreDownClick;
}
return (
{icon}
);
}
}
export default Maximize;
================================================
FILE: src/TitleBar/windows/Controls/Minimize.js
================================================
import React, { Component } from 'react';
import WindowFocus from '../../../windowFocus';
import { themeContextTypes } from '../../../style/theme/windows';
import { backgroundContextTypes } from '../../../style/background/windows';
import { isDarkColor } from '../../../color';
import Radium from 'radium'
var styles = {
button: {
WebkitUserSelect: 'none',
userSelect: 'none',
WebkitAppRegion: 'no-drag',
appRegion: 'no-drag',
cursor: 'default',
width: '46px',
height: '100%',
lineHeight: 0,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
':hover': {
transition: 'background-color 0.1s',
backgroundColor: '#e5e5e5'
},
':active': {
backgroundColor: '#cccccc'
}
},
buttonColorBackground: {
':hover': {
transition: 'background-color 0.1s',
backgroundColor: 'rgba(255, 255, 255, .13)'
},
':active': {
backgroundColor: 'rgba(255, 255, 255, .23)'
}
},
icon: {
width: '10px',
height: '1px'
}
};
@WindowFocus()
@Radium
class Minimize extends Component {
static contextTypes = {
...themeContextTypes,
...backgroundContextTypes
};
render() {
const { style, isWindowFocused, ...props } = this.props;
let svgFill = '#000000';
if (!isWindowFocused && this.context.theme !== 'dark') {
svgFill = 'rgba(0, 0, 0, .4)';
}
let componentStyle = { ...styles.button, ...style };
if (this.context.theme === 'dark' || this.context.background && isDarkColor(this.context.background)) {
svgFill = '#ffffff';
componentStyle = { ...componentStyle, ...styles.buttonColorBackground };
}
return (
);
}
}
export default Minimize;
================================================
FILE: src/TitleBar/windows/Controls/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Close from './Close';
import Minimize from './Minimize';
import Maximize from './Maximize';
var styles = {
controls: {
WebkitUserSelect: 'none',
userSelect: 'none',
cursor: 'default',
display: 'flex',
height: '32px'
}
};
class Controls extends Component {
static propTypes = {
onCloseClick: PropTypes.func,
onMinimizeClick: PropTypes.func,
onRestoreDownClick: PropTypes.func,
onMaximizeClick: PropTypes.func
};
render() {
return (
);
}
}
export default Controls;
================================================
FILE: src/TitleBar/windows/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Background, {
backgroundPropTypes
} from '../../style/background/windows';
import { hiddenPropTypes } from '../../style/hidden';
import { ColorContext, colorPropTypes } from '../../style/color/windows';
import {
ThemeContext,
themePropTypes,
themeContextTypes
} from '../../style/theme/windows';
import WindowFocus from '../../windowFocus';
import Controls from './Controls';
import styles from './styles/windows10';
@Background((nextProps, prevProps, background) => ({
...nextProps,
hasBackground: background
}))
@WindowFocus()
@ThemeContext()
@ColorContext()
class TitleBar extends Component {
static propTypes = {
...hiddenPropTypes,
...themePropTypes,
...colorPropTypes,
...backgroundPropTypes,
title: PropTypes.node,
controls: PropTypes.bool,
isMaximized: PropTypes.bool,
onCloseClick: PropTypes.func,
onMinimizeClick: PropTypes.func,
onMaximizeClick: PropTypes.func,
onRestoreDownClick: PropTypes.func
};
static childContextTypes = {
isMaximized: PropTypes.bool
};
static contextTypes = {
...themeContextTypes
};
getChildContext() {
return {
isMaximized: this.props.isMaximized
};
}
render() {
const {
children,
style,
controls,
title,
isWindowFocused,
hasBackground,
hidden,
...props
} = this.props;
delete props.isMaximized;
delete props.onCloseClick;
delete props.onMinimizeClick;
delete props.onMaximizeClick;
delete props.onRestoreDownClick;
let componentStyle = { ...styles.titleBar, ...style };
let titleStyle = styles.title;
if (!isWindowFocused && this.context.theme !== 'dark') {
titleStyle = { ...titleStyle, ...styles.unfocusedTitle };
}
if (this.context.theme === 'dark') {
titleStyle = { ...titleStyle, ...styles.titleDark };
}
componentStyle = {
...componentStyle,
visibility: !hidden ? 'visible' : 'hidden',
display: !hidden ? 'flex' : 'none'
};
if (this.context.theme === 'dark') {
componentStyle = { ...componentStyle, ...styles.titleBarDark };
}
const controlsComponent = !controls || ;
const titleComponent = !title || (
{this.props.title}
);
if (hasBackground) delete componentStyle.backgroundColor;
return (
{titleComponent}
{controlsComponent}
{children}
);
}
}
export default TitleBar;
================================================
FILE: src/TitleBar/windows/styles/windows10.js
================================================
export default {
titleBar: {
WebkitUserSelect: 'none',
userSelect: 'none',
WebkitAppRegion: 'drag',
appRegion: 'drag',
cursor: 'default',
display: 'flex',
alignItems: 'center',
width: '100%',
height: '31px',
backgroundColor: '#ffffff'
},
titleBarDark: {
backgroundColor: '#171717'
},
title: {
WebkitUserSelect: 'none',
userSelect: 'none',
cursor: 'default',
paddingLeft: '12px',
fontFamily: '"Segoe UI", "Arial"',
fontSize: '12px',
color: '#000000',
flex: 1
},
titleDark: {
color: '#ffffff'
},
unfocusedTitle: {
color: '#a9a9a9'
}
};
================================================
FILE: src/Toolbar/macOs/Nav/Item/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Text from '../../../../Text/macOs';
const styles = {
container: {
WebkitUserSelect: 'none',
userSelect: 'none',
WebkitAppRegion: 'no-drag',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
marginTop: '1px',
marginLeft: '5px',
marginRight: '5px',
width: '64px'
},
iconContainer: {
height: '25px',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
alignContent: 'center',
marginBottom: '1px'
}
};
class Item extends Component {
static propTypes = {
titel: PropTypes.string,
icon: PropTypes.oneOfType([PropTypes.element, PropTypes.array]),
selected: PropTypes.bool,
onClick: PropTypes.func
};
render() {
const { title, icon, style, selected, ...props } = this.props;
return (
);
}
}
export default Item;
================================================
FILE: src/Toolbar/macOs/Nav/index.js
================================================
import React, { Component } from 'react';
import { Style } from 'radium';
import Dimension, { dimensionPropTypes } from '../../../style/dimension';
import WindowFocus from '../../../windowFocus';
const styles = {
nav: {
display: 'flex',
alignItems: 'center'
}
};
@Dimension({ height: '54px' })
@WindowFocus()
class Nav extends Component {
static propTypes = {
...dimensionPropTypes
};
render() {
const { children, style, isWindowFocused, ...props } = this.props;
let componentStyle = { ...styles.nav };
let fillOpacity = '.8';
if (!isWindowFocused) {
componentStyle.opacity = '.5';
fillOpacity = '.3';
}
return (
{children}
);
}
}
export default Nav;
================================================
FILE: src/Toolbar/macOs/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Dimension, { dimensionPropTypes } from '../../style/dimension';
import Alignment, { alignmentPropTypes } from '../../style/alignment';
var styles = {
toolbar: {
WebkitUserSelect: 'none',
userSelect: 'none',
cursor: 'default',
display: 'flex',
justifyContent: 'center',
alignItems: 'center'
}
};
@Alignment()
@Dimension({ width: '100%' })
class Toolbar extends Component {
static propTypes = {
...alignmentPropTypes,
...dimensionPropTypes
};
static childContextTypes = {
titlebarChild: PropTypes.bool
};
getChildContext() {
return {
titlebarChild: true
};
}
render() {
const { style, ...props } = this.props;
return (
{this.props.children}
);
}
}
export default Toolbar;
================================================
FILE: src/ValueRef.js
================================================
import React, { Component } from 'react';
import { findDOMNode } from 'react-dom';
function ValueRef(ComposedComponent) {
return class extends Component {
get value() {
return findDOMNode(this).getElementsByTagName('input')[0].value;
}
set value(value) {
findDOMNode(this).getElementsByTagName('input')[0].value = value;
}
render() {
return ;
}
}
}
export default function(...options) {
if (options.length === 1 && typeof options[0] === 'function') return ValueRef.apply(null, [options[0]]);
return ValueRef.bind(options);
}
================================================
FILE: src/View/macOs/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Width, { widthPropTypes } from '../../style/width';
import Margin, { marginPropTypes } from '../../style/margin';
import Padding, { paddingPropTypes } from '../../style/padding';
import Alignment, { alignmentPropTypes } from '../../style/alignment';
import Background, { backgroundPropTypes } from '../../style/background/macOs';
import Hidden, { hiddenPropTypes } from '../../style/hidden';
import Dimension, { dimensionPropTypes } from '../../style/dimension';
var styles = {
display: 'flex',
position: 'relative'
};
@Width()
@Dimension()
@Alignment()
@Margin()
@Padding()
@Background()
@Hidden()
class View extends Component {
static propTypes = {
...alignmentPropTypes,
...widthPropTypes,
...marginPropTypes,
...paddingPropTypes,
...backgroundPropTypes,
...hiddenPropTypes,
...dimensionPropTypes,
direction: PropTypes.string,
layout: PropTypes.string
};
static defaultProps = {
layout: 'horizontal'
};
render() {
let { horizontalAlignment, children, style, direction, layout, ...props } = this.props;
let componentStyle = { ...styles, ...style };
if (direction) {
// direction will be deprecated on v0.3 and a warning will be shown
layout = direction === 'column' ? 'vertical' : 'horizontal';
}
if (layout === 'vertical') {
componentStyle.flexDirection = 'column';
if (horizontalAlignment) {
switch(horizontalAlignment) {
case 'center': componentStyle.alignItems = 'center'; break;
case 'left': componentStyle.alignItems = 'flex-start'; break;
case 'right': componentStyle.alignItems = 'flex-end'; break;
}
}
} else {
if (horizontalAlignment) {
switch(horizontalAlignment) {
case 'center': componentStyle.justifyContent = 'center'; break;
case 'left': componentStyle.justifyContent = 'flex-start'; break;
case 'right': componentStyle.justifyContent = 'flex-end'; break;
}
}
}
return (
{children}
);
}
}
export default View;
================================================
FILE: src/View/windows/index.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Width, { widthPropTypes } from '../../style/width';
import Margin, { marginPropTypes } from '../../style/margin';
import Padding, { paddingPropTypes } from '../../style/padding';
import Alignment, { alignmentPropTypes } from '../../style/alignment';
import Background, { backgroundContextTypes } from '../../style/background/windows';
import Hidden, { hiddenPropTypes } from '../../style/hidden';
import Dimension, { dimensionPropTypes } from '../../style/dimension';
import { ColorContext } from '../../style/color/windows';
import { ThemeContext } from '../../style/theme/windows';
var styles = {
display: 'flex',
position: 'relative'
};
@Width()
@Dimension()
@Alignment()
@Margin()
@Padding()
@Background()
@Hidden()
@ColorContext()
@ThemeContext()
class View extends Component {
static propTypes = {
...alignmentPropTypes,
...widthPropTypes,
...marginPropTypes,
...paddingPropTypes,
...backgroundContextTypes,
...hiddenPropTypes,
...dimensionPropTypes,
direction: PropTypes.string,
layout: PropTypes.string
};
static defaultProps = {
layout: 'horizontal'
};
render() {
let { horizontalAlignment, children, style, direction, layout, ...props } = this.props;
let componentStyle = { ...styles, ...style };
if (direction) {
// direction will be deprecated on v0.3 and a warning will be shown
layout = direction === 'column' ? 'vertical' : 'horizontal';
}
if (layout === 'vertical') {
componentStyle.flexDirection = 'column';
if (horizontalAlignment) {
switch(horizontalAlignment) {
case 'center': componentStyle.alignItems = 'center'; break;
case 'left': componentStyle.alignItems = 'flex-start'; break;
case 'right': componentStyle.alignItems = 'flex-end'; break;
}
}
} else {
if (horizontalAlignment) {
switch(horizontalAlignment) {
case 'center': componentStyle.justifyContent = 'center'; break;
case 'left': componentStyle.justifyContent = 'flex-start'; break;
case 'right': componentStyle.justifyContent = 'flex-end'; break;
}
}
}
return (
{children}
);
}
}
export default View;
================================================
FILE: src/Window/macOs/index.js
================================================
import React, { Component, Children } from 'react';
import PropTypes from 'prop-types';
import TitleBar from '../../TitleBar/macOs';
import View from '../../View/macOs';
import styles from './styles/10.11';
import WindowFocus from '../../windowFocus';
import Padding, {
paddingPropTypes,
removePaddingProps
} from '../../style/padding';
import Background, {
backgroundPropTypes,
removeBackgroundProps
} from '../../style/background/macOs';
import Alignment, { alignmentPropTypes } from '../../style/alignment';
import Hidden, { hiddenPropTypes } from '../../style/hidden';
import Dimension, { dimensionPropTypes } from '../../style/dimension';
@WindowFocus()
@Alignment()
@Hidden()
@Dimension({ width: '100vw', height: '100vh' })
class Window extends Component {
static propTypes = {
...paddingPropTypes,
...backgroundPropTypes,
...alignmentPropTypes,
...hiddenPropTypes,
...dimensionPropTypes,
chrome: PropTypes.bool
};
filterChildren() {
let titleBar = '';
let otherChildren = [];
Children.map(this.props.children, element => {
const TitleBarEl = ;
if (element.type === TitleBarEl.type) {
titleBar = element;
} else {
otherChildren = [...otherChildren, element];
}
});
return [titleBar, ...otherChildren];
}
render() {
let { style, chrome, isWindowFocused, ...props } = this.props;
let componentStyle = { ...styles.window, ...style };
if (chrome) {
componentStyle = {
...componentStyle,
...styles.chrome
};
if (!isWindowFocused) {
componentStyle = { ...componentStyle, ...styles.unfocused };
}
}
const [titleBar, ...children] = this.filterChildren();
let contentStyle = styles.content;
if (chrome) {
contentStyle = {
...contentStyle,
borderBottomLeftRadius: '4px',
borderBottomRightRadius: '4px'
};
}
let content = Background(
Padding({children} , props),
props
);
props = removePaddingProps(props);
props = removeBackgroundProps(props);
return (
{titleBar}
{content}
);
}
}
export default Window;
================================================
FILE: src/Window/macOs/styles/10.11.js
================================================
export default {
window: {
WebkitUserSelect: 'none',
userSelect: 'none',
cursor: 'default',
backgroundColor: '#ececec',
display: 'flex',
flexDirection: 'column',
boxSizing: 'border-box'
},
chrome: {
borderTopLeftRadius: '4px',
borderTopRightRadius: '4px',
borderBottomLeftRadius: '4px',
borderBottomRightRadius: '4px',
boxShadow:
'0 0 1px rgba(0, 0, 0, .26), ' + // Border
'0 0 5px rgba(0, 0, 0, .16), ' + // Small Glow
'0 8px 10px rgba(0, 0, 0, .06), ' + // Bottom Glow
'0 25px 65px rgba(0, 0, 0, .48) ' // Big shadow
},
unfocused: {
boxShadow:
'0 0 1px rgba(0, 0, 0, .31), ' + // Border
'0 0 5px rgba(0, 0, 0, .18), ' + // Small Glow
'0 8px 50px rgba(0, 0, 0, .3) ' // Big shadow
},
content: {
flex: 1,
padding: '24px 20px 20px 20px'
}
};
================================================
FILE: src/Window/windows/index.js
================================================
import React, { Component, Children } from 'react';
import PropTypes from 'prop-types';
import TitleBar from '../../TitleBar/windows';
import View from '../../View/windows';
import styles from './styles/windows10';
import WindowFocus from '../../windowFocus';
import Padding, {
paddingPropTypes,
removePaddingProps
} from '../../style/padding';
import Alignment, { alignmentPropTypes } from '../../style/alignment';
import Hidden, { hiddenPropTypes } from '../../style/hidden';
import Dimension, { dimensionPropTypes } from '../../style/dimension';
import {
ColorContext,
colorPropTypes,
colorContextTypes
} from '../../style/color/windows';
import {
ThemeContext,
themePropTypes,
themeContextTypes
} from '../../style/theme/windows';
@WindowFocus()
@Alignment()
@Hidden()
@Dimension({ width: '100vw', height: '100vh' })
@ColorContext()
@ThemeContext()
class Window extends Component {
static propTypes = {
...colorPropTypes,
...themePropTypes,
...paddingPropTypes,
...alignmentPropTypes,
...hiddenPropTypes,
...dimensionPropTypes,
chrome: PropTypes.bool
};
static contextTypes = {
...colorContextTypes,
...themeContextTypes
};
filterChildren() {
let titleBar = '';
let otherChildren = [];
Children.map(this.props.children, element => {
const TitleBarEl = ;
if (element.type === TitleBarEl.type) {
titleBar = element;
} else {
otherChildren = [...otherChildren, element];
}
});
return [titleBar, ...otherChildren];
}
render() {
let { style, background, chrome, isWindowFocused, ...props } = this.props;
let componentStyle = { ...styles.window, ...style };
if (chrome) {
componentStyle = {
...componentStyle,
...styles.chrome,
borderColor: this.context.color
};
if (!isWindowFocused) {
componentStyle = { ...componentStyle, ...styles.unfocused };
}
}
if (this.context.theme === 'dark') {
componentStyle = { ...componentStyle, ...styles.windowDark };
}
if (background) {
componentStyle = { ...componentStyle, backgroundColor: background };
}
const [titleBar, ...children] = this.filterChildren();
let content = Padding(
{children}
,
this.props
);
props = removePaddingProps(props);
return (
{titleBar}
{content}
);
}
}
export default Window;
================================================
FILE: src/Window/windows/styles/windows10.js
================================================
export default {
window: {
WebkitUserSelect: 'none',
userSelect: 'none',
cursor: 'default',
backgroundColor: '#ffffff',
display: 'flex',
flexDirection: 'column',
padding: 'none',
boxSizing: 'border-box'
},
windowDark: {
backgroundColor: '#171717'
},
chrome: {
borderWidth: '1px',
borderStyle: 'solid',
boxShadow: '0 2px 11px 3px rgba(0, 0, 0, .2)'
},
unfocused: {
borderColor: '#aaaaaa'
},
content: {
flexGrow: '1',
display: 'flex'
}
};
================================================
FILE: src/animation/bezierEasing.js
================================================
/**
* BezierEasing - use bezier curve for transition easing function
* by Gaëtan Renaudeau 2014 - 2015 – MIT License
*
* Credits: is based on Firefox's nsSMILKeySpline.cpp
* Usage:
* var spline = BezierEasing([ 0.25, 0.1, 0.25, 1.0 ])
* spline.get(x) => returns the easing value | x must be in [0, 1] range
*
*/
// These values are established by empiricism with tests (tradeoff: performance VS precision)
var NEWTON_ITERATIONS = 4;
var NEWTON_MIN_SLOPE = 0.001;
var SUBDIVISION_PRECISION = 0.0000001;
var SUBDIVISION_MAX_ITERATIONS = 10;
var kSplineTableSize = 11;
var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
var float32ArraySupported = typeof Float32Array === 'function';
function A(aA1, aA2) {
return 1.0 - 3.0 * aA2 + 3.0 * aA1;
}
function B(aA1, aA2) {
return 3.0 * aA2 - 6.0 * aA1;
}
function C(aA1) {
return 3.0 * aA1;
}
// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
function calcBezier(aT, aA1, aA2) {
return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
}
// Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
function getSlope(aT, aA1, aA2) {
return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
}
function binarySubdivide(aX, aA, aB, mX1, mX2) {
var currentX, currentT, i = 0;
do {
currentT = aA + (aB - aA) / 2.0;
currentX = calcBezier(currentT, mX1, mX2) - aX;
if (currentX > 0.0) {
aB = currentT;
} else {
aA = currentT;
}
} while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
return currentT;
}
function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
var currentSlope = getSlope(aGuessT, mX1, mX2);
if (currentSlope === 0.0) return aGuessT;
var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
aGuessT -= currentX / currentSlope;
}
return aGuessT;
}
/**
* points is an array of [ mX1, mY1, mX2, mY2 ]
*/
function BezierEasing(points, b, c, d) {
if (arguments.length === 4) {
return new BezierEasing([points, b, c, d]);
}
if (!(this instanceof BezierEasing)) return new BezierEasing(points);
if (!points || points.length !== 4) {
throw new Error('BezierEasing: points must contains 4 values');
}
for (var i = 0; i < 4; ++i) {
if (typeof points[i] !== 'number' || isNaN(points[i]) || !isFinite(points[i])) {
throw new Error('BezierEasing: points should be integers.');
}
}
if (points[0] < 0 || points[0] > 1 || points[2] < 0 || points[2] > 1) {
throw new Error('BezierEasing x values must be in [0, 1] range.');
}
this._str = 'BezierEasing(' + points + ')';
this._css = 'cubic-bezier(' + points + ')';
this._p = points;
this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
this._precomputed = false;
this.get = this.get.bind(this);
}
BezierEasing.prototype = {
get: function (x) {
var mX1 = this._p[0],
mY1 = this._p[1],
mX2 = this._p[2],
mY2 = this._p[3];
if (!this._precomputed) this._precompute();
if (mX1 === mY1 && mX2 === mY2) return x; // linear
// Because JavaScript number are imprecise, we should guarantee the extremes are right.
if (x === 0) return 0;
if (x === 1) return 1;
return calcBezier(this._getTForX(x), mY1, mY2);
},
getPoints: function () {
return this._p;
},
toString: function () {
return this._str;
},
toCSS: function () {
return this._css;
},
// Private part
_precompute: function () {
var mX1 = this._p[0],
mY1 = this._p[1],
mX2 = this._p[2],
mY2 = this._p[3];
this._precomputed = true;
if (mX1 !== mY1 || mX2 !== mY2)
this._calcSampleValues();
},
_calcSampleValues: function () {
var mX1 = this._p[0],
mX2 = this._p[2];
for (var i = 0; i < kSplineTableSize; ++i) {
this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
}
},
/**
* getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
*/
_getTForX: function (aX) {
var mX1 = this._p[0],
mX2 = this._p[2],
mSampleValues = this._mSampleValues;
var intervalStart = 0.0;
var currentSample = 1;
var lastSample = kSplineTableSize - 1;
for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
intervalStart += kSampleStepSize;
}
--currentSample;
// Interpolate to provide an initial guess for t
var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
var guessForT = intervalStart + dist * kSampleStepSize;
var initialSlope = getSlope(guessForT, mX1, mX2);
if (initialSlope >= NEWTON_MIN_SLOPE) {
return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
} else if (initialSlope === 0.0) {
return guessForT;
} else {
return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
}
}
};
// CSS mapping
BezierEasing.css = {
'ease': BezierEasing.ease = BezierEasing(0.25, 0.1, 0.25, 1.0),
'linear': BezierEasing.linear = BezierEasing(0.00, 0.0, 1.00, 1.0),
'ease-in': BezierEasing.easeIn = BezierEasing(0.42, 0.0, 1.00, 1.0),
'ease-out': BezierEasing.easeOut = BezierEasing(0.00, 0.0, 0.58, 1.0),
'ease-in-out': BezierEasing.easeInOut = BezierEasing(0.42, 0.0, 0.58, 1.0)
};
module.exports = BezierEasing;
================================================
FILE: src/color.js
================================================
function colorLuminance(hex, lum) {
// validate hex string
hex = String(hex).replace(/[^0-9a-f]/gi, '');
if (hex.length < 6) {
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
}
lum = lum || 0;
// convert to decimal and change luminosity
var rgb = '#', c, i;
for (i = 0; i < 3; i++) {
c = parseInt(hex.substr(i * 2, 2), 16);
c = Math.round(Math.min(Math.max(0, c + (c * lum)), 255)).toString(16);
rgb += (`00${c}`).substr(c.length);
}
return rgb;
}
export function hexToRgb(hex) {
let result;
if (hex.match(/^#.{3}$/)) {
result = /^#?([a-f\d])([a-f\d])([a-f\d])$/i.exec(hex);
result[1] += result[1];
result[2] += result[2];
result[3] += result[3];
} else {
result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
}
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
export function transparentize(color, amount) {
const c = hexToRgb(color);
return `rgba(${c.r}, ${c.g}, ${c.b}, ${Math.round((1 - amount) * 1000) / 1000})`;
}
export function darkenColor(color, percent) {
return colorLuminance(color, -percent);
}
export function ligthenColor(color) {
return color;
}
export function convertColor(color) {
var colors = {
'aliceblue':'#f0f8ff','antiquewhite':'#faebd7','aqua':'#00ffff','aquamarine':'#7fffd4','azure':'#f0ffff',
'beige':'#f5f5dc','bisque':'#ffe4c4','black':'#000000','blanchedalmond':'#ffebcd','blue':'#0000ff','blueviolet':'#8a2be2','brown':'#a52a2a','burlywood':'#deb887',
'cadetblue':'#5f9ea0','chartreuse':'#7fff00','chocolate':'#d2691e','coral':'#ff7f50','cornflowerblue':'#6495ed','cornsilk':'#fff8dc','crimson':'#dc143c','cyan':'#00ffff',
'darkblue':'#00008b','darkcyan':'#008b8b','darkgoldenrod':'#b8860b','darkgray':'#a9a9a9','darkgreen':'#006400','darkkhaki':'#bdb76b','darkmagenta':'#8b008b','darkolivegreen':'#556b2f',
'darkorange':'#ff8c00','darkorchid':'#9932cc','darkred':'#8b0000','darksalmon':'#e9967a','darkseagreen':'#8fbc8f','darkslateblue':'#483d8b','darkslategray':'#2f4f4f','darkturquoise':'#00ced1',
'darkviolet':'#9400d3','deeppink':'#ff1493','deepskyblue':'#00bfff','dimgray':'#696969','dodgerblue':'#1e90ff',
'firebrick':'#b22222','floralwhite':'#fffaf0','forestgreen':'#228b22','fuchsia':'#ff00ff',
'gainsboro':'#dcdcdc','ghostwhite':'#f8f8ff','gold':'#ffd700','goldenrod':'#daa520','gray':'#808080','green':'#008000','greenyellow':'#adff2f',
'honeydew':'#f0fff0','hotpink':'#ff69b4',
'indianred ':'#cd5c5c','indigo':'#4b0082','ivory':'#fffff0','khaki':'#f0e68c',
'lavender':'#e6e6fa','lavenderblush':'#fff0f5','lawngreen':'#7cfc00','lemonchiffon':'#fffacd','lightblue':'#add8e6','lightcoral':'#f08080','lightcyan':'#e0ffff','lightgoldenrodyellow':'#fafad2',
'lightgrey':'#d3d3d3','lightgreen':'#90ee90','lightpink':'#ffb6c1','lightsalmon':'#ffa07a','lightseagreen':'#20b2aa','lightskyblue':'#87cefa','lightslategray':'#778899','lightsteelblue':'#b0c4de',
'lightyellow':'#ffffe0','lime':'#00ff00','limegreen':'#32cd32','linen':'#faf0e6',
'magenta':'#ff00ff','maroon':'#800000','mediumaquamarine':'#66cdaa','mediumblue':'#0000cd','mediumorchid':'#ba55d3','mediumpurple':'#9370d8','mediumseagreen':'#3cb371','mediumslateblue':'#7b68ee',
'mediumspringgreen':'#00fa9a','mediumturquoise':'#48d1cc','mediumvioletred':'#c71585','midnightblue':'#191970','mintcream':'#f5fffa','mistyrose':'#ffe4e1','moccasin':'#ffe4b5',
'navajowhite':'#ffdead','navy':'#000080',
'oldlace':'#fdf5e6','olive':'#808000','olivedrab':'#6b8e23','orange':'#ffa500','orangered':'#ff4500','orchid':'#da70d6',
'palegoldenrod':'#eee8aa','palegreen':'#98fb98','paleturquoise':'#afeeee','palevioletred':'#d87093','papayawhip':'#ffefd5','peachpuff':'#ffdab9','peru':'#cd853f','pink':'#ffc0cb','plum':'#dda0dd','powderblue':'#b0e0e6','purple':'#800080',
'red':'#ff0000','rosybrown':'#bc8f8f','royalblue':'#4169e1',
'saddlebrown':'#8b4513','salmon':'#fa8072','sandybrown':'#f4a460','seagreen':'#2e8b57','seashell':'#fff5ee','sienna':'#a0522d','silver':'#c0c0c0','skyblue':'#87ceeb','slateblue':'#6a5acd','slategray':'#708090','snow':'#fffafa','springgreen':'#00ff7f','steelblue':'#4682b4',
'tan':'#d2b48c','teal':'#008080','thistle':'#d8bfd8','tomato':'#ff6347','turquoise':'#40e0d0',
'violet':'#ee82ee',
'wheat':'#f5deb3','white':'#ffffff','whitesmoke':'#f5f5f5',
'yellow':'#ffff00','yellowgreen':'#9acd32'
};
if (typeof color === 'string' && typeof colors[color.toLowerCase()] != 'undefined') {
return colors[color.toLowerCase()];
}
return color;
}
export function isDarkColor(color) {
const c = convertColor(color).substring(1); // strip #
const rgb = parseInt(c, 16); // convert rrggbb to decimal
const r = (rgb >> 16) & 0xff; // extract red
const g = (rgb >> 8) & 0xff; // extract green
const b = (rgb >> 0) & 0xff; // extract blue
const luma = 0.2126 * r + 0.7152 * g + 0.0722 * b; // per ITU-R BT.709
return luma < 40;
}
================================================
FILE: src/monitor.js
================================================
if (typeof window !== 'undefined') {
window.addEventListener('focus', windowFocus);
window.addEventListener('blur', windowBlur);
}
let isWindowFocused = true;
if (typeof document === 'object' && typeof document.hasFocus === 'function') {
isWindowFocused = document.hasFocus();
}
function windowFocus() {
isWindowFocused = true;
}
function windowBlur() {
isWindowFocused = false;
}
export function windowIsFocused() {
return isWindowFocused;
}
================================================
FILE: src/os.js
================================================
export const MACOS = 'macOs';
export const WINDOWS = 'windows';
export default function os() {
// explicitly set these to avoid issues
const w = window || null;
const n = navigator || null;
const p = process || (w && w.process) || null;
// via node
if (p && p.platform) {
if (p.platform === 'darwin') {
return MACOS;
}
if (p.platform.includes('win')) {
return WINDOWS;
}
}
// via user agent
if (n && n.userAgent) {
if (n.userAgent.includes('Macintosh')) {
return MACOS;
}
if (n.userAgent.includes('Windows')) {
return WINDOWS;
}
}
// default to macOs
return MACOS;
}
================================================
FILE: src/placeholderStyle.js
================================================
import React, { Component } from 'react';
import { Style } from 'radium';
function generateUniqueId() {
return Math.floor((Math.random() * 10000) + 1) + '-' + +Math.floor((Math.random() * 10000) + 1) + '-' + +Math.floor((Math.random() * 10000) + 1) + '-' + +Math.floor((Math.random() * 10000) + 1) + '-' + +Math.floor((Math.random() * 10000) + 1) + '-' + +Math.floor((Math.random() * 10000) + 1) + '-' + +Math.floor((Math.random() * 10000) + 1) + '-' +
Math.floor((Math.random() * 100000000000000));
}
function mapRules(selector, style) {
let styles = { 0: style };
if (style[':hover']) {
styles = { ...styles, ':hover': style[':hover'] };
delete styles[0][':hover'];
}
if (style[':active']) {
styles = { ...styles, ':active': style[':active'] };
delete styles[0][':active'];
}
if (style[':focus']) {
styles = { ...styles, ':focus': style[':focus'] };
delete styles[0][':focus'];
}
let rules = {};
for (var prop in styles) {
if (styles.hasOwnProperty(prop)) {
rules[`${selector} input${prop !== '0' ? prop : ''}::-webkit-input-placeholder`] = styles[prop];
rules[`${selector} input${prop !== '0' ? prop : ''}::-moz-placeholder`] = styles[prop];
rules[`${selector} input${prop !== '0' ? prop : ''}:-ms-input-placeholder`] = styles[prop];
rules[`${selector} input${prop !== '0' ? prop : ''}:placeholder`] = styles[prop];
}
}
return rules;
}
export default class extends Component {
constructor() {
super();
this._id = generateUniqueId();
}
render() {
const { children, placeholderStyle, ...props } = this.props;
return (
{children}
);
}
}
================================================
FILE: src/style/alignment.js
================================================
import PropTypes from 'prop-types';
import styleHelper, { extractProps } from '../styleHelper';
const allowedValues = ['left', 'right', 'center'];
export const alignmentPropTypes = {
horizontalAlignment: PropTypes.string,
verticalAlignment: PropTypes.string
};
export function removeAlignmentProps(props) {
return extractProps(props, alignmentPropTypes)[0];
}
function mapAlignmentStyle(key, value, props) {
let finalKey, finalValue;
if (allowedValues.indexOf(value) === -1) {
console.error('Unknown value for ' + key + ': ' + value);
} else {
let layout = 'horizontal';
if (props !== undefined && typeof props.layout !== 'undefined') {
layout = props.layout;
}
if (key === 'horizontalAlignment' && layout === 'horizontal' || key === 'verticalAlignment' && layout === 'vertical') {
finalKey = 'justifyContent';
switch (value) {
case 'center':
finalValue = 'center';
break;
case 'left':
finalValue = 'flex-start';
break;
case 'right':
finalValue = 'flex-end';
break;
}
} else if (key === 'verticalAlignment' && layout === 'horizontal' || key === 'horizontalAlignment' && layout === 'vertical') {
finalKey = 'alignItems';
switch (value) {
case 'center':
finalValue = 'center';
break;
case 'left':
finalValue = 'flex-start';
break;
case 'right':
finalValue = 'flex-end';
break;
}
}
}
return [finalKey, finalValue];
}
export default function(...options) {
return styleHelper(options, alignmentPropTypes, mapAlignmentStyle);
}
================================================
FILE: src/style/background/macOs.js
================================================
import PropTypes from 'prop-types';
import styleHelper, { extractProps } from '../../styleHelper';
export const backgroundPropTypes = {
background: PropTypes.string
};
export function removeBackgroundProps(props) {
return extractProps(props, backgroundPropTypes)[0];
}
export default function(...options) {
return styleHelper(options, backgroundPropTypes);
}
================================================
FILE: src/style/background/windows.js
================================================
import React, { Component, isValidElement } from 'react';
import PropTypes from 'prop-types';
import styleHelper, { extractProps } from '../../styleHelper';
import { ColorContext, colorContextTypes } from '../../style/color/windows';
import Radium from 'radium';
export const backgroundPropTypes = {
background: PropTypes.oneOfType([PropTypes.string, PropTypes.bool])
};
export const backgroundContextTypes = {
background: PropTypes.oneOfType([PropTypes.string, PropTypes.bool])
};
export function removeBackgroundProps(props) {
return extractProps(props, backgroundPropTypes)[0];
}
export default function(...options) {
if (options[0] && isValidElement(options[0])) {
@ColorContext(true)
@Radium
class BackgroundElement extends Component {
static contextTypes = { ...colorContextTypes };
render () {
const props = { ...options[1] };
if (typeof props.background === 'boolean') {
if (!props.background) delete props.background;
else if (this.context.color) props.background = this.context.color;
else delete props.background;
}
options[1] = { ...props };
return styleHelper(options, backgroundPropTypes);
}
}
return ;
}
return function (WrappedComponent) {
const ComposedComponent = styleHelper(options, backgroundPropTypes, null, null, options[0])(WrappedComponent);
@ColorContext(true)
class BackgroundComponent extends Component {
static contextTypes = { ...colorContextTypes };
render() {
const props = { ...this.props };
if (typeof props.background === 'boolean') {
if (!props.background) delete props.background;
else {
props.background = this.context.color;
}
}
return ;
}
}
return BackgroundComponent;
};
}
================================================
FILE: src/style/color/windows.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { applyDefaultProps } from '../../styleHelper';
export const colorPropTypes = {
color: PropTypes.oneOfType([PropTypes.string, PropTypes.bool])
};
export const colorContextTypes = {
color: PropTypes.oneOfType([PropTypes.string, PropTypes.bool])
};
const applyColorProps = (props, context) => applyDefaultProps(props, context, { color: '#0063ae' });
export function ColorContext(preserveProperty = false) {
return function (ComposedComponent) {
return class extends Component {
static propTypes = { ...colorPropTypes };
static contextTypes = { ...colorContextTypes };
static childContextTypes = { ...colorContextTypes };
getChildContext() {
return {
color: applyColorProps(this.props, this.context).color
};
}
render() {
const { ...props } = this.props;
if (!preserveProperty) delete props.color;
return (
);
}
};
}
}
================================================
FILE: src/style/dimension.js
================================================
import PropTypes from 'prop-types';
import styleHelper, { extractProps, parseDimension } from '../styleHelper';
export const dimensionPropTypes = {
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
height: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
};
export function removeDimensionProps(props) {
return extractProps(props, dimensionPropTypes)[0];
}
function mapDimensionStyle(key, value) {
return [key, parseDimension(value)];
}
export default function(...options) {
return styleHelper(options, dimensionPropTypes, mapDimensionStyle);
}
================================================
FILE: src/style/fontSize.js
================================================
import PropTypes from 'prop-types';
import styleHelper, { extractProps, parseDimension } from '../styleHelper';
export const fontSizePropTypes = {
size: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
};
export function removeFontSizeProps(props) {
return extractProps(props, fontSizePropTypes)[0];
}
function mapFontSizeStyle(key, value) {
return ['fontSize', parseDimension(value)];
}
function mapFontSizeStyles(styles) {
if (styles.fontSize && !styles.lineHeight) {
styles.lineHeight = parseDimension(parseInt(styles.fontSize) * 1.2);
}
return styles;
}
export default function(...options) {
return styleHelper(options, fontSizePropTypes, mapFontSizeStyle, mapFontSizeStyles);
}
================================================
FILE: src/style/hidden.js
================================================
import PropTypes from 'prop-types';
import styleHelper, { extractProps } from '../styleHelper';
export const hiddenPropTypes = {
hidden: PropTypes.bool
};
export function removeHiddenProps(props) {
return extractProps(props, hiddenPropTypes)[0];
}
function mapHiddenStyle(key, value) {
return value ? ['display', 'none'] : null;
}
export default function(...options) {
return styleHelper(options, hiddenPropTypes, mapHiddenStyle);
}
================================================
FILE: src/style/margin.js
================================================
import PropTypes from 'prop-types';
import styleHelper, { extractProps, parseDimension } from '../styleHelper';
export const marginPropTypes = {
margin: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
marginTop: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
marginLeft: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
marginRight: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
marginBottom: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
};
export function removeMarginProps(props) {
return extractProps(props, marginPropTypes)[0];
}
function mapMarginStyle(key, value) {
return [key, parseDimension(value)];
}
export default function(...options) {
return styleHelper(options, marginPropTypes, mapMarginStyle);
}
================================================
FILE: src/style/padding.js
================================================
import PropTypes from 'prop-types';
import styleHelper, { extractProps, parseDimension } from '../styleHelper';
export const paddingPropTypes = {
padding: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
paddingTop: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
paddingLeft: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
paddingRight: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
paddingBottom: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
};
export function removePaddingProps(props) {
return extractProps(props, paddingPropTypes)[0];
}
export function removeDuplicatePaddingProps(styles, props) {
if (props !== undefined && typeof props.style !== 'undefined') {
styles = { ...styles };
if (props.style.padding) {
delete styles.paddingBottom;
delete styles.paddingLeft;
delete styles.paddingRight;
delete styles.paddingTop;
return styles;
} else if (props.style.paddingBottom || props.style.paddingLeft || props.style.paddingRight || props.style.paddingTop) {
delete styles.padding;
return styles;
}
}
return styles;
}
function mapPaddingStyle(key, value) {
return [key, parseDimension(value)];
}
export default function(...options) {
return styleHelper(options, paddingPropTypes, mapPaddingStyle);
}
================================================
FILE: src/style/textAlign.js
================================================
import PropTypes from 'prop-types';
import styleHelper, { extractProps } from '../styleHelper';
const allowedValues = ['left', 'right', 'center'];
export const textAlignPropTypes = {
textAlign: PropTypes.string
};
export function removeTextAlignProps(props) {
return extractProps(props, textAlignPropTypes)[0];
}
function mapTextAlignStyle(key, value) {
let finalKey, finalValue;
if (allowedValues.indexOf(value) === -1) {
console.error('Unknown value for ' + key + ': ' + value);
} else {
finalKey = 'textAlign';
finalValue = value;
}
return [finalKey, finalValue];
}
export default function(...options) {
return styleHelper(options, textAlignPropTypes, mapTextAlignStyle);
}
================================================
FILE: src/style/theme/windows.js
================================================
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { applyDefaultProps } from '../../styleHelper';
export const themePropTypes = {
theme: PropTypes.string
};
export const themeContextTypes = {
theme: PropTypes.string
};
const applyThemeProps = (props, context) => applyDefaultProps(props, context, { theme: 'light' });
export function ThemeContext() {
return function (ComposedComponent) {
return class extends Component {
static propTypes = { ...themePropTypes };
static contextTypes = { ...themeContextTypes };
static childContextTypes = { ...themeContextTypes };
getChildContext() {
return {
theme: applyThemeProps(this.props, this.context).theme
};
}
render() {
const { ...props } = this.props;
delete props.theme;
return (
);
}
};
}
}
================================================
FILE: src/style/width.js
================================================
import PropTypes from 'prop-types';
import styleHelper, { extractProps, parseDimension } from '../styleHelper';
export const widthPropTypes = {
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
};
export function removeWidthProps(props) {
return extractProps(props, widthPropTypes)[0];
}
function mapWidthStyle(key, value) {
return [key, parseDimension(value)];
}
function mapWidthStyles(styles) {
if (styles.width) {
if (styles.flex) {
delete styles.flex;
} else if (styles.flexGrow) {
delete styles.flexGrow;
}
}
return styles;
}
export default function(...options) {
return styleHelper(options, widthPropTypes, mapWidthStyle, mapWidthStyles);
}
================================================
FILE: src/styleHelper.js
================================================
import React, { Component, cloneElement, isValidElement } from 'react';
export function parseDimension(value) {
if (typeof value === 'number') {
return value + 'px';
} else if (value.match(/^[0-9]+$/)) {
return value + 'px';
}
return value;
}
export function applyDefaultProps(props, context, defaultProps) {
let finalProps = { ...props };
for (let prop in defaultProps) {
if (defaultProps.hasOwnProperty(prop)) {
if (!props[prop]) {
if (context[prop]) {
finalProps[prop] = context[prop];
} else {
finalProps[prop] = defaultProps[prop];
}
} else if (props[prop] && typeof props[prop] === 'boolean' && typeof defaultProps[prop] !== 'boolean') {
if (context.color) {
finalProps[prop] = context[prop];
} else {
finalProps[prop] = defaultProps[prop];
}
}
}
}
return finalProps;
}
export function hasProps(props, proptypes) {
if (!proptypes) return false;
for (let prop in props) {
if (props.hasOwnProperty(prop)) {
if (proptypes[prop] !== undefined) {
return true;
}
}
}
return false;
}
export function extractProps(props, proptypes) {
if (!proptypes) return [{}, {}];
let finalProps = {};
let extractedProps = {};
for (let prop in props) {
if (props.hasOwnProperty(prop)) {
if (proptypes[prop] !== undefined) {
extractedProps[prop] = props[prop];
} else {
finalProps[prop] = props[prop];
}
}
}
return [finalProps, extractedProps];
}
export function mapStyle(prevStyles, nextStyles, defaultStyles, styleCallback, stylesCallback, props) {
let finalStyles = { ...prevStyles };
if (defaultStyles) {
for (let key in defaultStyles) {
if (defaultStyles.hasOwnProperty(key)) {
finalStyles[key] = defaultStyles[key];
}
}
}
for (let key in nextStyles) {
if (nextStyles.hasOwnProperty(key)) {
if (styleCallback) {
const result = styleCallback(key, nextStyles[key], props);
if (result) {
finalStyles[result[0]] = result[1];
}
} else finalStyles[key] = nextStyles[key];
}
}
if (typeof stylesCallback === 'function') return stylesCallback(finalStyles, props);
return finalStyles;
}
export default function styleHelper(options, propTypes, mapStyleCallback, mapStylesCallback, mapProps) {
if (!mapProps || typeof mapProps !== 'function') {
mapProps = props => props;
}
function doStyleHelper(WrappedComponent) {
const [element, elementProps, defaultStyles] = options;
if (isValidElement(element)) {
if (hasProps(elementProps, propTypes) || hasProps(defaultStyles, propTypes)) {
const styles = extractProps(elementProps, propTypes)[1];
const props = element.props ? { ...element.props } : {};
props.style = mapStyle(props.style, styles, defaultStyles, mapStyleCallback, mapStylesCallback, elementProps);
return cloneElement(element, mapProps(props, element.props, true));
}
return cloneElement(element, mapProps(element.props, element.props, false));
} else {
let defaultStyles;
if (options && Object.prototype.toString.call(options) === '[object Array]') {
defaultStyles = options[0];
}
return class extends Component {
render() {
if (hasProps(this.props, propTypes) || hasProps(defaultStyles, propTypes)) {
let [props, styles] = extractProps(this.props, propTypes);
if (!props) props = {};
props.style = mapStyle(props.style, styles, defaultStyles, mapStyleCallback, mapStylesCallback, this.props);
return ;
}
return
}
}
}
}
if (options[0] && isValidElement(options[0])) {
return doStyleHelper();
}
return doStyleHelper;
}
================================================
FILE: src/utils/mapStyles.js
================================================
export default function mapStyles(styles, map) {
let popped = [];
let mappedStyles = {};
for (let prop in map) {
if (map.hasOwnProperty(prop)) {
mappedStyles[prop] = {};
map[prop].forEach(key => {
if (styles !== undefined && typeof styles[key] !== 'undefined') {
popped.push(key);
mappedStyles[prop][key] = styles[key];
}
})
}
}
let remaining = {};
for (let prop in styles) {
if (styles.hasOwnProperty(prop)) {
if (popped.indexOf(prop) === -1) {
remaining[prop] = styles[prop];
}
}
}
let finalStyles = [remaining];
for (let prop in mappedStyles) {
if (mappedStyles.hasOwnProperty(prop)) {
finalStyles.push(mappedStyles[prop]);
}
}
return finalStyles;
}
================================================
FILE: src/windowFocus.js
================================================
import { windowIsFocused } from './monitor';
import React, { Component } from 'react';
function WindowFocus(options, ComposedComponent) {
return class extends Component {
constructor() {
super();
this.state = {
isWindowFocused: windowIsFocused()
};
}
componentDidMount() {
if (typeof window !== 'undefined') {
window.addEventListener('focus', this.windowFocus);
window.addEventListener('blur', this.windowBlur);
}
}
componentWillUnmount() {
if (typeof window !== 'undefined') {
window.removeEventListener('focus', this.windowFocus);
window.removeEventListener('blur', this.windowBlur);
}
}
windowFocus = () => {
this.setState({ isWindowFocused: true });
};
windowBlur = () => {
this.setState({ isWindowFocused: false });
};
render() {
return ;
}
}
}
export default function(...options) {
if (options.length === 1 && typeof options[0] === 'function') return WindowFocus.apply(null, [[], options[0]]);
return WindowFocus.bind(null, options);
}
================================================
FILE: test/mocha.opts
================================================
--compilers js:babel-core/register
--recursive
--require ./test/setup.js
================================================
FILE: test/setup.js
================================================
import { JSDOM } from 'jsdom';
const dom = new JSDOM('');
global.window = dom.window;
global.HTMLElement = dom.window.HTMLElement;
global.document = dom.window.document;
global.navigator = {
...global.window.navigator,
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.54 Safari/537.36'
};
global.__REACT_DEVTOOLS_GLOBAL_HOOK__ = {};
================================================
FILE: test/tests/box.js
================================================
import { expect } from 'chai';
import React from 'react';
import { renderToString } from 'react-dom/server';
import Box from '../../src/Box/macOs';
describe('Box', () => {
it('create box component with label', () => {
const string = renderToString( );
expect(string).to.match(/My Label/);
});
});
================================================
FILE: test/tests/button.js
================================================
import { expect } from 'chai';
import React from 'react';
import { renderToString } from 'react-dom/server';
import Button from '../../src/Button/windows';
describe('Button', () => {
it('create button component with text', () => {
const string = renderToString(Hello );
expect(string).to.match(/Hello/);
});
it('create button component with one node', () => {
const string = renderToString(
Hello
);
expect(string).to.match(/Hello/);
});
it('create button component with multiple nodes', () => {
const string = renderToString(
Hello
World
);
expect(string).to.match(/Hello/);
expect(string).to.match(/World/);
});
});
================================================
FILE: test/tests/checkbox.js
================================================
import { expect } from 'chai';
import React from 'react';
import { renderToString } from 'react-dom/server';
import CheckboxOSX from '../../src/Checkbox/macOs';
import CheckboxWindows from '../../src/Checkbox/windows';
describe('Checkbox', () => {
it('create osx checkbox', () => {
const string = renderToString( );
expect(string).to.match(/my label/);
});
it('create windows checkbox', () => {
const string = renderToString( );
expect(string).to.match(/my label/);
});
});
================================================
FILE: test/tests/color.js
================================================
import { expect } from 'chai';
import * as Color from '../../src/color';
describe('Color', () => {
describe('#colorLuminance', () => {
});
describe('#hexToRgb', () => {
it('works', () => {
expect(Color.hexToRgb('#000000')).to.deep.equal({ r: 0, g: 0, b: 0 });
expect(Color.hexToRgb('#1883d7')).to.deep.equal({ r: 24, g: 131, b: 215 });
expect(Color.hexToRgb('#ffffff')).to.deep.equal({ r: 255, g: 255, b: 255 });
expect(Color.hexToRgb('#000')).to.deep.equal({ r: 0, g: 0, b: 0 });
expect(Color.hexToRgb('#fff')).to.deep.equal({ r: 255, g: 255, b: 255 });
});
});
describe('#transparentize', () => {
it('works', () => {
expect(Color.transparentize('#000000', 0)).to.deep.equal('rgba(0, 0, 0, 1)');
expect(Color.transparentize('#000000', 0.4)).to.deep.equal('rgba(0, 0, 0, 0.6)');
expect(Color.transparentize('#000000', 0.7)).to.deep.equal('rgba(0, 0, 0, 0.3)');
expect(Color.transparentize('#000000', 1)).to.deep.equal('rgba(0, 0, 0, 0)');
});
});
describe('#darkenColor', () => {
});
describe('#ligthenColor', () => {
});
describe('#convertColor', () => {
it('works', () => {
expect(Color.convertColor('white')).to.equal('#ffffff');
expect(Color.convertColor('blue')).to.equal('#0000ff');
expect(Color.convertColor('black')).to.equal('#000000');
});
});
describe('#isDarkColor', () => {
it('works', () => {
expect(Color.isDarkColor('#000000')).to.be.true;
expect(Color.isDarkColor('#ffffff')).to.be.false;
});
});
});
================================================
FILE: test/tests/dialog.js
================================================
import { expect } from 'chai';
import React from 'react';
import { renderToString } from 'react-dom/server';
import Dialog from '../../src/Dialog/macOs';
describe('Dialog', () => {
it('create osx dialog', () => {
const string = renderToString( );
expect(string).to.match(/div/);
});
});
================================================
FILE: test/tests/index.js
================================================
import { expect } from 'chai';
import { MACOS, WINDOWS } from '../../src/os';
import * as components from '../../index'
describe('index', () => {
it('detect os', () => {
expect(components.os()).to.be.oneOf([MACOS, WINDOWS]);
});
it('should be exported', () => {
expect(components.Box).to.exist;
expect(components.Button).to.exist;
expect(components.Checkbox).to.exist;
expect(components.Dialog).to.exist;
expect(components.Label).to.exist;
expect(components.Link).to.exist;
expect(components.ListView).to.exist;
expect(components.ListViewFooter).to.exist;
expect(components.ListViewHeader).to.exist;
expect(components.ListViewRow).to.exist;
expect(components.ListViewSection).to.exist;
expect(components.ListViewSectionHeader).to.exist;
expect(components.ListViewSeparator).to.exist;
expect(components.MasterDetailsView).to.exist;
expect(components.NavPane).to.exist;
expect(components.Pin).to.exist;
expect(components.ProgressCircle).to.exist;
expect(components.Radio).to.exist;
expect(components.SearchField).to.exist;
expect(components.SegmentedControl).to.exist;
expect(components.SegmentedControlItem).to.exist;
expect(components.Text).to.exist;
expect(components.TextInput).to.exist;
expect(components.TitleBar).to.exist;
expect(components.Toolbar).to.exist;
expect(components.ToolbarNav).to.exist;
expect(components.ToolbarNavItem).to.exist;
expect(components.View).to.exist;
expect(components.Window).to.exist;
});
});
================================================
FILE: test/tests/label.js
================================================
import { expect } from 'chai';
import React from 'react';
import { renderToString } from 'react-dom/server';
import Label from '../../src/Label/windows';
describe('Label', () => {
it('create label component with text', () => {
const string = renderToString(Hello );
expect(string).to.match(/Hello/);
});
it('create label component with one node', () => {
const string = renderToString(
Hello
);
expect(string).to.match(/Hello/);
});
it('create label component with multiple nodes', () => {
const string = renderToString(
Hello
World
);
expect(string).to.match(/Hello/);
expect(string).to.match(/World/);
});
});
================================================
FILE: test/tests/link.js
================================================
import { expect } from 'chai';
import React from 'react';
import { renderToString } from 'react-dom/server';
import Link from '../../src/Link/macOs';
describe('Link', () => {
it('create osx link', () => {
const string = renderToString( My Link);
expect(string).to.match(/My Link/);
});
});
================================================
FILE: test/tests/listView.js
================================================
import { expect } from 'chai';
import React from 'react';
import { renderToString } from 'react-dom/server';
import ListView from '../../src/ListView/macOs';
import ListViewFooter from '../../src/ListView/macOs/Footer';
import ListViewHeader from '../../src/ListView/macOs/Header';
import ListViewRow from '../../src/ListView/macOs/Row';
import ListViewSection from '../../src/ListView/macOs/Section';
import ListViewSectionHeader from '../../src/ListView/macOs/Section/Header';
import ListViewSeparator from '../../src/ListView/macOs/Separator';
describe('ListView', () => {
it('create list view component', () => {
const string = renderToString( );
expect(string).to.match(/ {
const string = renderToString( );
expect(string).to.match(/ {
const string = renderToString( );
expect(string).to.match(/ {
const string = renderToString( );
expect(string).to.match(/ {
const string = renderToString( );
expect(string).to.match(/ {
const string = renderToString( );
expect(string).to.match(/