From 31cdb02dc77b1ebf4c236dd802c8ba8223bca64b Mon Sep 17 00:00:00 2001 From: Mikkel Laursen Date: Fri, 16 Dec 2016 14:18:44 -0700 Subject: [PATCH 01/38] Fixed Sass spelling from SASS -> Sass #179 --- docs/src/shared/components/Customization/Colors/README.md | 4 ++-- .../shared/components/Customization/Themes/ThemeBuilder.jsx | 4 ++-- docs/src/shared/components/Home/Home.jsx | 4 ++-- docs/src/shared/readmes/WhatsNew.md | 2 +- src/scss/components/_text-fields.scss | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/src/shared/components/Customization/Colors/README.md b/docs/src/shared/components/Customization/Colors/README.md index c4196125c5..807c2d95ff 100644 --- a/docs/src/shared/components/Customization/Colors/README.md +++ b/docs/src/shared/components/Customization/Colors/README.md @@ -15,12 +15,12 @@ All colors will have primary colors with suffixes: `50, 100, 200, 300, 400, 500, and all colors except for `brown`, `grey` and `blue-grey` will have accent suffixes of `100, 200, 400, 700`. In addition, the `$md-black-base` and `$md-white-base` variables are available. -To help with getting specific colors, there is a SASS Map of every color and a mixin that will create +To help with getting specific colors, there is a Sass Map of every color and a mixin that will create two class names for each material design color. ### `$md-color-map` This map contains every material design color so that you can quickly access them and optionally use -the [SASS Map functions](http://sass-lang.com/documentation/Sass/Script/Functions.html#map-functions) +the [Sass Map functions](http://sass-lang.com/documentation/Sass/Script/Functions.html#map-functions) to programatically get colors. This is really just used for the `react-md-color-class-names mixin`. ### `mixin react-md-color-class-names` diff --git a/docs/src/shared/components/Customization/Themes/ThemeBuilder.jsx b/docs/src/shared/components/Customization/Themes/ThemeBuilder.jsx index 8d1a5812d5..157daf1794 100644 --- a/docs/src/shared/components/Customization/Themes/ThemeBuilder.jsx +++ b/docs/src/shared/components/Customization/Themes/ThemeBuilder.jsx @@ -27,7 +27,7 @@ const ABOUT_THEME_BUILDER = ` ### Custom CSS Theme Builder Select a primary color, a secondary color, the secondary color's hue, and optionally toggle the light theme -to view a specific theme. When you have selected colors you like, either reference [Using with SASS](#using-with-sass) +to view a specific theme. When you have selected colors you like, either reference [Using with Sass](#using-with-sass) or [pre-compiled themes](#pre-compiled-themes). Not all themes will already be compiled and hosted on \`unpkg\`. `; @@ -134,7 +134,7 @@ export default class ThemeBuilder extends PureComponent { const compiledName = `react-md.${primary.replace('-', '_')}-${secondary.replace('-', '_')}${light ? '' : '.dark'}.min.css`; let howToUse = ` -#### Using with SASS +#### Using with Sass \`\`\`scss @import '~react-md/src/scss/react-md'; diff --git a/docs/src/shared/components/Home/Home.jsx b/docs/src/shared/components/Home/Home.jsx index e30be29a5a..57ca6648e0 100644 --- a/docs/src/shared/components/Home/Home.jsx +++ b/docs/src/shared/components/Home/Home.jsx @@ -13,8 +13,8 @@ import InlineSVG from 'components/InlineSVG'; const about = ` This project's goal is to be able to create a fully accessible material design -styled website using React Components and SASS. With the separation of styles in -SASS instead of inline styles, it should hopefully be easy to create custom +styled website using React Components and Sass. With the separation of styles in +Sass instead of inline styles, it should hopefully be easy to create custom components with the existing styles. `; diff --git a/docs/src/shared/readmes/WhatsNew.md b/docs/src/shared/readmes/WhatsNew.md index 55e155351a..47a9d17481 100644 --- a/docs/src/shared/readmes/WhatsNew.md +++ b/docs/src/shared/readmes/WhatsNew.md @@ -109,7 +109,7 @@ added the old v0.3.7 styles back into the `dist` folder for UMD. ### v1.0.0-alpha Released Whew. This was a big change. This was a complete rewrite from nested CSS priority to using my first attempt at BEM (so it definitely -isn't perfect). The SASS also changed to an _opt-in_ `mixin` framework. Styles will no longer be included when importing the `scss` files. +isn't perfect). The Sass also changed to an _opt-in_ `mixin` framework. Styles will no longer be included when importing the `scss` files. The styles can be created by using `react-md-everything` or `react-md-COMPONENTs`. This allows for access to variables by one import instead of having to specify multiple. Also, the dark theme was finally finished! Woo! Exciting! See the [upgrade guide](/discover-more/upgrade-guides/v1.0.0#now-vs-previous-versions) for more information. diff --git a/src/scss/components/_text-fields.scss b/src/scss/components/_text-fields.scss index c3060e132c..05568499c5 100644 --- a/src/scss/components/_text-fields.scss +++ b/src/scss/components/_text-fields.scss @@ -1555,7 +1555,7 @@ $md-text-field-desktop-floating-label-margin: 33px; /// Applies a color to all the browser placeholder psuedo elements. /// -/// @example scss - Basic Usage SASS +/// @example scss - Basic Usage SCSS /// .md-primary.md-toolbar { /// @include md-theme-placeholders($md-dark-theme-help-text-color); /// } From 0064fe9da39d5721e9f65d6b3d04d63c1dec8529 Mon Sep 17 00:00:00 2001 From: Mikkel Laursen Date: Fri, 16 Dec 2016 18:18:09 -0700 Subject: [PATCH 02/38] Fixed the Documentation Website for #177 The documentation website was _flashing_ after initial page load because the styles that were not in the main chunk were being injected into the head after initial page load. The Fonts and material-icons were also only being included after initial page load. I fixed the build steps to make sure that all styles are included in the main css bundle and moved the font libraries to the . --- docs/src/client/index.jsx | 11 ----------- docs/webpack-prod.config.js | 4 +++- docs/webpack.config.js | 4 ++++ 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/docs/src/client/index.jsx b/docs/src/client/index.jsx index b2764731a4..688c77c14a 100644 --- a/docs/src/client/index.jsx +++ b/docs/src/client/index.jsx @@ -7,17 +7,6 @@ import { syncHistoryWithStore } from 'react-router-redux'; import { Provider } from 'react-redux'; import { AppContainer } from 'react-hot-loader'; -import WebFont from 'webfontloader'; -WebFont.load({ - google: { - families: ['Roboto:300,400,500,700', 'Material Icons'], - }, - custom: { - families: ['FontAwesome'], - urls: ['https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css'], - }, -}); - import './_styles.scss'; import configureStore from 'stores/configureStore'; import onRouteUpdate from 'utils/onRouteUpdate'; diff --git a/docs/webpack-prod.config.js b/docs/webpack-prod.config.js index 5b955dac1a..c750ac5722 100644 --- a/docs/webpack-prod.config.js +++ b/docs/webpack-prod.config.js @@ -26,7 +26,9 @@ client.module.loaders = client.module.loaders.concat([{ loader: ExtractTextPlugin.extract('style', 'css!postcss!sass?outputStyle=compressed'), }, client.__imgLoader('file')]); client.plugins = client.plugins.concat([ - new ExtractTextPlugin('[name].[hash].min.css'), + new ExtractTextPlugin('[name].[hash].min.css', { + allChunks: true, + }), new HtmlWebpackPlugin(client.__htmlWebpackOptions), new webpack.optimize.UglifyJsPlugin({ sourceMap: false, diff --git a/docs/webpack.config.js b/docs/webpack.config.js index a8cead43e3..89bef3b419 100644 --- a/docs/webpack.config.js +++ b/docs/webpack.config.js @@ -11,6 +11,10 @@ module.exports = () => ({ inject: false, template: path.resolve(process.cwd(), 'src', 'template.js'), favicon: path.resolve(process.cwd(), 'src', 'client', 'favicon.ico'), + externalCSS: [ + 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css', + 'https://fonts.googleapis.com/css?family=Roboto:300,400,500,700%7CMaterial+Icons', + ], title: 'react-md', appMountId: 'app', From ee978bc9eca2b112bc1556aea59733d9e87b0c85 Mon Sep 17 00:00:00 2001 From: Mikkel Laursen Date: Fri, 16 Dec 2016 23:16:03 -0700 Subject: [PATCH 03/38] Updated SassDoc to be correctly cached #178 --- docs/src/shared/actions/fetch.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/src/shared/actions/fetch.js b/docs/src/shared/actions/fetch.js index bf37a9e374..0d9e4b7571 100644 --- a/docs/src/shared/actions/fetch.js +++ b/docs/src/shared/actions/fetch.js @@ -82,13 +82,14 @@ export function fetchCreator(endpoint, id, stateKey, { request, success, failure if (addId) { fullStateKey = (typeof stateKey === 'string' ? stateKey.split('.') : stateKey); fullStateKey.push(id); + fullStateKey = fullStateKey.filter(k => !!k); } return (dispatch, getState) => { const existingState = reduceKey(getState(), fullStateKey); // Only cache requests in development mode. - if (!__DEV__ && existingState && existingState.length) { + if (!__DEV__ && existingState && (!(existingState instanceof Array) || existingState.length)) { return null; } From c32eb3adc26587b391bdfceb1ee67de15c41f963 Mon Sep 17 00:00:00 2001 From: Mikkel Laursen Date: Sat, 17 Dec 2016 08:28:39 -0700 Subject: [PATCH 04/38] Moved Intl polyfills to the correct locations --- docs/package.json | 3 ++ docs/src/client/index.jsx | 18 ++++++- docs/src/server/index.js | 20 ++++--- docs/src/server/proxy.js | 6 +-- docs/src/server/reactMD.js | 12 +++++ .../ReactMD/file-inputs/UploadedFileCard.jsx | 7 --- .../ReactMD/pickers/date/LocaleExamples.jsx | 16 ------ .../ReactMD/pickers/time/LocaleExamples.jsx | 16 ------ docs/yarn.lock | 52 +++++++++++++++++-- 9 files changed, 94 insertions(+), 56 deletions(-) diff --git a/docs/package.json b/docs/package.json index b41b861b5d..5a1b110956 100644 --- a/docs/package.json +++ b/docs/package.json @@ -19,6 +19,7 @@ "apicache": "^0.4.1", "babel-polyfill": "^6.16.0", "bluebird": "^3.4.6", + "body-parser": "^1.15.2", "classnames": "^2.2.5", "compression": "^1.6.2", "ejs": "^2.5.2", @@ -26,7 +27,9 @@ "fuse.js": "^2.5.0", "helmet": "^3.1.0", "highlight.js": "^9.7.0", + "hpp": "^0.2.1", "intl": "^1.2.5", + "intl-locales-supported": "^1.0.0", "isomorphic-fetch": "^2.2.1", "lodash.throttle": "^4.1.1", "lorem-ipsum": "^1.0.3", diff --git a/docs/src/client/index.jsx b/docs/src/client/index.jsx index 688c77c14a..32da506435 100644 --- a/docs/src/client/index.jsx +++ b/docs/src/client/index.jsx @@ -49,4 +49,20 @@ if (module.hot) { }); } -renderApp(); +if (!global.Intl) { + require.ensure([], require => { + const lang = window.navigator.userLanguage || window.navigator.language || 'en-US'; + + require('intl'); + require('intl/locale-data/jsonp/en-US'); + require('intl/locale-data/jsonp/da-DK'); + + if (['en-US', 'da-DK'].indexOf(lang) === -1) { + require(`intl/locale-data/jsonp/${lang}`); + } + + renderApp(); + }); +} else { + renderApp(); +} diff --git a/docs/src/server/index.js b/docs/src/server/index.js index 219e8b67a6..bf0c95cecd 100644 --- a/docs/src/server/index.js +++ b/docs/src/server/index.js @@ -1,12 +1,14 @@ -const path = require('path'); -const express = require('express'); -const compression = require('compression'); -const logger = require('morgan'); -const { port } = require('../../serverConfig.json'); -const helmet = require('helmet'); +import path from 'path'; +import express from 'express'; +import compression from 'compression'; +import logger from 'morgan'; +import helmet from 'helmet'; +import hpp from 'hpp'; +import bodyParser from 'body-parser'; -const theme = require('./theme'); -const proxy = require('./proxy'); +import { port } from '../../serverConfig.json'; +import theme from './theme'; +import proxy from './proxy'; const app = express(); @@ -23,6 +25,8 @@ app.use(helmet({ noCache: false, })); app.use(compression()); +app.use(bodyParser.urlencoded({ extended: true })); +app.use(hpp()); app.use(logger(__DEV__ ? 'dev' : 'combined')); diff --git a/docs/src/server/proxy.js b/docs/src/server/proxy.js index f07931161d..03493aff15 100644 --- a/docs/src/server/proxy.js +++ b/docs/src/server/proxy.js @@ -1,4 +1,4 @@ -const fetch = require('isomorphic-fetch'); +import fetch from 'isomorphic-fetch'; /** * Does a very simple fetch for the requested url @@ -6,7 +6,7 @@ const fetch = require('isomorphic-fetch'); * @param {Object} req - The http request * @param {Object} res - The http response */ -module.exports = function proxy(req, res) { +export default function proxy(req, res) { // Soooo I don't know how to properly quote the url so that the query params get passed.. // So gotta manually do it here :/ const { url, start, limit } = req.query; @@ -19,4 +19,4 @@ module.exports = function proxy(req, res) { res.sendStatus(error.status || 500); }); } -}; +} diff --git a/docs/src/server/reactMD.js b/docs/src/server/reactMD.js index 9e6caee5f2..70912c2f72 100644 --- a/docs/src/server/reactMD.js +++ b/docs/src/server/reactMD.js @@ -5,10 +5,13 @@ import { Provider } from 'react-redux'; import { syncHistoryWithStore } from 'react-router-redux'; import getInitialDrawerState from './utils/getInitialDrawerState'; import getInitialQuickNavigationState from './utils/getInitialQuickNavigationState'; +import intlLocalesSupported from 'intl-locales-supported'; import routes from 'routes'; import configureStore from 'stores/configureStore'; +const SUPPORTED_LANGUAGES = ['en', 'en-US', 'da-DK']; + export default function reactMD(req, res) { const store = configureStore({ ui: { @@ -20,6 +23,15 @@ export default function reactMD(req, res) { const memoryHistory = createMemoryHistory(req.url); const history = syncHistoryWithStore(memoryHistory, store); + if (global.Intl) { + if (!intlLocalesSupported(SUPPORTED_LANGUAGES)) { + const Intl = require('intl'); + global.Intl.DateTimeFormat = Intl.DateTimeFormat; + } + } else { + global.Intl = require('intl'); + } + match({ history, routes, location: req.url }, async (error, redirectLocation, renderProps) => { if (error) { req.sendStatus(500); diff --git a/docs/src/shared/components/ReactMD/file-inputs/UploadedFileCard.jsx b/docs/src/shared/components/ReactMD/file-inputs/UploadedFileCard.jsx index 69f5a49171..40fe3c4862 100644 --- a/docs/src/shared/components/ReactMD/file-inputs/UploadedFileCard.jsx +++ b/docs/src/shared/components/ReactMD/file-inputs/UploadedFileCard.jsx @@ -8,13 +8,6 @@ import Media, { MediaOverlay } from 'react-md/lib/Media'; import Markdown from 'components/Markdown'; -if (__CLIENT__ && !global.Intl) { - require.ensure([], require => { - require('intl'); - require('intl/locale-data/jsonp/en-US'); - }); -} - export default class UploadedFileCard extends PureComponent { static propTypes = { file: PropTypes.shape({ diff --git a/docs/src/shared/components/ReactMD/pickers/date/LocaleExamples.jsx b/docs/src/shared/components/ReactMD/pickers/date/LocaleExamples.jsx index 924e50017c..fe4ac90676 100644 --- a/docs/src/shared/components/ReactMD/pickers/date/LocaleExamples.jsx +++ b/docs/src/shared/components/ReactMD/pickers/date/LocaleExamples.jsx @@ -4,22 +4,6 @@ import DatePicker from 'react-md/lib/Pickers/DatePickerContainer'; // or // import { DatePicker } from 'react-md/lib/Pickers'; -if (__CLIENT__ && !global.Intl) { - require.ensure([], require => { - const lang = typeof window !== 'undefined' - ? window.navigator.userLanguage || window.navigator.language - : 'en-US'; - - require('intl'); - require('intl/locale-data/jsonp/en-US'); - require('intl/locale-data/jsonp/da-DK'); - - if (['en-US', 'da-DK'].indexOf(lang) === -1) { - require(`intl/locale-data/jsonp/${lang}`); - } - }); -} - const today = new Date(); const LocaleExamples = () => (
diff --git a/docs/src/shared/components/ReactMD/pickers/time/LocaleExamples.jsx b/docs/src/shared/components/ReactMD/pickers/time/LocaleExamples.jsx index a6491856cb..4729d5b178 100644 --- a/docs/src/shared/components/ReactMD/pickers/time/LocaleExamples.jsx +++ b/docs/src/shared/components/ReactMD/pickers/time/LocaleExamples.jsx @@ -4,22 +4,6 @@ import TimePicker from 'react-md/lib/Pickers/TimePickerContainer'; // or // import { TimePicker } from 'react-md/lib/Pickers'; -if (__CLIENT__ && !global.Intl) { - require.ensure([], require => { - const lang = typeof window !== 'undefined' - ? window.navigator.userLanguage || window.navigator.language - : 'en-US'; - - require('intl'); - require('intl/locale-data/jsonp/en-US'); - require('intl/locale-data/jsonp/da-DK'); - - if (['en-US', 'da-DK'].indexOf(lang) === -1) { - require(`intl/locale-data/jsonp/${lang}`); - } - }); -} - const todayAt1522 = new Date(); todayAt1522.setHours(15); todayAt1522.setMinutes(22); diff --git a/docs/yarn.lock b/docs/yarn.lock index b3affb95b9..77f185ed2b 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -1058,6 +1058,21 @@ bluebird@^3.4.6: version "3.4.6" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.6.tgz#01da8d821d87813d158967e743d5fe6c62cf8c0f" +body-parser@^1.15.2: + version "1.15.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.15.2.tgz#d7578cf4f1d11d5f6ea804cef35dc7a7ff6dae67" + dependencies: + bytes "2.4.0" + content-type "~1.0.2" + debug "~2.2.0" + depd "~1.1.0" + http-errors "~1.5.0" + iconv-lite "0.4.13" + on-finished "~2.3.0" + qs "6.2.0" + raw-body "~2.1.7" + type-is "~1.6.13" + boolbase@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" @@ -1128,6 +1143,10 @@ bytes@2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.3.0.tgz#d5b680a165b6201739acb611542aabc2d8ceb070" +bytes@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.4.0.tgz#7d97196f9d5baf7f6935e25985549edd2a6c2339" + caller-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" @@ -3113,6 +3132,13 @@ hpkp@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/hpkp/-/hpkp-2.0.0.tgz#10e142264e76215a5d30c44ec43de64dee6d1672" +hpp@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/hpp/-/hpp-0.2.1.tgz#e103d0480397edfd50777be4ad735596286929cd" + dependencies: + lodash "^4.7.0" + type-is "^1.6.12" + hsts@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/hsts/-/hsts-2.0.0.tgz#a52234c6070decf214b2b6b70bb144d07e4776c7" @@ -3204,6 +3230,10 @@ https-browserify@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.0.tgz#b3ffdfe734b2a3d4a9efd58e8654c91fce86eafd" +iconv-lite@0.4.13: + version "0.4.13" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2" + iconv-lite@~0.4.13: version "0.4.15" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb" @@ -3366,6 +3396,10 @@ interpret@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.1.tgz#d579fb7f693b858004947af39fa0db49f795602c" +intl-locales-supported@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/intl-locales-supported/-/intl-locales-supported-1.0.0.tgz#9a9d94dbf104a87818881952dcb782053f0aeefa" + intl@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/intl/-/intl-1.2.5.tgz#82244a2190c4e419f8371f5aa34daa3420e2abde" @@ -4156,7 +4190,7 @@ lodash.uniq@^3.1.0: lodash._isiterateecall "^3.0.0" lodash.isarray "^3.0.0" -lodash@^4.0.0, lodash@^4.14.0, lodash@^4.16.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.6.1: +lodash@^4.0.0, lodash@^4.14.0, lodash@^4.16.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.6.1, lodash@^4.7.0: version "4.17.2" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.2.tgz#34a3055babe04ce42467b607d700072c7ff6bf42" @@ -5357,6 +5391,14 @@ range-parser@^1.0.3, range-parser@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" +raw-body@~2.1.7: + version "2.1.7" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.1.7.tgz#adfeace2e4fb3098058014d08c072dcc59758774" + dependencies: + bytes "2.4.0" + iconv-lite "0.4.13" + unpipe "1.0.0" + raw-loader@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-0.5.1.tgz#0c3d0beaed8a01c966d9787bf778281252a979aa" @@ -5495,7 +5537,7 @@ readable-stream@^1.0.27-1, readable-stream@^1.1.13, readable-stream@~1.1.9: isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@^2.0.0, "readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.1.5: +readable-stream@^2.0.0, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.1.5: version "2.2.2" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.2.tgz#a9e6fec3c7dda85f8bb1b3ba7028604556fc825e" dependencies: @@ -5507,7 +5549,7 @@ readable-stream@^2.0.0, "readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2. string_decoder "~0.10.x" util-deprecate "~1.0.1" -readable-stream@^2.0.1, readable-stream@~2.0.0, readable-stream@~2.0.5: +"readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@~2.0.0, readable-stream@~2.0.5: version "2.0.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" dependencies: @@ -6433,7 +6475,7 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" -type-is@~1.6.13: +type-is@^1.6.12, type-is@~1.6.13: version "1.6.14" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.14.tgz#e219639c17ded1ca0789092dd54a03826b817cb2" dependencies: @@ -6499,7 +6541,7 @@ unique-stream@^2.0.2: json-stable-stringify "^1.0.0" through2-filter "^2.0.0" -unpipe@~1.0.0: +unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" From c49184c70f42e406f46e32f88ebfa67cae982b22 Mon Sep 17 00:00:00 2001 From: Mikkel Laursen Date: Sat, 17 Dec 2016 08:30:19 -0700 Subject: [PATCH 05/38] Updated Tooltip Behavior on Touch Devices Updated the Tooltips so that it does not appear until the normal context menu would appear for a long touch. Also made it so the click event would not happen after the tooltip appears. --- src/js/Tooltips/TooltipContainer.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/js/Tooltips/TooltipContainer.js b/src/js/Tooltips/TooltipContainer.js index 62ded44163..d9b5bd39a0 100644 --- a/src/js/Tooltips/TooltipContainer.js +++ b/src/js/Tooltips/TooltipContainer.js @@ -4,6 +4,7 @@ import TransitionGroup from 'react-addons-transition-group'; import cn from 'classnames'; import { TAB } from '../constants/keyCodes'; +import captureNextEvent from '../utils/EventUtils/captureNextEvent'; import Tooltip from './Tooltip'; export default class TooltipContainer extends PureComponent { @@ -59,6 +60,8 @@ export default class TooltipContainer extends PureComponent { _stopContextMenu(e) { e.preventDefault(); window.removeEventListener('contextmenu', this._stopContextMenu, true); + captureNextEvent('click'); + this.setState({ visible: true }); } _showTooltip(e) { @@ -70,6 +73,7 @@ export default class TooltipContainer extends PureComponent { this._touched = true; window.addEventListener('contextmenu', this._stopContextMenu, true); + return; } From 7af131b678c7dc2d5dccb635205a1219e976803c Mon Sep 17 00:00:00 2001 From: Mikkel Laursen Date: Sat, 17 Dec 2016 08:30:35 -0700 Subject: [PATCH 06/38] Removed unused files --- src/js/utils/__mocks__/index.js | 19 -------- src/js/utils/index.js | 83 --------------------------------- 2 files changed, 102 deletions(-) delete mode 100644 src/js/utils/__mocks__/index.js delete mode 100644 src/js/utils/index.js diff --git a/src/js/utils/__mocks__/index.js b/src/js/utils/__mocks__/index.js deleted file mode 100644 index 052622ef55..0000000000 --- a/src/js/utils/__mocks__/index.js +++ /dev/null @@ -1,19 +0,0 @@ -/* eslint-env jest*/ -export const getOffset = jest.fn(() => ({ left: 0, top: 0 })); - -export const animate = jest.fn(); -export const isBetween = jest.fn(() => true); -export const isTouchDevice = jest.fn(); -export const getTouchOffset = jest.fn(e => { - if (!e) { - // position at 12 o'clock - return { offsetX: 136, offsetY: 12 }; - } else { - return { offsetX: e.offsetX, offsetY: e.offsetY }; - } -}); - -/* eslint-disable arrow-body-style */ -export const getField = jest.fn((props, state, field = 'value') => { - return typeof props[field] !== 'undefined' ? props[field] : state[field]; -}); diff --git a/src/js/utils/index.js b/src/js/utils/index.js deleted file mode 100644 index 1ccdcc5523..0000000000 --- a/src/js/utils/index.js +++ /dev/null @@ -1,83 +0,0 @@ -/* eslint-disable no-param-reassign */ - -export function setOverflow(enabled, selector) { - const el = selector ? document.querySelector(selector) : document.body; - if (enabled) { - el.classList.add('hide-overflow'); - } else { - el.classList.remove('hide-overflow'); - } -} - -export function easeInOut(currentTime, start, change, duration) { - currentTime /= duration / 2; - if (currentTime < 1) { - return change / 2 * currentTime * currentTime + start; - } - currentTime -= 1; - return -change / 2 * (currentTime * (currentTime - 2) - 1) + start; -} - -/** - * - * @param el - * @param increment - * @param elapsedTime - * @param transitionTime - * @param styleName - * @param currentValue - * @param finalValue - * @param next - */ -export function animate( - el, - increment, - elapsedTime, - transitionTime, - styleName, - startValue, - currentValue, - finalValue, - next -) { - elapsedTime += increment; - el.style[styleName] = `${easeInOut(elapsedTime, startValue, finalValue, transitionTime)}px`; - - if (elapsedTime < transitionTime) { - setTimeout(() => { - animate(el, increment, elapsedTime, transitionTime, styleName, startValue, currentValue, finalValue, next); - }, increment); - } else { - next(elapsedTime); - } -} - -/** - * Takes an event, a container node, and a function to call if the clicked - * element is not inside of the container node. - * - * @param {Object} event the click event - * @param {Object} node the container node to compare against - * @param {func} callback the function to call if the clicked element - * is not inside the container node - */ -export function onOutsideClick(event, node, callback) { - let target = event.target; - if (target === node) { return; } - - while (target.parentNode) { - if (target === node) { return; } - target = target.parentNode; - } - - callback(event); -} - -/** - * Checks if touch events are in the browser. - * @return {bool} true if it is a touch device - */ -export function isTouchDevice() { - return typeof window !== 'undefined' - && ('ontouchstart' in window || !!navigator.maxTouchPoints); -} From 435a91f52c992c0d461e3455ddd290da7e4f4135 Mon Sep 17 00:00:00 2001 From: Mikkel Laursen Date: Sat, 17 Dec 2016 17:11:14 -0700 Subject: [PATCH 07/38] Fixed double onChange firing for Switch #182 The switch's thumb and the switch's track need the onClick handler so that either the track can be clicked or the thumb can be _clicked_ by pressing the enter key. However, if a user actually touches or clicks the thumb itself, the click event propigates from the thumb to the track as well, so two onChange events are emitted. This commit prevents that click propigation from the switch's thumb. --- src/js/SelectionControls/SwitchThumb.js | 10 ++++++++++ src/js/SelectionControls/__tests__/SwitchThumb.js | 5 +++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/js/SelectionControls/SwitchThumb.js b/src/js/SelectionControls/SwitchThumb.js index 694b881e0c..8f0898c54e 100644 --- a/src/js/SelectionControls/SwitchThumb.js +++ b/src/js/SelectionControls/SwitchThumb.js @@ -16,6 +16,15 @@ export default class SwitchThumb extends PureComponent { className: PropTypes.string, disabled: PropTypes.bool, checked: PropTypes.bool, + onClick: PropTypes.func.isRequired, + }; + + _handleClick = (e) => { + // The switch's thumb needs to have an onClick handler to enable keyboard accessibility, however, + // this actually triggers two click events since the slider's track needs to be clickable as well. + // Stop propagation to prevent the thumb click AND track propagation click. + e.stopPropagation(); + this.props.onClick(e); }; render() { @@ -23,6 +32,7 @@ export default class SwitchThumb extends PureComponent { return ( {}; describe('SwitchThumb', () => { it('renders an AccessibleFakeInkedButton', () => { - const thumb = renderIntoDocument(); + const thumb = renderIntoDocument(); const btns = scryRenderedComponentsWithType(thumb, AccessibleFakeInkedButton); expect(btns.length).toBe(1); }); it('renders an AccessibleFakeInkedButton with the correct classNames', () => { - const props = { disabled: false, checked: false }; + const props = { disabled: false, checked: false, onClick: noop }; let thumb = renderIntoDocument(); let btn = findRenderedComponentWithType(thumb, AccessibleFakeInkedButton); expect(btn.props.className).toContain('md-switch-thumb'); From dc367b751272467bfca07cffb4a3b8772349e97c Mon Sep 17 00:00:00 2001 From: daturon Date: Mon, 19 Dec 2016 07:58:58 +0300 Subject: [PATCH 08/38] fix ISSUE 184 --- src/js/Sliders/Slider.js | 7 ++++--- src/js/utils/NumberUtils/calculateValueDistance.js | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/js/Sliders/Slider.js b/src/js/Sliders/Slider.js index c6bc19a5f1..ef7d53a9a9 100644 --- a/src/js/Sliders/Slider.js +++ b/src/js/Sliders/Slider.js @@ -253,10 +253,11 @@ export default class Slider extends PureComponent { `current value is '${step}'.` ); } else { - let name; - if (typeof props.value !== 'undefined' && props.value % step !== 0) { + let corrector = Math.pow(10, ('' + step).split('.')[1].length - 1), + name; + if (typeof props.value !== 'undefined' && (props.value * corrector) % (step * corrector) !== 0) { name = 'value'; - } else if (props.defaultValue % step !== 0) { + } else if ((props.defaultValue * corrector) % (step * corrector) !== 0) { name = 'defaultValue'; } diff --git a/src/js/utils/NumberUtils/calculateValueDistance.js b/src/js/utils/NumberUtils/calculateValueDistance.js index a0683bf03e..5d44125887 100644 --- a/src/js/utils/NumberUtils/calculateValueDistance.js +++ b/src/js/utils/NumberUtils/calculateValueDistance.js @@ -49,7 +49,8 @@ export default function calculateValueDistance(x, width, left, scale, step, min, if (normalize) { value = Math.round(distance / (width / scale)); if (step < 1) { - const modded = value % step; + const corrector = Math.pow(10, ('' + step).split('.')[1].length - 1); + const modded = (value * corrector) % (step * corrector); if (modded !== 0 && modded >= step / 2) { value += (step - modded); } else if (modded !== 0) { From 5c04147aa24049d032f81be88f21aecd8148faf2 Mon Sep 17 00:00:00 2001 From: daturon Date: Mon, 19 Dec 2016 08:15:22 +0300 Subject: [PATCH 09/38] fix ISSUE 184#code refactor --- src/js/Sliders/Slider.js | 4 ++-- src/js/utils/NumberUtils/calculateValueDistance.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/js/Sliders/Slider.js b/src/js/Sliders/Slider.js index ef7d53a9a9..7c548e97fc 100644 --- a/src/js/Sliders/Slider.js +++ b/src/js/Sliders/Slider.js @@ -253,8 +253,8 @@ export default class Slider extends PureComponent { `current value is '${step}'.` ); } else { - let corrector = Math.pow(10, ('' + step).split('.')[1].length - 1), - name; + const corrector = Math.pow(10, String(step).split('.')[1].length - 1); + let name; if (typeof props.value !== 'undefined' && (props.value * corrector) % (step * corrector) !== 0) { name = 'value'; } else if ((props.defaultValue * corrector) % (step * corrector) !== 0) { diff --git a/src/js/utils/NumberUtils/calculateValueDistance.js b/src/js/utils/NumberUtils/calculateValueDistance.js index 5d44125887..fad045dbd4 100644 --- a/src/js/utils/NumberUtils/calculateValueDistance.js +++ b/src/js/utils/NumberUtils/calculateValueDistance.js @@ -49,7 +49,7 @@ export default function calculateValueDistance(x, width, left, scale, step, min, if (normalize) { value = Math.round(distance / (width / scale)); if (step < 1) { - const corrector = Math.pow(10, ('' + step).split('.')[1].length - 1); + const corrector = Math.pow(10, String(step).split('.')[1].length - 1); const modded = (value * corrector) % (step * corrector); if (modded !== 0 && modded >= step / 2) { value += (step - modded); From 5ac081dae86abbe4758620916f866981fd81d373 Mon Sep 17 00:00:00 2001 From: daturon Date: Mon, 19 Dec 2016 08:24:51 +0300 Subject: [PATCH 10/38] fix ISSUE 184#code refactor --- src/js/Sliders/Slider.js | 5 ++++- src/js/utils/NumberUtils/calculateValueDistance.js | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/js/Sliders/Slider.js b/src/js/Sliders/Slider.js index 7c548e97fc..bd82532fd7 100644 --- a/src/js/Sliders/Slider.js +++ b/src/js/Sliders/Slider.js @@ -253,7 +253,10 @@ export default class Slider extends PureComponent { `current value is '${step}'.` ); } else { - const corrector = Math.pow(10, String(step).split('.')[1].length - 1); + const corrector = (typeof String(step).split('.')[1].length !== 'undefined' + && String(step).split('.')[1].length > 0) + ? Math.pow(10, String(step).split('.')[1].length) + : 1; let name; if (typeof props.value !== 'undefined' && (props.value * corrector) % (step * corrector) !== 0) { name = 'value'; diff --git a/src/js/utils/NumberUtils/calculateValueDistance.js b/src/js/utils/NumberUtils/calculateValueDistance.js index fad045dbd4..98e30dbfbb 100644 --- a/src/js/utils/NumberUtils/calculateValueDistance.js +++ b/src/js/utils/NumberUtils/calculateValueDistance.js @@ -49,7 +49,10 @@ export default function calculateValueDistance(x, width, left, scale, step, min, if (normalize) { value = Math.round(distance / (width / scale)); if (step < 1) { - const corrector = Math.pow(10, String(step).split('.')[1].length - 1); + const corrector = (typeof String(step).split('.')[1].length !== 'undefined' + && String(step).split('.')[1].length > 0) + ? Math.pow(10, String(step).split('.')[1].length) + : 1; const modded = (value * corrector) % (step * corrector); if (modded !== 0 && modded >= step / 2) { value += (step - modded); From b0d3527115b58e36761c81e067ad49c497691c32 Mon Sep 17 00:00:00 2001 From: daturon Date: Mon, 19 Dec 2016 08:32:59 +0300 Subject: [PATCH 11/38] fix ISSUE 184#code refactor --- src/js/Sliders/Slider.js | 2 +- src/js/utils/NumberUtils/calculateValueDistance.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/js/Sliders/Slider.js b/src/js/Sliders/Slider.js index bd82532fd7..930d486c3d 100644 --- a/src/js/Sliders/Slider.js +++ b/src/js/Sliders/Slider.js @@ -253,7 +253,7 @@ export default class Slider extends PureComponent { `current value is '${step}'.` ); } else { - const corrector = (typeof String(step).split('.')[1].length !== 'undefined' + const corrector = (typeof String(step).split('.')[1] !== 'undefined' && String(step).split('.')[1].length > 0) ? Math.pow(10, String(step).split('.')[1].length) : 1; diff --git a/src/js/utils/NumberUtils/calculateValueDistance.js b/src/js/utils/NumberUtils/calculateValueDistance.js index 98e30dbfbb..22816fc3f2 100644 --- a/src/js/utils/NumberUtils/calculateValueDistance.js +++ b/src/js/utils/NumberUtils/calculateValueDistance.js @@ -49,7 +49,7 @@ export default function calculateValueDistance(x, width, left, scale, step, min, if (normalize) { value = Math.round(distance / (width / scale)); if (step < 1) { - const corrector = (typeof String(step).split('.')[1].length !== 'undefined' + const corrector = (typeof String(step).split('.')[1] !== 'undefined' && String(step).split('.')[1].length > 0) ? Math.pow(10, String(step).split('.')[1].length) : 1; From e3e930e739a6f36d9265802c2215381a44dcd4e7 Mon Sep 17 00:00:00 2001 From: Mikkel Laursen Date: Mon, 19 Dec 2016 09:34:17 -0700 Subject: [PATCH 12/38] Removed distasteful jokes from Documentation website --- .../components/ReactMD/buttons/FlatButtonExamples.jsx | 8 ++++---- .../components/ReactMD/buttons/FloatingButtonExamples.jsx | 2 +- .../components/ReactMD/buttons/IconButtonExamples.jsx | 2 +- .../components/ReactMD/buttons/RaisedButtonExamples.jsx | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/src/shared/components/ReactMD/buttons/FlatButtonExamples.jsx b/docs/src/shared/components/ReactMD/buttons/FlatButtonExamples.jsx index 8d9ff840ee..814c6fddae 100644 --- a/docs/src/shared/components/ReactMD/buttons/FlatButtonExamples.jsx +++ b/docs/src/shared/components/ReactMD/buttons/FlatButtonExamples.jsx @@ -5,12 +5,12 @@ const FlatButtonExamples = () => (

