From 41787f4e6b9a5225a655852822a4b0ae57c7b95a Mon Sep 17 00:00:00 2001 From: Pietro Ghezzi Date: Wed, 7 Feb 2018 13:46:01 +0100 Subject: [PATCH] add position attribute to display the NumPad in different way (top, center, bottom), add material ui button style for keypad --- README.md | 13 ++-- lib/components/NumPad.js | 20 ++++-- lib/elements/Calendar.js | 2 + lib/elements/KeyPad.js | 80 ++++++++++------------- lib/elements/KeypadButton.js | 15 ++++- lib/elements/Wrapper.js | 30 ++++++--- package-lock.json | 121 +++++++++++++++++++++++++++++------ package.json | 1 + stories/index.js | 3 + 9 files changed, 197 insertions(+), 88 deletions(-) diff --git a/README.md b/README.md index d0f12e9f..2ed6ae16 100644 --- a/README.md +++ b/README.md @@ -99,10 +99,11 @@ Calendar input field. | `onChange` | `function` | **required** | function called when value change and is valid. | | `placeholder` | `string` | none | text to display as input placeholder. | | `label` | `string` | none | text to display as input label. | -| `theme` | `string` or `object` | 'blue' | string as the name of the theme or object as custom styles. | -| `dateFormat` | `string` | 'MM/DD/YYYY' | specify a different date format. | +| `position` | `string` | `center` | Position to the screen. `center`, `flex-start`, `flex-end | +| `theme` | `string` or `object` | `blue` | string as the name of the theme or object as custom styles. | +| `dateFormat` | `string` | `MM/DD/YYYY` | specify a different date format. | | `defaultValue` | `string` or `number` | none | default value for the input field. | -| `locale` | `string` | 'en' | locale for days and months | +| `locale` | `string` | `en` | locale for days and months | | `inputButtonContent` | `object` | none | override input button content | | `minDate` | `string` | none | min date for calendar input validation | | `maxDate` | `string` | none | max date for calendar input validation | @@ -157,19 +158,19 @@ const myTheme = { ``` - ## Keyboard support + `0, 1, 2, ... 9`: input number. `- and .`: input symbol. -`Esc`: close keypad or calendar. +`Esc`: close keypad or calendar. `Enter`: submit value. ## Calendar swipe support -On mobile is possible to switch between months by swipe. +On mobile is possible to switch between months by swipe. ## Demo / Examples diff --git a/lib/components/NumPad.js b/lib/components/NumPad.js index f8e2d2a2..f07a0ee9 100644 --- a/lib/components/NumPad.js +++ b/lib/components/NumPad.js @@ -6,7 +6,7 @@ import { InputField, Wrapper } from '../elements'; import globalCSS from '../styles/global-css'; import styles from '../styles'; -injectGlobal`${globalCSS}`; +injectGlobal`${globalCSS}`; // eslint-disable-line no-unused-expressions export default ({ element, validation, displayRule, inputButtonContent, keyValid }) => { class NumPad extends Component { @@ -33,8 +33,18 @@ export default ({ element, validation, displayRule, inputButtonContent, keyValid render() { const { show, value } = this.state; - const { placeholder, label, theme, dateFormat, locale, minDate, maxDate } = this.props; + const { + placeholder, + label, + theme, + dateFormat, + locale, + minDate, + maxDate, + position, + } = this.props; const customTheme = typeof theme === 'object' ? theme : styles(theme); + customTheme.position = position; return ( @@ -55,7 +65,7 @@ export default ({ element, validation, displayRule, inputButtonContent, keyValid {show && ( - + {React.createElement( element, { @@ -85,9 +95,10 @@ export default ({ element, validation, displayRule, inputButtonContent, keyValid NumPad.defaultProps = { children: undefined, placeholder: undefined, + position: 'flex-end', label: undefined, theme: undefined, - dateFormat: undefined, + dateFormat: 'MM/DD/YYYY', locale: 'en', value: '', minDate: undefined, @@ -98,6 +109,7 @@ export default ({ element, validation, displayRule, inputButtonContent, keyValid onChange: PropTypes.func.isRequired, children: PropTypes.oneOfType([PropTypes.object, PropTypes.arrayOf(PropTypes.element)]), placeholder: PropTypes.string, + position: PropTypes.string, label: PropTypes.string, locale: PropTypes.string, theme: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), diff --git a/lib/elements/Calendar.js b/lib/elements/Calendar.js index a6679cea..5ae0dd0e 100644 --- a/lib/elements/Calendar.js +++ b/lib/elements/Calendar.js @@ -73,6 +73,8 @@ const Content = styled.div` height: 250px; min-width: 300px; max-width: 440px; + transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms; + box-shadow: rgba(0, 0, 0, 0.25) 0px 14px 45px, rgba(0, 0, 0, 0.22) 0px 10px 18px; background: ${props => props.theme.background.primary}; `; diff --git a/lib/elements/KeyPad.js b/lib/elements/KeyPad.js index 96a1ad44..32de0aeb 100644 --- a/lib/elements/KeyPad.js +++ b/lib/elements/KeyPad.js @@ -10,22 +10,14 @@ import IconCancel from 'react-icons/lib/md/close'; import Button from './KeypadButton'; import Display from './Display'; -const Container = styled.div` - width: 100%; - height: 250px; - background-color: ${props => - Color(props.theme.color.secondary) - .alpha(0.9) - .string()}; -`; - const Content = styled.div` display: flex; flex-direction: column; - margin: auto; - width: 240px; - height: 100%; + width: 264px; + height: 250px; background: ${props => props.theme.background.primary}; + transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms; + box-shadow: rgba(0, 0, 0, 0.25) 0px 14px 45px, rgba(0, 0, 0, 0.22) 0px 10px 18px; `; const Label = styled.div` @@ -150,39 +142,37 @@ class KeyPad extends Component { } = this.props; return ( - - -
- - - - - confirm(this.state.input)} - disabled={!validation(this.state.input)} - > - {validation(this.state.input) ? : } - -
- - - {[7, 8, 9, 4, 5, 6, 1, 2, 3, '-', 0, '.'].map(key => ( - + + click(value)} disabled={disabled} /> + ); ButtonWrapper.defaultProps = { diff --git a/lib/elements/Wrapper.js b/lib/elements/Wrapper.js index 2d4fb196..41c28b21 100644 --- a/lib/elements/Wrapper.js +++ b/lib/elements/Wrapper.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from 'styled-components'; +import Color from 'color'; const BackgroundPanel = styled.div` position: fixed; @@ -15,17 +16,31 @@ const BackgroundPanel = styled.div` const Container = styled.div` display: flex; - height: 100vh; - justify-content: flex-end; - flex-direction: column; + width: 100%; + height: 100%; font-size: 1em; - font-family: ${props => (props.theme.fontFamily ? props.theme.fontFamily + ',' : '')} Arial, + align-items: ${props => props.theme.position}; + font-family: ${props => (props.theme.fontFamily ? `${props.theme.fontFamily},` : '')} Arial, sans-serif, Helvetica; `; +const Content = styled.div` + display: flex; + width: 100%; + justify-content: center; + align-items: ${props => props.theme.position}; + height: ${props => (props.theme.position === 'center' ? '100vh' : '250px')}; + background-color: ${props => + Color(props.theme.color.secondary) + .alpha(0.6) + .string()}; +`; + const Wrapper = props => ( - {props.children} + + {props.children} + ); @@ -33,11 +48,6 @@ Wrapper.displayName = 'Wrapper'; Wrapper.propTypes = { children: PropTypes.oneOfType([PropTypes.object, PropTypes.array]).isRequired, - inProp: PropTypes.bool, -}; - -Wrapper.defaultProps = { - inProp: false, }; export default Wrapper; diff --git a/package-lock.json b/package-lock.json index e65ca50f..1be36cc8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2626,7 +2626,6 @@ "resolved": "http://svnexus003.eoc.ch:8081/repository/npm-public/babel-runtime/-/babel-runtime-6.26.0.tgz", "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, "requires": { "core-js": "2.5.1", "regenerator-runtime": "0.11.0" @@ -2636,8 +2635,7 @@ "version": "2.5.1", "resolved": "http://svnexus003.eoc.ch:8081/repository/npm-public/core-js/-/core-js-2.5.1.tgz", - "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=", - "dev": true + "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=" } } }, @@ -2824,8 +2822,7 @@ "version": "1.9.1", "resolved": "http://svnexus003.eoc.ch:8081/repository/npm-public/bowser/-/bowser-1.9.1.tgz", "integrity": - "sha512-UXti1JB6oK8hO983AImunnV6j/fqAEeDlPXh99zhsP5g32oLbxJJ6qcOaUesR+tqqhnUVQHlRJyD0dfiV0Hxaw==", - "dev": true + "sha512-UXti1JB6oK8hO983AImunnV6j/fqAEeDlPXh99zhsP5g32oLbxJJ6qcOaUesR+tqqhnUVQHlRJyD0dfiV0Hxaw==" }, "brace-expansion": { "version": "1.1.8", @@ -3185,8 +3182,7 @@ "version": "1.0.0", "resolved": "http://svnexus003.eoc.ch:8081/repository/npm-public/chain-function/-/chain-function-1.0.0.tgz", - "integrity": "sha1-DUqzfn4Y6tC9xHuSB2QRjOWHM9w=", - "dev": true + "integrity": "sha1-DUqzfn4Y6tC9xHuSB2QRjOWHM9w=" }, "chalk": { "version": "2.3.0", @@ -3219,6 +3215,12 @@ } } }, + "change-emitter": { + "version": "0.1.6", + "resolved": + "http://svnexus003.eoc.ch:8081/repository/npm-public/change-emitter/-/change-emitter-0.1.6.tgz", + "integrity": "sha1-6LL+PX8at9aaMhma/5HqaTFAlRU=" + }, "chardet": { "version": "0.4.2", "resolved": "http://svnexus003.eoc.ch:8081/repository/npm-public/chardet/-/chardet-0.4.2.tgz", @@ -3931,7 +3933,6 @@ "http://svnexus003.eoc.ch:8081/repository/npm-public/css-in-js-utils/-/css-in-js-utils-2.0.0.tgz", "integrity": "sha512-yuWmPMD9FLi50Xf3k8W8oO3WM1eVnxEGCldCLyfusQ+CgivFk0s23yst4ooW6tfxMuSa03S6uUEga9UhX6GRrA==", - "dev": true, "requires": { "hyphenate-style-name": "1.0.2" } @@ -4513,8 +4514,7 @@ "version": "3.2.1", "resolved": "http://svnexus003.eoc.ch:8081/repository/npm-public/dom-helpers/-/dom-helpers-3.2.1.tgz", - "integrity": "sha1-MgPgf+0he9H0JLAZc1WC/Deyglo=", - "dev": true + "integrity": "sha1-MgPgf+0he9H0JLAZc1WC/Deyglo=" }, "dom-serializer": { "version": "0.1.0", @@ -7758,8 +7758,7 @@ "version": "1.0.2", "resolved": "http://svnexus003.eoc.ch:8081/repository/npm-public/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz", - "integrity": "sha1-MRYKNpMK2vH8BMYHT360FGXU7Es=", - "dev": true + "integrity": "sha1-MRYKNpMK2vH8BMYHT360FGXU7Es=" }, "iconv-lite": { "version": "0.4.19", @@ -7882,7 +7881,6 @@ "resolved": "http://svnexus003.eoc.ch:8081/repository/npm-public/inline-style-prefixer/-/inline-style-prefixer-3.0.8.tgz", "integrity": "sha1-hVG45bTVcyROZqNLBPfTIHaitTQ=", - "dev": true, "requires": { "bowser": "1.9.1", "css-in-js-utils": "2.0.0" @@ -9467,8 +9465,7 @@ "keycode": { "version": "2.1.9", "resolved": "http://svnexus003.eoc.ch:8081/repository/npm-public/keycode/-/keycode-2.1.9.tgz", - "integrity": "sha1-lkojxU5IiUBbSGGlyfBIDUUUHfo=", - "dev": true + "integrity": "sha1-lkojxU5IiUBbSGGlyfBIDUUUHfo=" }, "keypress": { "version": "0.2.1", @@ -10040,6 +10037,13 @@ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, + "lodash.merge": { + "version": "4.6.1", + "resolved": + "http://svnexus003.eoc.ch:8081/repository/npm-public/lodash.merge/-/lodash.merge-4.6.1.tgz", + "integrity": + "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==" + }, "lodash.mergewith": { "version": "4.6.0", "resolved": @@ -10075,6 +10079,12 @@ "integrity": "sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=", "dev": true }, + "lodash.throttle": { + "version": "4.1.1", + "resolved": + "http://svnexus003.eoc.ch:8081/repository/npm-public/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=" + }, "lodash.uniq": { "version": "4.5.0", "resolved": @@ -10254,6 +10264,26 @@ "sha512-k4NaW+vS7ytQn6MgJn3fYpQt20/mOgYM5Ft9BYMfQJDz2QT6yEeS9XJ8k2Nw8JTeWK/znPPW2n3UJGzyYEiMoA==", "dev": true }, + "material-ui": { + "version": "0.20.0", + "resolved": + "http://svnexus003.eoc.ch:8081/repository/npm-public/material-ui/-/material-ui-0.20.0.tgz", + "integrity": + "sha512-wkHkeU1SaGfCrtwIzBOl5vynNNNzVGW27ql0Ue5HZLB4WyRQ3YohJBdKa5lBrH5JD/Cgae7IzrP7cVWDyKpeLQ==", + "requires": { + "babel-runtime": "6.26.0", + "inline-style-prefixer": "3.0.8", + "keycode": "2.1.9", + "lodash.merge": "4.6.1", + "lodash.throttle": "4.1.1", + "prop-types": "15.6.0", + "react-event-listener": "0.5.3", + "react-transition-group": "1.2.1", + "recompose": "0.26.0", + "simple-assign": "0.1.0", + "warning": "3.0.0" + } + }, "math-expression-evaluator": { "version": "1.2.17", "resolved": @@ -13982,6 +14012,19 @@ "prop-types": "15.6.0" } }, + "react-event-listener": { + "version": "0.5.3", + "resolved": + "http://svnexus003.eoc.ch:8081/repository/npm-public/react-event-listener/-/react-event-listener-0.5.3.tgz", + "integrity": + "sha512-fTGYvhe7eTsqq0m664Km0rxKQcqLIGZWZINmy1LU0fu312tay8Mt3Twq2P5Xj1dfDVvvzT1Ql3/FDkiMPJ1MOg==", + "requires": { + "babel-runtime": "6.26.0", + "fbjs": "0.8.16", + "prop-types": "15.6.0", + "warning": "3.0.0" + } + }, "react-fuzzy": { "version": "0.5.1", "resolved": @@ -14127,6 +14170,20 @@ "prop-types": "15.6.0" } }, + "react-transition-group": { + "version": "1.2.1", + "resolved": + "http://svnexus003.eoc.ch:8081/repository/npm-public/react-transition-group/-/react-transition-group-1.2.1.tgz", + "integrity": + "sha512-CWaL3laCmgAFdxdKbhhps+c0HRGF4c+hdM4H23+FI1QBNUyx/AMeIJGWorehPNSaKnQNOAxL7PQmqMu78CDj3Q==", + "requires": { + "chain-function": "1.0.0", + "dom-helpers": "3.2.1", + "loose-envify": "1.3.1", + "prop-types": "15.6.0", + "warning": "3.0.0" + } + }, "react-treebeard": { "version": "2.1.0", "resolved": @@ -14239,6 +14296,27 @@ "resolve": "1.5.0" } }, + "recompose": { + "version": "0.26.0", + "resolved": + "http://svnexus003.eoc.ch:8081/repository/npm-public/recompose/-/recompose-0.26.0.tgz", + "integrity": + "sha512-KwOu6ztO0mN5vy3+zDcc45lgnaUoaQse/a5yLVqtzTK13czSWnFGmXbQVmnoMgDkI5POd1EwIKSbjU1V7xdZog==", + "requires": { + "change-emitter": "0.1.6", + "fbjs": "0.8.16", + "hoist-non-react-statics": "2.3.1", + "symbol-observable": "1.1.0" + }, + "dependencies": { + "hoist-non-react-statics": { + "version": "2.3.1", + "resolved": + "http://svnexus003.eoc.ch:8081/repository/npm-public/hoist-non-react-statics/-/hoist-non-react-statics-2.3.1.tgz", + "integrity": "sha1-ND24TGAYxlB3iJgkATWhQg7iLOA=" + } + } + }, "redent": { "version": "1.0.0", "resolved": "http://svnexus003.eoc.ch:8081/repository/npm-public/redent/-/redent-1.0.0.tgz", @@ -14315,8 +14393,7 @@ "resolved": "http://svnexus003.eoc.ch:8081/repository/npm-public/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz", "integrity": - "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A==", - "dev": true + "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A==" }, "regenerator-transform": { "version": "0.10.1", @@ -15135,6 +15212,12 @@ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, + "simple-assign": { + "version": "0.1.0", + "resolved": + "http://svnexus003.eoc.ch:8081/repository/npm-public/simple-assign/-/simple-assign-0.1.0.tgz", + "integrity": "sha1-F/0wZqXz13OPUDIbsPFMooHMS6o=" + }, "simple-swizzle": { "version": "0.2.2", "resolved": @@ -15668,8 +15751,7 @@ "resolved": "http://svnexus003.eoc.ch:8081/repository/npm-public/symbol-observable/-/symbol-observable-1.1.0.tgz", "integrity": - "sha512-dQoid9tqQ+uotGhuTKEY11X4xhyYePVnqGSoSm3OGKh2E8LZ6RPULp1uXTctk33IeERlrRJYoVSBglsL05F5Uw==", - "dev": true + "sha512-dQoid9tqQ+uotGhuTKEY11X4xhyYePVnqGSoSm3OGKh2E8LZ6RPULp1uXTctk33IeERlrRJYoVSBglsL05F5Uw==" }, "symbol-tree": { "version": "3.2.2", @@ -16467,7 +16549,6 @@ "version": "3.0.0", "resolved": "http://svnexus003.eoc.ch:8081/repository/npm-public/warning/-/warning-3.0.0.tgz", "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", - "dev": true, "requires": { "loose-envify": "1.3.1" } diff --git a/package.json b/package.json index 10d15134..0fb8c6ac 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ }, "dependencies": { "color": "^3.0.0", + "material-ui": "^0.20.0", "moment": "2.20.1", "prop-types": "^15.6.0", "react-icons": "2.2.7", diff --git a/stories/index.js b/stories/index.js index 579c6215..1582698e 100644 --- a/stories/index.js +++ b/stories/index.js @@ -15,6 +15,7 @@ storiesOf('Components', module) onChange={value => { console.log('value', value); }} + position="flex-start" label="Totale" defaultValue={10} > @@ -27,6 +28,7 @@ storiesOf('Components', module) onChange={value => { console.log('value', value); }} + position="flex-end" placeholder="birthdate" dateFormat="DD.MM.YYYY" > @@ -127,6 +129,7 @@ storiesOf('Components', module) label={'Birthdate'} locale="en" dateFormat="MM/DD/YYYY" + position="flex-end" minDate={'01/20/2018'} maxDate={'01/30/2018'} >