-
-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
228 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
{ | ||
"trailingComma": "none", | ||
"singleQuote": true | ||
"singleQuote": true, | ||
"endOfLine": "auto" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
import { | ||
Box, | ||
Checkbox, | ||
FormControlLabel, | ||
Grid, | ||
Stack, | ||
TextField, | ||
Typography | ||
} from '@mui/material'; | ||
import React, { useContext, useEffect, useRef, useState } from 'react'; | ||
import { Formik, FormikProps, useFormikContext } from 'formik'; | ||
import * as Yup from 'yup'; | ||
import ToolTextInput from '../../../components/input/ToolTextInput'; | ||
import ToolTextResult from '../../../components/result/ToolTextResult'; | ||
import ToolOptions from '../../../components/ToolOptions'; | ||
import { mergeText } from './service'; | ||
import { CustomSnackBarContext } from '../../../contexts/CustomSnackBarContext'; | ||
|
||
const initialValues = { | ||
joinCharacter: ' ', | ||
deleteBlank: true, | ||
deleteTrailing: true | ||
}; | ||
|
||
const validationSchema = Yup.object().shape({ | ||
joinCharacter: Yup.string().required('Join character is required'), | ||
deleteBlank: Yup.boolean().required('Delete blank is required'), | ||
deleteTrailing: Yup.boolean().required('Delete trailing is required') | ||
}); | ||
|
||
const mergeOptions = { | ||
description: | ||
'Symbol that connects broken\n' + 'pieces of text. (Space by default.)\n', | ||
accessor: 'joinCharacter' as keyof typeof initialValues | ||
}; | ||
|
||
const blankTrailingOptions: { | ||
title: string; | ||
description: string; | ||
accessor: keyof typeof initialValues; | ||
}[] = [ | ||
{ | ||
title: 'Delete Blank Lines', | ||
description: "Delete lines that don't have\n" + 'text symbols.\n', | ||
accessor: 'deleteBlank' | ||
}, | ||
{ | ||
title: 'Delete Trailing Spaces', | ||
description: 'Remove spaces and tabs at\n' + 'the end of the lines.\n', | ||
accessor: 'deleteTrailing' | ||
} | ||
]; | ||
|
||
const InputWithDesc = ({ | ||
description, | ||
value, | ||
onChange | ||
}: { | ||
description: string; | ||
value: string; | ||
onChange: (value: string) => void; | ||
}) => { | ||
return ( | ||
<Box> | ||
<TextField | ||
sx={{ backgroundColor: 'white' }} | ||
value={value} | ||
onChange={(event) => onChange(event.target.value)} | ||
/> | ||
<Typography fontSize={12} mt={1}> | ||
{description} | ||
</Typography> | ||
</Box> | ||
); | ||
}; | ||
|
||
const CheckboxWithDesc = ({ | ||
title, | ||
description, | ||
checked, | ||
onChange | ||
}: { | ||
title: string; | ||
description: string; | ||
checked: boolean; | ||
onChange: (value: boolean) => void; | ||
}) => { | ||
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => { | ||
onChange(event.target.checked); | ||
}; | ||
|
||
return ( | ||
<Box> | ||
<FormControlLabel | ||
control={ | ||
<Checkbox defaultChecked checked={checked} onChange={handleChange} /> | ||
} | ||
label={title} | ||
/> | ||
<Typography fontSize={12} mt={1}> | ||
{description} | ||
</Typography> | ||
</Box> | ||
); | ||
}; | ||
|
||
export default function JoinText() { | ||
const [input, setInput] = useState<string>(''); | ||
const formRef = useRef<FormikProps<typeof initialValues>>(null); | ||
const { showSnackBar } = useContext(CustomSnackBarContext); | ||
const [result, setResult] = useState<string>(''); | ||
|
||
const FormikListenerComponent = ({ input }: { input: string }) => { | ||
const { values } = useFormikContext<typeof initialValues>(); | ||
const { joinCharacter, deleteBlank, deleteTrailing } = values; | ||
|
||
useEffect(() => { | ||
try { | ||
setResult(mergeText(input, deleteBlank, deleteTrailing, joinCharacter)); | ||
} catch (exception: unknown) { | ||
if (exception instanceof Error) | ||
showSnackBar(exception.message, 'error'); | ||
} | ||
}, [values, input]); | ||
|
||
return null; | ||
}; | ||
|
||
return ( | ||
<Box> | ||
<Grid container spacing={2}> | ||
<Grid item xs={6}> | ||
<ToolTextInput | ||
title={'Text Pieces'} | ||
value={input} | ||
onChange={setInput} | ||
/> | ||
</Grid> | ||
<Grid item xs={6}> | ||
<ToolTextResult title={'Joined Text'} value={result} /> | ||
</Grid> | ||
</Grid> | ||
<ToolOptions> | ||
<Formik | ||
initialValues={initialValues} | ||
validationSchema={validationSchema} | ||
innerRef={formRef} | ||
onSubmit={() => {}} | ||
> | ||
{({ setFieldValue, values }) => ( | ||
<Stack direction={'row'} spacing={2}> | ||
<FormikListenerComponent input={input} /> | ||
<Box> | ||
<Typography fontSize={22}>Text Merged Options</Typography> | ||
<InputWithDesc | ||
value={values.joinCharacter} | ||
onChange={(value) => setFieldValue('joinCharacter', value)} | ||
description={mergeOptions.description} | ||
/> | ||
</Box> | ||
<Box> | ||
<Typography fontSize={22}> | ||
Blank Lines and Trailing Spaces | ||
</Typography> | ||
{blankTrailingOptions.map((option) => ( | ||
<CheckboxWithDesc | ||
key={option.accessor} | ||
title={option.title} | ||
checked={!!values[option.accessor]} | ||
onChange={(value) => setFieldValue(option.accessor, value)} | ||
description={option.description} | ||
/> | ||
))} | ||
</Box> | ||
</Stack> | ||
)} | ||
</Formik> | ||
</ToolOptions> | ||
</Box> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { defineTool } from '../../../tools/defineTool'; | ||
import { lazy } from 'react'; | ||
import image from '../../../assets/text.png'; | ||
|
||
export const tool = defineTool('string', { | ||
path: 'join', | ||
name: 'Text Joiner', | ||
image, | ||
description: | ||
"World's Simplest Text Tool World's simplest browser-based utility for joining text. Load your text in the input form on the left and you'll automatically get merged text on the right. Powerful, free, and fast. Load text – get joined lines", | ||
keywords: ['text', 'join'], | ||
component: lazy(() => import('./index')) | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
export function mergeText( | ||
text: string, | ||
deleteBlankLines: boolean = true, | ||
deleteTrailingSpaces: boolean = true, | ||
joinCharacter: string = '' | ||
): string { | ||
const lines = text.split('\n'); | ||
|
||
const processedLines = lines | ||
.map((line) => | ||
deleteTrailingSpaces ? line.replace(/ |\r\n|\n|\r/gm, '') : line | ||
) | ||
.filter((line) => !deleteBlankLines || line.trim() !== ''); | ||
|
||
// Join lines and remove spaces right after each line | ||
return processedLines.join(joinCharacter); | ||
} | ||
|
||
// Example usage | ||
const text: string = `This is a line with trailing spaces | ||
Another line with trailing spaces | ||
Final line without trailing spaces`; | ||
|
||
export const mergedTextWithBlankLines: string = mergeText(text, false); | ||
console.log('With blank lines:\n', mergedTextWithBlankLines); | ||
|
||
export const mergedTextWithoutBlankLines: string = mergeText(text, true); | ||
console.log('Without blank lines:\n', mergedTextWithoutBlankLines); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
import { tool as stringSplit } from './split/meta'; | ||
import { tool as stringJoin } from './join/meta'; | ||
|
||
export const stringTools = [stringSplit]; | ||
export const stringTools = [stringSplit, stringJoin]; |