Showing preview only (328K chars total). Download the full file or copy to clipboard to get everything.
Repository: FormidableLabs/radium
Branch: master
Commit: b8faaa0c1c4c
Files: 97
Total size: 305.1 KB
Directory structure:
gitextract_taxgn3kc/
├── .agignore
├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc
├── .flowconfig
├── .gitignore
├── .npmignore.publishr
├── .prettierignore
├── .prettierrc
├── .travis.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE-examples.md
├── LICENSE.md
├── README.md
├── appveyor.yml
├── bower.json
├── docs/
│ ├── README.md
│ ├── api/
│ │ └── README.md
│ ├── faq/
│ │ └── README.md
│ └── guides/
│ ├── README.md
│ └── upgrade-v0.16.x.md
├── examples/
│ ├── app.js
│ ├── client.js
│ ├── common.styles.js
│ ├── components/
│ │ ├── button.js
│ │ └── computed-well.js
│ ├── index.html
│ ├── server.js
│ └── webpack.config.js
├── index.js
├── interfaces/
│ ├── hoist-non-react-statics.js
│ └── inline-style-prefixer.js
├── karma.conf.coverage.js
├── karma.conf.ie.js
├── karma.conf.js
├── package.json
├── scripts/
│ └── update-prefix-data.js
├── src/
│ ├── __mocks__/
│ │ ├── exenv.js
│ │ └── prefixer.js
│ ├── __tests__/
│ │ ├── camel-case-props-to-dash-case-test.js
│ │ ├── clean-state-key-test.js
│ │ ├── enhancer-test.js
│ │ ├── get-radium-style-state-test.js
│ │ ├── get-state-key-test.js
│ │ ├── get-state-test.js
│ │ ├── keyframes-test.js
│ │ ├── media-query-test.js
│ │ ├── radium-test.js
│ │ ├── remove-nested-styles-test.js
│ │ ├── resolve-styles-test.js
│ │ ├── style-component-test.js
│ │ └── visited-test.js
│ ├── append-important-to-each-value.js
│ ├── append-px-if-needed.js
│ ├── camel-case-props-to-dash-case.js
│ ├── clean-state-key.js
│ ├── components/
│ │ ├── style-root.js
│ │ ├── style-sheet.js
│ │ └── style.js
│ ├── config.js
│ ├── context.js
│ ├── css-rule-set-to-string.js
│ ├── enhancer.js
│ ├── get-radium-style-state.js
│ ├── get-state-key.js
│ ├── get-state.js
│ ├── hash.js
│ ├── index.js
│ ├── keyframes.js
│ ├── map-object.js
│ ├── merge-styles.js
│ ├── plugins/
│ │ ├── check-props-plugin.js
│ │ ├── index.js
│ │ ├── keyframes-plugin.js
│ │ ├── merge-style-array-plugin.js
│ │ ├── mouse-up-listener.js
│ │ ├── prefix-plugin.js
│ │ ├── remove-nested-styles-plugin.js
│ │ ├── resolve-interaction-styles-plugin.js
│ │ ├── resolve-media-queries-plugin.js
│ │ └── visited-plugin.js
│ ├── prefix-data/
│ │ ├── dynamic.js
│ │ └── static.js
│ ├── prefixer.js
│ ├── resolve-styles.js
│ ├── style-keeper.js
│ └── test-helpers.js
├── test/
│ ├── .eslintrc
│ ├── enhancer-test.js
│ ├── mocha.opts
│ ├── radium-test.js
│ ├── setup.js
│ └── utils.js
├── webpack.config.js
└── webpack.config.minified.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .agignore
================================================
dist
lib
================================================
FILE: .babelrc
================================================
{
"plugins": [
"@babel/plugin-transform-destructuring",
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
],
[
"@babel/plugin-proposal-class-properties",
{
"loose": true,
},
],
],
"presets": [
[
"@babel/preset-env",
{
"modules": false
}
],
"@babel/preset-flow",
"@babel/preset-react"
],
"env": {
"commonjs": {
"plugins": [
"@babel/plugin-transform-destructuring",
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
],
[
"@babel/plugin-proposal-class-properties",
{
"loose": true,
},
],
],
"presets": [
[
"@babel/preset-env",
{
"modules": "commonjs"
}
],
"@babel/preset-flow",
"@babel/preset-react"
],
}
}
}
================================================
FILE: .editorconfig
================================================
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
================================================
FILE: .eslintignore
================================================
dist
lib
es
coverage
examples/dist
node_modules
================================================
FILE: .eslintrc
================================================
parser: "babel-eslint"
parserOptions:
ecmaVersion: 2018
sourceType: "module"
ecmaFeatures:
jsx: true
plugins: ["react", "flowtype", "prettier", "react-hooks"]
settings:
react:
pragma: "React"
version: "detect"
env:
browser: true
node: true
amd: false
mocha: true
jasmine: false
globals:
require: true
module: true
expect: true
sinon: true
ReactElement: true
Reflect: true
rules:
###########################################################################
# #
# POSSIBLE ERRORS: these rules point out areas where you might have #
# made mistakes. #
# #
###########################################################################
no-cond-assign: 2 # disallow assignment in conditional expressions
no-console: 2 # disallow use of console
no-constant-condition: 2 # disallow use of constant expressions in conditions
no-control-regex: 2 # disallow control characters in regular expressions
no-debugger: 2 # disallow use of debugger
no-dupe-keys: 2 # disallow duplicate keys when creating object literals
no-empty: 2 # disallow empty statements
no-empty-character-class: 2 # disallow the use of empty character classes in regular expressions
no-ex-assign: 2 # disallow assigning to the exception in a catch block
no-extra-boolean-cast: 2 # disallow double-negation boolean casts in a boolean context
no-extra-parens: 0 # disallow unnecessary parentheses
# NOTE: Allow for `return (/* JSX STUFF*/);` situations
no-extra-semi: 2 # disallow unnecessary semicolons
no-func-assign: 2 # disallow overwriting functions written as function declarations
no-inner-declarations: 2 # disallow function or variable declarations in nested blocks
no-invalid-regexp: 2 # disallow invalid regular expression strings in the RegExp
# constructor
no-irregular-whitespace: 2 # disallow irregular whitespace outside of strings and comments
no-negated-in-lhs: 2 # disallow negation of the left operand of an in expression
no-obj-calls: 2 # disallow the use of object properties of the global object (Math
# and JSON) as functions
no-regex-spaces: 2 # disallow multiple spaces in a regular expression literal
no-sparse-arrays: 2 # disallow sparse arrays
no-unreachable: 2 # disallow unreachable statements after a return, throw, continue,
# or break statement
use-isnan: 2 # disallow comparisons with the value NaN
valid-typeof: 2 # ensure that the results of typeof are compared against a
# valid string
valid-jsdoc: # ensure JSDoc comments are valid
[1, { "prefer": { "return": "returns" }, "requireReturn": false }]
###########################################################################
# #
# BEST PRACTICES: these rules are designed to prevent you from making #
# mistakes. They either prescribe a better way of doing something or #
# help you avoid pitfalls. #
# #
###########################################################################
block-scoped-var: 2 # treat var statements as if they were block scoped
complexity: [2, 250] # specify the maximum cyclomatic complexity allowed in a program
consistent-return: 0 # require return statements to either always or never specify values
curly: 2 # specify curly brace conventions for all control statements
default-case: 2 # require default case in switch statements
dot-notation: 2 # encourages use of dot notation whenever possible
eqeqeq: 2 # require the use of === and !==
guard-for-in: 2 # make sure for-in loops have an if statement
no-alert: 2 # disallow the use of alert, confirm, and prompt
no-caller: 2 # disallow use of arguments.caller or arguments.callee
no-div-regex: 2 # disallow division operators explicitly at beginning of regular
# expression
no-else-return: 2 # disallow else after a return in an if
no-eq-null: 2 # disallow comparisons to null without a type-checking operator
no-eval: 2 # disallow use of eval()
no-extend-native: 2 # disallow adding to native types
no-extra-bind: 2 # disallow unnecessary function binding
no-fallthrough: 2 # disallow fallthrough of case statements
no-floating-decimal: 2 # disallow the use of leading or trailing decimal points in numeric
# literals
no-implied-eval: 2 # disallow use of eval()-like methods
no-iterator: 2 # disallow usage of __iterator__ property
no-labels: 2 # disallow use of labeled statements
no-lone-blocks: 2 # disallow unnecessary nested blocks
no-loop-func: 0 # disallow creation of functions within loops
no-multi-spaces: 0 # disallow use of multiple spaces
no-multi-str: 2 # disallow use of multiline strings
no-native-reassign: 2 # disallow reassignments of native objects
no-new: 2 # disallow use of new operator when not part of the assignment or
# comparison
no-new-func: 2 # disallow use of new operator for Function object
no-new-wrappers: 2 # disallows creating new instances of String,Number, and Boolean
no-octal: 2 # disallow use of octal literals
no-octal-escape: 2 # disallow use of octal escape sequences in string literals, such as
# `var foo = "Copyright \251"`
no-process-env: 0 # disallow use of process.env
no-proto: 2 # disallow usage of __proto__ property
no-redeclare: 2 # disallow declaring the same variable more then once
no-return-assign: 0 # disallow use of assignment in return statement
no-script-url: 2 # disallow use of javascript urls.
no-self-compare: 2 # disallow comparisons where both sides are exactly the same
no-sequences: 2 # disallow use of comma operator
no-unused-expressions: 0 # disallow usage of expressions in statement position
no-void: 2 # disallow use of void operator
no-warning-comments: 0 # disallow usage of configurable warning terms in comments - e.g.
# TODO or FIXME
no-with: 2 # disallow use of the with statement
radix: 2 # require use of the second argument for parseInt()
vars-on-top: 0 # requires to declare all vars on top of their containing scope
wrap-iife: [2, "inside"] # require immediate function invocation to be wrapped in parentheses
yoda: [2, "never"] # require or disallow Yoda conditions
###########################################################################
# #
# STRICT MODE: these rules relate to using strict mode. #
# #
###########################################################################
strict: [2, "global"] # require that all modules have use strict
###########################################################################
# #
# VARIABLES: these rules have to do with variable declarations. #
# #
###########################################################################
no-catch-shadow: 2 # disallow the catch clause parameter name being the same as a
# variable in the outer scope
no-delete-var: 2 # disallow deletion of variables
no-label-var: 2 # disallow labels that share a name with a variable
no-shadow: 2 # disallow declaration of variables already declared in the
# outer scope
no-shadow-restricted-names: 2 # disallow shadowing of names such as arguments
no-undef: 2 # disallow use of undeclared variables unless mentioned in a
# /*global */ block
no-undef-init: 2 # disallow use of undefined when initializing variables
no-undefined: 0 # disallow use of undefined variable
no-unused-vars: 2 # disallow declaration of variables that are not used in
# the code
no-use-before-define: [2, { "functions": false }] # disallow use of variables before they are defined
no-var: 2
###########################################################################
# #
# NODE: these rules relate to functionality provided in Node.js. #
# #
###########################################################################
handle-callback-err: 0 # enforces error handling in callbacks
no-mixed-requires: [2, true] # disallow mixing regular variable and require declarations
no-new-require: 2 # disallow use of new operator with the require function
no-path-concat: 2 # disallow string concatenation with __dirname and __filename
no-process-exit: 0 # disallow process.exit()
no-restricted-modules: 0 # restrict usage of specified node modules
no-sync: 0 # disallow use of synchronous methods
###########################################################################
# #
# STYLISTIC ISSUES: these rules are purely matters of style and, #
# while valueable to enforce consistently across a project, are #
# quite subjective. #
# #
###########################################################################
brace-style: # enforce one true brace style
[2, "1tbs", { "allowSingleLine": true }]
camelcase: # require camel case names, except in properties
[2, { "properties": "never" }]
comma-spacing: 2 # enforce spacing before and after comma
consistent-this: [2, "self"] # enforces consistent naming when capturing the current execution context
eol-last: 2 # enforce newline at the end of file, with no multiple empty lines
func-names: 0 # require function expressions to have a name
func-style: [0, "expression"] # enforces use of function expressions
key-spacing: 2 # enforces spacing between keys and values in object literal properties
max-nested-callbacks: [2, 4] # specify the maximum depth callbacks can be nested
new-cap: 0 # require a capital letter for constructors
new-parens: 2 # disallow the omission of parentheses when invoking a constructor with no arguments
no-array-constructor: 2 # disallow use of the Array constructor
no-lonely-if: 0 # disallow if as the only statement in an else block
no-mixed-spaces-and-tabs: 2 # disallow mixed spaces and tabs for indentation
no-nested-ternary: 2 # disallow nested ternary expressions
no-new-object: 2 # disallow use of the Object constructor
semi-spacing: 2 # disallow space before semicolon
no-spaced-func: 2 # disallow space between function identifier and application
no-ternary: 0 # disallow the use of ternary operators
no-trailing-spaces: 2 # disallow trailing whitespace at the end of lines
no-multiple-empty-lines: 2 # disallow multiple empty lines
no-underscore-dangle: 0 # disallow dangling underscores in identifiers
one-var: 0 # allow just one var statement per function
padded-blocks: 0 # enforce padding within blocks
quotes: # specify whether double or single quotes should be used
[2, "single", "avoid-escape"]
quote-props: 0 # require quotes around object literal property names
semi: [2, "always"] # require or disallow use of semicolons instead of ASI
sort-vars: 0 # sort variables within the same declaration block
keyword-spacing: # require a space before and after certain keywords
["error", {"before": true, "after": true }]
space-before-blocks: 2 # require or disallow space before blocks
space-in-brackets: 0 # require or disallow spaces inside brackets
space-in-parens: 0 # require or disallow spaces inside parentheses
space-infix-ops: 2 # require spaces around operators
spaced-comment: 2 # require or disallow a space immediately following
# the // in a line comment
wrap-regex: 0 # require regex literals to be wrapped in parentheses
space-before-function-paren: [2, "never"]
###########################################################################
# #
# LEGACY: these rules are included for compatibility with JSHint and #
# JSLint. While the names of the rules may not match up with their #
# JSHint/JSLint counterpart, the functionality is the same. #
# #
###########################################################################
max-depth: 0 # specify the maximum depth that blocks can be nested
max-len: [2, 100, 4] # specify the maximum length of a line in your program
max-params: [2, 5] # limits the number of parameters that can be used in the function
# declaration
max-statements: 0 # specify the maximum number of statement allowed in a function
no-bitwise: 0 # disallow use of bitwise operators
no-plusplus: 0 # disallow use of unary operators, ++ and --
###########################################################################
# #
# React JSX #
# #
###########################################################################
jsx-quotes: 2
react/jsx-boolean-value: 2
react/jsx-no-undef: 2
react/jsx-sort-props: 2
react/jsx-uses-react: 2
react/jsx-uses-vars: 2
react/no-did-mount-set-state: 2
react/no-did-update-set-state: 2
react/no-multi-comp: 0
react/no-unknown-property: 2
react/prop-types: 0
react/react-in-jsx-scope: 2
react/self-closing-comp: 2
react/sort-comp: 2
react/sort-prop-types: 2
react/jsx-wrap-multilines: 2
###########################################################################
# #
# Flowtype #
# #
###########################################################################
flowtype/define-flow-type: 2
flowtype/use-flow-type: 2
###########################################################################
# #
# Prettier #
# #
###########################################################################
prettier/prettier: [
"error",
{
"bracketSpacing": false,
"singleQuote": true,
"parser": "babylon"
}
]
###########################################################################
# #
# React Hooks #
# #
###########################################################################
react-hooks/rules-of-hooks: 2
react-hooks/exhaustive-deps: 2
================================================
FILE: .flowconfig
================================================
[ignore]
.*/dist/.*
.*/lib/.*
.*/node_modules/.*/node_modules/.*
.*/node_modules/babel-core/.*
.*/node_modules/babel-loader/.*
.*/node_modules/babel-register/.*
.*/node_modules/config-chain/.*
.*/node_modules/flow-bin/.*
.*/node_modules/inline-style-prefixer/.*
.*/node_modules/invariant/.*
.*/node_modules/mkdirp/.*
.*/node_modules/nodemon/.*
.*/node_modules/npmconf/.*
.*/node_modules/react-hot-loader/.*
.*/node_modules/rimraf/.*
.*/node_modules/watchify/.*
.*/node_modules/webpack-dev-server/.*
.*/node_modules/webpack/.*
.*/node_modules/hoist-non-react-statics/.*
[include]
src
[libs]
interfaces
[options]
esproposal.class_static_fields=enable
esproposal.class_instance_fields=enable
================================================
FILE: .gitignore
================================================
### SublimeText ###
*.sublime-workspace
### OSX ###
.AppleDouble
.DS_Store
.LSOverride
Icon
# Thumbnails
._*
# Files that might appear on external disk
.Spotlight-V100
.Trashes
### Windows ###
# Windows image file caches
ehthumbs.db
Thumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# App specific
.tmp
.vscode
_site
coverage
dist
es
lib
node_modules
npm-debug.log*
yarn-error.log*
package-lock.json
================================================
FILE: .npmignore.publishr
================================================
/*
!/es
!/dist
!/docs
!/lib
!/src
!LICENSE.txt
!CHANGELOG.md
!README.md
!package.json
================================================
FILE: .prettierignore
================================================
dist
lib
es
coverage
examples/dist
node_modules
================================================
FILE: .prettierrc
================================================
{
"bracketSpacing": false,
"singleQuote": true
}
================================================
FILE: .travis.yml
================================================
dist: trusty
language: node_js
addons:
chrome: stable
node_js:
- "8"
- "10"
- "12"
# Use container-based Travis infrastructure.
sudo: false
before_install:
# GUI for real browsers.
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
# Headless chrome
- google-chrome-stable --headless --disable-gpu --remote-debugging-port=9222 http://localhost &
branches:
only:
- master
notifications:
email:
on_success: change
on_failure: always
cache: yarn
script:
# Output useful info for debugging.
- node --version
- yarn --version
# Make sure we can actually build the examples.
- yarn run build-examples
# Run tests
- yarn run lint
- yarn run build
- yarn run test-coverage
# Upload to coveralls, but don't _fail_ if coveralls is down.
- cat coverage/lcov.info | node_modules/.bin/coveralls || echo "Coveralls upload failed"
================================================
FILE: CHANGELOG.md
================================================
# Radium Changelog
## 0.26.2
- Update `peerDependencies` for React to include 17.
## 0.26.1 (September 29, 2020)
#### Dependency Upgrades
- Bump handlebars from 4.1.2 to 4.5.3 (#1035)
- Bump elliptic from 6.4.0 to 6.5.3 (#1045)
- Bump eslint-utils from 1.3.1 to 1.4.3 (#1039)
- Bump tree-kill from 1.2.0 to 1.2.2 (#1046)
- Bump websocket-extensions from 0.1.1 to 0.1.4 (#1044)
- Bump fstream from 1.0.11 to 1.0.12 (#1038)
- Bump sshpk from 1.11.0 to 1.16.1 (#1037)
- Bump webpack-dev-server from 2.11.1 to 3.1.11 (#1036)
- Bump is-my-json-valid from 2.16.0 to 2.20.5 (#1048)
- Bump http-proxy from 1.16.2 to 1.18.1 (#1047)
#### Bug Fixes
- Fix initial enhancer state for fn components (#1041)
## 0.26.0 (September 5, 2019)
#### Bug Fixes
- Add hook and forwardRef support (#1027)
#### Breaking Changes
- Radium now requires React@16.8.0+ (#1027)
## 0.25.2 (June 7, 2019)
#### Bug Fixes
- Bump handlebars from 4.0.6 to 4.1.2 (#1026)
- Fixed bug with undefined \_extraRadiumStateKeys (#1025)
- Update unitless CSS property list and licensing (#1020)
## 0.25.1 (December 16, 2018)
#### Bug Fixes
- Pass `snapshot` argument to `componentDidUpdate (#1013)
#### Infra/Tooling
- Fix console warnings when running examples (#1002)
- Upgrade karma to 3.0 (#1003)
- Refactor enhancer for readability (#1004)
- Replace Isparta with Istanbul (#1011)
- Prettier (#1012)
## 0.25.0 (September 16, 2018)
- Use `Reflect` to construct es native classes in a way that preserves the value of `this` used in
the constructor. (#999, #1001)
- Handle multiple animationName props (#909)
## 0.24.1 (July 9, 2018)
- Make `<StyleSheet>` manually update `<style>` tag DOM, fixing media queries on component level flickering. (#626, #950)
## 0.24.0 (March 29, 2018)
- Fix `render` methods that return array of children or `React.Fragment`. (#950)
- Upgrade tests to React 16.2 (for `Fragment` support)
## 0.23.0 (March 15, 2018)
- Support ES7 arrow functions for React class methods. (#738)
## 0.22.1 (March 1, 2018)
- Fix `keyframes` bug from prefixed inline styles. (#973)
## 0.22.0 (February 9, 2018)
### Breaking Changes
- Radium now exports defaults as `.default`, so for runtimes like Node.js for all files in `lib/**`. We have changed `package.json:main` to point to `/index.js` instead of `/lib/index.js` as a convenience wrapper to expose mostly what was there before so behavior of `const Radium = require('radium');` works mostly as it did before. Caveats:
- When using webpack2+ to build code with `require('radium')` in it you will need to change that to become `require('radium').default`.
- Any imports of a default export from a file in lib like `const Enhancer = require('radium/lib/enhancer');` will need to be changed to `const Enhancer = require('radium/lib/enhancer').default;`.
- We have a full examples repository of how imports work in all likely scenarios that should come up. https://github.com/FormidableLabs/radium-experiments-v0.22
### Features
- Add `es` ESM module export files.
### Fixes
- Fix `package.json:scripts.postinstall` task to correctly work for git-based dependencies.
## 0.21.2 (January 25, 2018)
- Fix multiple-value prefixed inline styles. (#962, #958, #951)
## 0.21.1 (January 18, 2018)
- Call `componentDidUpdate()` inherited method (#957).
## 0.21.0 (January 8, 2018)
- Automatically clear browser state of elements when unmounting and remounting (#956).
- `resolveStyles` returns `{ extraRadiumStateKeys, element }` instead of just `element`.
## 0.20.1 (January 8, 2018)
- Fix `v0.20.0` build.
## 0.20.0 (January 8, 2018)
- Upgrade `inline-style-prefixer` to version `^4.0.0`.
## 0.19.6 (October 5, 2017)
- Allow native ES classes to be used with the Radium enhancer.
## 0.19.5 (October 5, 2017)
- Enable React 16 in `peerDependencies` and update tests to React 16.
## 0.19.4 (July 21, 2017)
- Remove `.babelrc` from published npm registry package.
## 0.19.3 (July 20, 2017)
- Remove `publishr` from prod `dependencies` in npm registry package.
## 0.19.2 (July 20, 2017)
- Switch to `publishr` workflow. (#894, #731, #900)
- Remove `rimraf` from prod `dependencies` in npm registry package.
- Remove `postinstall` from `scripts` in npm registry package. (#794)
## 0.19.1 (May 17, 2017)
### Bug Fixes
- Makes `prop-types` a `dependencies` instead of a `peerDependencies` in `package.json` per the `prop-types` [integration guide](https://github.com/facebook/prop-types#how-to-depend-on-this-package).
## 0.19.0 (May 15, 2017)
### Improvements
- Unreverts PropTypes-related diff, which is now a minor version instead of a patch
## 0.18.4 (May 15, 2017)
### Bug Fixes
- Reverts PropTypes-related diff, which should have been a minor version instead of a patch
## 0.18.3 (May 15, 2017)
### Improvements
- Update dependencies
- Update deprecated React syntax in examples
- Use React "prop-types" package
## 0.18.2 (March 15, 2017)
### Improvements
- Update `inline-style-prefixer` to v2.0.5 (#880).
- Use `React.PureComponent` to avoid unnecessary rendering (#868).
- Update all dependencies
## 0.18.1 (July 19, 2016)
### Bug Fixes
- Fix unused props warning when passing `radiumConfig` to `StyleRoot` (#787).
## 0.18.0 (July 15, 2016)
### Breaking Changes
- Revert `content` auto-quoting in `Style` component (#783).
### Bug Fixes
- Silence React 15.2 unused props deprecation warning (#782).
## 0.17.2 (July 12, 2016)
### Bug Fixes
- Fix `content` values in `Style` component (#719).
- Improve stateless component check to work with native arrow functions (#771).
### Improvements
- Add support for `:disabled` pseudo-class (#689).
- Add plugin to remove nested style objects and prevent `[Object object]` from rendering in the DOM (#703).
## 0.17.1 (March 30, 2016)
### Bug Fixes
- Remove babel modules accidentally published as dependencies.
### Improvements
- Add support for `scopeSelector` without nested selectors in `Style` component.
## 0.17.0 (March 24, 2016)
### Bug Fixes
- Upgrade `inline-style-prefixer` to version `1.0.3` with a fix for `display` values being removed in IE10.
### Improvements
- Add `TestMode` for controlling internal Radium state and behavior during tests.
### Breaking Changes
- `inline-style-prefixer` has updated vendor prefixes, removing some outdated prefixes like `-moz-transform`.
## 0.16.6 (February 9, 2016)
### Bug Fixes
- The `lib/` directory did not get built property in 0.16.6. `lib/` now contains all changes from 0.16.5.
## 0.16.5 (January 27, 2016)
### Bug Fixes
- Don't merge media query styles, fixes #550
- Don't add className if empty, fixes #539
### Improvements
- Passing `'all'` as the `userAgent` will add all prefixes, useful for caching server-rendered pages, thanks @oliviertassinari (this applies to inline styles and style rendered as CSS, but does not yet include adding all the prefixed versions of `keyframes`)
- Add support for `:visited` styles:
```jsx
const url = 'https://github.com/formidablelabs/radium';
const VisitedLink = Radium(() => (
<a href={url} style={{color: 'gray', ':visited': {color: 'black'}}}>
{url}
</a>
));
```
## 0.16.4 (January 23, 2016)
### Bug Fixes
- Add `px` suffix if needed _before_ prefixing, since the list in `appendPxIfNeeded` does not include prefixed variants
- Radium now calls `toString` on values itself, instead of relying on `inline-style-prefixer` or React to do so (they don't)
### Improvements
- Much lighter `npm install radium` by removing `babel` & co from `dependencies` before publishing
- Radium now ignores children or props that are themselves Radium enhanced components, for a nice perf gain. Thanks @spacenick
## 0.16.3 (January 21, 2016)
- Published under the `test` tag, so not installable via npm latest
- Forgot to add `-test` to the version
- See changelog for 0.16.4 instead
## 0.16.2 (January 8, 2016)
### Bug Fixes
- `<StyleSheet/> Component:`
- Bind the private method \_onChange to the class instance
- Wrap setState in setTimeout and keep track of isMounted, #500
- Remove duplicate declaration of componentWillUnmount and move `this._isMounted = true` inside `componentDidMount`
- Clear up docs around StyleRoot props, clear up issues in #496
- Properly prefix keyframes: Use `inline-style-prefixer`’s `prefixedKeyframes`, #488
- Ensure unique classname is generated for media query rules (hash on query _and_ ruleCSS string)
## 0.16.1 (January 5, 2016)
### Bug Fixes
- `<StyleRoot>` no longer throws an error on unmount
## 0.16.0 (January 5, 2016)
### New Features
- Server-side rendering for media queries and keyframes!
### Breaking Changes
- To use keyframes and media queries, you must wrap your components in the `<StyleRoot>` component, typically in `<App>`: https://github.com/FormidableLabs/radium/tree/master/docs/api#styleroot-component
- The result of Radium.keyframes is the animation name, and should be assigned to the `animationName` prop: https://github.com/FormidableLabs/radium/tree/master/docs/api#keyframes
- printStyles have been removed, in favor of '@media print' media queries, which are now rendered as CSS so they work correctly: https://github.com/FormidableLabs/radium/tree/master/docs/guides#media-queries
### Bug Fixes
- Don't add extra media query listeners
- Append px to numeric values on properties that don't accept unitless values
### Improvements
- Upgrade `inline-style-prefixer` to version 0.6.2 (Edge support)
- Better error on duplicate keys
- Upgrade to Babel 6
- `<Style>` adds the `scopeSelector` to comma separated selectors
- `<Style>` now accepts `radiumConfig` directly with the `userAgent` field
## 0.15.3 (November 16, 2015)
### Bug Fixes
- Fix `"files"` section in `package.json`, should fix `npm install issues`
## 0.15.2 (November 15, 2015)
### Bug Fixes
- IE vender prefix (ms) is now converted to dash-case correctly (-ms), thanks @PallasKatze, fixes #413
- Super getChildContext is no longer ignored, thanks @richardfickling, fixes #412
- Update to inline-style-prefixer v0.5.1 and changed the userAgent error to a console.warning
## 0.15.1 (November 11, 2015)
### Bug Fixes
- Fix bug where active styles on multiple elements in the same component were not being removed on mouse up, fixes #410
## 0.15.0 (November 11, 2015)
### New Features
- Radium now uses [inline-style-prefixer](https://github.com/rofrischmann/inline-style-prefixer) to do all prefixing. Because `inline-style-prefixer` relies on the userAgent (similar to autoprefixer), it produces the same prefixes on both the client and the server. This is a huge step in making Radium truly universal (see [example](https://github.com/FormidableLabs/radium/blob/master/examples/server.js)). Thanks much to @rofrischmann for putting up with my API suggestions and requests!
- Any Radium component can also be configured at render time via a [`radiumConfig`](https://github.com/FormidableLabs/radium/blob/master/docs/api/README.md#radium). This was mainly required for passing the `userAgent` during a server-side render.
### Breaking Changes
- Style component no longer supports the `prefix` prop. It automatically gets the correct userAgent to pass to the prefixer from `radiumConfig` context
### Bug Fixes
- Radium wrapper now replaces the `style` propType, if defined, with array or object, fixing #396
- Stateless components now support context, thanks @ThomWright
- Static fields on stateless components are now transferred to the Radium wrapper (`defualtProps`, `propTypes`, etc)
### Improvements
- Code has been ES2015-ified: const and let, import/export, fat arrows,
- Code has moved from `modules` to `src`
## 0.14.3 (October 19, 2015)
### Bug Fixes
- camelCasePropsToDashCase handles uppercase first character correctly, fixing #387
## 0.14.2 (October 17, 2015)
### Bug Fixes
- `:active` styles now triggered by space or enter
- Callback `ref`s are now ignored, fixing #346
- Heavy use of media queries no longer causes setState on an unmounted component, fixing #382
### New Features
- Stateless components (function taking props) are now supported
### Improvements
- Updated examples to for React 0.14.0
- Allow replacing the prefixer used by `Radium.keyframes` and `<Style>`
## 0.14.1 (September 15, 2015)
### Bug Fixes
- Don't require object-assign, which wasn't in normal dependencies
## 0.14.0 (September 15, 2015)
### Breaking Changes
- `Config.setMatchMedia` has been replaced by the `matchMedia` field in the config passed to `@Radium` ([see documentation](https://github.com/FormidableLabs/radium/tree/master/docs/api#configmatchmedia))
### New Features
- Plugin system, via the config passed to `@Radium` (see docs for [`config.plugins`](https://github.com/FormidableLabs/radium/tree/master/docs/api#configplugins) and the [plugin API](https://github.com/FormidableLabs/radium/tree/master/docs/api#plugins))
### Improvements
- Flatten nested arrays in `style`, #344, thanks @almost
- Universal/isomorphic example `npm run universal`, thanks @jurgob and @moret
### Bug Fixes
- Static properties are now copied again in IE < 10, #349, thanks @bobbyrenwick
## 0.13.8 (August 24, 2015)
### Bug Fixes
- Fix static class methods disappearing in IE10, #313
- Fix bug when using spread operator to pass props to a DOM element, #322
## 0.13.7 (August 5, 2015)
### Bug Fixes
- Fix double resolving bug on props.children, #307
## 0.13.6 (August 5, 2015)
### New Features
- Resolve styles on elements found in props and children as function, #298
- [<PrintStyleSheet>](https://github.com/FormidableLabs/radium/tree/master/docs/api#printstylesheet-component) component and `printStyles` property to add print styles to your components, #299, thanks @bobbyrenwick
### Improvements
- Show component name when warning in prefixer, #302, thanks @AnSavvides
### Bug Fixes
- Fix bug with \_radiumDidResolveStyles that was breaking in React 0.14.0-beta2
- Un-prefix values before checking isUnitlessNumber, #305, thanks @AnSavvides
- Prevent errors from getters that do not have setters as static props of React components, #306, thanks @rolandpoulter
## 0.13.5 (July 29, 2015)
### Improvements
- Support for old and tweener flexbox syntax, #279, thanks @sylvaingi
- Only calls console.warn during development, not in production
### Bug Fixes
- Don't call resolveStyles more than once on the same element, #293
- Allow null or undefined values in style, #263
- Remove redundant babel-core from dependencies
- Fix using numeric 0 as key to getState, #275
- Don't wrap display name with "Radium(...)", #271
- Fix older firefox missing `float` property, #277, thanks @bencao
- Don't warn when mixing `transform` properties, #272, thanks @MattHauglustaine
- Use for loop instead of Array prototype on the result of window.getComputedStyle, which was breaking Android web view, #267, thanks @bsbeeks
- Ignore functions as children instead of blowing up, #265, thanks @Cottin
### Misc
- Add `test-dev` command for faster test feedback during development
## 0.13.4 (July 14, 2015)
### Bug Fixes
- Fix regression with multiple states (tests were failing) from 0.13.3
## 0.13.3 (July 13, 2015)
### Bug Fixes
- Fix hotloading component methods, #255, thanks @bobbyrenwick
- Add displayName to shorthand warning, #253, thanks @bobbyrenwick
- Warn and ignore null/undefined values, #250, thanks @AnSavvides
- Don't warn when mixing border & borderRadius, and more shorthand warning updates, #246, thanks @nathanfriemel
- Remove react from peerDependencies so Radium can be used with the 0.14 beta, #242, thanks @dariocravero
- Fix transfering defaultProps and friends in IE <11, #241, thanks @bobbyrenwick
- Don't alias matchMedia, fixes IE <11 bug, #238
- Stop mutating style state, #237
### Misc
- Migrate tests to Karma, #240, thanks @exogen
## 0.13.2 (June 25, 2015)
### Bug Fixes
- Use `console.warn` instead of `console.warning` (duh)
## 0.13.1 (June 24, 2015)
### New Features
- [Radium.Config.setMatchMedia](https://github.com/FormidableLabs/radium/tree/master/docs/api#configsetmatchmedia) for server rendering
### Bug Fixes
- Don't resolve `style` prop of custom components, e.g. `<MyComponent style={...} />`, #202 (thanks @azazdeaz)
- Fix not using dash-case on server with Style, #207
- Fix server rendering when using fallback array of values (uses first one)
- Fix numeric fallbacks, #221
### Misc
- Update dependencies
- Warn when mixing longhand and shorthand
## 0.13.0 (June 7, 2015)
### Breaking Changes
- `Radium.wrap` and `Radium.Enhancer` have been merged and moved to `Radium()`. Just wrap your component, `Button = Radium(Button);`, or use the decorator `@Radium`
- `Style` component `rules` prop now takes an object instead of an array
### New Features
- Support fallback values (e.g. `#fff` for `rgba(...)`)
### Bug Fixes
- Fix react external in webpack config
- Fix keyframes throwing on IE9 (now does feature detection)
- Fix windows build
- `string` and `number` children are no longer wrapped in an extraneous `<span>`
## 0.12.2 (May 22, 2015)
### Breaking Changes
None
### New Features
- Support prefixing for old flexbox implementations
### Bug Fixes
- Stop using react internals `CSSPropertyOperations.createMarkupForStyles`, which further reduces the build size
## 0.12.1 (May 22, 2015)
### Bug Fixes
- Fix Enhancer (displayName, etc) #165
- Reduce size of distributed build
- Tests for prefixing, fix #161
## 0.12.0 (May 16, 2015)
### New Features
- Support for ES6 classes with Radium.Enhancer
- Vendor-prefixing
- Keyframes animation helper
- Radium.getState API
### Bug Fixes
- Fix errors during server-side rendering #141
- Fix passing a single child or string #139
## 0.11.1 (April 28, 2015)
### Bug Fixes
- Checked in updated `dist` files from `0.11.0`. Whoops!
## 0.11.0 (April 28, 2015)
### Breaking Changes
- Complete API rewrite.
- Added new "Wrap" API.
- Wrap React component config with `Radium.wrap()` to automatically add
browser state handlers, media query behavior, and array-based style
resolution.
- Removed all mixins.
- Removed context-based media query behavior.
- Replaced with global media query handler.
- Removed modifiers, states, and media queries from style objects.
- Replaced `modifiers` with array-based `style` prop resolution.
- Replaced `states` object with inline state keys: `:hover`
- Replaced `mediaQueries` object with inline queries:
`@media (min-width: 200px)`
### New Features
- Apply separate browser state styles to multiple elements in the same
component.
================================================
FILE: CONTRIBUTING.md
================================================
Thanks for contributing!
## Development
### Installing dependencies
```bash
npm install
```
You will find all building blocks that make up Radium in the [`src`](src) folder.
### Testing
For ease, we've wrapped up all our individual test commands into:
```sh
$ npm run build-lib OR watch-lib # One time / watched src file build
$ npm run test # Single pass of all tests.
$ npm run test-dev # Watch test file changes and rerun tests automatically.
```
#### Frontend
You will find tests for each module inside [`src/__tests__`](src/__tests__). Whenever making any changes, ensure that all existing tests pass by running `npm run test-frontend`. You can also have [`Karma`](http://karma-runner.github.io/) running in the background and run your tests every time you make a change by doing `npm run test-dev-frontend`.
If you are adding a new feature or some extra functionality, you should also make sure to accompany those changes with appropriate tests.
#### Backend
We have a small number of tests for SSR/Node.js usage in [`test`](test). Whenever making any relevant changes, ensure that all existing tests pass by running `npm run test-node`. You will need to have a babel watch running if you are changing source files since these tests rely on built files in `lib/`, which you can do easily with `npm run watch-lib` in a separate terminal.
To get watched test files automagically updated and run, use `npm run test-node-dev`.
### Linting
Before commiting any changes, be sure to do `npm run lint`; this will lint all relevant files using [ESLint](http://eslint.org/) and report on any changes that you need to make. You can also run `npm run fixlint` to fix most common lint errors automatically.
### Flow
- [Install flow](http://flowtype.org/docs/getting-started.html#installing-flow)
- Run `flow` to check for missing annotations and static type check failures
### Examples
You can run examples locally by simply doing `npm run examples`; this will start a webpack dev server (the config file is found at [examples/webpack.config.js](examples/webpack.config.js)) making Radium examples available at `http://localhost:8080`.
Please note that if you use `npm run test-dev` as above, Karma will use port `8080`. You can change the port used by the examples by running `npm run examples -- --port 8000`.
### Before submitting a PR...
Thanks for taking the time to help us make Radium even better! Before you go ahead and submit a PR, make sure that you have done the following:
- Run the tests (you did add tests, right?) using `npm run test-dev`.
- Run lint and flow using `npm run lint`
## Releasing a new version to NPM (only for project administrators):
1. Update `CHANGELOG.md`, following format for previous versions
2. Commit as "Changelog for version 0.XX.Y"
3. Run `npm version patch` (or `minor`, `major` as appropriate) to run tests and lint, build the `lib` ands `dist` directories, , then update `package.json` and add a git tag.
4. Run `npm publish` and publish to NPM if all is well.
5. Run `git push && git push --tags`
## Contributor Covenant Code of Conduct
### Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.
### Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
### Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
### Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
### Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at lauren.eastridge@formidable.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
### Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/
[version]: http://contributor-covenant.org/version/1/4/
### Architecture
#### Enhancer HOC (enhancer.js)
- Component is wrapped by `Radium` which runs it through `enhancer.js::enhanceWithRadium()`.
- A composed component is created
- ES modules - `Reflect` is used to create enhanced component from prototype of original component
- Stateless components - a simple wrapper component is created which calls the original component
- Everything else - enhanced component is created by shallow copying the original component
- An enhanced component is created
- static `_isRadiumEnhanced = true` property is added
- `_radiumStyleState = {}` is added to component state
- In render, `resolveStyles.js:resolveStyles` is called on the original rendered elements before they are returned. (see resolveStyles section)
- in componentDidUpdate, unused state keys are removed if necessary
- in componentWillUnmount, mouse and media query listeners are removed
#### Style Resolver `resolveStyles.js::resolveStyles`
- Called on the original rendered elements before they are returned. It iterates over the elements and children, rewriting props to add event handlers required to capture user interactions (e.g. mouse over). It also replaces the style prop because it adds in the various interaction styles (e.g. :hover).
- extraStateKeyMap is created by determining which state fields are no longer needed [?]
- If the rendered elements are an array, they are recursively mapped over with resolveStyles
- New children are resolved
- Recurse into children and call `resolveStyles` on each one
- New props are resolved
- Recurse through props and call `resolveStyles` on any React components in props. Otherwise return props as-is
- Plugins are run ONLY on simple ReactDOM elements that have a style prop
- plugins are called with the component, its props and a bunch of helper functions
- if the props were changed/added by any plugin, then return those
- see plugins section for more
- If anything changed, clone the element and return that. Otherwise just return the element.
#### Plugins
- _merge-styles-array-plugin_ - If the component styles are an array, it deeply merges them. Otherwise, it returns them unmodified.
- _check-props-plugin_ - Recursively checks props and warns (in dev mode) if shorthand and longhand are mixed.
- _resolve-media-queries-plugin_ - Handles media query style entries (like '@media (...)': { ... }), applying them only when the appropriate media query is hit
- _resolve-interaction-styles-plugin_ - Handles `:hover`, `:active` and `:focus` styles by adding/wrapping mouse event listeners with functions that update radium's state.
- _keyframes-plugin_ - Handles keyframe styles
- _visited-plugin_ - Handles `:visited` styles
- _remove-nested-styles-plugin_ - Recursively flattens nested styles into a flat object
- _prefix-plugin_ - Uses browser detection and a mapping to add vendor prefixes to CSS properties and values as needed
================================================
FILE: LICENSE-examples.md
================================================
The examples provided by Formidable Labs are for non-commercial testing and evaluation purposes only. Formidable Labs reserves all rights not expressly
granted.
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
FORMIDABLE LABS 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: LICENSE.md
================================================
The MIT License (MIT)
Copyright (c) 2015 Formidable Labs
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
================================================
[![Maintenance Status][maintenance-image]](#maintenance-status)
[![Travis Status][trav_img]][trav_site]
[![AppVeyor Status][appveyor_img]][appveyor_site]
[![Coverage Status][cov_img]][cov_site]
[![NPM Package][npm_img]][npm_site]
[![Dependency Status][david_img]][david_site]
![gzipped size][size_img]
# Radium
```sh
yarn add radium
# or
npm install --save radium
```
Radium is a set of tools to manage inline styles on React elements. It gives you powerful styling capabilities without CSS.
_Inspired by_ <a href="https://speakerdeck.com/vjeux/react-css-in-js">React: CSS in JS</a>
by <a href="https://twitter.com/Vjeux">vjeux</a>.
## Maintenance Status
**Archived:** This project is no longer maintained by Formidable. We are no longer responding to issues or pull requests unless they relate to security concerns. We encourage interested developers to fork this project and make it their own!
## Overview
Eliminating CSS in favor of inline styles that are computed on the fly is a powerful approach, providing a number of benefits over traditional CSS:
- Scoped styles without selectors
- Avoids specificity conflicts
- Source order independence
- Dead code elimination
- Highly expressive
Despite that, there are some common CSS features and techniques that inline styles don't easily accommodate: media queries, browser states (:hover, :focus, :active) and modifiers (no more .btn-primary!). Radium offers a standard interface and abstractions for dealing with these problems.
When we say expressive, we mean it: math, concatenation, regex, conditionals, functions–JavaScript is at your disposal. Modern web applications demand that the display changes when data changes, and Radium is here to help.
For a short technical explanation, see [How does Radium work?](#how-does-radium-work).
## Features
- Conceptually simple extension of normal inline styles
- Browser state styles to support `:hover`, `:focus`, and `:active`
- Media queries
- Automatic vendor prefixing
- Keyframes animation helper
- ES6 class and `createClass` support
## Docs
- [Overview][docs_guides]
- [API Docs][docs_api]
- [Frequently Asked Questions (FAQ)][docs_faq]
## Usage
Start by wrapping your component class with `Radium()`, like `export default Radium(Component)`, or `Component = Radium(Component)`, which works with classes, `createClass`, and stateless components (functions that take props and return a ReactElement). Then, write a style object as you normally would with inline styles, and add in styles for interactive states and media queries. Pass the style object to your component via `style={...}` and let Radium do the rest!
```jsx
<Button kind="primary">Radium Button</Button>
```
```jsx
import Radium from 'radium';
import React from 'react';
import color from 'color';
class Button extends React.Component {
static propTypes = {
kind: PropTypes.oneOf(['primary', 'warning']).isRequired
};
render() {
// Radium extends the style attribute to accept an array. It will merge
// the styles in order. We use this feature here to apply the primary
// or warning styles depending on the value of the `kind` prop. Since its
// all just JavaScript, you can use whatever logic you want to decide which
// styles are applied (props, state, context, etc).
return (
<button style={[styles.base, styles[this.props.kind]]}>
{this.props.children}
</button>
);
}
}
Button = Radium(Button);
// You can create your style objects dynamically or share them for
// every instance of the component.
var styles = {
base: {
color: '#fff',
// Adding interactive state couldn't be easier! Add a special key to your
// style object (:hover, :focus, :active, or @media) with the additional rules.
':hover': {
background: color('#0074d9')
.lighten(0.2)
.hexString()
}
},
primary: {
background: '#0074D9'
},
warning: {
background: '#FF4136'
}
};
```
## Importing Radium
As of `v0.22.x`, Radium is built as an ECMAScript Modules-first project. We now have a `package.json:module` entry pointing to our library files with `import|export` statements instead of CommonJS `require`s. We still support CommonJS `require`s with a special `package.json:main` entry pointing to root `index.js` to smooth over this transition. The basic takeaways are:
If you are using **ESM** with **webpack** or **`@std/esm`** with **Node.js**, imports like the following work fine without any gotchas:
```js
import Radium from 'radium';
import Radium, {Style} from 'radium';
```
If you are using **CommonJS** with **Node.js** or **webpack@1** requires work like normal:
```js
const Radium = require('radium');
const {Style} = require('radium');
```
If you are using **CommonJS** with **webpack@2+**, however, you must instead add `.default` to the root `Radium` object import:
```js
const Radium = require('radium').default; // CHANGED: Must add `.default`
const {Style} = require('radium'); // Works as per normal
```
If you cannot change the `require` statements directly (say Radium is included from a different library your project depends on) you can manually tweak the Radium import in your project's webpack configuration with the following:
```js
resolve: {
alias: {
radium: require.resolve('radium/index');
}
}
```
which will allow `const Radium = require('radium');` to still work. The configuration effectively forces webpack to point to code from `package.json:main` (which points to `/index.js`) instead of what is in `package.json:module`.
_Note:_ Radium uses `Reflect` which is not supported in IE11. You will need to bring in a polyfill like [CoreJs](https://github.com/zloirock/core-js#ecmascript-reflect) in order to support <IE11.
## Examples
To see the universal examples:
```
npm install
npm run universal
```
To see local client-side only examples in action, do this:
```
npm install
npm run examples
```
## How does Radium work?
Following is a short technical explanation of Radium's inner workings:
- Wrap the `render` function
- Recurse into the result of the original `render`
- For each element:
- Add handlers to props if interactive styles are specified, e.g. `onMouseEnter` for `:hover`, wrapping existing handlers if necessary
- If any of the handlers are triggered, e.g. by hovering, Radium calls `setState` to update a Radium-specific field on the components state object
- On re-render, resolve any interactive styles that apply, e.g. `:hover`, by looking up the element's key or ref in the Radium-specific state
## More with Radium
You can find a list of other tools, components, and frameworks to help you build with Radium on our [wiki](https://github.com/FormidableLabs/radium/wiki). Contributions welcome!
## Contributing
Please see [CONTRIBUTING](https://github.com/FormidableLabs/radium/blob/master/CONTRIBUTING.md)
[trav_img]: https://api.travis-ci.com/FormidableLabs/radium.svg
[trav_site]: https://travis-ci.com/FormidableLabs/radium
[cov_img]: https://img.shields.io/coveralls/FormidableLabs/radium.svg
[cov_site]: https://coveralls.io/r/FormidableLabs/radium
[npm_img]: https://img.shields.io/npm/v/radium.svg
[npm_site]: https://www.npmjs.org/package/radium
[david_img]: https://img.shields.io/david/FormidableLabs/radium.svg
[david_site]: https://david-dm.org/FormidableLabs/radium
[size_img]: https://badges.herokuapp.com/size/npm/radium/dist/radium.min.js?gzip=true&label=gzipped
[docs_guides]: https://github.com/FormidableLabs/radium/tree/master/docs/guides
[docs_api]: https://github.com/FormidableLabs/radium/tree/master/docs/api
[docs_faq]: https://github.com/FormidableLabs/radium/tree/master/docs/faq
[appveyor_img]: https://ci.appveyor.com/api/projects/status/github/formidablelabs/radium?branch=master&svg=true
[appveyor_site]: https://ci.appveyor.com/project/ryan-roemer/radium
[maintenance-image]: https://img.shields.io/badge/maintenance-archived-red.svg
================================================
FILE: appveyor.yml
================================================
# Test against this version of Node.js
environment:
matrix:
- nodejs_version: "8"
- nodejs_version: "10"
- nodejs_version: "12"
# Install scripts. (runs after repo cloning)
install:
- ps: Install-Product node $env:nodejs_version
- yarn install
# Post-install test scripts.
test_script:
# Output useful info for debugging.
- node --version
- yarn --version
# Run tests
- yarn run build
- yarn run test-ie
# Don't actually build.
build: off
matrix:
fast_finish: true
cache:
- node_modules
- "%LOCALAPPDATA%/Yarn"
================================================
FILE: bower.json
================================================
{
"name": "radium",
"homepage": "https://github.com/FormidableLabs/radium",
"description": "A set of tools to manage inline styles on React elements",
"main": "dist/radium.js",
"keywords": [
"react",
"style",
"inline"
],
"license": "MIT",
"ignore": [
"**/.*",
"CHANGELOG.md",
"CONTRIBUTING.md",
"LICENSE.md",
"README.md",
"appveyor.yml",
"coverage",
"docs",
"examples",
"karma.conf.coverage.js",
"karma.conf.js",
"lib",
"src",
"es",
"scripts",
"node_modules",
"package.json",
"webpack.config.js",
"webpack.config.minified.js"
]
}
================================================
FILE: docs/README.md
================================================
### Overview
The `radium-docs` [documentation site](http://formidable.com/open-source/radium/) source lives here in `/docs`. The `docs/**/docs.js` components are imported into `radium-docs` and deployed from there.
### Deployment
Submit a pull request to `master`. Once it is merged you will need to run `update-project` from within `radium-docs` and merge into `master`. A new push to `master` in `radium-docs` will trigger a deployment.
================================================
FILE: docs/api/README.md
================================================
# Radium API
**Table of Contents**
- [Sample Style Object](#sample-style-object)
- [Radium](#radium)
- [config.matchMedia](#configmatchmedia)
- [config.plugins](#configplugins)
- [config.userAgent](#configuseragent)
- [getState](#getstate)
- [keyframes](#keyframes)
- [Plugins](#plugins)
- [Style Component](#style-component)
- [StyleRoot Component](#styleroot-component)
- [TestMode](#testmode)
## Sample Style Object
```jsx
var styles = {
base: {
backgroundColor: '#0074d9',
border: 0,
borderRadius: '0.3em',
color: '#fff',
cursor: 'pointer',
fontSize: 16,
outline: 'none',
padding: '0.4em 1em',
':hover': {
backgroundColor: '#0088FF'
},
':focus': {
backgroundColor: '#0088FF'
},
':active': {
backgroundColor: '#005299',
transform: 'translateY(2px)',
},
// Media queries must start with @media, and follow the same syntax as CSS
'@media (min-width: 992px)': {
padding: '0.6em 1.2em'
},
'@media (min-width: 1200px)': {
padding: '0.8em 1.5em',
// Media queries can also have nested :hover, :focus, or :active states
':hover': {
backgroundColor: '#329FFF'
}
}
},
red: {
backgroundColor: '#d90000',
':hover': {
backgroundColor: '#FF0000'
},
':focus': {
backgroundColor: '#FF0000'
},
':active': {
backgroundColor: '#990000'
}
}
};
```
## Radium
`Radium` itself is a higher-order component, whose job is to:
- Provide initial state
- Process the `style` attribute after `render()`
- Clean up any resources when the component unmounts
Usage with `class`:
```jsx
class MyComponent extends React.Component { ... }
MyComponent = Radium(MyComponent);
```
Usage with `createClass`:
```jsx
var MyComponent = React.createClass({ ... });
export default Radium(MyComponent);
```
`Radium`'s primary job is to apply interactive or media query styles, but even if you are not using any special styles, the higher order component will still:
- Merge arrays of styles passed as the `style` attribute
- Automatically vendor prefix the `style` object
You can also pass a configuration object to `Radium`:
```jsx
class MyComponent extends React.Component { ... }
MyComponent = Radium({matchMedia: mockMatchMedia})(MyComponent);
// or with createClass
var MyComponent = React.createClass({ ... });
module.exports = Radium({matchMedia: mockMatchMedia})(MyComponent);
```
You may want to have project-wide Radium settings. Simply create a function that
wraps Radium, and use it instead of `Radium`:
```jsx
function ConfiguredRadium(component) {
return Radium(config)(component);
}
// Usage
class MyComponent extends React.Component { ... }
MyComponent = ConfiguredRadium(MyComponent);
```
Radium can be called any number of times with a config object, and later configs
will be merged with and overwrite previous configs. That way, you can still
override settings on a per-component basis:
```jsx
class MySpecialComponent extends React.Component { ... }
MySpecialComponent = ConfiguredRadium(config)(MySpecialComponent);
```
Alternatively, if the config value can change every time the component is rendered (userAgent, for example), you can pass configuration to any component wrapped in `Radium` using the `radiumConfig` prop:
```jsx
<App radiumConfig={{userAgent: req.headers['user-agent']}} />
```
The config will be passed down via [context](https://facebook.github.io/react/docs/context.html) to all child components. Fields in the `radiumConfig` prop or context will override those passed into the `Radium()` function.
Possible configuration values:
- [`matchMedia`](#configmatchmedia)
- [`plugins`](#configplugins)
- [`userAgent`](#configuseragent)
### config.matchMedia
Allows you to replace the `matchMedia` function that Radium uses. The default is `window.matchMedia`, and the primary use case for replacing it is to use media queries on the server. You'll have to send the width and height of the page to the server somehow, and then use a [mock for match media](https://github.com/azazdeaz/match-media-mock) that implements the [`window.matchMedia` API](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia). Your code could look like this:
**Server**
You can require `Radium` on the server / using CommonJS with:
```jsx
var Radium = require('radium');
```
```jsx
var ConfiguredRadium = require('./configured-radium');
var matchMediaMock = require('match-media-mock').create();
ConfiguredRadium.setMatchMedia(matchMediaMock);
app.get('/app/:width/:height', function(req, res) {
matchMediaMock.setConfig({
type: 'screen',
width: req.params.width,
height: req.params.height,
});
// Your application code uses `ConfiguredRadium` instead of `Radium`
var html = React.renderToString(<RadiumApp />);
res.end(html);
});
```
**ConfiguredRadium.js**
```jsx
var Radium = require('radium');
var _matchMedia = null;
function ConfiguredRadium(component) {
return Radium({
matchMedia: _matchMedia
})(component);
}
ConfiguredRadium.setMatchMedia = function (matchMedia) {
_matchMedia = matchMedia;
};
module.exports = ConfiguredRadium;
```
**MyComponent.js**
```jsx
var ConfiguredRadium = require('./configured-radium');
class MyComponent extends React.Component { ... }
MyComponent = ConfiguredRadium(MyComponent);
```
See [#146](https://github.com/FormidableLabs/radium/pull/146) for more info.
### config.plugins
**Array<Plugin>**
Replaces all plugins with the provided set. See [Plugins](#plugins) for more information.
Because the `plugins` config replaces all plugins, you have to provide the built-ins if you want to keep the default Radium functionality. A simple example of creating and adding a `styleLogger` plugin:
```jsx
function styleLogger({componentName, style}) {
console.log('Name: ' + componentName, style);
}
function ConfiguredRadium(component) {
return Radium({
plugins: [
Radium.Plugins.mergeStyleArray,
Radium.Plugins.checkProps,
Radium.Plugins.resolveMediaQueries,
Radium.Plugins.resolveInteractionStyles,
Radium.Plugins.keyframes,
Radium.Plugins.visited,
Radium.Plugins.removeNestedStyles,
Radium.Plugins.prefix,
styleLogger,
Radium.Plugins.checkProps,
],
})(component);
}
// Usage
class MyComponent extends React.Component { ... }
MyComponent = ConfiguredRadium(MyComponent);
```
You will typically want to put plugins before the final `checkProps` so that you can still benefit from the checks it provides. If your plugin might produce other pseudo-style blocks, like `@media` consumed by `resolveMediaQueries` or `:hover` consumed by `resolveInteractionStyles`, you would want to have your plugin run before those plugins.
You can of course omit any or all of the built-in plugins, and replace them with your own version. For example, you may want to omit `Radium.Plugins.prefix` entirely if you aren't using vendor prefixes or are using a [compile-time solution](https://github.com/UXtemple/babel-plugin-react-autoprefix) instead.
### config.userAgent
**string**
Set the user agent passed to [inline-style-prefixer](https://github.com/rofrischmann/inline-style-prefixer) to perform prefixing on style objects. Mainly used during server rendering, passed in via the `radiumConfig` prop. Using express:
```jsx
<App radiumConfig={{userAgent: req.headers['user-agent']}} />
```
For a complete example, see [examples/server.js](https://github.com/FormidableLabs/radium/blob/master/examples/server.js).
## getState
**Radium.getState(state, elementKey, value)**
_Note: `getState` will not work in a stateless component, because even though Radium maintains the state internally, the stateless component does not have access to it, by definition_
Query Radium's knowledge of the browser state for a given element key. This is particularly useful if you would like to set styles for one element when another element is in a particular state, e.g. show a message when a button is hovered.
Note that the target element specified by `elementKey` must have the state you'd like to check defined in its style object so that Radium knows to add the handlers. It can be empty, e.g. `':hover': {}`.
Parameters:
- **state** - you'll usually pass `this.state`, but sometimes you may want to pass a previous state, like in `shouldComponentUpdate`, `componentWillUpdate`, and `componentDidUpdate`
- **elementKey** - if you used multiple elements, pass the same `key=""` or `ref=""`. If you only have one element, you can leave it blank (`'main'` will be inferred)
- **value** - one of the following: `:active`, `:focus`, and `:hover`
- **returns** `true` or `false`
Usage:
```jsx
Radium.getState(this.state, 'button', ':hover')
```
## keyframes
**Radium.keyframes(keyframes, [name])**
Create a keyframes animation for use in an inline style. `keyframes` returns an opaque object you must assign to the `animationName` property. `Plugins.keyframes` detects the object and adds CSS to the Radium root's style sheet. Radium will automatically apply vendor prefixing to keyframe styles. In order to use `keyframes`, you must wrap your application in the [`StyleRoot component`](#styleroot-component).
`keyframes` takes an optional second parameter, a `name` to prepend to the animation's name to aid in debugging.
```jsx
class Spinner extends React.Component {
render () {
return (
<div>
<div style={styles.inner} />
</div>
);
}
}
Spinner = Radium(Spinner);
var pulseKeyframes = Radium.keyframes({
'0%': {width: '10%'},
'50%': {width: '50%'},
'100%': {width: '10%'},
}, 'pulse');
var styles = {
inner: {
// Use a placeholder animation name in `animation`
animation: 'x 3s ease 0s infinite',
// Assign the result of `keyframes` to `animationName`
animationName: pulseKeyframes,
background: 'blue',
height: '4px',
margin: '0 auto',
}
};
```
Multiple keyframe animations can be chained together by passing an array of `keyframes` objects
as the value of the `animationName` property. These keyframe animations timing and iteration count
can be managed with [traditional css rules for keyframe animations](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Using_CSS_animations)
```jsx
@Radium
class Spinner extends React.Component {
render () {
return (
<div>
<div style={styles.inner} />
</div>
);
}
}
const pulseAnimation = Radium.keyframes(
{
'0%': {width: '10%'},
'50%': {width: '50%'},
'100%': {width: '10%'},
},
'pulse',
);
const blendAnimation = Radium.keyframes(
{
'0%': {background: 'red'},
'25%': {background: 'yellow'},
'50%': {background: 'green'},
'75%': {background: 'blue'},
'100%': {background: 'red'},
},
'blend',
);
const styles = {
inner: {
animationName: [pulseAnimation, blendAnimation],
animationDuration: '2.5s, 8s',
animationIterationCount: 'infinite, infinite',
animationTimingFunction: 'linear, cubic-bezier(0.1, 0.7, 1.0, 0.1)',
height: '4px',
margin: '0 auto',
},
};
```
## Plugins
### Built-in Plugins
Almost everything that Radium does, except iteration, is implemented as a plugin. Radium ships with a base set of plugins, all of which can be accessed via `Radium.Plugins.pluginName`. They are called in the following order:
- `mergeStyleArray` - If the `style` attribute is an array, intelligently merge each style object in the array. Deep merges nested style objects, such as `:hover`.
- `checkProps` - Performs basic correctness checks, such as ensuring you do not mix longhand and shorthand properties.
- `resolveMediaQueries` - Handles style entries like `'@media (...)': { ... }`, applying them only when the appropriate media query is hit. Can be configured using [config.matchMedia](#configmatchmedia).
- `resolveInteractionStyles` - Handles `':hover'`, `':focus'`, and `':active'` styles.
- `prefix` - Uses in-browser detection and a small mapping to add vendor prefixes to CSS properties and values.
- `checkProps` - Same as above, just run after everything else.
### Plugin Interface
All plugins are functions accept a PluginConfig, and return a PluginResult. The annotated flow types follow. A plugin is called once for every *rendered element* that has a `style` attribute, for example the `div` and `span` in `return <div style={...}><span style={...} /></div>;`.
**PluginConfig**
```jsx
type PluginConfig = {
// Adds a chunk of css to the root style sheet
addCSS: (css: string) => {remove: () => void},
// Helper function when adding CSS
appendImportantToEachValue: (style: Object) => Object;
// May not be readable if code has been minified
componentName: string,
// The Radium configuration
config: Config,
// Converts an object of CSS rules to a string, for use with addCSS
cssRuleSetToString: (
selector: string,
rules: Object,
userAgent: ?string,
) => string,
// Retrieve the value of a field on the component
getComponentField: (key: string) => any,
// Retrieve the value of a field global to the Radium module
// Used so that tests can easily clear global state.
getGlobalState: (key: string) => any,
// Retrieve the value of some state specific to the rendered element.
// Requires the element to have a unique key or ref or for an element key
// to be passed in.
getState: (stateKey: string, elementKey?: string) => any,
// Helper function when adding CSS
hash: (data: string) => string,
// Returns true if the value is a nested style object
isNestedStyle: (value: any) => bool,
// Access to the mergeStyles utility
mergeStyles: (styles: Array<Object>) => Object,
// The props of the rendered element. This can be changed by each plugin,
// and successive plugins will see the result of previous plugins.
props: Object,
// Calls setState on the component with the given key and value.
// By default this is specific to the rendered element, but you can override
// by passing in the `elementKey` parameter.
setState: (stateKey: string, value: any, elementKey?: string) => void,
// The style prop of the rendered element. This can be changed by each plugin,
// and successive plugins will see the result of previous plugins. Kept
// separate from `props` for ease of use.
style: Object,
// uses the exenv npm module
ExecutionEnvironment: {
canUseEventListeners: bool,
canUseDOM: bool,
}
};
```
**PluginResult**
```jsx
type PluginResult = ?{
// Merged into the component directly. Useful for storing things for which you
// don't need to re-render, event subscriptions, for instance.
componentFields?: Object,
// Merged into a Radium controlled global state object. Use this instead of
// module level state for ease of clearing state between tests.
globalState?: Object,
// Merged into the rendered element's props.
props?: Object,
// Replaces (not merged into) the rendered element's style property.
style?: Object,
};
```
If your plugin consumes custom style blocks, it should merge any applicable style blocks and strip any others out of the style object before returning to avoid errors farther down. For example, a hypothetical `enumPropResolver` might know how to resolve keys of the form `'propName=value'`, such that if `this.props.propName === 'value'`, it will merge in that style object. `enumPropResolver` should then also strip any other keys that will not be merged. Thus, if this style object is passed to `enumPropResolver`, and `this.props.type === 'error'`:
```jsx
{
'type=success': {color: 'blue'},
'type=error': {color: 'red'},
'type=warning': {color: 'yellow'},
}
```
`enumPropResolver` should then return an object with the style property equal to:
```jsx
{
color: 'red'
}
```
## Style Component
The `<Style>` component renders an HTML `<style>` tag containing a set of CSS rules. Using it, you can define an optional `scopeSelector` that all selectors in the resulting `<style>` element will include.
Without the `<Style>` component, it is prohibitively difficult to write a `<style>` element in React. To write a normal `<style>` element, you need to write your CSS as a multiline string inside of the element. `<Style>` simplifies this process, and adds prefixing and the ability to scope selectors.
If you include a `scopeSelector`, you can include CSS rules that should apply to that selector as well as any nested selectors. For example, the following
```jsx
<Style
scopeSelector=".scoping-class"
rules={{
color: 'blue',
span: {
fontFamily: 'Lucida Console, Monaco, monospace'
}
}}
/>
```
will return:
```html
<style>
.scoping-class {
color: 'blue';
}
.scoping-class span {
font-family: 'Lucida Console, Monaco, monospace';
}
</style>
```
### Props
#### rules
An object of CSS rules to render. Each key of the rules object is a CSS selector and the value is an object of styles. If rules is empty, the component will render nothing.
```jsx
var Radium = require('radium');
var Style = Radium.Style;
// or
import Radium, { Style } from 'radium';
<Style rules={{
body: {
margin: 0,
fontFamily: 'Helvetica Neue, Helvetica, Arial, sans-serif'
},
html: {
background: '#ccc',
fontSize: '100%'
},
mediaQueries: {
'(min-width: 550px)': {
html: {
fontSize: '120%'
}
},
'(min-width: 1200px)': {
html: {
fontSize: '140%'
}
}
},
'h1, h2, h3': {
fontWeight: 'bold'
}
}} />
```
#### scopeSelector
A string that any included selectors in `rules` will be appended to. Use to scope styles in the component to a particular element. A good use case might be to generate a unique ID for a component to scope any styles to the particular component that owns the `<Style>` component instance.
```jsx
<div className="TestClass">
<Style
scopeSelector=".TestClass"
rules={{
h1: {
fontSize: '2em'
}
}}
/>
</div>
```
### Notes
Some style properties, like [`content`](https://developer.mozilla.org/en-US/docs/Web/CSS/content), allow quoted strings or keywords as values. Because all non-numerical property values are written
as strings in Radium style objects, you must explicitly add quotes to string value for these properties: `content: "'Hello World!'"`.
## StyleRoot Component
_Props: Accepts all props valid on `div` and optional `radiumConfig`_
Usually wrapped around your top-level App component. StyleRoot wraps its children in a plain div followed by the root style sheet. Radium plugins, like keyframes and media queries, use this style sheet to inject CSS at runtime. Because the style sheet appears after your rendered elements, it is populated correctly during a server render.
StyleRoot transfers all of its props to the rendered `div`, and is itself wrapped in Radium, so you can pass it inline styles or `radiumConfig`.
```jsx
import {StyleRoot} from 'radium';
class App extends React.Component {
render() {
return (
<StyleRoot>
... rest of your app ...
</StyleRoot>
);
}
}
```
**Note:** StyleRoot passes the style-keeper (the object where styles are collected) down to other Radium components via context. Because of this, you cannot use keyframes or media queries in *direct children* of the `<StyleRoot>`, e.g.
```jsx
// COUNTEREXAMPLE, DOES NOT WORK
<StyleRoot>
<div style={{'@media print': {color: 'black'}}} />
</StyleRoot>
```
You'll have to break out that piece into a proper component:
```jsx
class BodyText extends React.Component {
render() {
return <div style={{'@media print': {color: 'black'}}} />;
}
}
class App extends React.Component {
render() {
return (
<StyleRoot>
<BodyText>...</BodyText>
</StyleRoot>
);
}
}
```
## TestMode
Directly off the main Radium object you can access `TestMode`, used to control internal Radium state and behavior during tests. It is only available in non-production builds.
- `Radium.TestMode.clearState()` - clears the global Radium state, currently only the cache of media query listeners.
- `Radium.TestMode.enable()` - enables "test mode", which doesn’t throw or warn as much. Currently it just doesn’t throw when using addCSS without StyleRoot.
- `Radium.TestMode.disable()` - disables "test mode"
================================================
FILE: docs/faq/README.md
================================================
# Frequently Asked Questions
- [How do I use pseudo-selectors like `:checked`, `:last`, `:before`, or `:after`?](#how-do-i-use-pseudo-selectors-like-checked-last-before-or-after)
- [How can I use `ReactCSSTransitionGroup` without any classes?](#how-can-i-use-reactcsstransitiongroup-without-any-classes)
- [How can I use Radium with jsbin?](#how-can-i-use-radium-with-jsbin)
- [Can I use my favourite CSS/LESS/SASS syntax?](#can-i-use-my-favourite-csslesssass-syntax)
- [Can I use Radium with Bootstrap?](#can-i-use-radium-with-bootstrap)
- [Why doesn't Radium work on react-router's Link, or react-bootstrap's Button, or SomeOtherComponent?](#why-doesnt-radium-work-on-react-routers-link-or-react-bootstraps-button-or-someothercomponent)
- [How can I get rid of `userAgent` warnings in tests?](#how-can-i-get-rid-of-useragent-warnings-in-tests)
- [Why do React warnings have the wrong component name?](#why-do-react-warnings-have-the-wrong-component-name)
- [Why does the browser state of a child element not reset after unmounting and remounting?](#why-does-the-browser-state-of-a-child-element-not-reset-after-unmounting-and-remounting)
## How do I use pseudo-selectors like `:checked`, `:last`, `:before`, or `:after`?
Radium only provides the interactivity pseudo-selectors `:hover`, `:active`, and `:focus`. You need to use JavaScript logic to implement the others. To implement `:checked` for example:
```jsx
class CheckForBold extends React.Component {
constructor() {
super();
this.state = {isChecked: false};
}
_onChange = () => {
this.setState({isChecked: !this.state.isChecked});
};
render() {
return (
<label style={{fontWeight: this.state.isChecked ? 'bold' : 'normal'}}>
<input
checked={this.state.isChecked}
onChange={this._onChange}
type="checkbox"
/>
{' '}Check for bold
</label>
);
}
}
```
Instead of `:first` and `:last`, change behavior during array iteration. Note that the border property is broken down into parts to avoid complications as in issue [#95](https://github.com/FormidableLabs/radium/issues/95).
```jsx
var droids = [
'R2-D2',
'C-3PO',
'Huyang',
'Droideka',
'Probe Droid'
];
class DroidList extends React.Component {
render() {
return (
<ul style={{padding: 0}}>
{droids.map((droid, index, arr) =>
<li key={index} style={{
borderColor: 'black',
borderRadius: index === 0 ? '12px 12px 0 0' :
index === (arr.length - 1) ? '0 0 12px 12px' : '',
borderStyle: 'solid',
borderWidth: index === (arr.length - 1) ? '1px' : '1px 1px 0 1px',
cursor: 'pointer',
listStyle: 'none',
padding: 12,
':hover': {
background: '#eee'
}
}}>
{droid}
</li>
)}
</ul>
);
}
}
DroidList = Radium(DroidList);
```
Instead of `:before` and `:after`, add extra elements when rendering your HTML.
## How can I use `ReactCSSTransitionGroup` without any classes?
Try out the experimental [`ReactStyleTransitionGroup`](https://github.com/adambbecker/react-style-transition-group) instead.
## How can I use Radium with jsbin?
To get the latest version, drop this into the HTML:
```html
<script src="https://unpkg.com/radium/dist/radium.js"></script>
```
We also recommend changing the JavaScript language to ES6/Babel.
## Can I use my favourite CSS/LESS/SASS syntax?
Yes, with the help of the [react-styling](https://github.com/halt-hammerzeit/react-styling) module, which requires [template strings](https://babeljs.io/docs/learn-es2015/#template-strings). Using react-styling you can write your styles in any syntax you like (curly braces or tabs, CSS, LESS/SASS, anything will do).
The example from the main Readme (using regular CSS syntax)
```jsx
<Button kind="primary">Radium Button</Button>
```
```jsx
import styler from 'react-styling/flat'
class Button extends React.Component {
static propTypes = {
kind: PropTypes.oneOf(['primary', 'warning']).isRequired
}
render() {
return (
<button style={style[`button_${this.props.kind}`]}>
{this.props.children}
</button>
)
}
}
Button = Radium(Button);
const style = styler`
.button {
color: #fff;
:hover {
background: ${color('#0074d9').lighten(0.2).hexString()};
}
&.primary {
background: #0074D9;
}
&.warning {
background: #FF4136;
}
}
`
```
You can find a more advanced example in the [react-styling readme](https://github.com/halt-hammerzeit/react-styling#radium).
## Can I use Radium with Bootstrap?
See issue [#323](https://github.com/FormidableLabs/radium/issues/323) for discussion.
## Why doesn't Radium work on react-router's Link, or react-bootstrap's Button, or SomeOtherComponent?
Radium doesn't mess with the `style` prop of non-DOM elements. This includes thin wrappers like `react-router`'s `Link` component. We can't assume that a custom component will use `style` the same way DOM elements do. For instance, it could be a string enum to select a specific style. In order for resolving `style` on a custom element to work, that element needs to actually pass that `style` prop to the DOM element underneath, in addition to passing down all the event handlers (`onMouseEnter`, etc). Since Radium has no control over the implementation of other components, resolving styles on them is not safe.
A workaround is to wrap your custom component in Radium, even if you do not have the source, like this:
```jsx
var Link = require('react-router').Link;
Link = Radium(Link);
```
Huge thanks to [@mairh](https://github.com/mairh) for coming up with this idea in issue [#324](https://github.com/FormidableLabs/radium/issues/324).
We are also exploring adding a mechanism to bypass Radium's check, see issue [#258](https://github.com/FormidableLabs/radium/issues/258).
## How can I get rid of `userAgent` warnings in tests?
You might see warnings like this when testing React components that use Radium:
```
Radium: userAgent should be supplied for server-side rendering. See https://github.com/FormidableLabs/radium/tree/master
/docs/api#radium for more information.
Either the global navigator was undefined or an invalid userAgent was provided. Using a valid userAgent? Please let us k
now and create an issue at https://github.com/rofrischmann/inline-style-prefixer/issues
```
This isn't an issue if you run your tests in a browser-like environment such as jsdom or PhantomJS, but if you just run them in Node, there will be no userAgent defined. In your test setup, you can define one:
```jsx
global.navigator = {userAgent: 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2454.85 Safari/537.36'};
```
Make sure it is a real user agent that `inline-style-prefixer` recognizes, or you'll still get the second error. The above UA is [Chrome 49 from the `inline-style-prefixer` tests](https://github.com/rofrischmann/inline-style-prefixer/blob/master/test/prefixer-test.js).
## Why do React warnings have the wrong component name?
You may see the name "Constructor" instead of your component name, for example: "Warning: Failed propType: Invalid prop `onClick` of type `function` supplied to `Constructor`, expected `string`." or "Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of `Constructor`."
Your transpiler is probably not able to set the `displayName` property of the component correctly, which can happen if you wrap `React.createClass` immediately with `Radium`, e.g. `var Button = Radium(React.createClass({ ... }));`. Instead, wrap your component afterward, ex. `Button = Radium(Button);`, or when exporting, ex. `export default Radium(Button);`, or set `displayName` manually.
## Why does the browser state of a child element not reset after unmounting and remounting?
If you have an element that takes a browser state (e.g. `:active`, `:hover`, `:focus`), you need to give it a unique `key` prop. There is a case where if you only have a single element in your component that takes an interactive style, you do not need to provide a `key`; however, if you remove the element and show it again, it will maintain it's state, which is usually unexpected behavior. To fix this, simply give it a custom `key` prop.
================================================
FILE: docs/guides/README.md
================================================
# Using Radium
**Table of Contents**
- [How do I do it, then?](#how-do-i-do-it-then)
- [Modifiers](#modifiers)
- [Browser States](#browser-states)
- [Media Queries](#media-queries)
- [Nested browser states](#nested-browser-states)
- [Known issues with media queries](#known-issues-with-media-queries)
- [Styling Multiple Elements in a Single Component](#styling-multiple-elements-in-a-single-component)
- [Styling one element depending on another's state](#styling-one-element-depending-on-anothers-state)
- [Fallback Values](#fallback-values)
- [Style Component](#style-component)
Radium is a toolset for easily writing React component styles. It resolves browser states and media queries to apply the correct styles to your components, all without selectors, specificity, or source order dependence.
## How do I do it, then?
First, require or import Radium at the top of component file:
```jsx
import Radium from 'radium';
// If you want to use the <Style /> component you can do
import Radium, { Style } from 'radium';
```
Let's create a fictional `<Button>` component. It will have a set of default styles, will adjust its appearance based on modifiers, and will include hover, focus, and active states.
```jsx
class Button extends React.Component {
render() {
return (
<button>
{this.props.children}
</button>
);
}
}
```
Radium is activated by wrapping your component:
```jsx
class Button extends React.Component {
// ...
}
export default Radium(Button);
// or
class Button extends React.Component {
// ...
}
Button = Radium(Button);
```
Radium resolves nested style objects into a flat object that can be applied directly to a React element. If you're not familiar with handling inline styles in React, see the React guide to the subject [here](https://reactjs.org/docs/dom-elements.html#style). A basic style object looks like this:
```jsx
var baseStyles = {
background: 'blue',
border: 0,
borderRadius: 4,
color: 'white',
padding: '1.5em'
};
```
We usually nest styles inside a shared `styles` object for easy access:
```jsx
var styles = {
base: {
background: 'blue',
border: 0,
borderRadius: 4,
color: 'white',
padding: '1.5em'
}
};
```
Next, simply pass your styles to the `style` attribute of an element:
```jsx
// Inside render
return (
<button style={styles.base}>
{this.props.children}
</button>
);
```
From there, React will apply our styles to the `button` element. This is not very exciting. In fact, React does this by default, without the extra step of using Radium. Radium becomes useful when you need to do more complex things, like handling modifiers, states, and media queries. But, even without those complex things, Radium will still merge an array of styles and automatically apply vendor prefixes for you.
## Modifiers
Radium provides one shorthand for dealing with styles that are modified by your props or state. You can pass an array of style objects to the `style` attribute, and they will be merged together intelligently (`:hover` states, for instance, will merge instead of overwrite). This works the same way as it does in [React Native](https://facebook.github.io/react-native/docs/style.html#using-styles).
```jsx
<Button
size="large"
block={true}>
Cool Button!
</Button>
```
Start by adding another style to your `styles` object:
```jsx
var styles = {
base: {
background: 'blue',
border: 0,
borderRadius: 4,
color: 'white',
padding: '1.5em'
},
block: {
display: 'block'
}
};
```
Then, include that style object in the array passed to the `style` attribute if the conditions match:
```jsx
// Inside render
return (
<button
style={[
styles.base,
this.props.block && styles.block
]}>
{this.props.children}
</button>
);
```
Radium will ignore any elements of the array that aren't objects, such as the result of `this.props.block && styles.block` when `this.props.block` is `false` or `undefined`.
## Browser States
Radium supports styling for three browser states that are targeted with pseudo-selectors in normal CSS: `:hover`, `:focus`, and `:active`.
To add styles for these states, add a special key to your style object with the additional rules. Additionally, you will need to add a unique `key` prop to the elements that take these styles:
```jsx
var styles = {
base: {
background: 'blue',
border: 0,
borderRadius: 4,
color: 'white',
padding: '1.5em',
':hover': {
backgroundColor: 'red'
},
':focus': {
backgroundColor: 'green'
},
':active': {
backgroundColor: 'yellow'
},
},
block: {
display: 'block',
':hover': {
boxShadow: '0 3px 0 rgba(0,0,0,0.2)'
}
},
};
class MyComponent extends Component {
...
render() {
return (
<div key="1" style={styles.base}>
<div key="2" style={styles.block} />
</div>
);
}
...
}
export default Radium(MyComponent);
```
Radium will merge styles for any active states when your component is rendered. If you are having trouble with browser states, check out [this section](https://github.com/FormidableLabs/radium/tree/master/docs/faq#why-does-the-browser-state-of-a-child-element-not-reset-after-unmounting-and-remounting) of the FAQ.
## Media queries
Add media queries to your style objects the same way as you would add browser state modifiers like `:hover`. The key must start with `@media`, and the [syntax](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Media_queries) is identical to CSS:
```jsx
var style = {
width: '25%',
'@media (min-width: 320px)': {
width: '100%'
}
};
```
Radium will apply the correct styles for the currently active media queries. Top level CSS rules in your media queries will be converted to CSS and rendered in an actual `<style>` element with `!important` appended instead of being applied inline so they will work with server-side rendering. Note that you must wrap your top-level component in the `<StyleRoot>` component to render the Radium stylesheet. Print styles will also work as normal, since they are rendered to CSS.
### Nested browser states
Media query styles can also contain nested browser states:
```jsx
var style = {
width: '25%',
'@media (min-width: 320px)': {
width: '100%',
':hover': {
background: 'white'
}
}
};
```
### Known issues with media queries
#### IE9 Support
IE9 supports CSS media queries, but doesn't support the `matchMedia` API. You'll need a [polyfill that includes addListener](https://github.com/paulirish/matchMedia.js/).
## Styling multiple elements in a single component
Radium allows you to style multiple elements in the same component. You just have to give each element that has browser state modifiers like :hover or media queries a unique `key` or `ref` attribute:
```jsx
// Inside render
return (
<div>
<div key="one" style={[styles.both, styles.one]} />
<div key="two" style={[styles.both, styles.two]} />
</div>
);
var styles = {
both: {
background: 'black',
border: 'solid 1px white',
height: 100,
width: 100
},
one: {
':hover': {
background: 'blue',
}
},
two: {
':hover': {
background: 'red',
}
}
};
```
## Styling one element depending on another's state
You can query Radium's state using `Radium.getState`. This allows you to style or render one element based on the state of another, e.g. showing a message when a button is hovered.
```jsx
// Inside render
return (
<div>
<button key="keyForButton" style={[styles.button]}>Hover me!</button>
{Radium.getState(this.state, 'keyForButton', ':hover') ? (
<span>{' '}Hovering!</span>
) : null}
</div>
);
var styles = {
button: {
// Even though we don't have any special styles on the button, we need
// to add empty :hover styles here to tell Radium to track this element's
// state.
':hover': {}
}
};
```
## Fallback values
Sometimes you need to provide an additional value for a single CSS property in case the first one isn't applied successfully. Simply pass an array of values, and Radium will test them and apply the first one that works:
```jsx
var styles = {
button: {
background: ['rgba(255, 255, 255, .5)', '#fff']
}
};
```
Is equivalent to the following CSS (note that the order is reversed):
```css
.button {
background: #fff;
background: rgba(255, 255, 255, .5);
}
```
## `<Style>` component
Want to add a style selector within your component? Need to pass properties to the `html` and `body` elements or group selectors (e.g. `h1, h2, h3`) that share properties? Radium has you covered with the `<Style />` component - read how to use it [here](https://github.com/FormidableLabs/radium/tree/master/docs/api#style-component).
================================================
FILE: docs/guides/upgrade-v0.16.x.md
================================================
# v0.16.x Upgrade Guide
Version `0.16.x` brought a handful of [breaking, but really good changes](https://github.com/FormidableLabs/radium/blob/master/CHANGELOG.md#breaking-changes). Here's how you upgrade your app.
## Keyframes and Media Queries with Server Side Rendering
If you're using keyframes or media queries, you will need to wrap the top-level component in a `<StyleRoot/>` component.
You can't use keyframes or media queries in the direct children of `<StyleRoot/>`. See the docs for more details: https://github.com/FormidableLabs/radium/tree/master/docs/api#styleroot-component
### How to Make the Change
Old syntax (`v0.15.x`)
```jsx
import Radium from 'radium';
@Radium
class App extends React.Component {
render() {
return (
<div>
... rest of your app ...
</div>
);
}
}
```
New syntax (`v0.16.x`)
```jsx
import {StyleRoot} from 'radium';
// No need for @Radium decorator; StyleRoot is already wrapped.
class App extends React.Component {
render() {
return (
<StyleRoot>
... rest of your app ...
</StyleRoot>
);
}
}
```
## Keyframes
Wrap your root component in `<StyleRoot/>` (see above).
The result of Radium.keyframes is now a placeholder object that Radium processes at render time, and must be assigned to the animationName prop.
https://github.com/FormidableLabs/radium/tree/master/docs/api#keyframes
### How to Make the Change
Old syntax (`v0.15.x`)
```jsx
import Radium from 'radium';
@Radium
class Spinner extends React.Component {
render() {
return (
<div>
<div style={styles.inner} />
</div>
);
}
}
var pulseKeyframes = Radium.keyframes({
'0%': { width: '10%' },
'50%': { width: '50%' },
'100%': { width: '10%' },
});
var styles = {
inner: {
animation: pulseKeyframes + ' 3s ease 0s infinite',
background: 'blue',
height: '4px',
margin: '0 auto',
}
};
```
New syntax (`v0.16.x`)
```jsx
import Radium from 'radium';
@Radium
class Spinner extends React.Component {
render () {
return (
<div>
<div style={styles.inner} />
</div>
);
}
}
var pulseKeyframes = Radium.keyframes({
'0%': { width: '10%' },
'50%': { width: '50%' },
'100%': { width: '10%' },
}, 'pulse');
var styles = {
inner: {
// Use a placeholder animation name (e.g. x) in `animation`
animation: 'x 3s ease 0s infinite',
// Assign the result of `keyframes` to `animationName`
animationName: pulseKeyframes,
background: 'blue',
height: '4px',
margin: '0 auto',
}
};
```
## Print Styles
`printStyles` have been removed, in favor of `@media print` media queries, which are now rendered as CSS so they work correctly: https://github.com/FormidableLabs/radium/tree/master/docs/guides#media-queries
In any component you were declaring a static `printStyles` property before, you now define the print styles using media queries: `{'@media print': { ... }}`
### How to Make the Change
Old syntax (`v0.15.x`)
```jsx
import {PrintStyleSheet} from 'radium';
@Radium
class MyComponent extends React.Component {
static printStyles = {
wrapper: { background: 'white' },
text: { color: 'black' }
};
render() {
return (
<div className={this.printStyleClass.wrapper}>
<p className={this.printStyleClass.text}>Prints as black text on white background</p>
</div>
);
}
}
class App extends React.Component {
render() {
return (
<div>
<PrintStyleSheet />
<MyComponent/>
</div>
);
}
}
```
New syntax (`v0.16.x`)
```jsx
import {StyleRoot} from 'radium';
@Radium
class MyComponent extends React.Component {
render() {
return (
<div style={{'@media print': { color: white }}}>
<p style={{'@media print': { color: black }}}>Prints as black text on white background</p>
</div>
);
}
}
class App extends React.Component {
render() {
return (
<StyleRoot>
<MyComponent/>
</StyleRoot>
);
}
}
```
================================================
FILE: examples/app.js
================================================
/**
* The examples provided by Formidable Labs are for non-commercial testing and
* evaluation purposes only. Formidable Labs reserves all rights not expressly
* granted.
*
* 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
* FORMIDABLE LABS 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.
*/
/* eslint-disable no-use-before-define */
import React from 'react';
import {resetListStyle, resetBoxModel} from './common.styles';
import Button from './components/button';
import ComputedWell from './components/computed-well';
import Radium, {getState, keyframes, Style, StyleRoot} from '../src';
//
// Radium with ES6 class syntax
//
class HoverMessage extends React.Component {
render() {
return (
<div>
<button key="button" style={{display: 'flex', ':hover': {}}}>
Hover me!
</button>
{getState(this.state, 'button', ':hover') ? (
<span> Hovering!</span>
) : null}
</div>
);
}
}
HoverMessage = Radium(HoverMessage);
//
// Radium with ES7 decorator
//
@Radium
class TwoSquares extends React.Component {
render() {
return (
<div>
<div key="one" style={[squareStyles.all, squareStyles.one]} />
<div key="two" style={[squareStyles.all, squareStyles.two]} />
<div
disabled
key="three"
style={[squareStyles.all, squareStyles.three]}
/>
<div style={{clear: 'both'}} />
</div>
);
}
}
class Spinner extends React.Component {
render() {
return (
<div>
<div
style={[spinnerStyles.inner, {'@media print': {height: '10px'}}]}
/>
</div>
);
}
}
Spinner = Radium(Spinner);
class MultiSpinner extends React.Component {
render() {
return (
<div>
<div
style={[
multiAnimationStyles.inner,
{'@media print': {height: '10px'}}
]}
/>
</div>
);
}
}
MultiSpinner = Radium(MultiSpinner);
const VisitedLink = Radium(() => (
<a
href="https://github.com/formidablelabs/radium"
style={{color: 'gray', ':visited': {color: 'black'}}}
>
https://github.com/formidablelabs/radium
</a>
));
class App extends React.Component {
_remount() {
this.setState({shouldRenderNull: true});
setTimeout(
function() {
this.setState({shouldRenderNull: false});
}.bind(this),
100
);
}
render() {
if (this.state && this.state.shouldRenderNull) {
return null;
}
return (
<StyleRoot>
<VisitedLink />
<p />
<HoverMessage />
<p />
<TwoSquares />
<p />
<Spinner />
<p />
<MultiSpinner />
<p />
<Button onClick={this._remount.bind(this)}>Unmount and remount</Button>
<p />
<Button>Button</Button>
<p />
<Button color="red">Button</Button>
<p />
<Button
style={{
fontSize: '1.5em',
borderRadius: 3
}}
>
Button
</Button>
<div style={{margin: '20px 0', width: 220}}>
{Array.apply(null, Array(100)).map(function(_, i) {
return <div key={'tile' + i} style={tileStyle} />;
})}
<div style={{clear: 'both'}} />
</div>
<ul style={listStyle}>
<li>
Create and use reusable rules with the help of spread operators.
</li>
</ul>
<Style
rules={{
body: {
margin: 0,
fontFamily: 'Helvetica Neue, Helvetica, Arial, sans-serif'
},
mediaQueries: {
'(max-width: 600px)': {
body: {
background: 'gray'
}
},
'(max-width: 500px)': {
body: {
background: 'blue'
},
'p, h1': {
color: 'white'
}
}
}
}}
/>
<ComputedWell>Click me!</ComputedWell>
<div className="scoping-class">
<Style
rules={{
span: {
fontFamily: 'Lucida Console, Monaco, monospace'
},
color: 'blue'
}}
scopeSelector=".scoping-class"
/>
<span>This content has scoped styles</span>
</div>
</StyleRoot>
);
}
}
App = Radium(App);
const squareStyles = {
all: {
background: 'black',
border: 'solid 1px white',
float: 'left',
height: 100,
width: 100
},
one: {
':hover': {
background: 'blue'
}
},
two: {
':hover': {
background: 'red'
}
},
three: {
':hover': {
background: 'yellow'
},
':disabled': {
background: 'red'
}
}
};
const tileStyle = {
display: 'block',
float: 'left',
background: '#ccc',
width: 20,
height: 20,
textAlign: 'center',
border: '1px solid white',
cursor: 'pointer',
':hover': {
background: '#999'
}
};
const pulseAnimation = keyframes(
{
'0%': {width: '10%'},
'50%': {width: '50%'},
'100%': {width: '10%'}
},
'pulse'
);
const blendAnimation = Radium.keyframes(
{
'0%': {background: 'red'},
'25%': {background: 'yellow'},
'50%': {background: 'green'},
'75%': {background: 'blue'},
'100%': {background: 'red'}
},
'blend'
);
const spinnerStyles = {
inner: {
animation: 'x 3s ease 0s infinite',
animationName: pulseAnimation,
background: 'blue',
height: '4px',
margin: '0 auto'
}
};
const multiAnimationStyles = {
inner: {
animationName: [pulseAnimation, blendAnimation],
animationDuration: '2.5s, 8s',
animationIterationCount: 'infinite, infinite',
animationTimingFunction: 'linear, cubic-bezier(0.1, 0.7, 1.0, 0.1)',
height: '4px',
margin: '0 auto'
}
};
const listStyle = {
...resetListStyle,
...resetBoxModel,
marginTop: 15,
marginBottom: 15,
marginLeft: 15,
marginRight: 15
};
export default App;
================================================
FILE: examples/client.js
================================================
/**
* The examples provided by Formidable Labs are for non-commercial testing and
* evaluation purposes only. Formidable Labs reserves all rights not expressly
* granted.
*
* 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
* FORMIDABLE LABS 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.
*/
import React from 'react';
import ReactDOM from 'react-dom';
import App from './app';
ReactDOM.render(<App />, document.getElementById('app'));
================================================
FILE: examples/common.styles.js
================================================
export const resetListStyle = {
listStyle: 'none'
};
export const resetBoxModel = {
marginTop: 0,
marginRight: 0,
marginBottom: 0,
marginLeft: 0,
paddingTop: 0,
paddingRight: 0,
paddingBottom: 0,
paddingLeft: 0
};
================================================
FILE: examples/components/button.js
================================================
/**
* The examples provided by Formidable Labs are for non-commercial testing and
* evaluation purposes only. Formidable Labs reserves all rights not expressly
* granted.
*
* 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
* FORMIDABLE LABS 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.
*/
/* eslint-disable no-use-before-define */
import React from 'react';
import PropTypes from 'prop-types';
import Radium from '../../src';
@Radium
class Button extends React.Component {
render() {
return (
<button
onClick={this.props.onClick}
style={[
styles.base,
this.props.color === 'red' && styles.red,
this.props.style
]}
>
{this.props.children}
</button>
);
}
}
Button.propTypes = {
color: PropTypes.string,
onClick: PropTypes.func
};
const styles = {
base: {
fontSize: 16,
backgroundColor: '#0074d9',
color: '#fff',
border: 0,
borderRadius: '0.3em',
padding: '0.4em 1em',
cursor: 'pointer',
outline: 'none',
'@media (min-width: 992px)': {
padding: '0.6em 1.2em'
},
'@media (min-width: 1200px)': {
padding: '0.8em 1.5em'
},
':hover': {
backgroundColor: '#0088FF'
},
':focus': {
backgroundColor: '#0088FF'
},
':active': {
backgroundColor: '#005299',
transform: 'translateY(2px)'
}
},
red: {
backgroundColor: '#d90000',
':hover': {
backgroundColor: '#FF0000'
},
':focus': {
backgroundColor: '#FF0000'
},
':active': {
backgroundColor: '#990000'
}
}
};
export default Button;
================================================
FILE: examples/components/computed-well.js
================================================
/**
* The examples provided by Formidable Labs are for non-commercial testing and
* evaluation purposes only. Formidable Labs reserves all rights not expressly
* granted.
*
* 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
* FORMIDABLE LABS 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.
*/
import React from 'react';
import ReactDOM from 'react-dom';
import Radium from '../../src';
class ComputedWell extends React.Component {
getInitialState() {
return {
dynamicBg: '#000'
};
}
getStyles() {
return {
padding: '1em',
borderRadius: 5,
background: this.state.dynamicBg
};
}
handleSubmit(ev) {
ev.preventDefault();
this.setState({
dynamicBg: ReactDOM.findDOMNode(this.refs.input).value
});
}
render() {
return (
<form onSubmit={this.handleSubmit.bind(this)} style={this.getStyles()}>
<input placeholder="black" ref="input" type="text" />
<button>Change Background Color</button>
</form>
);
}
}
export default Radium(ComputedWell);
================================================
FILE: examples/index.html
================================================
<!DOCTYPE html>
<!--
The examples provided by Formidable Labs are for non-commercial testing and evaluation purposes only. Formidable Labs reserves all rights not expressly
granted.
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
FORMIDABLE LABS 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.
-->
<html>
<head>
<title>Radium Examples</title>
</head>
<body>
<h1>Radium Examples</h1>
<div id="app"><!-- {{app}} --></div>
<script src="app.js"></script>
</body>
</html>
================================================
FILE: examples/server.js
================================================
/**
* The examples provided by Formidable Labs are for non-commercial testing and
* evaluation purposes only. Formidable Labs reserves all rights not expressly
* granted.
*
* 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
* FORMIDABLE LABS 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.
*/
const express = require('express');
const proxy = require('express-http-proxy');
const React = require('react');
const ReactDOMServer = require('react-dom/server');
import App from './app'; // Leave ESM import
const fs = require('fs');
const path = require('path');
const indexHTML = fs
.readFileSync(path.resolve(__dirname, 'index.html'))
.toString();
const app = express();
const host = 'localhost';
const port = 8000;
app.use('/app.js', proxy('localhost:8080', {forwardPath: () => '/app.js'}));
app.get('/', (req, res) => {
const appHtml = ReactDOMServer.renderToString(
<App radiumConfig={{userAgent: req.headers['user-agent']}} />
);
res.write(indexHTML.replace('<!-- {{app}} -->', appHtml));
res.end();
});
app.listen(port, host, () => {
// eslint-disable-next-line no-console
console.log('Access the universal app at http://%s:%d', host, port);
});
================================================
FILE: examples/webpack.config.js
================================================
/**
* The examples provided by Formidable Labs are for non-commercial testing and
* evaluation purposes only. Formidable Labs reserves all rights not expressly
* granted.
*
* 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
* FORMIDABLE LABS 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.
*/
var path = require('path'); // eslint-disable-line no-var
module.exports = {
cache: true,
entry: {
app: './examples/client.js'
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/',
filename: '[name].js',
chunkFilename: '[chunkhash].js'
},
module: {
rules: [
{
test: /\.js$/,
include: [__dirname, path.resolve(__dirname, '../src')],
loader: 'babel-loader'
}
]
}
};
================================================
FILE: index.js
================================================
module.exports = require('./lib').default;
module.exports.default = module.exports;
================================================
FILE: interfaces/hoist-non-react-statics.js
================================================
declare module 'hoist-non-react-statics' {
/*
S - source component statics
TP - target component props
SP - additional source component props
*/
declare module.exports: <TP, SP, S>(
target: React$ComponentType<TP>,
source: React$ComponentType<SP> & S,
blacklist?: {[key: $Keys<S>]: boolean}
) => React$ComponentType<TP> & $Shape<S>;
}
================================================
FILE: interfaces/inline-style-prefixer.js
================================================
declare class InlineStylePrefixer {
static prefixAll: typeof prefixAll;
prefixedKeyframes: string;
constructor(config: {
keepUnprefixed?: boolean,
userAgent?: ?string
}): void;
prefix(style: Object): Object;
}
declare function prefixAll(style: Object): Object;
declare function createStaticPrefixer(browserData: Object): typeof prefixAll;
declare function createDynamicPrefixer(
browserData: Object,
prefixAll: typeof prefixAll
): typeof InlineStylePrefixer;
declare module 'inline-style-prefixer' {
declare module.exports: typeof InlineStylePrefixer;
}
declare module 'inline-style-prefixer/static/createPrefixer' {
declare module.exports: typeof createStaticPrefixer;
}
declare module 'inline-style-prefixer/dynamic/createPrefixer' {
declare module.exports: typeof createDynamicPrefixer;
}
================================================
FILE: karma.conf.coverage.js
================================================
module.exports = function(config) {
require('./karma.conf.js')(config);
config.set({
webpack: {
module: {
rules: config.webpack.module.rules.slice(1).concat([
{
test: /\.js$/,
exclude: [/node_modules/],
use: {
loader: 'babel-loader',
options: {
plugins: ['istanbul']
}
}
}
])
}
},
reporters: config.reporters.concat(['coverage']),
plugins: config.plugins.concat(['karma-coverage']),
coverageReporter: {
reporters: [
{
type: 'text'
},
{
type: 'lcovonly',
subdir: '.'
}
]
}
});
};
================================================
FILE: karma.conf.ie.js
================================================
module.exports = function(config) {
require('./karma.conf.js')(config);
config.set({
plugins: config.plugins.concat('karma-ie-launcher'),
browsers: ['IE9'],
customLaunchers: {
IE9: {
base: 'IE',
'x-ua-compatible': 'IE=EmulateIE9'
}
}
});
};
================================================
FILE: karma.conf.js
================================================
const path = require('path');
process.env.BABEL_ENV = 'commonjs';
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['mocha', 'sinon-chai'],
files: [
// Polyfills for IE9 in React 16.
require.resolve('core-js/es6/map'),
require.resolve('core-js/es6/set'),
'src/__tests__/**/*.js'
],
preprocessors: {
[path.join(
path.dirname(require.resolve('core-js/package.json')),
'es6/**/*.js' // eslint-disable-line prettier/prettier
)]: ['webpack'],
'src/__tests__/**/*.js': ['webpack']
},
webpack: {
cache: true,
module: {
rules: [
{
test: /\.js$/,
enforce: 'pre',
include: path.resolve('src/'),
loader: 'babel-loader'
},
{
test: /\.css$/,
loader: 'style-loader!css-loader'
}
]
},
resolve: {
modules: [
path.join(__dirname, 'node_modules'),
path.join(__dirname, 'src')
],
extensions: ['.js']
}
},
webpackServer: {
quiet: false,
noInfo: true,
stats: {
assets: false,
colors: true,
version: false,
hash: false,
timings: false,
chunks: false,
chunkModules: false
}
},
exclude: [],
port: 8080,
logLevel: config.LOG_INFO,
colors: true,
autoWatch: false,
// Run a customized instance of headless chrome for dev + Travis CI.
browsers: ['ChromeHeadlessCustom'],
customLaunchers: {
ChromeHeadlessCustom: {
base: 'ChromeHeadless',
// --no-sandbox for https://github.com/travis-ci/docs-travis-ci-com/pull/1671/files
flags: ['--no-sandbox']
}
},
reporters: ['mocha'],
browserNoActivityTimeout: 60000,
plugins: [
'karma-chrome-launcher',
'karma-mocha',
'karma-mocha-reporter',
'karma-sinon-chai',
'karma-webpack'
],
browserConsoleLogOptions: {
level: 'log',
format: '%b %T: %m',
terminal: true
},
captureTimeout: 100000,
singleRun: true
});
};
================================================
FILE: package.json
================================================
{
"name": "radium",
"version": "0.26.2",
"description": "A set of tools to manage inline styles on React elements",
"main": "index.js",
"module": "es/index.js",
"jsnext:main": "es/index.js",
"sideEffects": false,
"repository": {
"type": "git",
"url": "https://github.com/formidablelabs/radium.git"
},
"homepage": "https://github.com/formidablelabs/radium",
"bugs": "https://github.com/formidablelabs/radium/issues",
"directories": {
"example": "examples"
},
"scripts": {
"postinstall": "cd lib || npm run build",
"preversion": "npm test && npm run lint",
"version": "npm run build",
"postversion": "publishr postversion -V",
"postpublish": "publishr postpublish -V",
"version-dry-run": "publishr dry-run -V",
"build": "npm run clean && builder concurrent --buffer build-lib build-dist build-es",
"build-babel": "babel src --ignore \"**/__tests__/*\",\"**/__mocks__/*\"",
"build-lib": "builder run --env \"{\\\"BABEL_ENV\\\":\\\"commonjs\\\"}\" build-babel -- -d lib --verbose",
"build-dist-dev": "webpack",
"build-dist-prod": "webpack --config=webpack.config.minified.js",
"build-dist": "builder concurrent --buffer build-dist-dev build-dist-prod",
"build-examples": "webpack --config examples/webpack.config.js",
"build-es": "builder run build-babel -- -d es",
"clean": "rimraf lib es dist",
"examples": "webpack-dev-server --config examples/webpack.config.js --no-info --content-base examples",
"examples-server": "babel-node examples/server.js",
"flow": "flow check",
"eslint": "eslint .",
"fixlint": "npm run eslint -- --fix",
"lint": "builder concurrent --buffer eslint flow",
"start": "builder run --env \"{\\\"BABEL_ENV\\\":\\\"commonjs\\\"}\" examples-server",
"test-node": "mocha \"test/**/*-test.js\"",
"test-node-dev": "mocha --watch \"test/**/*-test.js\"",
"test-frontend": "karma start",
"test-frontend-coverage": "karma start karma.conf.coverage.js",
"test-frontend-ie": "karma start karma.conf.ie.js",
"test-frontend-dev": "karma start --no-single-run --auto-watch",
"test": "npm run test-node && npm run test-frontend",
"test-coverage": "npm run test-node && npm run test-frontend-coverage",
"test-ie": "npm run test-node && npm run test-frontend-ie",
"test-dev": "builder concurrent test-node-dev test-frontend-dev",
"universal": "builder concurrent start examples",
"update-prefix-data": "babel-node scripts/update-prefix-data.js && eslint --fix src/prefix-data",
"watch-lib": "npm run build-lib -- --watch"
},
"license": "MIT",
"dependencies": {
"@babel/cli": "^7.0.0",
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-decorators": "^7.0.0",
"@babel/plugin-transform-destructuring": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/preset-flow": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.0",
"builder": "^3.2.3",
"exenv": "^1.2.1",
"hoist-non-react-statics": "3.3.0",
"inline-style-prefixer": "^4.0.0",
"prop-types": "^15.5.8",
"publishr": "^1.0.0",
"rimraf": "^2.6.1",
"webpack": "^3.10.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0"
},
"devDependencies": {
"@babel/node": "^7.0.0",
"babel-eslint": "^10.0.1",
"babel-plugin-istanbul": "^5.1.0",
"caniuse-api": "^2.0.0",
"chai": "^3.5.0",
"color": "^1.0.3",
"core-js": "^2.5.3",
"coveralls": "^2.12.0",
"enzyme": "^3.10.0",
"enzyme-adapter-react-16": "^1.14.0",
"eslint": "^5.16.0",
"eslint-plugin-flowtype": "3.9.1",
"eslint-plugin-prettier": "^3.1.0",
"eslint-plugin-react": "^7.13.0",
"eslint-plugin-react-hooks": "1.6.0",
"express": "^4.15.2",
"express-http-proxy": "^0.11.0",
"flow-bin": "^0.100.0",
"inject-loader": "^3.0.1",
"jsdom": "^12.0.0",
"jsdom-global": "^3.0.2",
"karma": "^3.0.0",
"karma-babel-preprocessor": "^6.0.1",
"karma-chrome-launcher": "^2.2.0",
"karma-coverage": "^1.1.1",
"karma-ie-launcher": "^1.0.0",
"karma-mocha": "^1.3.0",
"karma-mocha-reporter": "^2.2.2",
"karma-sinon-chai": "^1.2.4",
"karma-webpack": "^3.0.0",
"mocha": "^3.2.0",
"node-libs-browser": "^2.0.0",
"nodemon": "^1.11.0",
"object-assign": "^4.1.1",
"prettier": "^1.15.3",
"react": "^16.8.3",
"react-dom": "^16.8.3",
"react-test-renderer": "^16.8.3",
"sinon": "^1.17.7",
"sinon-chai": "^2.8.0",
"webpack-dev-server": "^3.1.11"
},
"publishr": {
"dependencies": [
"^babel-",
"^@babel/",
"^builder$",
"^publishr$",
"^rimraf$",
"^webpack"
],
"files": {
".npmignore": ".npmignore.publishr"
},
"scripts": {
"postinstall": ""
}
}
}
================================================
FILE: scripts/update-prefix-data.js
================================================
/**
* Update the files in `src/prefix-data` to match the `browserList` below. Run
* this if browser support changes or `inline-style-prefixer` gets fixes for the
* supported browsers.
*
* **Note**: Not valid Node code (without std/esm). Use `babel-node` to exec.
*/
import path from 'path';
import generateData from 'inline-style-prefixer/generator';
const browserList = {
chrome: 30,
android: 4,
firefox: 25,
ios_saf: 6,
safari: 6,
ie: 9,
ie_mob: 9,
edge: 12,
opera: 13,
op_mini: 5,
and_uc: 9,
and_chr: 30
};
generateData(browserList, {
staticPath: path.join(__dirname, '../src/prefix-data/static.js'),
dynamicPath: path.join(__dirname, '../src/prefix-data/dynamic.js')
});
================================================
FILE: src/__mocks__/exenv.js
================================================
export default {
canUseDOM: true,
canUseEventListeners: true
};
================================================
FILE: src/__mocks__/prefixer.js
================================================
export default {
getPrefixedStyle: style => style
};
================================================
FILE: src/__tests__/camel-case-props-to-dash-case-test.js
================================================
import camelCasePropsToDashCase from 'camel-case-props-to-dash-case';
describe('camelCasePropsToDashCase', function() {
it('converts to dash case correctly', function() {
const result = camelCasePropsToDashCase({
borderLeft: '1px solid black',
WebkitBoxSizing: 'border-box',
msTransform: 'rotate(90deg)'
});
expect(result).to.deep.equal({
'border-left': '1px solid black',
'-webkit-box-sizing': 'border-box',
'-ms-transform': 'rotate(90deg)'
});
});
});
================================================
FILE: src/__tests__/clean-state-key-test.js
================================================
import cleanStateKey from 'clean-state-key';
describe('cleanStateKey', () => {
it('returns the key as a string', () => {
const key = 1;
expect(cleanStateKey(key)).to.equal('1');
});
it('returns main if no key is passed', () => {
expect(cleanStateKey()).to.equal('main');
});
});
================================================
FILE: src/__tests__/enhancer-test.js
================================================
const {getElement, renderFcIntoDocument} = require('test-helpers');
const resolveStyles = sinon.spy(require('resolve-styles'), 'default');
const Enhancer = require('inject-loader!enhancer')({
'./resolve-styles': resolveStyles
}).default;
import React, {Component} from 'react';
describe('Enhancer', () => {
it('sets up initial state', () => {
class Composed extends Component {
render() {
return <div />;
}
}
const Enhanced = Enhancer(Composed);
const ref = React.createRef();
renderFcIntoDocument(<Enhanced ref={ref} />);
expect(ref.current.state).to.deep.equal({_radiumStyleState: {}});
});
it('sets up initial state on a function component', () => {
// using plugin API to get state as state hooks keep things pretty private
// so we cannot just dive into the component instance like with the class example
const dummyPlugin = sinon.spy();
const Composed = props => <div {...props} />;
const Enhanced = Enhancer(Composed, {
plugins: [dummyPlugin]
});
renderFcIntoDocument(<Enhanced style={{color: 'red'}} />);
const pluginApi = dummyPlugin.getCall(0).args[0];
expect(pluginApi.getComponentField('state')).to.deep.equal({
_radiumStyleState: {}
});
});
it('merges with existing state', () => {
class Composed extends Component {
constructor(props) {
super(props);
this.state = {foo: 'bar'};
}
render() {
return <div />;
}
}
const Enhanced = Enhancer(Composed);
const ref = React.createRef();
renderFcIntoDocument(<Enhanced ref={ref} />);
expect(ref.current.state).to.deep.equal({
foo: 'bar',
_radiumStyleState: {}
});
});
it('receives the given props', () => {
class Composed extends Component {
constructor(props) {
super(props);
}
render() {
return <div />;
}
}
const Enhanced = Enhancer(Composed);
const output = renderFcIntoDocument(<Enhanced foo="bar" />);
expect(output.props.children.props).to.deep.equal({foo: 'bar'});
});
it('calls existing render function, then resolveStyles', () => {
const renderMock = sinon.spy();
class Composed extends Component {
render() {
renderMock();
return null;
}
}
const Enhanced = Enhancer(Composed);
renderFcIntoDocument(<Enhanced />);
expect(renderMock).to.have.been.called;
expect(resolveStyles).to.have.been.called;
});
it('calls existing constructor only once', () => {
const constructorMock = sinon.spy();
class Composed extends Component {
constructor(props) {
super(props);
constructorMock();
}
render() {
return <div />;
}
}
const Enhanced = Enhancer(Composed);
renderFcIntoDocument(<Enhanced />);
expect(constructorMock).to.have.been.calledOnce;
});
it('uses the existing displayName', () => {
class Composed extends Component {
render() {
return <div />;
}
}
Composed.displayName = 'Composed';
const Enhanced = Enhancer(Composed);
const ref = React.createRef();
renderFcIntoDocument(<Enhanced ref={ref} />);
expect(ref.current.constructor.displayName).to.equal(Composed.displayName);
});
it('calls existing componentWillUnmount function', () => {
const existingComponentWillUnmount = sinon.spy();
class Composed extends Component {
componentWillUnmount() {
existingComponentWillUnmount();
}
render() {
return <div />;
}
}
const Enhanced = Enhancer(Composed);
const ref = React.createRef();
renderFcIntoDocument(<Enhanced ref={ref} />);
ref.current.componentWillUnmount();
expect(existingComponentWillUnmount).to.have.been.called;
});
it('removes mouse up listener on componentWillUnmount', () => {
const removeMouseUpListener = sinon.spy();
class Composed extends Component {
constructor(props) {
super(props);
this._radiumMouseUpListener = {remove: removeMouseUpListener};
}
render() {
return <div />;
}
}
const Enhanced = Enhancer(Composed);
const ref = React.createRef();
renderFcIntoDocument(<Enhanced ref={ref} />);
ref.current.componentWillUnmount();
expect(removeMouseUpListener).to.have.been.called;
});
it('removes media query listeners on componentWillUnmount', () => {
const mediaQueryListenersByQuery = {
'(min-width: 1000px)': {remove: sinon.spy()},
'(max-width: 600px)': {remove: sinon.spy()},
'(min-resolution: 2dppx)': {remove: sinon.spy()}
};
class Composed extends Component {
constructor(props) {
super(props);
this._radiumMediaQueryListenersByQuery = mediaQueryListenersByQuery;
}
render() {
return <div />;
}
}
const Enhanced = Enhancer(Composed);
const ref = React.createRef();
renderFcIntoDocument(<Enhanced ref={ref} />);
ref.current.componentWillUnmount();
Object.keys(mediaQueryListenersByQuery).forEach(key => {
expect(mediaQueryListenersByQuery[key].remove).to.have.been.called;
});
});
it('manually populates all static properties for IE <10', () => {
class Composed extends Component {
static staticMethod() {
return {bar: 'foo'};
}
render() {}
}
Composed.foo = 'bar';
const Enhanced = Enhancer(Composed);
expect(Enhanced.foo).to.equal('bar');
expect(Enhanced.staticMethod()).to.deep.equal({bar: 'foo'});
});
it('works with defaultProps', () => {
class Composed extends Component {
static defaultProps = {foo: 'bar'};
render() {
return <div>{this.props.foo}</div>;
}
}
const Enhanced = Enhancer(Composed);
const output = renderFcIntoDocument(<Enhanced />);
expect(getElement(output, 'div').textContent).to.equal('bar');
});
it('copies methods across to top level prototype', () => {
class Composed extends React.Component {
getStyles() {
return [{color: 'black'}];
}
render() {
return <div style={this.getStyles()}>Hello World!</div>;
}
}
const Enhanced = Enhancer(Composed);
Object.keys(Composed.prototype).forEach(key => {
expect(Enhanced.prototype.hasOwnProperty(key)).to.equal(true);
});
});
});
================================================
FILE: src/__tests__/get-radium-style-state-test.js
================================================
import {Component} from 'react';
import getRadiumStyleState from 'get-radium-style-state';
describe('getRadiumStyleState', () => {
it('gets the _lastRadiumState if available', () => {
const state = {someKey: true};
class Test extends Component {
_lastRadiumState = state;
}
const instance = new Test();
expect(getRadiumStyleState(instance)).to.deep.equal(state);
});
it('gets the _radiumStyleState if available', () => {
const state = {someKey: true};
class Test extends Component {
state = {_radiumStyleState: state};
}
const instance = new Test();
expect(getRadiumStyleState(instance)).to.deep.equal(state);
});
it('returns an empty object if nothing is available', () => {
class Test extends Component {}
const instance = new Test();
expect(getRadiumStyleState(instance)).to.deep.equal({});
});
});
================================================
FILE: src/__tests__/get-state-key-test.js
================================================
import React from 'react';
import getStateKey from 'get-state-key';
import {getRenderOutput} from 'test-helpers';
describe('getStateKey', () => {
it('gets the ref if it is a string', () => {
class Test extends React.Component {
render() {
return <div ref="myRef" />;
}
}
const output = getRenderOutput(<Test />);
expect(getStateKey(output)).to.equal('myRef');
});
it('gets the key if the ref is not a string', () => {
class Test extends React.Component {
render() {
return <div key="myKey" ref={ref => (this.ref = ref)} />;
}
}
const output = getRenderOutput(<Test />);
expect(getStateKey(output)).to.equal('myKey');
});
it('gets the key if there is no ref', () => {
class Test extends React.Component {
render() {
return <div key="myKey" />;
}
}
const output = getRenderOutput(<Test />);
expect(getStateKey(output)).to.equal('myKey');
});
});
================================================
FILE: src/__tests__/get-state-test.js
================================================
import getState from 'get-state';
describe('getState', () => {
it('successfully gets the state if passed number zero', () => {
const result = getState(
{_radiumStyleState: {'0': {':hover': true}}},
0,
':hover'
);
expect(result).to.equal(true);
});
});
================================================
FILE: src/__tests__/keyframes-test.js
================================================
/* eslint-disable react/prop-types */
import Radium, {StyleRoot, keyframes} from 'index';
import {expectCSS, getElement, renderFcIntoDocument} from 'test-helpers';
import React, {Component} from 'react';
import TestUtils from 'react-dom/test-utils';
const CHROME_14_USER_AGENT =
'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 ' +
'(KHTML, like Gecko) Chrome/14.0.812.0 Safari/535.1';
describe('keyframes', () => {
it('adds prefix to keyframes when needed', () => {
const anim = keyframes({from: {left: 0}, to: {left: 100}}, 'slide');
class TestComponent extends Component {
render() {
return (
<StyleRoot
radiumConfig={{userAgent: CHROME_14_USER_AGENT}}
style={{animationName: anim}}
/>
);
}
}
const output = TestUtils.renderIntoDocument(<TestComponent />);
const style = getElement(output, 'style');
expectCSS(
style,
`
@-webkit-keyframes slide-radium-animation-1bdcc98d {
from {left: 0;}
to {left: 100px;}
}
`
);
});
it('adds prefix to multiple keyframes when needed', () => {
const anim = keyframes({from: {left: 0}, to: {left: 100}}, 'slide');
const anim2 = keyframes({from: {top: 0}, to: {top: 100}}, 'slideTop');
class TestComponent extends Component {
render() {
return (
<StyleRoot
radiumConfig={{userAgent: CHROME_14_USER_AGENT}}
style={{animationName: [anim, anim2]}}
/>
);
}
}
const output = TestUtils.renderIntoDocument(<TestComponent />);
const style = getElement(output, 'style');
expectCSS(
style,
`
@-webkit-keyframes slide-radium-animation-1bdcc98d {
from {left: 0;}
to {left: 100px;}
}
@-webkit-keyframes slideTop-radium-animation-c623736d {
from {top: 0;}
to {top: 100px;}
}
`
);
});
it('renders keyframes in root style component', () => {
const animation = keyframes(
{
from: {left: '-1000px'},
to: {left: 0}
},
'SlideFromLeft'
);
class TestComponent extends Component {
render() {
return <StyleRoot style={{animationName: animation}} />;
}
}
const output = TestUtils.renderIntoDocument(<TestComponent />);
const style = getElement(output, 'style');
expectCSS(
style,
`
@keyframes SlideFromLeft-radium-animation-1b668a10 {
from{
left: -1000px;
}
to{
left: 0;
}
}
`
);
});
it('renders multiple keyframes in root style component', () => {
const animation = keyframes(
{
from: {left: '-1000px'},
to: {left: 0}
},
'SlideFromLeft'
);
const animation2 = keyframes(
{
from: {top: '-1000px'},
to: {top: 0}
},
'SlideFromTop'
);
class TestComponent extends Component {
render() {
return <StyleRoot style={{animationName: [animation, animation2]}} />;
}
}
const output = TestUtils.renderIntoDocument(<TestComponent />);
const style = getElement(output, 'style');
expectCSS(
style,
`
@keyframes SlideFromLeft-radium-animation-1b668a10 {
from{
left: -1000px;
}
to{
left: 0;
}
}
@keyframes SlideFromTop-radium-animation-edccf130{
from{
top:-1000px;
}
to{
top:0;
}
}
`
);
});
it('adds px suffix when property is not unitless', () => {
const animation = keyframes(
{
from: {left: -1000},
to: {left: 10}
},
'SlideFromLeft'
);
class TestComponent extends Component {
render() {
return <StyleRoot style={{animationName: animation}} />;
}
}
const output = TestUtils.renderIntoDocument(<TestComponent />);
const style = getElement(output, 'style');
expectCSS(
style,
`
@keyframes SlideFromLeft-radium-animation-ab5ed129 {
from{
left: -1000px;
}
to{
left: 10px;
}
}
`
);
});
it('adds px suffix when property is not unitless to multiple keyframes', () => {
const animation = keyframes(
{
from: {left: -1000},
to: {left: 10}
},
'SlideFromLeft'
);
const animation2 = keyframes(
{
from: {top: -1000},
to: {top: 10}
},
'SlideFromTop'
);
class TestComponent extends Component {
render() {
return <StyleRoot style={{animationName: [animation, animation2]}} />;
}
}
const output = TestUtils.renderIntoDocument(<TestComponent />);
const style = getElement(output, 'style');
expectCSS(
style,
`
@keyframes SlideFromLeft-radium-animation-ab5ed129 {
from{
left: -1000px;
}
to{
left: 10px;
}
}
@keyframes SlideFromTop-radium-animation-3a6534c9 {
from{
top:-1000px;
}
to{
top: 10px;
}
}
`
);
});
it('renders keyframes from child component', () => {
const animation = keyframes(
{
from: {left: '-1000px'},
to: {left: 0}
},
'SlideFromLeft'
);
@Radium
class ChildComponent extends Component {
render() {
return <div style={{animationName: animation}} />;
}
}
class TestComponent extends Component {
render() {
return (
<StyleRoot>
<ChildComponent />
</StyleRoot>
);
}
}
const output = TestUtils.renderIntoDocument(<TestComponent />);
const style = getElement(output, 'style');
expectCSS(
style,
`
@keyframes SlideFromLeft-radium-animation-1b668a10 {
from{
left: -1000px;
}
to{
left: 0;
}
}
`
);
});
it('renders multiple keyframes from child component', () => {
const animation = keyframes(
{
from: {left: '-1000px'},
to: {left: 0}
},
'SlideFromLeft'
);
const animation2 = keyframes(
{
from: {top: -1000},
to: {top: 0}
},
'SlideFromTop'
);
@Radium
class ChildComponent extends Component {
render() {
return <div style={{animationName: [animation, animation2]}} />;
}
}
@Radium
class TestComponent extends Component {
render() {
return (
<StyleRoot>
<ChildComponent />
</StyleRoot>
);
}
}
const output = renderFcIntoDocument(<TestComponent />);
const style = getElement(output, 'style');
expectCSS(
style,
`
@keyframes SlideFromLeft-radium-animation-1b668a10 {
from{
left: -1000px;
}
to{
left: 0;
}
}
@keyframes SlideFromTop-radium-animation-edccf130 {
from{
top:-1000px;
}
to{
top: 0;
}
}
`
);
});
});
================================================
FILE: src/__tests__/media-query-test.js
================================================
/* eslint-disable react/prop-types */
import Radium, {StyleRoot} from 'index';
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-dom/test-utils';
import {
expectColor,
expectCSS,
getElement,
renderFcIntoDocument
} from 'test-helpers';
// Win on at least ie9 _can't_ sinon.stub() window.onerror like normal.
// So, we monkeypatch directly like savages.
const origWindowOnerror = window.onerror;
describe('Media query tests', () => {
let sandbox;
let errorSpy;
beforeEach(() => {
sandbox = sinon.sandbox.create();
errorSpy = sinon.spy();
window.addEventListener('error', errorSpy);
Radium.TestMode.clearState();
});
afterEach(() => {
sandbox.restore();
window.removeEventListener('error', errorSpy);
window.onerror = origWindowOnerror;
Radium.TestMode.disable();
});
it('listens for media queries', () => {
const addListener = sinon.spy();
const matchMedia = sinon.spy(() => ({addListener}));
@Radium({matchMedia})
class TestComponent extends Component {
render() {
return (
<div
style={{
'@media (min-width: 600px)': {':hover': {color: 'blue'}}
}}
/>
);
}
}
renderFcIntoDocument(<TestComponent />);
expect(matchMedia.lastCall.args[0]).to.equal('(min-width: 600px)');
expect(addListener.lastCall.args[0]).to.be.a('function');
});
it('only listens once per component across renders', () => {
const addListener = sinon.spy();
const matchMedia = sinon.spy(() => ({addListener}));
let renders = 0;
@Radium({matchMedia})
class TestComponent extends Component {
render() {
renders++;
return (
<div
style={{
'@media (min-width: 600px)': {':hover': {color: 'blue'}}
}}
/>
);
}
}
const node = document.createElement('div');
ReactDOM.render(<TestComponent />, node);
ReactDOM.render(<TestComponent />, node);
expect(renders).to.equal(2);
expect(matchMedia).to.have.been.calledOnce;
expect(addListener).to.have.been.calledOnce;
});
it('listens once per component with same @media in multiple styles', () => {
const addListener = sinon.spy();
const matchMedia = sinon.spy(() => ({addListener}));
@Radium({matchMedia})
class TestComponent extends Component {
render() {
return (
<div>
<div
key="first"
style={{
'@media (max-width: 400px)': {':hover': {color: 'blue'}}
}}
/>
<div
key="second"
style={{
'@media (max-width: 400px)': {':hover': {color: 'blue'}}
}}
/>
</div>
);
}
}
renderFcIntoDocument(<TestComponent />);
expect(matchMedia).to.have.been.calledOnce;
expect(addListener).to.have.been.calledOnce;
});
it('applies nested styles inline when media query matches', () => {
const truthyMatchMedia = () => {
return {
matches: true,
addListener: () => {},
removeListener: () => {}
};
};
@Radium({matchMedia: truthyMatchMedia})
class TestComponent extends Component {
render() {
return (
<div
style={{
'@media (min-width: 600px)': {':hover': {color: 'blue'}}
}}
/>
);
}
}
const output = renderFcIntoDocument(<TestComponent />);
const div = getElement(output, 'div');
TestUtils.SimulateNative.mouseOver(div);
expect(div.style.color).to.equal('blue');
});
it('merges nested pseudo styles', () => {
const truthyMatchMedia = () => {
return {
matches: true,
addListener: () => {},
removeListener: () => {}
};
};
@Radium({matchMedia: truthyMatchMedia})
class TestComponent extends Component {
render() {
return (
<div
style={[
{':hover': {background: 'green', color: 'green'}},
{
'@media (max-width: 400px)': {
':hover': {background: 'yellow'}
}
},
{'@media (max-width: 400px)': {':hover': {color: 'white'}}}
]}
/>
);
}
}
const output = renderFcIntoDocument(<TestComponent />);
const div = getElement(output, 'div');
TestUtils.SimulateNative.mouseOver(div);
expect(div.style.background).to.equal('yellow');
expect(div.style.color).to.equal('white');
});
it('calls component setState when media query changes', () => {
const listeners = [];
const addListener = sinon.spy(listener => listeners.push(listener));
const mql = {addListener, matches: true};
const matchMedia = sinon.spy(() => mql);
@Radium({matchMedia})
class TestComponent extends Component {
render() {
return (
<div
style={{
'@media (min-width: 600px)': {':hover': {color: 'blue'}}
}}
/>
);
}
}
// First, render with matching media query and verify the hover color
const output = renderFcIntoDocument(<TestComponent />);
const div = getElement(output, 'div');
TestUtils.SimulateNative.mouseOver(div);
expect(div.style.color).to.equal('blue');
// Next, make the media query fail, and check again
mql.matches = false;
listeners.forEach(listener => listener(mql));
expect(div.style.color).to.equal('');
});
it('saves listeners on component for later removal', () => {
const mql = {addListener: sinon.spy(), removeListener: sinon.spy()};
const matchMedia = sinon.spy(() => mql);
@Radium({matchMedia})
class TestComponent extends Component {
render() {
return (
<div
style={{
'@media (min-width: 600px)': {':hover': {color: 'blue'}}
}}
/>
);
}
}
const output = renderFcIntoDocument(<TestComponent />);
ReactDOM.unmountComponentAtNode(ReactDOM.findDOMNode(output).parentNode);
expect(mql.addListener).to.have.been.calledOnce;
expect(mql.removeListener).to.have.been.calledOnce;
});
it('renders top level print styles as CSS', () => {
const matchMedia = sinon.spy(() => ({
addListener: () => {},
matches: true
}));
const ChildComponent = Radium(() => (
<span style={{'@media print': {color: 'black'}}} />
));
const TestComponent = Radium({matchMedia})(() => (
<StyleRoot>
<ChildComponent />
</StyleRoot>
));
const output = renderFcIntoDocument(<TestComponent />);
const span = getElement(output, 'span');
expect(span.className).to.not.be.empty;
const style = getElement(output, 'style');
expectCSS(
style,
`
@media print{
.${span.className}{
color:black !important;
}
}
`
);
});
it("doesn't error on unmount", () => {
const matchMedia = () => ({
addListener: () => {},
matches: true
});
const ChildComponent = Radium(() => (
<span style={{'@media print': {color: 'black'}}} />
));
const TestComponent = Radium({matchMedia})(() => (
<StyleRoot>
<ChildComponent />
</StyleRoot>
));
const output = renderFcIntoDocument(<TestComponent />);
ReactDOM.unmountComponentAtNode(ReactDOM.findDOMNode(output).parentNode);
});
it('respects ordering', () => {
// Use small values for media queries so they all pass.
const ChildComponent = Radium(() => (
<span
style={[
{
'@media (min-width: 10px)': {background: 'green'},
'@media (min-width: 20px)': {color: 'blue'}
},
{
'@media (min-width: 10px)': {color: 'white'}
}
]}
/>
));
const TestComponent = Radium(() => (
<StyleRoot>
<ChildComponent />
</StyleRoot>
));
const root = document.createElement('div');
document.body.appendChild(root);
ReactDOM.render(<TestComponent />, root);
const span = document.getElementsByTagName('span')[0];
const computedStyle = window.getComputedStyle(span);
expectColor(computedStyle.getPropertyValue('color'), 'white');
});
it("doesn't add className if no media styles", () => {
const ChildComponent = Radium(() => <span style={{color: 'black'}} />);
const TestComponent = Radium(() => (
<StyleRoot>
<ChildComponent />
</StyleRoot>
));
const output = renderFcIntoDocument(<TestComponent />);
const span = getElement(output, 'span');
expect(span.className).to.be.empty;
});
it('retains original className', () => {
const ChildComponent = Radium(() => (
<span className="original" style={{'@media print': {color: 'black'}}} />
));
const TestComponent = Radium(() => (
<StyleRoot>
<ChildComponent />
</StyleRoot>
));
const output = renderFcIntoDocument(<TestComponent />);
const span = getElement(output, 'span');
expect(span.className).to.contain(' original');
});
it('throws without StyleRoot', () => {
const ChildComponent = Radium(() => (
<span style={{'@media (min-width: 10px)': {background: 'green'}}} />
));
let error;
class ErrorBoundary extends React.Component {
componentDidCatch(e) {
error = e;
}
render() {
return this.props.children;
}
}
const TestComponent = () => (
<ErrorBoundary>
<ChildComponent />
</ErrorBoundary>
);
// React 16 - need to handle exceptions globally.
// In DEV (aka our tests), need to silence global error handlers and such.
// https://github.com/facebook/react/issues/10474#issuecomment-322909303
window.onerror = sinon.stub();
sandbox.stub(console, 'error');
renderFcIntoDocument(<TestComponent />);
expect(error.message).to.contain(
'please wrap your application in the StyleRoot component'
);
});
it("doesn't throw without StyleRoot when in test mode", () => {
Radium.TestMode.enable();
const TestComponent = Radium(() => (
<div>
<span style={{'@media (min-width: 10px)': {background: 'green'}}} />
</div>
));
expect(() => renderFcIntoDocument(<TestComponent />)).not.to.throw();
});
it("doesn't try to setState if not mounted", () => {
sandbox.stub(console, 'error');
sandbox.stub(console, 'warn');
const addListener = sinon.spy();
const mockMatchMedia = function() {
return {
matches: true,
addListener: addListener,
removeListener() {}
};
};
@Radium({matchMedia: mockMatchMedia})
class TestComponent extends Component {
render() {
return (
<div
style={{
'@media (min-width: 600px)': {':hover': {color: 'blue'}}
}}
/>
);
}
}
const output = renderFcIntoDocument(<TestComponent />);
expect(addListener).to.have.been.called;
ReactDOM.unmountComponentAtNode(ReactDOM.findDOMNode(output).parentNode);
const listener = addListener.lastCall.args[0];
listener(mockMatchMedia);
expect(console.error).not.to.have.been.called; // eslint-disable-line no-console
expect(console.warn).not.to.have.been.called; // eslint-disable-line no-console
});
});
================================================
FILE: src/__tests__/radium-test.js
================================================
/* eslint-disable react/prop-types */
import Radium from 'index';
import React, {Component} from 'react';
import MouseUpListener from 'plugins/mouse-up-listener';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
import TestUtils from 'react-dom/test-utils';
import {getElement, getElements, renderFcIntoDocument} from 'test-helpers';
describe('Radium blackbox tests', () => {
let sandbox;
beforeEach(() => {
sandbox = sinon.sandbox.create();
});
afterEach(() => {
sandbox.restore();
});
it('merges styles', () => {
@Radium
class TestComponent extends Component {
render() {
return <div style={[{color: 'blue'}, {background: 'red'}]} />;
}
}
const output = renderFcIntoDocument(<TestComponent />);
const div = getElement(output, 'div');
expect(div.style.color).to.equal('blue');
expect(div.style.background).to.equal('red');
});
it('merges nested styles', () => {
@Radium
class TestComponent extends Component {
render() {
return (
<div
style={[
[{color: 'blue'}, [{height: '2px', padding: '9px'}]],
{background: 'red'}
]}
/>
);
}
}
const output = renderFcIntoDocument(<TestComponent />);
const div = getElement(output, 'div');
expect(div.style.color).to.equal('blue');
expect(div.style.background).to.equal('red');
expect(div.style.height).to.equal('2px');
expect(div.style.padding).to.equal('9px');
});
it('merges nested styles in function components', () => {
const TestComponent = Radium(() => (
<div
style={[
[{color: 'blue'}, [{height: '2px', padding: '9px'}]],
{background: 'red'}
]}
/>
));
const output = renderFcIntoDocument(<TestComponent />);
const div = getElement(output, 'div');
expect(div.style.color).to.equal('blue');
expect(div.style.background).to.equal('red');
expect(div.style.height).to.equal('2px');
expect(div.style.padding).to.equal('9px');
});
it('merges nested styles and forwards ref in function components with forwardRef', () => {
const TestComponent = Radium(
React.forwardRef((props, ref) => (
<div
ref={ref}
style={[
[{color: 'blue'}, [{height: '2px', padding: '9px'}]],
{background: 'red'}
]}
/>
))
);
const testRef = React.createRef();
const output = renderFcIntoDocument(<TestComponent ref={testRef} />);
const div = getElement(output, 'div');
expect(testRef.current).to.equal(div);
expect(div.style.color).to.equal('blue');
expect(div.style.background).to.equal('red');
expect(div.style.height).to.equal('2px');
expect(div.style.padding).to.equal('9px');
});
it('resolves styles on props', () => {
class InnerComponent extends Component {
render() {
return this.props.header;
}
}
@Radium
class TestComponent extends Component {
render() {
return (
<InnerComponent
header={<div style={[{color: 'blue'}, {background: 'red'}]} />}
/>
);
}
}
const output = renderFcIntoDocument(<TestComponent />);
const div = getElement(output, 'div');
expect(div.style.color).to.equal('blue');
expect(div.style.background).to.equal('red');
});
it('resolves styles on props', () => {
class InnerComponent extends Component {
render() {
return this.props.stuff;
}
}
@Radium
class TestComponent extends Component {
render() {
return (
<InnerComponent
stuff={
<div
style={[
{color: 'blue'},
{background: 'red', ':active': {color: 'green'}}
]}
/>
}
/>
);
}
}
const output = renderFcIntoDocument(<TestComponent />);
const div = getElement(output, 'div');
expect(div.style.color).to.equal('blue');
expect(div.style.background).to.equal('red');
TestUtils.Simulate.mouseDown(div);
expect(div.style.color).to.equal('green');
});
it('resolves styles on functions', () => {
class InnerComponent extends Component {
render() {
return this.props.children('arg');
}
}
@Radium
class TestComponent extends Component {
render() {
return (
<InnerComponent>
{arg => (
<div
style={[
{color: 'blue'},
{background: 'red', ':active': {color: 'green'}}
]}
>
{arg}
</div>
)}
</InnerComponent>
);
}
}
const output = renderFcIntoDocument(<TestComponent />);
const div = getElement(output, 'div');
expect(div.style.color).to.equal('blue');
expect(div.style.background).to.equal('red');
expect(div.textContent).to.equal('arg');
TestUtils.Simulate.mouseDown(div);
expect(div.style.color).to.equal('green');
});
it('adds hover styles', () => {
@Radium
class TestComponent extends Component {
render() {
return (
<div
style={{
background: 'red',
color: 'blue',
':hover': {color: 'green'}
}}
/>
);
}
}
const output = renderFcIntoDocument(<TestComponent />);
const div = getElement(output, 'div');
expect(div.style.color).to.equal('blue');
expect(div.style.background).to.equal('red');
TestUtils.SimulateNative.mouseOver(div);
expect(div.style.color).to.equal('green');
});
it('adds active styles', () => {
@Radium
class TestComponent extends Component {
render() {
return (
<div
style={{
background: 'red',
color: 'blue',
':active': {color: 'green'}
}}
/>
);
}
}
const output = renderFcIntoDocument(<TestComponent />);
const div = getElement(output, 'div');
expect(div.style.color).to.equal('blue');
expect(div.style.background).to.equal('red');
TestUtils.Simulate.mouseDown(div);
expect(div.style.color).to.equal('green');
});
it('removes active styles on mouseup', () => {
@Radium
class TestComponent extends Component {
render() {
return (
<div>
<span
key="a"
style={{
background: 'red',
color: 'blue',
':active': {color: 'green'}
}}
/>
<button
key="b"
style={{
background: 'red',
color: 'blue',
':active': {color: 'green'}
}}
/>
<nav
key="c"
style={{
background: 'red',
color: 'blue',
':active': {color: 'green'}
}}
/>
</div>
);
}
}
const output = renderFcIntoDocument(<TestComponent />);
const span = getElement(output, 'span');
const button = getElement(output, 'button');
const nav = getElement(output, 'nav');
expect(span.style.color).to.equal('blue');
expect(button.style.color).to.equal('blue');
expect(nav.style.color).to.equal('blue');
TestUtils.Simulate.mouseDown(span);
expect(span.style.color).to.equal('green');
MouseUpListener.__triggerForTests();
expect(span.style.color).to.equal('blue');
TestUtils.Simulate.mouseDown(button);
expect(button.style.color).to.equal('green');
MouseUpListener.__triggerForTests();
expect(button.style.color).to.equal('blue');
TestUtils.Simulate.mouseDown(nav);
expect(nav.style.color).to.equal('green');
MouseUpListener.__triggerForTests();
expect(nav.style.color).to.equal('blue');
});
it('passes snapshot to the componentDidUpdate of the component, Issue #985', () => {
const SNAPSHOT = 'SNAPSHOT';
class SnapshotComp extends Component {
componentDidMount() {
this.forceUpdate();
}
getSnapshotBeforeUpdate() {
return SNAPSHOT;
}
componentDidUpdate(props, state, snapshot) {
expect(snapshot).to.equal(SNAPSHOT);
}
render() {
return null;
}
}
sinon.spy(SnapshotComp.prototype, 'componentDidUpdate');
const TestComponent = Radium(SnapshotComp);
renderFcIntoDocument(<TestComponent />);
expect(SnapshotComp.prototype.componentDidUpdate).to.have.been.calledOnce;
});
it('resets state for unmounted components, Issue #524', () => {
class TestComponent extends Component {
state = {showSpan: true};
render() {
return (
<div>
<button onClick={() => this.setState({showSpan: true})} />
{this.state.showSpan && (
<span
key="s"
onClick={() => this.setState({showSpan: false})}
style={{
color: 'blue',
':hover': {color: 'red'}
}}
/>
)}
</div>
);
}
}
const WrappedTestComponent = Radium(TestComponent);
const output = renderFcIntoDocument(<WrappedTestComponent />);
let spans = getElements(output, 'span');
const button = getElement(output, 'button');
expect(spans[0].style.color).to.equal('blue');
TestUtils.Simulate.mouseEnter(spans[0]);
expect(spans[0].style.color).to.equal('red');
TestUtils.Simulate.click(spans[0]);
spans = getElements(output, 'span');
expect(spans).to.have.length(0);
TestUtils.Simulate.click(button);
spans = getElements(output, 'span');
expect(spans)
.to.have.length(1)
.and.to.have.deep.property('[0].style.color', 'blue');
});
it('resolves styles on multiple elements nested far down, Issue #307', () => {
@Radium
class TestComponent extends Component {
render() {
return (
<section>
<section>
<section>
<header
key="header"
style={{
color: 'yellow',
':hover': {color: 'blue'}
}}
/>
<footer
key="footer"
style={{
color: 'green',
':hover': {color: 'red'}
}}
/>
</section>
</section>
</section>
);
}
}
const output = renderFcIntoDocument(<TestComponent />);
const header = getElement(output, 'header');
expect(header.style.color).to.equal('yellow');
const footer = getElement(output, 'footer');
expect(footer.style.color).to.equal('green');
TestUtils.SimulateNative.mouseOver(header);
TestUtils.SimulateNative.mouseOver(footer);
expect(header.style.color).to.equal('blue');
expect(footer.style.color).to.equal('red');
});
it('resolves styles if an element has element children', () => {
@Radium
class Inner extends Component {
static propTypes = {children: PropTypes.node};
render() {
return (
<div style={[{color: 'blue'}, {background: 'red'}]}>
{this.props.children}
</div>
);
}
}
@Radium
class Outer extends Component {
render() {
return (
<Inner>
<span>We will break you.</span>
</Inner>
);
}
}
const output = renderFcIntoDocument(<Outer />);
const div = getElement(output, 'div');
expect(div.style.color).to.equal('blue');
expect(div.style.background).to.equal('red');
});
it('calls toString on object values', () => {
@Radium
class TestComponent extends Component {
render() {
return (
<div
style={{
background: {toString: () => 'red'}
}}
/>
);
}
}
const output = renderFcIntoDocument(<TestComponent />);
const div = getElement(output, 'div');
expect(div.style.background).to.equal('red');
});
it('accepts a config', () => {
const truthyMatchMedia = function() {
return {
matches: true,
addListener: function() {},
removeListener: function() {}
};
};
@Radium({
matchMedia: truthyMatchMedia
})
class TestComponent extends Component {
render() {
return (
<div
style={{
'@media (min-width: 600px)': {':hover': {color: 'blue'}}
}}
/>
);
}
}
const output = renderFcIntoDocument(<TestComponent />);
const div = getElement(output, 'div');
TestUtils.SimulateNative.mouseOver(div);
expect(div.style.color).to.equal('blue');
});
// this doesn't seem to actually work...
// https://github.com/FormidableLabs/radium/issues/862#issuecomment-340953580
xit('transforms fallback values', () => {
@Radium()
class TestComponent extends Component {
render() {
return (
<div
style={{
height: ['100%', '100vh']
}}
/>
);
}
}
const output = renderFcIntoDocument(<TestComponent />);
const div = getElement(output, 'div');
expect({...div.style}).to.include({
height: '100%;height:100vh'
});
});
it('adds active styles on space', () => {
@Radium
class TestComponent extends Component {
render() {
return (
<div
style={{
background: 'red',
color: 'blue',
':active': {color: 'green'}
}}
/>
);
}
}
const output = renderFcIntoDocument(<TestComponent />);
const div = getElement(output, 'div');
expect(div.style.color).to.equal('blue');
expect(div.style.background).to.equal('red');
TestUtils.SimulateNative.keyDown(div, {key: ' '});
expect(div.style.color).to.equal('green');
TestUtils.SimulateNative.keyUp(div, {key: ' '});
expect(div.style.color).to.equal('blue');
});
it('works with children as keyed object ala React Router', () => {
@Radium
class TestComponent extends Component {
render() {
return (
<div>
{this.props.children.nav}
{this.props.children.main}
</div>
);
}
}
const output = renderFcIntoDocument(
<TestComponent>
{{
nav: <nav>nav</nav>,
main: <main>main</main>
}}
</TestComponent>
);
const nav = getElement(output, 'nav');
expect(nav.innerText).to.equal('nav');
const main = getElement(output, 'main');
expect(main.innerText).to.equal('main');
});
it('preserves array children as arrays', () => {
@Radium
class TestComponent extends Component {
render() {
expect(Array.isArray(this.props.children)).to.equal(true);
return <div>{this.props.children}</div>;
}
}
const output = renderFcIntoDocument(
<TestComponent>
{[<nav key="nav">nav</nav>, <main key="main">main</main>]}
</TestComponent>
);
const nav = getElement(output, 'nav');
expect(nav.innerText).to.equal('nav');
const main = getElement(output, 'main');
expect(main.innerText).to.equal('main');
});
it('calls existing onMouseEnter handler', () => {
const handleMouseEnter = sinon.spy();
@Radium
class TestComponent extends Component {
render() {
return (
<div
onMouseEnter={handleMouseEnter}
style={{':hover': {color: 'red'}}}
/>
);
}
}
const output = renderFcIntoDocument(<TestComponent />);
const div = getElement(output, 'div');
TestUtils.SimulateNative.mouseOver(div);
expect(handleMouseEnter).to.have.been.called;
});
it('calls existing onMouseLeave handler', () => {
const handleMouseLeave = sinon.spy();
@Radium
class TestComponent extends Component {
render() {
return (
<div
onMouseLeave={handleMouseLeave}
style={{':hover': {color: 'red'}}}
/>
);
}
}
const output = renderFcIntoDocument(<TestComponent />);
const div = getElement(output, 'div');
TestUtils.SimulateNative.mouseOut(div);
expect(handleMouseLeave).to.have.been.called;
});
it('calls existing onMouseDown handler', () => {
const handleMouseDown = sinon.spy();
@Radium
class TestComponent extends Component {
render() {
return (
<div
onMouseDown={handleMouseDown}
style={{':active': {color: 'red'}}}
/>
);
}
}
const output = renderFcIntoDocument(<TestComponent />);
const div = getElement(output, 'div');
TestUtils.SimulateNative.mouseDown(div);
expect(handleMouseDown).to.have.been.called;
});
it('calls existing onFocus handler', () => {
const handleFocus = sinon.spy();
@Radium
class TestComponent extends Component {
render() {
return (
<input onFocus={handleFocus} style={{':focus': {color: 'red'}}} />
);
}
}
const output = renderFcIntoDocument(<TestComponent />);
const input = getElement(output, 'input');
TestUtils.SimulateNative.focus(input);
expect(handleFocus).to.have.been.called;
});
it('calls existing onBlur handler', () => {
const handleBlur = sinon.spy();
@Radium
class TestComponent extends Component {
render() {
return <input onBlur={handleBlur} style={{':focus': {color: 'red'}}} />;
}
}
const output = renderFcIntoDocument(<TestComponent />);
const input = getElement(output, 'input');
TestUtils.SimulateNative.blur(input);
expect(handleBlur).to.have.been.called;
});
it('ignores callback refs', () => {
@Radium
class TestComponent extends Component {
render() {
return (
<div>
<span key="a" ref={() => {}} style={{':hover': {color: 'red'}}} />
<nav key="b" ref={() => {}} style={{':hover': {color: 'red'}}} />
</div>
);
}
}
const output = renderFcIntoDocument(<TestComponent />);
const span = getElement(output, 'span');
const nav = getElement(output, 'nav');
TestUtils.SimulateNative.mouseOver(span);
expect(span.style.color).to.equal('red');
expect(nav.style.color).to.equal('');
TestUtils.SimulateNative.mouseOver(nav);
expect(nav.style.color).to.equal('red');
});
describe('plugins', () => {
it('runs a custom plugin', () => {
const makeItRedPlugin = () => ({style: {color: 'red'}});
@Radium
class TestComponent extends Component {
render() {
return <div style={{}} />;
}
}
const output = renderFcIntoDocument(
<TestComponent radiumConfig={{plugins: [makeItRedPlugin]}} />
);
const div = getElement(output, 'div');
expect(div.style.color).to.equal('red');
});
});
/* eslint-disable no-console */
it("doesn't try to setState if not mounted", () => {
sandbox.stub(console, 'error');
sandbox.stub(console, 'warn');
let setStateCaptured;
const plugin = function({setState}) {
setStateCaptured = setState;
};
@Radium({plugins: [plugin]})
class TestComponent extends Component {
render() {
return <div style={{color: 'blue'}} />;
}
}
const output = renderFcIntoDocument(<TestComponent />);
ReactDOM.unmountComponentAtNode(ReactDOM.findDOMNode(output).parentNode);
setStateCaptured('whatever');
expect(console.error).not.to.have.been.called;
expect(console.warn).not.to.have.been.called;
});
/* eslint-enable no-console */
it('works with stateless components', () => {
let MyStatelessComponent = props => (
<div style={{color: 'blue', ':hover': {color: 'red'}}}>
{props.children}
</div>
);
// Babel is forced to use regular functions when defining arrow functions.
// Arrow functions should not technically have prototypes,
// so remove it here to make sure Radium doesn't fail with real arrow functions.
MyStatelessComponent.prototype = undefined;
MyStatelessComponent = Radium(MyStatelessComponent);
const output = renderFcIntoDocument(
<MyStatelessComponent>hello world</MyStatelessComponent>
);
const div = getElement(output, 'div');
expect(div.style.color).to.equal('blue');
expect(div.innerText).to.equal('hello world');
TestUtils.SimulateNative.mouseOver(div);
expect(div.style.color).to.equal('red');
});
// Regression test: https://github.com/FormidableLabs/radium/issues/738
it('works with arrow-based render methods in components', () => {
class TestComponent extends Component {
render = () => {
return (
<div style={{color: 'blue', ':hover': {color: 'red'}}}>
{this.props.children}
</div>
);
};
}
const Wrapped = Radium(TestComponent);
const output = renderFcIntoDocument(<Wrapped>hello world</Wrapped>);
// Check prototype is not mutated.
expect(TestComponent.prototype).to.not.have.property('render');
const div = getElement(output, 'div');
expect(div.style.color).to.equal('blue');
expect(div.innerText).to.equal('hello world');
TestUtils.SimulateNative.mouseOver(div);
expect(div.style.color).to.equal('red');
});
// Regression test: https://github.com/FormidableLabs/radium/issues/738
it('works with arrow-based render methods in components with complex inheritence', () => {
class First extends Component {}
class Second extends First {}
class TestComponent extends Second {
render = () => {
return (
<div style={{color: 'blue', ':hover': {color: 'red'}}}>
{this.props.children}
</div>
);
};
}
const Wrapped = Radium(TestComponent);
const output = renderFcIntoDocument(<Wrapped>hello world</Wrapped>);
// Check prototypes are not mutated.
expect(First.prototype).to.not.have.property('render');
expect(Second.prototype).to.not.have.property('render');
expect(TestComponent.prototype).to.not.have.property('render');
const div = getElement(output, 'div');
expect(div.style.color).to.equal('blue');
expect(div.innerText).to.equal('hello world');
TestUtils.SimulateNative.mouseOver(div);
expect(div.style.color).to.equal('red');
});
// Regression test: https://github.com/FormidableLabs/radium/issues/950
it('works with array children', () => {
class TestComponent extends Component {
render = () => {
return [
<div key="key0" style={{color: 'blue', ':hover': {color: 'red'}}}>
{this.props.children}
</div>,
<div key="key1" style={{color: 'yellow', ':hover': {color: 'green'}}}>
two
</div>
];
};
}
const Wrapped = Radium(TestComponent);
const output = renderFcIntoDocument(<Wrapped>hello world</Wrapped>);
const divs = getElements(output, 'div');
expect(divs[0].style.color).to.equal('blue');
expect(divs[0].getAttribute('data-radium')).to.equal('true');
expect(divs[0].innerText).to.equal('hello world');
TestUtils.SimulateNative.mouseOver(divs[0]);
expect(divs[0].style.color).to.equal('red');
expect(divs[1].style.color).to.equal('yellow');
expect(divs[1].innerText).to.equal('two');
TestUtils.SimulateNative.mouseOver(divs[1]);
expect(divs[1].style.color).to.equal('green');
});
it('works with Fragments', () => {
class TestComponent extends Component {
render = () => {
return (
<React.Fragment>
<div key="key0" style={{color: 'blue', ':hover': {color: 'red'}}}>
{this.props.children}
</div>
<div
key="key1"
style={{color: 'yellow', ':hover': {color: 'green'}}}
>
two
</div>
</React.Fragment>
);
};
}
const Wrapped = Radium(TestComponent);
const output = renderFcIntoDocument(<Wrapped>hello world</Wrapped>);
const divs = getElements(output, 'div');
expect(divs[0].style.color).to.equal('blue');
expect(divs[0].getAttribute('data-radium')).to.equal('true');
expect(divs[0].innerText).to.equal('hello world');
TestUtils.SimulateNative.mouseOver(divs[0]);
expect(divs[0].style.color).to.equal('red');
expect(divs[1].style.color).to.equal('yellow');
expect(divs[1].innerText).to.equal('two');
TestUtils.SimulateNative.mouseOver(divs[1]);
expect(divs[1].style.color).to.equal('green');
});
it('works fine if passing null, undefined, or false in style', () => {
const TestComponent = Radium(() => (
<div style={{background: undefined, border: false, color: null}} />
));
const output = renderFcIntoDocument(<TestComponent />);
const div = getElement(output, 'div');
expect(div.style.background).to.equal('');
expect(div.style.border).to.equal('');
expect(div.style.color).to.equal('');
});
it('transfers defaultProps for stateless components', () => {
const defaultProps = {foo: PropTypes.string};
let MyStatelessComponent = () => <div />;
MyStatelessComponent.defaultProps = defaultProps;
MyStatelessComponent = Radium(MyStatelessComponent);
expect(MyStatelessComponent.defaultProps).to.equal(defaultProps);
});
/* eslint-disable no-console */
it('replaces style propType with array or object', () => {
sandbox.stub(console, 'error');
sandbox.stub(console, 'warn');
class TestComponent extends Component {
render() {
return <div style={this.props.style} />;
}
}
TestComponent.propTypes = {style: PropTypes.object};
TestComponent = Radium(TestComponent);
renderFcIntoDocument(<TestComponent style={[]} />);
expect(console.error).not.to.have.been.called;
expect(console.warn).not.to.have.been.called;
});
/* eslint-enable no-console */
describe('config', () => {
it('receives config from radiumConfig prop', () => {
const plugin = sinon.spy();
@Radium
class TestComponent extends Component {
render() {
return <div style={{}} />;
}
}
renderFcIntoDocument(
<TestComponent radiumConfig={{plugins: [plugin]}} />
);
expect(plugin).to.have.been.called;
});
it('receives config from context', () => {
const plugin = sinon.spy();
@Radium
class ParentComponent extends Component {
render() {
return (
<div style={{}}>
<ChildComponent />
</div>
);
}
}
@Radium
class ChildComponent extends Component {
render() {
return <div style={{}} />;
}
}
renderFcIntoDocument(
<ParentComponent radiumConfig={{plugins: [plugin]}} />
);
expect(plugin).to.have.callCount(2);
});
});
describe('inline prefixes', () => {
let TestComponent;
beforeEach(() => {
class Composed extends Component {
render() {
return React.createElement('div', {
style: {
color: 'red',
display: 'flex'
}
});
}
}
TestComponent = Composed;
});
// Regression test: https://github.com/FormidableLabs/radium/issues/958
it('handles no user agent', () => {
const userAgent = '';
const Wrapped = Radium({userAgent})(TestComponent);
const output = renderFcIntoDocument(<Wrapped />);
const div = getElement(output, 'div');
expect(div.style.color).to.equal('red');
expect(div.style.display).to.equal('flex');
});
// Regression test: https://github.com/FormidableLabs/radium/issues/958s
it('handles non-matching user agent', () => {
const userAgent = 'testy-mctestface';
const Wrapped = Radium({userAgent})(TestComponent);
const output = renderFcIntoDocument(<Wrapped />);
const div = getElement(output, 'div');
expect(div.style.color).to.equal('red');
expect(div.style.display).to.equal('flex');
});
it('handles matching user agent', () => {
const iOSChrome47 =
'Mozilla/5.0 (iPad; CPU OS 8_0_0 like Mac OS X) AppleWebKit/600.1.4 ' +
'(KHTML, like Gecko) CriOS/47.0.2526.107 Mobile/12H321 Safari/600.1.4';
const webkitFlex = '-webkit-flex';
// Check if we _can_ even have the expected value. (Can't on IE9).
class FlexCanary extends Component {
render() {
return React.createElement('div', {
style: {
display: webkitFlex
}
});
}
}
const canary = renderFcIntoDocument(<FlexCanary />);
const expectedDisplay = getElement(canary, 'div').style.display;
const Wrapped = Radium({userAgent: iOSChrome47})(TestComponent);
const output = renderFcIntoDocument(<Wrapped />);
const div = getElement(output, 'div');
expect(div.style.color).to.equal('red');
expect(div.style.display).to.equal(expectedDisplay);
});
});
});
================================================
FILE: src/__tests__/remove-nested-styles-test.js
================================================
/* eslint-disable react/prop-types */
import Radium, {StyleRoot} from 'index';
import React from 'react';
import {getElement, renderFcIntoDocument} from 'test-helpers';
describe('removeNestedStyles plugin tests', () => {
it('removes nested style objects', () => {
const ChildComponent = Radium(() => (
<span style={{color: 'red', foo: {color: 'blue'}}} />
));
const TestComponent = Radium(() => (
<StyleRoot>
<ChildComponent />
</StyleRoot>
));
const output = renderFcIntoDocument(<TestComponent />);
const span = getElement(output, 'span');
expect(span.style.foo).to.not.exist;
});
it('should not remove style objects that have a toString function defined', () => {
const styleObject = {color: 'blue'};
styleObject.toString = () => 'bar';
const ChildComponent = Radium(() => (
<span style={{color: 'red', foo: styleObject}} />
));
const TestComponent = Radium(() => (
<StyleRoot>
<ChildComponent />
</StyleRoot>
));
const output = renderFcIntoDocument(<TestComponent />);
const span = getElement(output, 'span');
expect(span.style.foo).to.equal('bar');
});
});
================================================
FILE: src/__tests__/resolve-styles-test.js
================================================
import React from 'react';
import MouseUpListener from 'plugins/mouse-up-listener';
import objectAssign from 'object-assign';
const resolveStyles = require('inject-loader!resolve-styles')({
exenv: require('__mocks__/exenv')
}).default;
const genComponent = function(initialState = {}) {
return {
setState: sinon.spy(function(newState) {
objectAssign(this.state, newState);
}),
state: initialState,
_radiumIsMounted: true
};
};
// http://stackoverflow.com/a/25395068/13932
const permutate = function(arr) {
const permutations = [];
if (arr.length === 1) {
return [arr];
}
for (let i = 0; i < arr.length; i++) {
const subPerms = permutate(arr.slice(0, i).concat(arr.slice(i + 1)));
for (let j = 0; j < subPerms.length; j++) {
subPerms[j].unshift(arr[i]);
permutations.push(subPerms[j]);
}
}
return permutations;
};
const getChildrenArray = function(children) {
const childrenArray = [];
React.Children.forEach(children, function(child) {
childrenArray.push(child);
});
return childrenArray;
};
describe('resolveStyles', () => {
beforeEach(() => {
MouseUpListener.subscribe = sinon.spy();
});
describe('no-op behavior', () => {
it('handles null rendered element', () => {
const component = genComponent();
resolveStyles(component, null);
});
it("doesn't explode", () => {
const component = genComponent();
const renderedElement = <div />;
const result = resolveStyles(component, renderedElement).element;
expect(result).to.equal(renderedElement);
expect(result.props).to.equal(renderedElement.props);
});
it('passes through normal style objects', () => {
const component = genComponent();
const renderedElement = <div style={{color: 'blue'}} />;
const result = resolveStyles(component, renderedElement).element;
expect(result.props.style).to.deep.equal(renderedElement.props.style);
});
it('passes through normal style objects of children', () => {
const component = genComponent();
const style = {color: 'blue'};
const renderedElement = (
<div>
<div style={style} />
</div>
);
const result = resolveStyles(component, renderedElement).element;
const children = getChildrenArray(result.props.children);
expect(children[0].props.style).to.deep.equal(style);
});
it("doesn't wrap string children in spans", () => {
const component = genComponent();
const renderedElement = <div>Hello</div>;
const result = resolveStyles(component, renderedElement).element;
expect(result.props.children).to.equal('Hello');
});
it("doesn't wrap number children in spans", () => {
const component = genComponent();
const renderedElement = <div>{88347}</div>;
const result = resolveStyles(component, renderedElement).element;
expect(result.props.children).to.equal(88347);
});
it('ignores invalid children', () => {
const component = genComponent();
// JSX won't let this through, so do it with a plain object instead
const renderedElement = {
props: {
children: [null]
}
};
const result = resolveStyles(component, renderedElement).element;
const children = getChildrenArray(result.props.children);
expect(children[0]).to.be.undefined;
});
it('only processes an element once', () => {
sinon.spy(React, 'cloneElement');
const component = genComponent();
const renderedElement = (
<div style={[{background: 'white'}, {color: 'blue'}]} />
);
let result = resolveStyles(component, renderedElement).element;
result = resolveStyles(component, result).element;
expect(result.props.style).to.deep.equal({
background: 'white',
color: 'blue'
});
expect(React.cloneElement).to.have.been.calledOnce;
React.cloneElement.restore();
});
});
describe('style array', () => {
it('merges an array of style objects', () => {
const component = genComponent();
const renderedElement = (
<div style={[{background: 'white'}, {color: 'blue'}]} />
);
const result = resolveStyles(component, renderedElement).element;
expect(result.props.style).to.deep.equal({
background: 'white',
color: 'blue'
});
});
it('skips falsy and non-object entries', () => {
const component = genComponent();
const renderedElement = (
<div
style={[
{background: 'white'},
false,
null,
''.someUndefinedVar,
'',
[1, 2, 3],
{color: 'blue'}
]}
/>
);
const result = resolveStyles(component, renderedElement).element;
expect(result.props.style).to.deep.equal({
background: 'white',
color: 'blue'
});
});
it('overwrites earlier styles with later ones', () => {
const component = genComponent();
const renderedElement = (
<div style={[{background: 'white'}, {background: 'blue'}]} />
);
const result = resolveStyles(component, renderedElement).element;
expect(result.props.style).to.deep.equal({
background: 'blue'
});
});
it('merges nested special styles', () => {
const component = genComponent();
const renderedElement = (
<div
style={[
{':hover': {background: 'white'}},
{':hover': {color: 'blue'}}
]}
/>
);
let result = resolveStyles(component, renderedElement).element;
result.props.onMouseEnter();
result = resolveStyles(component, renderedElement).element;
expect(result.props.style).to.deep.equal({
background: 'white',
color: 'blue'
});
});
});
const createPseduoStyleTests = function(
pseudo,
onHandlerName,
offHandlerName
) {
it('strips special styles if not applied', () => {
const component = genComponent();
const style = {background: 'blue'};
style[':' + pseudo] = {background: 'red'};
const renderedElement = <div style={style} />;
const result = resolveStyles(component, renderedElement).element;
expect(result.props.style).to.deep.equal({background: 'blue'});
});
it('adds appropriate handlers for ' + pseudo + ' styles', () => {
const component = genComponent();
const style = {background: 'blue'};
style[':' + pseudo] = {background: 'red'};
const renderedElement = <div style={style} />;
const result = resolveStyles(component, renderedElement).element;
expect(typeof result.props[onHandlerName]).to.equal('function');
if (offHandle
gitextract_taxgn3kc/ ├── .agignore ├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .flowconfig ├── .gitignore ├── .npmignore.publishr ├── .prettierignore ├── .prettierrc ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE-examples.md ├── LICENSE.md ├── README.md ├── appveyor.yml ├── bower.json ├── docs/ │ ├── README.md │ ├── api/ │ │ └── README.md │ ├── faq/ │ │ └── README.md │ └── guides/ │ ├── README.md │ └── upgrade-v0.16.x.md ├── examples/ │ ├── app.js │ ├── client.js │ ├── common.styles.js │ ├── components/ │ │ ├── button.js │ │ └── computed-well.js │ ├── index.html │ ├── server.js │ └── webpack.config.js ├── index.js ├── interfaces/ │ ├── hoist-non-react-statics.js │ └── inline-style-prefixer.js ├── karma.conf.coverage.js ├── karma.conf.ie.js ├── karma.conf.js ├── package.json ├── scripts/ │ └── update-prefix-data.js ├── src/ │ ├── __mocks__/ │ │ ├── exenv.js │ │ └── prefixer.js │ ├── __tests__/ │ │ ├── camel-case-props-to-dash-case-test.js │ │ ├── clean-state-key-test.js │ │ ├── enhancer-test.js │ │ ├── get-radium-style-state-test.js │ │ ├── get-state-key-test.js │ │ ├── get-state-test.js │ │ ├── keyframes-test.js │ │ ├── media-query-test.js │ │ ├── radium-test.js │ │ ├── remove-nested-styles-test.js │ │ ├── resolve-styles-test.js │ │ ├── style-component-test.js │ │ └── visited-test.js │ ├── append-important-to-each-value.js │ ├── append-px-if-needed.js │ ├── camel-case-props-to-dash-case.js │ ├── clean-state-key.js │ ├── components/ │ │ ├── style-root.js │ │ ├── style-sheet.js │ │ └── style.js │ ├── config.js │ ├── context.js │ ├── css-rule-set-to-string.js │ ├── enhancer.js │ ├── get-radium-style-state.js │ ├── get-state-key.js │ ├── get-state.js │ ├── hash.js │ ├── index.js │ ├── keyframes.js │ ├── map-object.js │ ├── merge-styles.js │ ├── plugins/ │ │ ├── check-props-plugin.js │ │ ├── index.js │ │ ├── keyframes-plugin.js │ │ ├── merge-style-array-plugin.js │ │ ├── mouse-up-listener.js │ │ ├── prefix-plugin.js │ │ ├── remove-nested-styles-plugin.js │ │ ├── resolve-interaction-styles-plugin.js │ │ ├── resolve-media-queries-plugin.js │ │ └── visited-plugin.js │ ├── prefix-data/ │ │ ├── dynamic.js │ │ └── static.js │ ├── prefixer.js │ ├── resolve-styles.js │ ├── style-keeper.js │ └── test-helpers.js ├── test/ │ ├── .eslintrc │ ├── enhancer-test.js │ ├── mocha.opts │ ├── radium-test.js │ ├── setup.js │ └── utils.js ├── webpack.config.js └── webpack.config.minified.js
SYMBOL INDEX (249 symbols across 33 files)
FILE: examples/app.js
class HoverMessage (line 26) | class HoverMessage extends React.Component {
method render (line 27) | render() {
class TwoSquares (line 45) | @Radium
method render (line 47) | render() {
class Spinner (line 63) | class Spinner extends React.Component {
method render (line 64) | render() {
class MultiSpinner (line 77) | class MultiSpinner extends React.Component {
method render (line 78) | render() {
class App (line 103) | class App extends React.Component {
method _remount (line 104) | _remount() {
method render (line 115) | render() {
FILE: examples/components/button.js
class Button (line 20) | @Radium
method render (line 22) | render() {
FILE: examples/components/computed-well.js
class ComputedWell (line 18) | class ComputedWell extends React.Component {
method getInitialState (line 19) | getInitialState() {
method getStyles (line 25) | getStyles() {
method handleSubmit (line 33) | handleSubmit(ev) {
method render (line 41) | render() {
FILE: src/__tests__/enhancer-test.js
class Composed (line 11) | class Composed extends Component {
method render (line 12) | render() {
method constructor (line 44) | constructor(props) {
method render (line 48) | render() {
method constructor (line 65) | constructor(props) {
method render (line 68) | render() {
method render (line 82) | render() {
method constructor (line 98) | constructor(props) {
method render (line 102) | render() {
method render (line 115) | render() {
method componentWillUnmount (line 132) | componentWillUnmount() {
method render (line 135) | render() {
method constructor (line 151) | constructor(props) {
method render (line 155) | render() {
method constructor (line 175) | constructor(props) {
method render (line 179) | render() {
method staticMethod (line 196) | static staticMethod() {
method render (line 199) | render() {}
method render (line 214) | render() {
method getStyles (line 227) | getStyles() {
method render (line 230) | render() {
class Composed (line 43) | class Composed extends Component {
method render (line 12) | render() {
method constructor (line 44) | constructor(props) {
method render (line 48) | render() {
method constructor (line 65) | constructor(props) {
method render (line 68) | render() {
method render (line 82) | render() {
method constructor (line 98) | constructor(props) {
method render (line 102) | render() {
method render (line 115) | render() {
method componentWillUnmount (line 132) | componentWillUnmount() {
method render (line 135) | render() {
method constructor (line 151) | constructor(props) {
method render (line 155) | render() {
method constructor (line 175) | constructor(props) {
method render (line 179) | render() {
method staticMethod (line 196) | static staticMethod() {
method render (line 199) | render() {}
method render (line 214) | render() {
method getStyles (line 227) | getStyles() {
method render (line 230) | render() {
class Composed (line 64) | class Composed extends Component {
method render (line 12) | render() {
method constructor (line 44) | constructor(props) {
method render (line 48) | render() {
method constructor (line 65) | constructor(props) {
method render (line 68) | render() {
method render (line 82) | render() {
method constructor (line 98) | constructor(props) {
method render (line 102) | render() {
method render (line 115) | render() {
method componentWillUnmount (line 132) | componentWillUnmount() {
method render (line 135) | render() {
method constructor (line 151) | constructor(props) {
method render (line 155) | render() {
method constructor (line 175) | constructor(props) {
method render (line 179) | render() {
method staticMethod (line 196) | static staticMethod() {
method render (line 199) | render() {}
method render (line 214) | render() {
method getStyles (line 227) | getStyles() {
method render (line 230) | render() {
class Composed (line 81) | class Composed extends Component {
method render (line 12) | render() {
method constructor (line 44) | constructor(props) {
method render (line 48) | render() {
method constructor (line 65) | constructor(props) {
method render (line 68) | render() {
method render (line 82) | render() {
method constructor (line 98) | constructor(props) {
method render (line 102) | render() {
method render (line 115) | render() {
method componentWillUnmount (line 132) | componentWillUnmount() {
method render (line 135) | render() {
method constructor (line 151) | constructor(props) {
method render (line 155) | render() {
method constructor (line 175) | constructor(props) {
method render (line 179) | render() {
method staticMethod (line 196) | static staticMethod() {
method render (line 199) | render() {}
method render (line 214) | render() {
method getStyles (line 227) | getStyles() {
method render (line 230) | render() {
class Composed (line 97) | class Composed extends Component {
method render (line 12) | render() {
method constructor (line 44) | constructor(props) {
method render (line 48) | render() {
method constructor (line 65) | constructor(props) {
method render (line 68) | render() {
method render (line 82) | render() {
method constructor (line 98) | constructor(props) {
method render (line 102) | render() {
method render (line 115) | render() {
method componentWillUnmount (line 132) | componentWillUnmount() {
method render (line 135) | render() {
method constructor (line 151) | constructor(props) {
method render (line 155) | render() {
method constructor (line 175) | constructor(props) {
method render (line 179) | render() {
method staticMethod (line 196) | static staticMethod() {
method render (line 199) | render() {}
method render (line 214) | render() {
method getStyles (line 227) | getStyles() {
method render (line 230) | render() {
class Composed (line 114) | class Composed extends Component {
method render (line 12) | render() {
method constructor (line 44) | constructor(props) {
method render (line 48) | render() {
method constructor (line 65) | constructor(props) {
method render (line 68) | render() {
method render (line 82) | render() {
method constructor (line 98) | constructor(props) {
method render (line 102) | render() {
method render (line 115) | render() {
method componentWillUnmount (line 132) | componentWillUnmount() {
method render (line 135) | render() {
method constructor (line 151) | constructor(props) {
method render (line 155) | render() {
method constructor (line 175) | constructor(props) {
method render (line 179) | render() {
method staticMethod (line 196) | static staticMethod() {
method render (line 199) | render() {}
method render (line 214) | render() {
method getStyles (line 227) | getStyles() {
method render (line 230) | render() {
class Composed (line 131) | class Composed extends Component {
method render (line 12) | render() {
method constructor (line 44) | constructor(props) {
method render (line 48) | render() {
method constructor (line 65) | constructor(props) {
method render (line 68) | render() {
method render (line 82) | render() {
method constructor (line 98) | constructor(props) {
method render (line 102) | render() {
method render (line 115) | render() {
method componentWillUnmount (line 132) | componentWillUnmount() {
method render (line 135) | render() {
method constructor (line 151) | constructor(props) {
method render (line 155) | render() {
method constructor (line 175) | constructor(props) {
method render (line 179) | render() {
method staticMethod (line 196) | static staticMethod() {
method render (line 199) | render() {}
method render (line 214) | render() {
method getStyles (line 227) | getStyles() {
method render (line 230) | render() {
class Composed (line 150) | class Composed extends Component {
method render (line 12) | render() {
method constructor (line 44) | constructor(props) {
method render (line 48) | render() {
method constructor (line 65) | constructor(props) {
method render (line 68) | render() {
method render (line 82) | render() {
method constructor (line 98) | constructor(props) {
method render (line 102) | render() {
method render (line 115) | render() {
method componentWillUnmount (line 132) | componentWillUnmount() {
method render (line 135) | render() {
method constructor (line 151) | constructor(props) {
method render (line 155) | render() {
method constructor (line 175) | constructor(props) {
method render (line 179) | render() {
method staticMethod (line 196) | static staticMethod() {
method render (line 199) | render() {}
method render (line 214) | render() {
method getStyles (line 227) | getStyles() {
method render (line 230) | render() {
class Composed (line 174) | class Composed extends Component {
method render (line 12) | render() {
method constructor (line 44) | constructor(props) {
method render (line 48) | render() {
method constructor (line 65) | constructor(props) {
method render (line 68) | render() {
method render (line 82) | render() {
method constructor (line 98) | constructor(props) {
method render (line 102) | render() {
method render (line 115) | render() {
method componentWillUnmount (line 132) | componentWillUnmount() {
method render (line 135) | render() {
method constructor (line 151) | constructor(props) {
method render (line 155) | render() {
method constructor (line 175) | constructor(props) {
method render (line 179) | render() {
method staticMethod (line 196) | static staticMethod() {
method render (line 199) | render() {}
method render (line 214) | render() {
method getStyles (line 227) | getStyles() {
method render (line 230) | render() {
class Composed (line 195) | class Composed extends Component {
method render (line 12) | render() {
method constructor (line 44) | constructor(props) {
method render (line 48) | render() {
method constructor (line 65) | constructor(props) {
method render (line 68) | render() {
method render (line 82) | render() {
method constructor (line 98) | constructor(props) {
method render (line 102) | render() {
method render (line 115) | render() {
method componentWillUnmount (line 132) | componentWillUnmount() {
method render (line 135) | render() {
method constructor (line 151) | constructor(props) {
method render (line 155) | render() {
method constructor (line 175) | constructor(props) {
method render (line 179) | render() {
method staticMethod (line 196) | static staticMethod() {
method render (line 199) | render() {}
method render (line 214) | render() {
method getStyles (line 227) | getStyles() {
method render (line 230) | render() {
class Composed (line 211) | class Composed extends Component {
method render (line 12) | render() {
method constructor (line 44) | constructor(props) {
method render (line 48) | render() {
method constructor (line 65) | constructor(props) {
method render (line 68) | render() {
method render (line 82) | render() {
method constructor (line 98) | constructor(props) {
method render (line 102) | render() {
method render (line 115) | render() {
method componentWillUnmount (line 132) | componentWillUnmount() {
method render (line 135) | render() {
method constructor (line 151) | constructor(props) {
method render (line 155) | render() {
method constructor (line 175) | constructor(props) {
method render (line 179) | render() {
method staticMethod (line 196) | static staticMethod() {
method render (line 199) | render() {}
method render (line 214) | render() {
method getStyles (line 227) | getStyles() {
method render (line 230) | render() {
class Composed (line 226) | class Composed extends React.Component {
method render (line 12) | render() {
method constructor (line 44) | constructor(props) {
method render (line 48) | render() {
method constructor (line 65) | constructor(props) {
method render (line 68) | render() {
method render (line 82) | render() {
method constructor (line 98) | constructor(props) {
method render (line 102) | render() {
method render (line 115) | render() {
method componentWillUnmount (line 132) | componentWillUnmount() {
method render (line 135) | render() {
method constructor (line 151) | constructor(props) {
method render (line 155) | render() {
method constructor (line 175) | constructor(props) {
method render (line 179) | render() {
method staticMethod (line 196) | static staticMethod() {
method render (line 199) | render() {}
method render (line 214) | render() {
method getStyles (line 227) | getStyles() {
method render (line 230) | render() {
FILE: src/__tests__/get-radium-style-state-test.js
class Test (line 7) | class Test extends Component {
class Test (line 16) | class Test extends Component {
class Test (line 24) | class Test extends Component {}
FILE: src/__tests__/get-state-key-test.js
class Test (line 7) | class Test extends React.Component {
method render (line 8) | render() {
method render (line 20) | render() {
method render (line 32) | render() {
class Test (line 19) | class Test extends React.Component {
method render (line 8) | render() {
method render (line 20) | render() {
method render (line 32) | render() {
class Test (line 31) | class Test extends React.Component {
method render (line 8) | render() {
method render (line 20) | render() {
method render (line 32) | render() {
FILE: src/__tests__/keyframes-test.js
constant CHROME_14_USER_AGENT (line 8) | const CHROME_14_USER_AGENT =
class TestComponent (line 15) | class TestComponent extends Component {
method render (line 16) | render() {
method render (line 44) | render() {
method render (line 82) | render() {
method render (line 123) | render() {
method render (line 165) | render() {
method render (line 206) | render() {
method render (line 255) | render() {
method render (line 308) | render() {
class TestComponent (line 43) | class TestComponent extends Component {
method render (line 16) | render() {
method render (line 44) | render() {
method render (line 82) | render() {
method render (line 123) | render() {
method render (line 165) | render() {
method render (line 206) | render() {
method render (line 255) | render() {
method render (line 308) | render() {
class TestComponent (line 81) | class TestComponent extends Component {
method render (line 16) | render() {
method render (line 44) | render() {
method render (line 82) | render() {
method render (line 123) | render() {
method render (line 165) | render() {
method render (line 206) | render() {
method render (line 255) | render() {
method render (line 308) | render() {
class TestComponent (line 122) | class TestComponent extends Component {
method render (line 16) | render() {
method render (line 44) | render() {
method render (line 82) | render() {
method render (line 123) | render() {
method render (line 165) | render() {
method render (line 206) | render() {
method render (line 255) | render() {
method render (line 308) | render() {
class TestComponent (line 164) | class TestComponent extends Component {
method render (line 16) | render() {
method render (line 44) | render() {
method render (line 82) | render() {
method render (line 123) | render() {
method render (line 165) | render() {
method render (line 206) | render() {
method render (line 255) | render() {
method render (line 308) | render() {
class TestComponent (line 205) | class TestComponent extends Component {
method render (line 16) | render() {
method render (line 44) | render() {
method render (line 82) | render() {
method render (line 123) | render() {
method render (line 165) | render() {
method render (line 206) | render() {
method render (line 255) | render() {
method render (line 308) | render() {
class ChildComponent (line 247) | @Radium
method render (line 249) | render() {
method render (line 301) | render() {
class TestComponent (line 254) | class TestComponent extends Component {
method render (line 16) | render() {
method render (line 44) | render() {
method render (line 82) | render() {
method render (line 123) | render() {
method render (line 165) | render() {
method render (line 206) | render() {
method render (line 255) | render() {
method render (line 308) | render() {
class ChildComponent (line 299) | @Radium
method render (line 249) | render() {
method render (line 301) | render() {
class TestComponent (line 306) | @Radium
method render (line 16) | render() {
method render (line 44) | render() {
method render (line 82) | render() {
method render (line 123) | render() {
method render (line 165) | render() {
method render (line 206) | render() {
method render (line 255) | render() {
method render (line 308) | render() {
FILE: src/__tests__/media-query-test.js
class TestComponent (line 42) | @Radium({matchMedia})
method render (line 44) | render() {
method render (line 69) | render() {
method render (line 97) | render() {
method render (line 134) | render() {
method render (line 163) | render() {
method render (line 196) | render() {
method render (line 227) | render() {
method render (line 423) | render() {
class TestComponent (line 67) | @Radium({matchMedia})
method render (line 44) | render() {
method render (line 69) | render() {
method render (line 97) | render() {
method render (line 134) | render() {
method render (line 163) | render() {
method render (line 196) | render() {
method render (line 227) | render() {
method render (line 423) | render() {
class TestComponent (line 95) | @Radium({matchMedia})
method render (line 44) | render() {
method render (line 69) | render() {
method render (line 97) | render() {
method render (line 134) | render() {
method render (line 163) | render() {
method render (line 196) | render() {
method render (line 227) | render() {
method render (line 423) | render() {
class TestComponent (line 132) | @Radium({matchMedia: truthyMatchMedia})
method render (line 44) | render() {
method render (line 69) | render() {
method render (line 97) | render() {
method render (line 134) | render() {
method render (line 163) | render() {
method render (line 196) | render() {
method render (line 227) | render() {
method render (line 423) | render() {
class TestComponent (line 161) | @Radium({matchMedia: truthyMatchMedia})
method render (line 44) | render() {
method render (line 69) | render() {
method render (line 97) | render() {
method render (line 134) | render() {
method render (line 163) | render() {
method render (line 196) | render() {
method render (line 227) | render() {
method render (line 423) | render() {
class TestComponent (line 194) | @Radium({matchMedia})
method render (line 44) | render() {
method render (line 69) | render() {
method render (line 97) | render() {
method render (line 134) | render() {
method render (line 163) | render() {
method render (line 196) | render() {
method render (line 227) | render() {
method render (line 423) | render() {
class TestComponent (line 225) | @Radium({matchMedia})
method render (line 44) | render() {
method render (line 69) | render() {
method render (line 97) | render() {
method render (line 134) | render() {
method render (line 163) | render() {
method render (line 196) | render() {
method render (line 227) | render() {
method render (line 423) | render() {
class ErrorBoundary (line 369) | class ErrorBoundary extends React.Component {
method componentDidCatch (line 370) | componentDidCatch(e) {
method render (line 374) | render() {
method removeListener (line 417) | removeListener() {}
class TestComponent (line 421) | @Radium({matchMedia: mockMatchMedia})
method render (line 44) | render() {
method render (line 69) | render() {
method render (line 97) | render() {
method render (line 134) | render() {
method render (line 163) | render() {
method render (line 196) | render() {
method render (line 227) | render() {
method render (line 423) | render() {
FILE: src/__tests__/radium-test.js
class TestComponent (line 23) | @Radium
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class TestComponent (line 38) | @Radium
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class InnerComponent (line 105) | class InnerComponent extends Component {
method render (line 106) | render() {
method render (line 131) | render() {
method render (line 168) | render() {
class TestComponent (line 111) | @Radium
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class InnerComponent (line 130) | class InnerComponent extends Component {
method render (line 106) | render() {
method render (line 131) | render() {
method render (line 168) | render() {
class TestComponent (line 136) | @Radium
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class InnerComponent (line 167) | class InnerComponent extends Component {
method render (line 106) | render() {
method render (line 131) | render() {
method render (line 168) | render() {
class TestComponent (line 173) | @Radium
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class TestComponent (line 207) | @Radium
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class TestComponent (line 235) | @Radium
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class TestComponent (line 263) | @Radium
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class SnapshotComp (line 326) | class SnapshotComp extends Component {
method componentDidMount (line 327) | componentDidMount() {
method getSnapshotBeforeUpdate (line 331) | getSnapshotBeforeUpdate() {
method componentDidUpdate (line 335) | componentDidUpdate(props, state, snapshot) {
method render (line 339) | render() {
class TestComponent (line 354) | class TestComponent extends Component {
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class TestComponent (line 397) | @Radium
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class Inner (line 441) | @Radium
method render (line 444) | render() {
class Outer (line 453) | @Radium
method render (line 455) | render() {
class TestComponent (line 473) | @Radium
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class TestComponent (line 501) | @Radium({
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class TestComponent (line 526) | @Radium()
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class TestComponent (line 548) | @Radium
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class TestComponent (line 580) | @Radium
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class TestComponent (line 609) | @Radium
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class TestComponent (line 633) | @Radium
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class TestComponent (line 655) | @Radium
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class TestComponent (line 677) | @Radium
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class TestComponent (line 699) | @Radium
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class TestComponent (line 718) | @Radium
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class TestComponent (line 733) | @Radium
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class TestComponent (line 761) | @Radium
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class TestComponent (line 787) | @Radium({plugins: [plugin]})
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class TestComponent (line 833) | class TestComponent extends Component {
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class First (line 861) | class First extends Component {}
class Second (line 862) | class Second extends First {}
class TestComponent (line 863) | class TestComponent extends Second {
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class TestComponent (line 893) | class TestComponent extends Component {
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class TestComponent (line 924) | class TestComponent extends Component {
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class TestComponent (line 986) | class TestComponent extends Component {
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class TestComponent (line 1005) | @Radium
method render (line 25) | render() {
method render (line 40) | render() {
method render (line 113) | render() {
method render (line 138) | render() {
method render (line 175) | render() {
method render (line 209) | render() {
method render (line 237) | render() {
method render (line 265) | render() {
method render (line 356) | render() {
method render (line 399) | render() {
method render (line 475) | render() {
method render (line 505) | render() {
method render (line 528) | render() {
method render (line 550) | render() {
method render (line 582) | render() {
method render (line 611) | render() {
method render (line 635) | render() {
method render (line 657) | render() {
method render (line 679) | render() {
method render (line 701) | render() {
method render (line 720) | render() {
method render (line 735) | render() {
method render (line 763) | render() {
method render (line 789) | render() {
method render (line 987) | render() {
method render (line 1007) | render() {
class ParentComponent (line 1022) | @Radium
method render (line 1024) | render() {
class ChildComponent (line 1033) | @Radium
method render (line 1035) | render() {
class Composed (line 1052) | class Composed extends Component {
method render (line 1053) | render() {
class FlexCanary (line 1095) | class FlexCanary extends Component {
method render (line 1096) | render() {
FILE: src/__tests__/resolve-styles-test.js
class CustomComponent (line 595) | class CustomComponent extends React.Component {}
class CustomComponent (line 610) | class CustomComponent extends React.Component {}
FILE: src/__tests__/style-component-test.js
constant MSIE9_USER_AGENT (line 6) | const MSIE9_USER_AGENT =
FILE: src/append-important-to-each-value.js
function appendImportantToEachValue (line 6) | function appendImportantToEachValue(style: Object): Object {
FILE: src/append-px-if-needed.js
function appendPxIfNeeded (line 53) | function appendPxIfNeeded(
FILE: src/components/style-sheet.js
class StyleSheet (line 8) | class StyleSheet extends Component<WithRadiumContextsProps> {
method super (line 13) | super(...arguments);
FILE: src/components/style.js
class Style (line 17) | class Style extends PureComponent<StyleProps> {
FILE: src/css-rule-set-to-string.js
function createMarkupForStyles (line 8) | function createMarkupForStyles(style: Object): string {
FILE: src/enhancer.js
constant KEYS_TO_IGNORE_WHEN_COPYING_PROPERTIES (line 19) | const KEYS_TO_IGNORE_WHEN_COPYING_PROPERTIES = [
constant RADIUM_METHODS (line 30) | let RADIUM_METHODS;
function copyProperties (line 32) | function copyProperties(source, target) {
function isStateless (line 48) | function isStateless(component: Function): boolean {
function isNativeClass (line 61) | function isNativeClass(component: Function): boolean {
function copyArrowFuncs (line 71) | function copyArrowFuncs(enhancedSelf: Object, ComposedComponent: constru...
function trimRadiumState (line 97) | function trimRadiumState(enhancer: EnhancerApi) {
function cleanUpEnhancer (line 116) | function cleanUpEnhancer(enhancer: EnhancerApi) {
method copyProperties (line 326) | copyProperties(ComposedComponent.prototype, RadiumEnhancer.prototype);
function NewComponent (line 346) | function NewComponent() {
method if (line 366) | if (
FILE: src/hash.js
function hash (line 6) | function hash(text: string): string {
FILE: src/index.js
function Radium (line 9) | function Radium(ComposedComponent: constructor) {
FILE: src/keyframes.js
method __process (line 18) | __process(userAgent) {
FILE: src/merge-styles.js
function isNestedStyle (line 1) | function isNestedStyle(value) {
function mergeStyles (line 12) | function mergeStyles(styles) {
FILE: src/plugins/keyframes-plugin.js
function keyframesPlugin (line 6) | function keyframesPlugin(
FILE: src/plugins/mouse-up-listener.js
function _handleMouseUp (line 6) | function _handleMouseUp() {
method if (line 13) | if (_callbacks.indexOf(callback) === -1) {
FILE: src/plugins/prefix-plugin.js
function prefixPlugin (line 7) | function prefixPlugin(
FILE: src/plugins/remove-nested-styles-plugin.js
function removeNestedStyles (line 5) | function removeNestedStyles({
FILE: src/plugins/resolve-media-queries-plugin.js
function _getWindowMatchMedia (line 7) | function _getWindowMatchMedia(ExecutionEnvironment) {
method remove (line 92) | remove() {
FILE: src/plugins/visited-plugin.js
function visited (line 5) | function visited({
FILE: src/prefixer.js
function transformValues (line 20) | function transformValues(style) {
function flattenStyleValues (line 50) | function flattenStyleValues(style) {
function getPrefixer (line 84) | function getPrefixer(
FILE: src/resolve-styles.js
constant DEFAULT_CONFIG (line 19) | const DEFAULT_CONFIG = {
method remove (line 289) | remove() {}
method if (line 382) | if (!extraStateKeyMap) {
FILE: src/style-keeper.js
method if (line 15) | if (this._listeners.indexOf(listener) === -1) {
method if (line 31) | if (!this._cssSet[css]) {
FILE: src/test-helpers.js
function getRenderOutput (line 7) | function getRenderOutput(element) {
class Wrapper (line 13) | class Wrapper extends Component {
method render (line 14) | render() {
function renderFcIntoDocument (line 19) | function renderFcIntoDocument(element) {
function getElement (line 23) | function getElement(output, tagName) {
function getElements (line 29) | function getElements(output, tagName) {
function cleanCSS (line 35) | function cleanCSS(css) {
function expectCSS (line 39) | function expectCSS(styleElement, css) {
function expectColor (line 47) | function expectColor(actual, expected) {
function createEsClass (line 51) | function createEsClass(renderFn) {
FILE: test/enhancer-test.js
class Composed (line 52) | class Composed extends React.Component {
method render (line 53) | render() {
class TestComponent (line 62) | class TestComponent extends React.Component {
method constructor (line 63) | constructor() {
method componentWillReceiveProps (line 70) | componentWillReceiveProps() {
method checkProp (line 74) | checkProp() {
method checkState (line 78) | checkState() {
method touchState (line 82) | touchState() {
method render (line 86) | render() {
FILE: test/radium-test.js
class Composed (line 13) | class Composed extends React.Component {
method render (line 14) | render() {
method render (line 127) | render() {
method render (line 154) | render() {
class Component (line 76) | class Component extends React.Component {
method render (line 77) | render() {
class Composed (line 126) | class Composed extends React.Component {
method render (line 14) | render() {
method render (line 127) | render() {
method render (line 154) | render() {
class Composed (line 153) | class Composed extends React.Component {
method render (line 14) | render() {
method render (line 127) | render() {
method render (line 154) | render() {
Condensed preview — 97 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (329K chars).
[
{
"path": ".agignore",
"chars": 9,
"preview": "dist\nlib\n"
},
{
"path": ".babelrc",
"chars": 978,
"preview": "{\n \"plugins\": [\n \"@babel/plugin-transform-destructuring\",\n [\n \"@babel/plugin-proposal-decorators\",\n {\n "
},
{
"path": ".editorconfig",
"chars": 323,
"preview": "# EditorConfig helps developers define and maintain consistent\n# coding styles between different editors and IDEs\n# edit"
},
{
"path": ".eslintignore",
"chars": 48,
"preview": "dist\nlib\nes\ncoverage\nexamples/dist\nnode_modules\n"
},
{
"path": ".eslintrc",
"chars": 18140,
"preview": "parser: \"babel-eslint\"\n\nparserOptions:\n ecmaVersion: 2018\n sourceType: \"module\"\n ecmaFeatures:\n jsx: true\n\nplugins"
},
{
"path": ".flowconfig",
"chars": 692,
"preview": "[ignore]\n.*/dist/.*\n.*/lib/.*\n.*/node_modules/.*/node_modules/.*\n.*/node_modules/babel-core/.*\n.*/node_modules/babel-loa"
},
{
"path": ".gitignore",
"chars": 448,
"preview": "### SublimeText ###\n*.sublime-workspace\n\n### OSX ###\n.AppleDouble\n.DS_Store\n.LSOverride\nIcon\n\n# Thumbnails\n._*\n\n# Files "
},
{
"path": ".npmignore.publishr",
"chars": 86,
"preview": "/*\n!/es\n!/dist\n!/docs\n!/lib\n!/src\n!LICENSE.txt\n!CHANGELOG.md\n!README.md\n!package.json\n"
},
{
"path": ".prettierignore",
"chars": 47,
"preview": "dist\nlib\nes\ncoverage\nexamples/dist\nnode_modules"
},
{
"path": ".prettierrc",
"chars": 53,
"preview": "{\n \"bracketSpacing\": false,\n \"singleQuote\": true\n}\n"
},
{
"path": ".travis.yml",
"chars": 884,
"preview": "dist: trusty\n\nlanguage: node_js\n\naddons:\n chrome: stable\n\nnode_js:\n - \"8\"\n - \"10\"\n - \"12\"\n\n# Use container-based Tra"
},
{
"path": "CHANGELOG.md",
"chars": 18584,
"preview": "# Radium Changelog\n\n## 0.26.2\n\n- Update `peerDependencies` for React to include 17.\n\n## 0.26.1 (September 29, 2020)\n\n###"
},
{
"path": "CONTRIBUTING.md",
"chars": 9328,
"preview": "Thanks for contributing!\n\n## Development\n\n### Installing dependencies\n\n```bash\nnpm install\n```\n\nYou will find all buildi"
},
{
"path": "LICENSE-examples.md",
"chars": 606,
"preview": "The examples provided by Formidable Labs are for non-commercial testing and evaluation purposes only. Formidable Labs re"
},
{
"path": "LICENSE.md",
"chars": 1082,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2015 Formidable Labs\n\nPermission is hereby granted, free of charge, to any person o"
},
{
"path": "README.md",
"chars": 7950,
"preview": "[![Maintenance Status][maintenance-image]](#maintenance-status)\n[![Travis Status][trav_img]][trav_site]\n[ source lives here in `/d"
},
{
"path": "docs/api/README.md",
"chars": 20426,
"preview": "# Radium API\n\n**Table of Contents**\n\n- [Sample Style Object](#sample-style-object)\n- [Radium](#radium)\n - [config.match"
},
{
"path": "docs/faq/README.md",
"chars": 8436,
"preview": "# Frequently Asked Questions\n\n- [How do I use pseudo-selectors like `:checked`, `:last`, `:before`, or `:after`?](#how-d"
},
{
"path": "docs/guides/README.md",
"chars": 8832,
"preview": "# Using Radium\n\n**Table of Contents**\n\n- [How do I do it, then?](#how-do-i-do-it-then)\n- [Modifiers](#modifiers)\n- [Brow"
},
{
"path": "docs/guides/upgrade-v0.16.x.md",
"chars": 4026,
"preview": "# v0.16.x Upgrade Guide\n\nVersion `0.16.x` brought a handful of [breaking, but really good changes](https://github.com/Fo"
},
{
"path": "examples/app.js",
"chars": 6478,
"preview": "/**\n * The examples provided by Formidable Labs are for non-commercial testing and\n * evaluation purposes only. Formidab"
},
{
"path": "examples/client.js",
"chars": 789,
"preview": "/**\n * The examples provided by Formidable Labs are for non-commercial testing and\n * evaluation purposes only. Formidab"
},
{
"path": "examples/common.styles.js",
"chars": 233,
"preview": "export const resetListStyle = {\n listStyle: 'none'\n};\n\nexport const resetBoxModel = {\n marginTop: 0,\n marginRight: 0,"
},
{
"path": "examples/components/button.js",
"chars": 1990,
"preview": "/**\n * The examples provided by Formidable Labs are for non-commercial testing and\n * evaluation purposes only. Formidab"
},
{
"path": "examples/components/computed-well.js",
"chars": 1401,
"preview": "/**\n * The examples provided by Formidable Labs are for non-commercial testing and\n * evaluation purposes only. Formidab"
},
{
"path": "examples/index.html",
"chars": 826,
"preview": "<!DOCTYPE html>\n<!--\nThe examples provided by Formidable Labs are for non-commercial testing and evaluation purposes onl"
},
{
"path": "examples/server.js",
"chars": 1524,
"preview": "/**\n * The examples provided by Formidable Labs are for non-commercial testing and\n * evaluation purposes only. Formidab"
},
{
"path": "examples/webpack.config.js",
"chars": 1099,
"preview": "/**\n * The examples provided by Formidable Labs are for non-commercial testing and\n * evaluation purposes only. Formidab"
},
{
"path": "index.js",
"chars": 84,
"preview": "module.exports = require('./lib').default;\nmodule.exports.default = module.exports;\n"
},
{
"path": "interfaces/hoist-non-react-statics.js",
"chars": 367,
"preview": "declare module 'hoist-non-react-statics' {\n /*\n S - source component statics\n TP - target component props\n SP "
},
{
"path": "interfaces/inline-style-prefixer.js",
"chars": 829,
"preview": "declare class InlineStylePrefixer {\n static prefixAll: typeof prefixAll;\n\n prefixedKeyframes: string;\n\n constructor(c"
},
{
"path": "karma.conf.coverage.js",
"chars": 737,
"preview": "module.exports = function(config) {\n require('./karma.conf.js')(config);\n config.set({\n webpack: {\n module: {\n"
},
{
"path": "karma.conf.ie.js",
"chars": 291,
"preview": "module.exports = function(config) {\n require('./karma.conf.js')(config);\n config.set({\n plugins: config.plugins.con"
},
{
"path": "karma.conf.js",
"chars": 2184,
"preview": "const path = require('path');\n\nprocess.env.BABEL_ENV = 'commonjs';\n\nmodule.exports = function(config) {\n config.set({\n "
},
{
"path": "package.json",
"chars": 4883,
"preview": "{\n \"name\": \"radium\",\n \"version\": \"0.26.2\",\n \"description\": \"A set of tools to manage inline styles on React elements\""
},
{
"path": "scripts/update-prefix-data.js",
"chars": 711,
"preview": "/**\n * Update the files in `src/prefix-data` to match the `browserList` below. Run\n * this if browser support changes or"
},
{
"path": "src/__mocks__/exenv.js",
"chars": 68,
"preview": "export default {\n canUseDOM: true,\n canUseEventListeners: true\n};\n"
},
{
"path": "src/__mocks__/prefixer.js",
"chars": 55,
"preview": "export default {\n getPrefixedStyle: style => style\n};\n"
},
{
"path": "src/__tests__/camel-case-props-to-dash-case-test.js",
"chars": 512,
"preview": "import camelCasePropsToDashCase from 'camel-case-props-to-dash-case';\n\ndescribe('camelCasePropsToDashCase', function() {"
},
{
"path": "src/__tests__/clean-state-key-test.js",
"chars": 301,
"preview": "import cleanStateKey from 'clean-state-key';\n\ndescribe('cleanStateKey', () => {\n it('returns the key as a string', () ="
},
{
"path": "src/__tests__/enhancer-test.js",
"chars": 6427,
"preview": "const {getElement, renderFcIntoDocument} = require('test-helpers');\nconst resolveStyles = sinon.spy(require('resolve-sty"
},
{
"path": "src/__tests__/get-radium-style-state-test.js",
"chars": 881,
"preview": "import {Component} from 'react';\nimport getRadiumStyleState from 'get-radium-style-state';\n\ndescribe('getRadiumStyleStat"
},
{
"path": "src/__tests__/get-state-key-test.js",
"chars": 973,
"preview": "import React from 'react';\nimport getStateKey from 'get-state-key';\nimport {getRenderOutput} from 'test-helpers';\n\ndescr"
},
{
"path": "src/__tests__/get-state-test.js",
"chars": 287,
"preview": "import getState from 'get-state';\n\ndescribe('getState', () => {\n it('successfully gets the state if passed number zero'"
},
{
"path": "src/__tests__/keyframes-test.js",
"chars": 7241,
"preview": "/* eslint-disable react/prop-types */\n\nimport Radium, {StyleRoot, keyframes} from 'index';\nimport {expectCSS, getElement"
},
{
"path": "src/__tests__/media-query-test.js",
"chars": 11642,
"preview": "/* eslint-disable react/prop-types */\n\nimport Radium, {StyleRoot} from 'index';\nimport React, {Component} from 'react';\n"
},
{
"path": "src/__tests__/radium-test.js",
"chars": 29847,
"preview": "/* eslint-disable react/prop-types */\n\nimport Radium from 'index';\nimport React, {Component} from 'react';\nimport MouseU"
},
{
"path": "src/__tests__/remove-nested-styles-test.js",
"chars": 1193,
"preview": "/* eslint-disable react/prop-types */\n\nimport Radium, {StyleRoot} from 'index';\nimport React from 'react';\nimport {getEl"
},
{
"path": "src/__tests__/resolve-styles-test.js",
"chars": 23560,
"preview": "import React from 'react';\nimport MouseUpListener from 'plugins/mouse-up-listener';\nimport objectAssign from 'object-ass"
},
{
"path": "src/__tests__/style-component-test.js",
"chars": 3146,
"preview": "/* eslint-disable react/prop-types */\n\nimport {Style} from 'index';\nimport React from 'react';\nimport {expectCSS, getEle"
},
{
"path": "src/__tests__/visited-test.js",
"chars": 1272,
"preview": "/* eslint-disable react/prop-types */\n\nimport Radium, {StyleRoot} from 'index';\nimport React from 'react';\nimport {expec"
},
{
"path": "src/append-important-to-each-value.js",
"chars": 291,
"preview": "/* @flow */\n\nimport appendPxIfNeeded from './append-px-if-needed';\nimport mapObject from './map-object';\n\nexport default"
},
{
"path": "src/append-px-if-needed.js",
"chars": 1340,
"preview": "/* @flow */\n\n// Copied from https://github.com/facebook/react/blob/\n// b87aabdfe1b7461e7331abb3601d9e6bb27544bc/\n// pack"
},
{
"path": "src/camel-case-props-to-dash-case.js",
"chars": 833,
"preview": "/* @flow */\n\nconst _camelCaseRegex = /([a-z])?([A-Z])/g;\n\nconst _camelCaseReplacer = function(match, p1, p2) {\n return "
},
{
"path": "src/clean-state-key.js",
"chars": 156,
"preview": "/* flow */\n\nconst cleanStateKey = key => {\n return key === null || typeof key === 'undefined' ? 'main' : key.toString()"
},
{
"path": "src/components/style-root.js",
"chars": 1335,
"preview": "/* @flow */\n\nimport React, {useContext, useRef} from 'react';\nimport type {Node} from 'react';\n\nimport Enhancer from '.."
},
{
"path": "src/components/style-sheet.js",
"chars": 1481,
"preview": "/* @flow */\n\nimport React, {Component} from 'react';\n\nimport StyleKeeper from '../style-keeper';\nimport {withRadiumConte"
},
{
"path": "src/components/style.js",
"chars": 2528,
"preview": "/* @flow */\n\nimport cssRuleSetToString from '../css-rule-set-to-string';\n\nimport React, {type Node, PureComponent} from "
},
{
"path": "src/config.js",
"chars": 606,
"preview": "/** @flow */\n/* eslint-disable no-use-before-define, block-scoped-const */\n\nimport type {PluginConfig, PluginResult} fro"
},
{
"path": "src/context.js",
"chars": 1315,
"preview": "/* @flow */\nimport React, {type Context, type ComponentType, useContext} from 'react';\nimport hoistStatics from 'hoist-n"
},
{
"path": "src/css-rule-set-to-string.js",
"chars": 906,
"preview": "/* @flow */\n\nimport appendPxIfNeeded from './append-px-if-needed';\nimport camelCasePropsToDashCase from './camel-case-pr"
},
{
"path": "src/enhancer.js",
"chars": 12082,
"preview": "/* @flow */\n\nimport React, {\n useState,\n useContext,\n useRef,\n useEffect,\n forwardRef\n} from 'react';\nimport PropTy"
},
{
"path": "src/get-radium-style-state.js",
"chars": 227,
"preview": "/* @flow */\n\nconst getRadiumStyleState = function(component: any) {\n return (\n component._lastRadiumState ||\n (co"
},
{
"path": "src/get-state-key.js",
"chars": 208,
"preview": "/* @flow */\n\nconst getStateKey = function(renderedElement: any): string {\n return typeof renderedElement.ref === 'strin"
},
{
"path": "src/get-state.js",
"chars": 423,
"preview": "/* @flow */\n\nimport cleanStateKey from './clean-state-key';\n\nconst getState = function(\n state: {_radiumStyleState: {[k"
},
{
"path": "src/hash.js",
"chars": 454,
"preview": "/* @flow */\n\n// a simple djb2 hash based on hash-string:\n// https://github.com/MatthewBarker/hash-string/blob/master/sou"
},
{
"path": "src/index.js",
"chars": 1152,
"preview": "import Enhancer from './enhancer';\nimport Plugins from './plugins';\nimport Style from './components/style';\nimport Style"
},
{
"path": "src/keyframes.js",
"chars": 1030,
"preview": "/* @flow */\n\nimport cssRuleSetToString from './css-rule-set-to-string';\nimport hash from './hash';\nimport {getPrefixedKe"
},
{
"path": "src/map-object.js",
"chars": 304,
"preview": "/* @flow */\n\nexport default function mapObject<TValue, TNext>(\n object: {[key: string]: TValue},\n mapper: (value: TVal"
},
{
"path": "src/merge-styles.js",
"chars": 1443,
"preview": "export function isNestedStyle(value) {\n // Don't merge objects overriding toString, since they should be converted\n //"
},
{
"path": "src/plugins/check-props-plugin.js",
"chars": 3239,
"preview": "/* @flow */\n\nimport type {PluginConfig, PluginResult} from './index';\n\nlet checkProps = (() => {}: any);\n\nif (process.en"
},
{
"path": "src/plugins/index.js",
"chars": 3483,
"preview": "/** @flow */\n/* eslint-disable block-scoped-const */\n\nimport type {Config} from '../config';\n\nimport checkPropsPlugin fr"
},
{
"path": "src/plugins/keyframes-plugin.js",
"chars": 1006,
"preview": "/* @flow */\n\nimport type {PluginConfig, PluginResult} from './index';\nimport type {Keyframes} from '../keyframes';\n\nexpo"
},
{
"path": "src/plugins/merge-style-array-plugin.js",
"chars": 491,
"preview": "/* @flow */\n\nimport type {PluginConfig, PluginResult} from './index';\n\n// Convenient syntax for multiple styles: `style="
},
{
"path": "src/plugins/mouse-up-listener.js",
"chars": 845,
"preview": "/* @flow */\n\nconst _callbacks = [];\nlet _mouseUpListenerIsActive = false;\n\nfunction _handleMouseUp() {\n _callbacks.forE"
},
{
"path": "src/plugins/prefix-plugin.js",
"chars": 331,
"preview": "/* @flow */\n\nimport type {PluginConfig, PluginResult} from './index';\n\nimport {getPrefixedStyle} from '../prefixer';\n\nex"
},
{
"path": "src/plugins/remove-nested-styles-plugin.js",
"chars": 474,
"preview": "/** @flow */\n\nimport type {PluginConfig, PluginResult} from './index';\n\nexport default function removeNestedStyles({\n i"
},
{
"path": "src/plugins/resolve-interaction-styles-plugin.js",
"chars": 3558,
"preview": "/** @flow */\n\nimport type {PluginConfig, PluginResult} from './index';\n\nimport MouseUpListener from './mouse-up-listener"
},
{
"path": "src/plugins/resolve-media-queries-plugin.js",
"chars": 4193,
"preview": "/** @flow */\n\nimport type {MatchMediaType} from '../config';\nimport type {PluginConfig, PluginResult} from './index';\n\nl"
},
{
"path": "src/plugins/visited-plugin.js",
"chars": 976,
"preview": "/** @flow */\n\nimport type {PluginConfig, PluginResult} from './index';\n\nexport default function visited({\n addCSS,\n ap"
},
{
"path": "src/prefix-data/dynamic.js",
"chars": 16405,
"preview": "import calc from 'inline-style-prefixer/dynamic/plugins/calc';\nimport crossFade from 'inline-style-prefixer/dynamic/plug"
},
{
"path": "src/prefix-data/static.js",
"chars": 4020,
"preview": "import calc from 'inline-style-prefixer/static/plugins/calc';\nimport crossFade from 'inline-style-prefixer/static/plugin"
},
{
"path": "src/prefixer.js",
"chars": 4499,
"preview": "/**\n * Based on https://github.com/jsstyles/css-vendor, but without having to\n * convert between different cases all the"
},
{
"path": "src/resolve-styles.js",
"chars": 13278,
"preview": "/* @flow */\n\nimport type {Config} from './config';\n\nimport appendImportantToEachValue from './append-important-to-each-v"
},
{
"path": "src/style-keeper.js",
"chars": 1153,
"preview": "/* @flow */\n\nexport default class StyleKeeper {\n _userAgent: string | typeof undefined;\n _listeners: Array<() => void>"
},
{
"path": "src/test-helpers.js",
"chars": 1642,
"preview": "import Color from 'color';\nimport React, {Component} from 'react';\nimport ReactDOM from 'react-dom';\nimport ShallowRende"
},
{
"path": "test/.eslintrc",
"chars": 38,
"preview": "parserOptions:\n sourceType: \"script\"\n"
},
{
"path": "test/enhancer-test.js",
"chars": 3427,
"preview": "'use strict';\n\nconst React = require('react');\n\nconst Enhancer = require('../lib/enhancer').default;\nconst createEsClass"
},
{
"path": "test/mocha.opts",
"chars": 36,
"preview": "--require test/setup.js\n--recursive\n"
},
{
"path": "test/radium-test.js",
"chars": 4963,
"preview": "'use strict';\n\nconst React = require('react');\n\nconst Radium = require('..');\nconst render = require('./utils').render;\n"
},
{
"path": "test/setup.js",
"chars": 303,
"preview": "'use strict';\n\nconst chai = require('chai');\nconst sinonChai = require('sinon-chai');\n\n// Add chai plugins.\nchai.use(sin"
},
{
"path": "test/utils.js",
"chars": 347,
"preview": "'use strict';\n\nconst React = require('react');\nconst renderToString = require('react-dom/server').renderToString;\n\nconst"
},
{
"path": "webpack.config.js",
"chars": 584,
"preview": "const path = require('path');\n\nmodule.exports = {\n cache: true,\n entry: path.join(__dirname, 'src/index.js'),\n extern"
},
{
"path": "webpack.config.minified.js",
"chars": 532,
"preview": "const webpack = require('webpack');\nconst base = require('./webpack.config');\n\nmodule.exports = Object.assign({}, base, "
}
]
About this extraction
This page contains the full source code of the FormidableLabs/radium GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 97 files (305.1 KB), approximately 78.9k tokens, and a symbol index with 249 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.