From f9662fed2545d88198eeb08f4d3eeb9d560fffe9 Mon Sep 17 00:00:00 2001 From: Hannu Lyytikainen Date: Mon, 5 Mar 2018 18:54:05 +0200 Subject: [PATCH] Add FieldPhoneNumberInput component --- .../FieldPhoneNumberInput.example.js | 43 +++++++++++ .../FieldPhoneNumberInput.js | 74 +++++++++++++++++++ src/components/index.js | 1 + src/examples.js | 2 + 4 files changed, 120 insertions(+) create mode 100644 src/components/FieldPhoneNumberInput/FieldPhoneNumberInput.example.js create mode 100644 src/components/FieldPhoneNumberInput/FieldPhoneNumberInput.js diff --git a/src/components/FieldPhoneNumberInput/FieldPhoneNumberInput.example.js b/src/components/FieldPhoneNumberInput/FieldPhoneNumberInput.example.js new file mode 100644 index 00000000..134a9aa2 --- /dev/null +++ b/src/components/FieldPhoneNumberInput/FieldPhoneNumberInput.example.js @@ -0,0 +1,43 @@ +import React from 'react'; +import { reduxForm, propTypes as formPropTypes } from 'redux-form'; +import * as validators from '../../util/validators'; +import { Button } from '../../components'; +import FieldPhoneNumberInput from './FieldPhoneNumberInput'; + +const formName = 'Styleguide.FieldPhoneNumberInput.Form'; + +const FormComponent = props => { + const { form, handleSubmit, invalid, pristine, submitting } = props; + const required = validators.required('This field is required'); + const submitDisabled = invalid || pristine || submitting; + return ( +
+ + + + ); +}; + +FormComponent.propTypes = formPropTypes; + +const Form = reduxForm({ + form: formName, +})(FormComponent); + +export const PhoneNumber = { + component: Form, + props: { + onSubmit(values) { + console.log('onSubmit:', values); + }, + }, + group: 'inputs', +}; diff --git a/src/components/FieldPhoneNumberInput/FieldPhoneNumberInput.js b/src/components/FieldPhoneNumberInput/FieldPhoneNumberInput.js new file mode 100644 index 00000000..cd422189 --- /dev/null +++ b/src/components/FieldPhoneNumberInput/FieldPhoneNumberInput.js @@ -0,0 +1,74 @@ +import React from 'react'; + +import { TextInputField } from '../../components'; + +/** + * Slice a local number that is in the form + * of 555 01234567 + */ +const sliceLocal = numbers => { + if (numbers.length <= 3) { + return numbers; + } + return `${numbers.slice(0, 3)} ${numbers.slice(3, 10)}`; +}; + +/** + * Slice an international phone number i.e. + * the part that is followed after a '+' or '00'. + */ +const sliceInternational = numbers => { + if (numbers.length <= 3) { + return numbers; + } + if (numbers.length <= 5) { + return `${numbers.slice(0, 3)} ${numbers.slice(3)}`; + } + return `${numbers.slice(0, 3)} ${numbers.slice(3, 5)} ${numbers.slice(5, 12)}`; +}; + +/** + * Normalize a phone number. + * + * Uses one of the following formats: + * + * +123 55 1234567 + * 00123 55 1234567 + * 555 1234567 + */ +const normalizePhone = value => { + if (!value) { + return value; + } + + const leadingPlus = value.match(/^\+/g); + const leadingZeros = value.match(/^00/g); + const numbers = value.replace(/[^\d]/g, ''); + + if (leadingPlus) { + const plus = leadingPlus[0]; + const sliced = sliceInternational(numbers); + return `${plus}${sliced}`; + } + + if (leadingZeros && numbers.length > 2) { + const zeros = leadingZeros[0]; + const trailingNumbers = numbers.substring(2, numbers.length); + const sliced = sliceInternational(trailingNumbers); + return `${zeros}${sliced}`; + } + + return sliceLocal(numbers); +}; + +const FieldPhoneNumberInput = props => { + const inputProps = { + ...props, + type: 'text', + normalize: normalizePhone, + }; + + return ; +}; + +export default FieldPhoneNumberInput; diff --git a/src/components/index.js b/src/components/index.js index e0e8849b..aa2b2ad4 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -36,6 +36,7 @@ export { default as FieldCurrencyInput } from './FieldCurrencyInput/FieldCurrenc export { default as FieldDateInput } from './FieldDateInput/FieldDateInput'; export { default as FieldDateRangeInput } from './FieldDateRangeInput/FieldDateRangeInput'; export { default as FieldGroupCheckbox } from './FieldGroupCheckbox/FieldGroupCheckbox'; +export { default as FieldPhoneNumberInput } from './FieldPhoneNumberInput/FieldPhoneNumberInput'; export { default as FieldReviewRating } from './FieldReviewRating/FieldReviewRating'; export { default as Footer } from './Footer/Footer'; export { default as Form } from './Form/Form'; diff --git a/src/examples.js b/src/examples.js index 9ba919e2..6b057aa6 100644 --- a/src/examples.js +++ b/src/examples.js @@ -12,6 +12,7 @@ import * as FieldCurrencyInput from './components/FieldCurrencyInput/FieldCurren import * as FieldDateInput from './components/FieldDateInput/FieldDateInput.example'; import * as FieldDateRangeInput from './components/FieldDateRangeInput/FieldDateRangeInput.example'; import * as FieldGroupCheckbox from './components/FieldGroupCheckbox/FieldGroupCheckbox.example'; +import * as FieldPhoneNumberInput from './components/FieldPhoneNumberInput/FieldPhoneNumberInput.example'; import * as FieldReviewRating from './components/FieldReviewRating/FieldReviewRating.example'; import * as Footer from './components/Footer/Footer.example'; import * as IconBannedUser from './components/IconBannedUser/IconBannedUser.example'; @@ -101,6 +102,7 @@ export { FieldDateInput, FieldDateRangeInput, FieldGroupCheckbox, + FieldPhoneNumberInput, FieldReviewRating, Footer, IconBannedUser,