From 18602112713c23600c34f03339e5cb745092f660 Mon Sep 17 00:00:00 2001 From: Prolland006 Date: Tue, 3 Nov 2020 17:13:39 +0100 Subject: [PATCH 1/5] #1066 Capitalization across Community Platform --- src/components/Form/Fields.tsx | 49 +++++++++++++++++++ .../Content/EventsCreate/EventsCreate.tsx | 8 ++- src/pages/Howto/Content/Common/Howto.form.tsx | 9 ++-- .../Howto/Content/Common/HowtoStep.form.tsx | 10 ++-- .../formSections/UserInfos.section.tsx | 9 ++-- 5 files changed, 74 insertions(+), 11 deletions(-) diff --git a/src/components/Form/Fields.tsx b/src/components/Form/Fields.tsx index 2e62ea46c2..902dba33e1 100644 --- a/src/components/Form/Fields.tsx +++ b/src/components/Form/Fields.tsx @@ -8,6 +8,7 @@ import { } from './elements' import { FieldRenderProps } from 'react-final-form' import 'react-datepicker/dist/react-datepicker.css' +import { capitalizeFirstLetter } from 'src/utils/helpers' // any props can be passed to field and down to child component // input and meta props come from react field render props and will be @@ -25,6 +26,9 @@ interface IDatePickerFieldProps extends IFieldProps { customChange?: (location) => void } +const toCapitalizedFirstletterInput = e => { + e.target.value = capitalizeFirstLetter(e.target.value) +} export const InputField = ({ input, meta, @@ -48,6 +52,30 @@ export const InputField = ({ ) : null} ) +export const FormattedInputField = ({ + input, + meta, + customOnBlur, + ...rest +}: IFieldProps) => ( + <> + { + if (customOnBlur) { + customOnBlur(e) + } + input.onBlur() + }} + onInput={toCapitalizedFirstletterInput} + /> + {meta.error && meta.touched ? ( + {meta.error} + ) : null} + +) export const DatePickerField = ({ input, meta, @@ -97,3 +125,24 @@ export const TextAreaField = ({ {meta.error && meta.touched && {meta.error}} ) + +export const FormattedTextAreaField = ({ + input, + meta, + disabled, + ...rest +}: IFieldProps) => + disabled ? ( + // want disabled textarea to just render as styled div to remove scrollbars + {input.value} + ) : ( + <> + + {meta.error && meta.touched && {meta.error}} + + ) diff --git a/src/pages/Events/Content/EventsCreate/EventsCreate.tsx b/src/pages/Events/Content/EventsCreate/EventsCreate.tsx index 7ebe109636..ef8b459835 100644 --- a/src/pages/Events/Content/EventsCreate/EventsCreate.tsx +++ b/src/pages/Events/Content/EventsCreate/EventsCreate.tsx @@ -4,7 +4,11 @@ import { Form, Field } from 'react-final-form' import arrayMutators from 'final-form-arrays' import TEMPLATE from './Template' import { UploadedFile } from 'src/pages/common/UploadedFile/UploadedFile' -import { InputField, DatePickerField } from 'src/components/Form/Fields' +import { + FormattedInputField, + InputField, + DatePickerField, +} from 'src/components/Form/Fields' import { Button } from 'src/components/Button' import { EventStore } from 'src/stores/Events/events.store' import Heading from 'src/components/Heading' @@ -153,7 +157,7 @@ export class EventsCreate extends React.Component { data-cy="title" validate={required} validateFields={[]} - component={InputField} + component={FormattedInputField} maxLength="140" placeholder="Title of your event (max 140 characters)" /> diff --git a/src/pages/Howto/Content/Common/Howto.form.tsx b/src/pages/Howto/Content/Common/Howto.form.tsx index f325a32c59..c22c0e0482 100644 --- a/src/pages/Howto/Content/Common/Howto.form.tsx +++ b/src/pages/Howto/Content/Common/Howto.form.tsx @@ -8,7 +8,10 @@ import createDecorator from 'final-form-calculate' import { IHowtoFormInput } from 'src/models/howto.models' import Text from 'src/components/Text' import { UploadedFile } from 'src/pages/common/UploadedFile/UploadedFile' -import { InputField, TextAreaField } from 'src/components/Form/Fields' +import { + FormattedInputField, + FormattedTextAreaField, +} from 'src/components/Form/Fields' import { SelectField } from 'src/components/Form/Select.field' import { HowtoStep } from './HowtoStep.form' import { Button } from 'src/components/Button' @@ -228,7 +231,7 @@ export class HowtoForm extends React.PureComponent { ? this.validateTitle(value) : false } - component={InputField} + component={FormattedInputField} maxLength="50" placeholder="Make a chair from.. (max 50 characters)" /> @@ -282,7 +285,7 @@ export class HowtoForm extends React.PureComponent { data-cy="intro-description" validate={required} validateFields={[]} - component={TextAreaField} + component={FormattedTextAreaField} style={{ resize: 'none', flex: 1, diff --git a/src/pages/Howto/Content/Common/HowtoStep.form.tsx b/src/pages/Howto/Content/Common/HowtoStep.form.tsx index 51d3f960c4..d8b7e7980d 100644 --- a/src/pages/Howto/Content/Common/HowtoStep.form.tsx +++ b/src/pages/Howto/Content/Common/HowtoStep.form.tsx @@ -1,6 +1,10 @@ import React from 'react' import { Field } from 'react-final-form' -import { TextAreaField, InputField } from 'src/components/Form/Fields' +import { + FormattedTextAreaField, + FormattedInputField, + InputField, +} from 'src/components/Form/Fields' import Heading from 'src/components/Heading' import { ImageInputField } from 'src/components/Form/ImageInput.field' import Flex from 'src/components/Flex' @@ -142,7 +146,7 @@ class HowtoStep extends React.PureComponent { { placeholder="Explain what you are doing in this step. if it gets to long break it into 2 steps (max 700 characters)" maxLength="700" data-cy="step-description" - component={TextAreaField} + component={FormattedTextAreaField} style={{ resize: 'vertical', height: '300px' }} validate={required} validateFields={[]} diff --git a/src/pages/Settings/content/formSections/UserInfos.section.tsx b/src/pages/Settings/content/formSections/UserInfos.section.tsx index 58127acf88..79189a16b9 100644 --- a/src/pages/Settings/content/formSections/UserInfos.section.tsx +++ b/src/pages/Settings/content/formSections/UserInfos.section.tsx @@ -3,7 +3,10 @@ import { Field } from 'react-final-form' import Heading from 'src/components/Heading' import Text from 'src/components/Text' import Flex from 'src/components/Flex' -import { InputField, TextAreaField } from 'src/components/Form/Fields' +import { + FormattedInputField, + FormattedTextAreaField, +} from 'src/components/Form/Fields' import { FlagSelectField } from 'src/components/Form/FlagSelect' import { Button } from 'src/components/Button' import 'react-flags-select/scss/react-flags-select.scss' @@ -68,7 +71,7 @@ export class UserInfosSection extends React.Component { { Date: Fri, 16 Jul 2021 14:48:40 -0700 Subject: [PATCH 2/5] refactor capitalize input function --- src/components/Form/Fields.tsx | 76 +++++++++++++--------------------- 1 file changed, 29 insertions(+), 47 deletions(-) diff --git a/src/components/Form/Fields.tsx b/src/components/Form/Fields.tsx index 902dba33e1..7f9f12ad21 100644 --- a/src/components/Form/Fields.tsx +++ b/src/components/Form/Fields.tsx @@ -14,6 +14,10 @@ import { capitalizeFirstLetter } from 'src/utils/helpers' // input and meta props come from react field render props and will be // picked up by typing type FieldProps = FieldRenderProps & { children?: React.ReactNode } + +type InputModifiers = { + capitalize?: boolean +} export interface IFieldProps extends FieldProps { // additional fields intending to pass down disabled?: boolean @@ -26,13 +30,19 @@ interface IDatePickerFieldProps extends IFieldProps { customChange?: (location) => void } -const toCapitalizedFirstletterInput = e => { - e.target.value = capitalizeFirstLetter(e.target.value) +const processInputModifiers = (value: any, modifiers: InputModifiers = {}) => { + if (typeof value !== 'string') return value + if (modifiers.capitalize) { + value = capitalizeFirstLetter(value) + } + return value } + export const InputField = ({ input, meta, customOnBlur, + modifiers, ...rest }: IFieldProps) => ( <> @@ -41,41 +51,22 @@ export const InputField = ({ {...input} {...rest} onBlur={e => { - if (customOnBlur) { - customOnBlur(e) + if (modifiers) { + e.target.value = processInputModifiers(e.target.value, modifiers) + input.onChange(e) } - input.onBlur() - }} - /> - {meta.error && meta.touched ? ( - {meta.error} - ) : null} - -) -export const FormattedInputField = ({ - input, - meta, - customOnBlur, - ...rest -}: IFieldProps) => ( - <> - { if (customOnBlur) { customOnBlur(e) } - input.onBlur() + input.onBlur(e) }} - onInput={toCapitalizedFirstletterInput} /> {meta.error && meta.touched ? ( {meta.error} ) : null} ) + export const DatePickerField = ({ input, meta, @@ -110,6 +101,8 @@ export const TextAreaField = ({ input, meta, disabled, + modifiers, + customOnBlur, ...rest }: IFieldProps) => disabled ? ( @@ -121,27 +114,16 @@ export const TextAreaField = ({ invalid={meta.error && meta.touched} {...input} {...rest} - /> - {meta.error && meta.touched && {meta.error}} - - ) - -export const FormattedTextAreaField = ({ - input, - meta, - disabled, - ...rest -}: IFieldProps) => - disabled ? ( - // want disabled textarea to just render as styled div to remove scrollbars - {input.value} - ) : ( - <> - { + if (modifiers) { + e.target.value = processInputModifiers(e.target.value, modifiers) + input.onChange(e) + } + if (customOnBlur) { + customOnBlur(e) + } + input.onBlur() + }} /> {meta.error && meta.touched && {meta.error}} From 8045d08d823f05ad3e3affa26a9c9075b319a7e5 Mon Sep 17 00:00:00 2001 From: "Chris\\Laptop" Date: Fri, 16 Jul 2021 14:49:15 -0700 Subject: [PATCH 3/5] update auto capitalization for forms --- .../Events/Content/EventsCreate/EventsCreate.tsx | 9 +++------ src/pages/Howto/Content/Common/Howto.form.tsx | 11 +++++------ src/pages/Howto/Content/Common/HowtoStep.form.tsx | 14 ++++++-------- .../content/formSections/UserInfos.section.tsx | 10 ++++------ 4 files changed, 18 insertions(+), 26 deletions(-) diff --git a/src/pages/Events/Content/EventsCreate/EventsCreate.tsx b/src/pages/Events/Content/EventsCreate/EventsCreate.tsx index f54bcccac2..aa02c8fdf3 100644 --- a/src/pages/Events/Content/EventsCreate/EventsCreate.tsx +++ b/src/pages/Events/Content/EventsCreate/EventsCreate.tsx @@ -4,11 +4,7 @@ import { Form, Field } from 'react-final-form' import arrayMutators from 'final-form-arrays' import TEMPLATE from './Template' import { UploadedFile } from 'src/pages/common/UploadedFile/UploadedFile' -import { - FormattedInputField, - InputField, - DatePickerField, -} from 'src/components/Form/Fields' +import { InputField, DatePickerField } from 'src/components/Form/Fields' import { Button } from 'src/components/Button' import { EventStore } from 'src/stores/Events/events.store' import Heading from 'src/components/Heading' @@ -150,7 +146,8 @@ export class EventsCreate extends React.Component { data-cy="title" validate={required} validateFields={[]} - component={FormattedInputField} + modifiers={{ capitalize: true }} + component={InputField} maxLength="140" placeholder="Title of your event (max 140 characters)" /> diff --git a/src/pages/Howto/Content/Common/Howto.form.tsx b/src/pages/Howto/Content/Common/Howto.form.tsx index 601db438de..faba44f3fa 100644 --- a/src/pages/Howto/Content/Common/Howto.form.tsx +++ b/src/pages/Howto/Content/Common/Howto.form.tsx @@ -8,10 +8,7 @@ import createDecorator from 'final-form-calculate' import { IHowtoFormInput } from 'src/models/howto.models' import Text from 'src/components/Text' import { UploadedFile } from 'src/pages/common/UploadedFile/UploadedFile' -import { - FormattedInputField, - FormattedTextAreaField, -} from 'src/components/Form/Fields' +import { InputField, TextAreaField } from 'src/components/Form/Fields' import { SelectField } from 'src/components/Form/Select.field' import { HowtoStep } from './HowtoStep.form' import { Button } from 'src/components/Button' @@ -244,7 +241,8 @@ export class HowtoForm extends React.PureComponent { validateFields={[]} validate={this.validateTitle} isEqual={COMPARISONS.textInput} - component={FormattedInputField} + modifiers={{ capitalize: true }} + component={InputField} maxLength="50" placeholder="Make a chair from.. (max 50 characters)" /> @@ -301,8 +299,9 @@ export class HowtoForm extends React.PureComponent { data-cy="intro-description" validate={required} validateFields={[]} + modifiers={{ capitalize: true }} isEqual={COMPARISONS.textInput} - component={FormattedTextAreaField} + component={TextAreaField} style={{ resize: 'none', flex: 1, diff --git a/src/pages/Howto/Content/Common/HowtoStep.form.tsx b/src/pages/Howto/Content/Common/HowtoStep.form.tsx index a43e198463..aa049ae9c2 100644 --- a/src/pages/Howto/Content/Common/HowtoStep.form.tsx +++ b/src/pages/Howto/Content/Common/HowtoStep.form.tsx @@ -1,10 +1,6 @@ -import { PureComponent } from 'react'; +import { PureComponent } from 'react' import { Field } from 'react-final-form' -import { - FormattedTextAreaField, - FormattedInputField, - InputField, -} from 'src/components/Form/Fields' +import { TextAreaField, InputField } from 'src/components/Form/Fields' import Heading from 'src/components/Heading' import { ImageInputField } from 'src/components/Form/ImageInput.field' import Flex from 'src/components/Flex' @@ -147,7 +143,8 @@ class HowtoStep extends PureComponent { { placeholder="Explain what you are doing in this step. if it gets to long break it into 2 steps (max 700 characters)" maxLength="700" data-cy="step-description" - component={FormattedTextAreaField} + modifiers={{ capitalize: true }} + component={TextAreaField} style={{ resize: 'vertical', height: '300px' }} validate={required} validateFields={[]} diff --git a/src/pages/Settings/content/formSections/UserInfos.section.tsx b/src/pages/Settings/content/formSections/UserInfos.section.tsx index 33dba8e4be..a1fc864baa 100644 --- a/src/pages/Settings/content/formSections/UserInfos.section.tsx +++ b/src/pages/Settings/content/formSections/UserInfos.section.tsx @@ -3,10 +3,7 @@ import { Field } from 'react-final-form' import Heading from 'src/components/Heading' import Text from 'src/components/Text' import Flex from 'src/components/Flex' -import { - FormattedInputField, - FormattedTextAreaField, -} from 'src/components/Form/Fields' +import { InputField, TextAreaField } from 'src/components/Form/Fields' import { FlagSelectField } from 'src/components/Form/FlagSelect' import { Button } from 'src/components/Button' import 'react-flags-select/scss/react-flags-select.scss' @@ -71,7 +68,7 @@ export class UserInfosSection extends React.Component { { Date: Fri, 16 Jul 2021 14:54:21 -0700 Subject: [PATCH 4/5] add manual capitalization methods --- .../Content/Howto/HowtoDescription/HowtoDescription.tsx | 9 +++++++-- src/pages/Howto/Content/HowtoList/HowToCard.tsx | 4 +++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/pages/Howto/Content/Howto/HowtoDescription/HowtoDescription.tsx b/src/pages/Howto/Content/Howto/HowtoDescription/HowtoDescription.tsx index 8f16b3af63..455c26e2f5 100644 --- a/src/pages/Howto/Content/Howto/HowtoDescription/HowtoDescription.tsx +++ b/src/pages/Howto/Content/Howto/HowtoDescription/HowtoDescription.tsx @@ -13,7 +13,11 @@ import TimeNeeded from 'src/assets/icons/icon-time-needed.svg' import DifficultyLevel from 'src/assets/icons/icon-difficulty-level.svg' import { Button } from 'src/components/Button' import { IUser } from 'src/models/user.models' -import { isAllowToEditContent, emStringToPx } from 'src/utils/helpers' +import { + isAllowToEditContent, + emStringToPx, + capitalizeFirstLetter, +} from 'src/utils/helpers' import theme from 'src/themes/styled.theme' import ArrowIcon from 'src/assets/icons/icon-arrow-select.svg' import { FlagIconHowTos } from 'src/components/Icons/FlagIcon/FlagIcon' @@ -147,7 +151,8 @@ export default class HowtoDescription extends PureComponent { {this.dateLastEditText(howto)} - {howto.title} + {/* HACK 2021-07-16 - new howtos auto capitalize title but not older */} + {capitalizeFirstLetter(howto.title)} {howto.description} diff --git a/src/pages/Howto/Content/HowtoList/HowToCard.tsx b/src/pages/Howto/Content/HowtoList/HowToCard.tsx index 580c7fcd33..ac36d811af 100644 --- a/src/pages/Howto/Content/HowtoList/HowToCard.tsx +++ b/src/pages/Howto/Content/HowtoList/HowToCard.tsx @@ -7,6 +7,7 @@ import { FlagIconHowTos } from 'src/components/Icons/FlagIcon/FlagIcon' import TagDisplay from 'src/components/Tags/TagDisplay/TagDisplay' import { IHowtoDB } from 'src/models/howto.models' import Heading from 'src/components/Heading' +import { capitalizeFirstLetter } from 'src/utils/helpers' interface IProps { howto: IHowtoDB @@ -48,7 +49,8 @@ export const HowToCard = (props: IProps) => ( - {props.howto.title} + {/* HACK 2021-07-16 - new howtos auto capitalize title but not older */} + {capitalizeFirstLetter(props.howto.title)} {props.howto.creatorCountry && ( From f72181d76c67aaddcda3988f220bb32fc3dd1133 Mon Sep 17 00:00:00 2001 From: "Chris\\Laptop" Date: Fri, 16 Jul 2021 15:21:33 -0700 Subject: [PATCH 5/5] More render capitlizations --- src/components/EventCard/EventCard.tsx | 4 ++-- src/pages/Howto/Content/Howto/Step/Step.tsx | 11 ++++++++--- .../content/formSections/UserInfos.section.tsx | 1 - 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/components/EventCard/EventCard.tsx b/src/components/EventCard/EventCard.tsx index 4ca7864853..f50a4e5cc4 100644 --- a/src/components/EventCard/EventCard.tsx +++ b/src/components/EventCard/EventCard.tsx @@ -5,7 +5,7 @@ import { Button } from 'src/components/Button' import TagDisplay from 'src/components/Tags/TagDisplay/TagDisplay' import FlagIconEvents from 'src/components/Icons/FlagIcon/FlagIcon' import { IEvent } from '../../models/events.models' -import { getMonth, getDay } from 'src/utils/helpers' +import { getMonth, getDay, capitalizeFirstLetter } from 'src/utils/helpers' import { LinkTargetBlank } from '../Links/LinkTargetBlank/LinkTargetBlank' interface IProps { @@ -76,7 +76,7 @@ export const EventCard = (props: IProps) => ( > - {props.event.title} + {capitalizeFirstLetter(props.event.title)} diff --git a/src/pages/Howto/Content/Howto/Step/Step.tsx b/src/pages/Howto/Content/Howto/Step/Step.tsx index f5898d1d83..cc43a18732 100644 --- a/src/pages/Howto/Content/Howto/Step/Step.tsx +++ b/src/pages/Howto/Content/Howto/Step/Step.tsx @@ -1,4 +1,4 @@ -import { PureComponent } from 'react'; +import { PureComponent } from 'react' import Linkify from 'react-linkify' import ReactPlayer from 'react-player' import { Box } from 'rebass' @@ -8,6 +8,7 @@ import ImageGallery from 'src/components/ImageGallery' import Text from 'src/components/Text' import { IHowtoStep } from 'src/models/howto.models' import { IUploadedFileMeta } from 'src/stores/storage' +import { capitalizeFirstLetter } from 'src/utils/helpers' import styled from 'styled-components' interface IProps { @@ -57,11 +58,15 @@ export default class Step extends PureComponent { > - {step.title} + {/* HACK 2021-07-16 - new howtos auto capitalize title but not older */} + {capitalizeFirstLetter(step.title)} - {step.text} + + {/* HACK 2021-07-16 - new howtos auto capitalize title but not older */} + {capitalizeFirstLetter(step.text)} + diff --git a/src/pages/Settings/content/formSections/UserInfos.section.tsx b/src/pages/Settings/content/formSections/UserInfos.section.tsx index a1fc864baa..6f45724fb1 100644 --- a/src/pages/Settings/content/formSections/UserInfos.section.tsx +++ b/src/pages/Settings/content/formSections/UserInfos.section.tsx @@ -100,7 +100,6 @@ export class UserInfosSection extends React.Component {