Flat buttons can be unstyled or styled with the primary/secondary color.

- + +

When a flat button is disabled, any styling will be overridden and they will not be clickable.

- +
); diff --git a/docs/src/shared/components/ReactMD/buttons/FloatingButtonExamples.jsx b/docs/src/shared/components/ReactMD/buttons/FloatingButtonExamples.jsx index 88b966b5c3..472e3e9976 100644 --- a/docs/src/shared/components/ReactMD/buttons/FloatingButtonExamples.jsx +++ b/docs/src/shared/components/ReactMD/buttons/FloatingButtonExamples.jsx @@ -16,7 +16,7 @@ const FloatingButtonExamples = () => ( will not be clickable.

- +
); diff --git a/docs/src/shared/components/ReactMD/buttons/IconButtonExamples.jsx b/docs/src/shared/components/ReactMD/buttons/IconButtonExamples.jsx index 5786ee2a6b..e8a5ab3bff 100644 --- a/docs/src/shared/components/ReactMD/buttons/IconButtonExamples.jsx +++ b/docs/src/shared/components/ReactMD/buttons/IconButtonExamples.jsx @@ -17,7 +17,7 @@ const IconButtonExamples = () => ( will not be clickable.

- +

An icon Button can be rendered as a link. Tooltips diff --git a/docs/src/shared/components/ReactMD/buttons/RaisedButtonExamples.jsx b/docs/src/shared/components/ReactMD/buttons/RaisedButtonExamples.jsx index a2d90c6cc7..8c4d9070c9 100644 --- a/docs/src/shared/components/ReactMD/buttons/RaisedButtonExamples.jsx +++ b/docs/src/shared/components/ReactMD/buttons/RaisedButtonExamples.jsx @@ -5,12 +5,12 @@ const RaisedButtonExamples = () => (

Raised buttons can be unstyled or styled with the primary/secondary color.

+
); From 35cd5483416f7c3543582fa216b38942b59661ca Mon Sep 17 00:00:00 2001 From: Mikkel Laursen Date: Mon, 19 Dec 2016 09:56:42 -0700 Subject: [PATCH 13/38] Added create-react-app installation notes --- README.md | 18 ++++++++++++++++++ docs/src/shared/readmes/Installation.md | 22 ++++++++++++++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 518280ecb4..5ddb28e1db 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,24 @@ $ npm i -S react \ ## Usage +### Using create-react-app +`create-react-app` does [not support Sass](https://github.com/facebookincubator/create-react-app/issues/78), so +here are some steps to get it working: + +```bash +$ create-react-app my-app --scripts-version --custom-react-scripts +$ npm i -S react-md +``` + +Customize the `.env` to include SASS. + +See [custom-react-scripts](https://github.com/kitze/create-react-app) for more information. + +If this is not a solution for you, you can always run `npm run eject` from your app and add Sass yourself. + +### Using one of the Boilerplates +If `create-react-app` is not your thing, you can try using one of the available [boilerplates](https://react-md.mlaursen.com/discover-more/boilerplates). + ### Basic Webpack Usage ```js diff --git a/docs/src/shared/readmes/Installation.md b/docs/src/shared/readmes/Installation.md index 03a5bc6f41..1e3f39c8dd 100644 --- a/docs/src/shared/readmes/Installation.md +++ b/docs/src/shared/readmes/Installation.md @@ -17,8 +17,26 @@ Once installed, the components can be accessed by `react-md` or `react-md/lib` a The [Roboto font](https://www.google.com/fonts/specimen/Roboto) and [material-icons](https://design.google.com/icons/) should be included as well (or some equivalent). These fonts can be included via [WebFontLoader](https://github.com/typekit/webfontloader) -or by locally hosting and using the provided sass mixins to include them. The -example below will include the fonts with the WebFontLoader. +or by locally hosting and using the provided sass mixins to include them. See [host-material-icons](/customization/typography?tab=1#mixin-host-material-icons) +and [host-google-font](/customization/typography?tab=1#mixin-host-google-font) for more details. + +### Using create-react-app +`create-react-app` does [not support Sass](https://github.com/facebookincubator/create-react-app/issues/78), so +here are some steps to get it working: + +```bash +$ create-react-app my-app --scripts-version --custom-react-scripts +$ npm i -S react-md +``` + +Customize the `.env` to include SASS. + +See [custom-react-scripts](https://github.com/kitze/create-react-app) for more information. + +If this is not a solution for you, you can always run `npm run eject` from your app and add Sass yourself. + +### Using one of the Boilerplates +If `create-react-app` is not your thing, you can try using one of the available [boilerplates](/discover-more/boilerplates). ### Webpack Example From 35d71e8da2e42092d0bcebe3ae8328754e13534f Mon Sep 17 00:00:00 2001 From: Mikkel Laursen Date: Mon, 19 Dec 2016 09:56:54 -0700 Subject: [PATCH 14/38] Fixed fuse.js link for #189 --- docs/src/shared/components/ReactMD/autocompletes/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/shared/components/ReactMD/autocompletes/README.md b/docs/src/shared/components/ReactMD/autocompletes/README.md index 3d844f68e2..d0125a4209 100644 --- a/docs/src/shared/components/ReactMD/autocompletes/README.md +++ b/docs/src/shared/components/ReactMD/autocompletes/README.md @@ -11,6 +11,6 @@ allow a single best match to appear inline and the user can autocomplete by usin Since there are many different ways to filter or sort data, there are only two basic filters included. A `caseInsensitiveFilter` and a `fuzzyFilter`. They are both pretty basic so -you might want to include another library like [fuse.js](https:github.com/krisk/Fuse) or +you might want to include another library like [fuse.js](https://github.com/krisk/Fuse) or something else. I didn't want to force a library dependency, so it was not included. The `Inline` completion view uses a simple find by best match ignoring case by default. From adaf2b698e6d0696abfce0388f093522c3b5b4b2 Mon Sep 17 00:00:00 2001 From: Mikkel Laursen Date: Mon, 19 Dec 2016 09:56:42 -0700 Subject: [PATCH 15/38] Added create-react-app installation notes --- README.md | 55 +++++++++++++++++++++++ docs/src/shared/readmes/Installation.md | 59 ++++++++++++++++++++++++- 2 files changed, 112 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 518280ecb4..36a1c1dd0d 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,61 @@ $ npm i -S react \ ## Usage +### Using create-react-app +`create-react-app` does [not support Sass](https://github.com/facebookincubator/create-react-app/issues/78), so +here are some steps to get it working: + +```bash +$ create-react-app my-app --scripts-version --custom-react-scripts +$ npm i -S react-md +``` + +Customize the `.env` to include SASS. See [custom-react-scripts](https://github.com/kitze/create-react-app) +for more information. + +If this is not a solution for you, you can always run `yarn run eject` (or `npm run eject`) from your app and add Sass yourself. + +```bash +$ create-react-app my-app +$ yarn run eject +$ yarn add react-md +$ yarn add --dev sass-loader node-sass +$ vim -O config/webpack.config.dev.js config/webpack.config.prod.js +``` + +Add an scss/sass exclusion on line 109 (webpack.config.dev.js) and line 115 (webpack.config.prod.js) + +```js + exclude: [ + /\.html$/, + /\.(js|jsx)$/, + /\.css$/, + /\.json$/, + /\.svg$/, + /\.s(c|a)ss$/, + ], +``` + +In the dev config, add a new loader after the CSS loader: + +```js + { + test: /\.s(a|c)ss$/, + loader: 'style!css?importLoaders=2!postcss!sass?sourceMap&outputStyle=expanded' + }, +``` + +In the prod config: +```js + { + test: /\.s(a|c)ss$/, + loader: ExtractTextPlugin.extract('style', 'css?importLoaders=2!postcss!sass?outputStyle=compressed') + }, +``` + +### Using one of the Boilerplates +If `create-react-app` is not your thing, you can try using one of the available [boilerplates](https://react-md.mlaursen.com/discover-more/boilerplates). + ### Basic Webpack Usage ```js diff --git a/docs/src/shared/readmes/Installation.md b/docs/src/shared/readmes/Installation.md index 03a5bc6f41..9faaba49de 100644 --- a/docs/src/shared/readmes/Installation.md +++ b/docs/src/shared/readmes/Installation.md @@ -17,8 +17,63 @@ Once installed, the components can be accessed by `react-md` or `react-md/lib` a The [Roboto font](https://www.google.com/fonts/specimen/Roboto) and [material-icons](https://design.google.com/icons/) should be included as well (or some equivalent). These fonts can be included via [WebFontLoader](https://github.com/typekit/webfontloader) -or by locally hosting and using the provided sass mixins to include them. The -example below will include the fonts with the WebFontLoader. +or by locally hosting and using the provided sass mixins to include them. See [host-material-icons](/customization/typography?tab=1#mixin-host-material-icons) +and [host-google-font](/customization/typography?tab=1#mixin-host-google-font) for more details. + +### Using create-react-app +`create-react-app` does [not support Sass](https://github.com/facebookincubator/create-react-app/issues/78), so +here are some steps to get it working: + +```bash +$ create-react-app my-app --scripts-version --custom-react-scripts +$ npm i -S react-md +``` + +Customize the `.env` to include SASS. See [custom-react-scripts](https://github.com/kitze/create-react-app) +for more information. + +If this is not a solution for you, you can always run `yarn run eject` (or `npm run eject`) from your app and add Sass yourself. + +```bash +$ create-react-app my-app +$ yarn run eject +$ yarn add react-md +$ yarn add --dev sass-loader node-sass +$ vim -O config/webpack.config.dev.js config/webpack.config.prod.js +``` + +Add an scss/sass exclusion on line 109 (webpack.config.dev.js) and line 115 (webpack.config.prod.js) + +```js + exclude: [ + /\.html$/, + /\.(js|jsx)$/, + /\.css$/, + /\.json$/, + /\.svg$/, + /\.s(c|a)ss$/, + ], +``` + +In the dev config, add a new loader after the CSS loader: + +```js + { + test: /\.s(a|c)ss$/, + loader: 'style!css?importLoaders=2!postcss!sass?sourceMap&outputStyle=expanded' + }, +``` + +In the prod config: +```js + { + test: /\.s(a|c)ss$/, + loader: ExtractTextPlugin.extract('style', 'css?importLoaders=2!postcss!sass?outputStyle=compressed') + }, +``` + +### Using one of the Boilerplates +If `create-react-app` is not your thing, you can try using one of the available [boilerplates](/discover-more/boilerplates). ### Webpack Example From cc292195d923f891588cf88d53154356507102d6 Mon Sep 17 00:00:00 2001 From: Mikkel Laursen Date: Mon, 19 Dec 2016 09:56:54 -0700 Subject: [PATCH 16/38] Fixed fuse.js link for #189 --- docs/src/shared/components/ReactMD/autocompletes/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/shared/components/ReactMD/autocompletes/README.md b/docs/src/shared/components/ReactMD/autocompletes/README.md index 3d844f68e2..d0125a4209 100644 --- a/docs/src/shared/components/ReactMD/autocompletes/README.md +++ b/docs/src/shared/components/ReactMD/autocompletes/README.md @@ -11,6 +11,6 @@ allow a single best match to appear inline and the user can autocomplete by usin Since there are many different ways to filter or sort data, there are only two basic filters included. A `caseInsensitiveFilter` and a `fuzzyFilter`. They are both pretty basic so -you might want to include another library like [fuse.js](https:github.com/krisk/Fuse) or +you might want to include another library like [fuse.js](https://github.com/krisk/Fuse) or something else. I didn't want to force a library dependency, so it was not included. The `Inline` completion view uses a simple find by best match ignoring case by default. From 8114484eb839a51ab509cfd6a61e64e7a61f8091 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damian=20G=C4=85dziak?= Date: Mon, 19 Dec 2016 19:21:41 +0100 Subject: [PATCH 17/38] Grid without spacing affects on right aligned cell Styles of ``md-grid--no-spacing`` should not affect on ``md-cell--right`` ``margin-left: auto;`` attribute. --- src/scss/_grids.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/scss/_grids.scss b/src/scss/_grids.scss index f698ebcd04..34b045ea03 100644 --- a/src/scss/_grids.scss +++ b/src/scss/_grids.scss @@ -149,6 +149,10 @@ $md-grid-max-columns: $md-grid-desktop-columns !default; > .md-cell { margin: 0; + + &.md-cell--right { + @extend %md-cell--right; + } } } } From f4d42c1ce9043fcb888691272f57e14285e90515 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damian=20G=C4=85dziak?= Date: Mon, 19 Dec 2016 20:18:13 +0100 Subject: [PATCH 18/38] Fix scss lint warnings --- src/scss/_grids.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/scss/_grids.scss b/src/scss/_grids.scss index 34b045ea03..f3a2965ab1 100644 --- a/src/scss/_grids.scss +++ b/src/scss/_grids.scss @@ -149,7 +149,8 @@ $md-grid-max-columns: $md-grid-desktop-columns !default; > .md-cell { margin: 0; - + + // scss-lint:disable NestingDepth &.md-cell--right { @extend %md-cell--right; } From 5eccb3dd0c4525e21c31d23df972f2305b0b8b57 Mon Sep 17 00:00:00 2001 From: Mikkel Laursen Date: Tue, 20 Dec 2016 10:54:09 -0700 Subject: [PATCH 19/38] Password TextField Positioning Bugfix #192 Updated the Password TextField to use the top positioning instead of a bottom positioning since the top will always be a static size as compared to the bottom which can include multiline messages and counters and other stuff. --- src/js/TextFields/PasswordButton.js | 14 +++++++- src/js/TextFields/TextField.js | 3 ++ src/scss/components/_text-fields.scss | 52 ++++++++++++++++++--------- 3 files changed, 51 insertions(+), 18 deletions(-) diff --git a/src/js/TextFields/PasswordButton.js b/src/js/TextFields/PasswordButton.js index 4d85eaa510..603683b587 100644 --- a/src/js/TextFields/PasswordButton.js +++ b/src/js/TextFields/PasswordButton.js @@ -12,6 +12,8 @@ export default class PasswordButton extends PureComponent { iconChildren: PropTypes.node, onKeyUp: PropTypes.func, onKeyDown: PropTypes.func, + block: PropTypes.bool, + floating: PropTypes.bool, }; constructor(props) { @@ -62,7 +64,15 @@ export default class PasswordButton extends PureComponent { render() { const { keyboardFocus } = this.state; - const { active, passwordVisible, iconClassName, iconChildren, ...props } = this.props; + const { + active, + passwordVisible, + iconClassName, + iconChildren, + block, + floating, + ...props + } = this.props; return ( ); @@ -165,6 +181,7 @@ export default class Search extends PureComponent { return (
search} + leftIcon={search} /> {closeVisible ? close : null}
From d5592e6f8302eb3f5ddc16c12e0f345f7663ac67 Mon Sep 17 00:00:00 2001 From: Mikkel Laursen Date: Wed, 11 Jan 2017 11:42:55 -0700 Subject: [PATCH 36/38] Removed all references to waitForInkTransition in documentation website --- .../components/PhoneSizeDemo/ClosePhoneSizeDemoButton.jsx | 2 +- .../src/shared/components/PropTypesPage/ComponentTitle.jsx | 2 -- .../components/ReactMD/dialogs/FullPageDialogExamples.jsx | 4 ++-- .../components/ReactMD/dialogs/SimpleDialogExamples.jsx | 7 +------ .../ReactMD/drawers/MobileRightDrawerExample.jsx | 3 +-- .../shared/components/ReactMD/drawers/SimpleExample.jsx | 2 +- .../ReactMD/navigation-drawers/SimpleExample.jsx | 1 - .../components/ReactMD/tabs/MusicTabExample/More.jsx | 1 - .../ReactMD/tabs/MusicTabExample/MusicToolbar.jsx | 2 +- docs/src/shared/components/SassDocPage/FindInPage.jsx | 2 +- 10 files changed, 8 insertions(+), 18 deletions(-) diff --git a/docs/src/shared/components/PhoneSizeDemo/ClosePhoneSizeDemoButton.jsx b/docs/src/shared/components/PhoneSizeDemo/ClosePhoneSizeDemoButton.jsx index e6d70a897a..c13db427e8 100644 --- a/docs/src/shared/components/PhoneSizeDemo/ClosePhoneSizeDemoButton.jsx +++ b/docs/src/shared/components/PhoneSizeDemo/ClosePhoneSizeDemoButton.jsx @@ -33,6 +33,6 @@ export default class ClosePhoneSizeDemoButton extends PureComponent { } render() { - return @@ -88,7 +87,6 @@ export default class ComponentTitle extends PureComponent { ; - const action = ; + const action = } + nav={} actions={expandedActions} title={stats.filename} titleStyle={{ position: 'absolute' }} diff --git a/docs/src/shared/components/ReactMD/drawers/SimpleExample.jsx b/docs/src/shared/components/ReactMD/drawers/SimpleExample.jsx index bd91a8eb0f..59f097426a 100644 --- a/docs/src/shared/components/ReactMD/drawers/SimpleExample.jsx +++ b/docs/src/shared/components/ReactMD/drawers/SimpleExample.jsx @@ -39,7 +39,7 @@ export default class SimpleExample extends PureComponent { render() { const left = this.state.position === 'left'; - const close = ; + const close = ; const header = ( ( raised className="md-cell--right" primary - waitForInkTransition /> ); More.propTypes = { diff --git a/docs/src/shared/components/ReactMD/tabs/MusicTabExample/MusicToolbar.jsx b/docs/src/shared/components/ReactMD/tabs/MusicTabExample/MusicToolbar.jsx index ed3ae6a872..539d4124f4 100644 --- a/docs/src/shared/components/ReactMD/tabs/MusicTabExample/MusicToolbar.jsx +++ b/docs/src/shared/components/ReactMD/tabs/MusicTabExample/MusicToolbar.jsx @@ -5,7 +5,7 @@ import Button from 'react-md/lib/Buttons/Button'; const MusicToolbar = ({ onCloseClick }) => ( keyboard_arrow_left} + nav={} title="Metal" actions={} /> diff --git a/docs/src/shared/components/SassDocPage/FindInPage.jsx b/docs/src/shared/components/SassDocPage/FindInPage.jsx index 8a486db194..76988b3cfb 100644 --- a/docs/src/shared/components/SassDocPage/FindInPage.jsx +++ b/docs/src/shared/components/SassDocPage/FindInPage.jsx @@ -76,7 +76,7 @@ export default class FindInPage extends PureComponent { render() { const { filteredNavItems } = this.state; const { visible, onVisibilityToggle } = this.props; - const closeButton = ; + const closeButton = ; const autocomplete = ( Date: Sun, 15 Jan 2017 04:09:32 +0800 Subject: [PATCH 37/38] Fix #214 (SelectField fails on zero-valued option) --- src/js/SelectFields/SelectField.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/SelectFields/SelectField.js b/src/js/SelectFields/SelectField.js index f78fc6c652..1cc06aa28b 100644 --- a/src/js/SelectFields/SelectField.js +++ b/src/js/SelectFields/SelectField.js @@ -644,7 +644,7 @@ export default class SelectField extends PureComponent { break; case 'object': primaryText = item[itemLabel]; - itemValue = item[itemValueKey] || item[itemLabel]; + itemValue = typeof item[itemValueKey] !== 'undefined' ? item[itemValueKey] : item[itemLabel]; props = Object.keys(item).reduce((validProps, key) => { if (key !== itemLabel && key !== itemValueKey && key !== 'primaryText' && VALID_LIST_ITEM_PROPS.indexOf(key) !== -1 From e0de0eece9a80f4592ccb5202aff174ec0e66d9b Mon Sep 17 00:00:00 2001 From: Mikkel Laursen Date: Sat, 14 Jan 2017 13:44:36 -0700 Subject: [PATCH 38/38] Version bump to 1.0.1 --- README.md | 10 +++++----- docs/src/shared/readmes/Prerequisites.md | 2 +- docs/src/shared/readmes/WhatsNew.md | 15 +++++++++++++++ package.json | 2 +- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 25af712443..7a2f2c0049 100644 --- a/README.md +++ b/README.md @@ -125,12 +125,12 @@ You can also use the UMD build from [unpkg](https://unpkg.com/#/): ```html - - + + - + ``` @@ -140,14 +140,14 @@ You can also use the UMD build from [unpkg](https://unpkg.com/#/): - +
- +