import { getIn } from 'formik'; import React from 'react'; import type { IFormikExpressionFieldProps } from './FormikExpressionField'; import { FormikForm } from '../FormikForm'; import { FormikFormField } from './FormikFormField'; import { CollapsibleSection } from '../../collapsibleSection/CollapsibleSection'; import type { ISpelError } from '../inputs'; import { ExpressionInput, ExpressionPreview } from '../inputs'; import { TextInput } from '../inputs/TextInput'; import { ExpressionError } from '../inputs/expression/ExpressionError'; import type { ILayoutProps } from '../layouts'; import { errorMessage, messageMessage } from '../validation/categories'; export interface IRegexpProps { RegexHelp?: JSX.Element; regexName: string; // The name of the regex field in formik replaceName: string; // The name of the replace field in formik } export type IFormikExpressionRegexFieldProps = IFormikExpressionFieldProps & IRegexpProps; export interface IFormikExpressionRegexFieldState { spelPreview: string; spelError: ISpelError; } export class FormikExpressionRegexField extends React.Component< IFormikExpressionRegexFieldProps, IFormikExpressionRegexFieldState > { public static defaultProps: Partial = { markdown: false }; public state: IFormikExpressionRegexFieldState = { spelPreview: null, spelError: null, }; private renderRegexFields(fieldProps: IFormikExpressionRegexFieldProps, defaultExpanded: boolean) { const { RegexHelp, regexName, replaceName } = fieldProps; const sectionHeading = ({ chevron }: { chevron: JSX.Element }) => ( {' '} {chevron} Regex {RegexHelp}{' '} ); const validateRegexString = (regexString: string): string => { try { RegExp(regexString); return ''; } catch (error) { return error.message; } }; const RegexLayout = ({ input }: ILayoutProps) =>
{input}
; return (
s/ } input={(props) => } touched={true} /> / } input={(props) => } /> /g
); } private renderPreview( props: IFormikExpressionRegexFieldProps, spelPreview: string, regex: string, replace: string, ): React.ReactNode { const { markdown } = props; if (!regex) { return ; } try { const replacedSpelPreview = spelPreview.replace(new RegExp(regex, 'g'), replace); return !!replacedSpelPreview && ; } catch (err) { // Fallback when regex error -- shouldn't happen with formik 1.x return ; } } private renderFormField(validationMessage: React.ReactNode, regex: string) { const { context, placeholder, help, label, actions } = this.props; return ( (
this.setState(exprChange)} context={context} placeholder={placeholder} {...props} /> {this.renderRegexFields(this.props, !!regex)}
)} help={help} label={label} actions={actions} validationMessage={validationMessage} touched={true} /> ); } public render() { const { spelPreview, spelError } = this.state; const { regexName, replaceName } = this.props; return ( { const regex: string = getIn(formik.values, regexName); const replace: string = getIn(formik.values, replaceName); const regexError = getIn(formik.errors, regexName) || getIn(formik.errors, replaceName); if (regexError) { return this.renderFormField(errorMessage(regexError), regex); } else if (spelError) { return this.renderFormField(, regex); } else if (spelPreview) { const message = this.renderPreview(this.props, spelPreview, regex, replace); return this.renderFormField(message, regex); } return this.renderFormField(messageMessage(null), regex); }} /> ); } }