adding text joiner

This commit is contained in:
Made4Uo
2024-06-23 00:47:12 -07:00
parent 3ca1b7cd02
commit cbb7790e8f
6 changed files with 228 additions and 3 deletions

View File

@@ -1,4 +1,5 @@
{
"trailingComma": "none",
"singleQuote": true
"singleQuote": true,
"endOfLine": "auto"
}

View File

@@ -23,7 +23,7 @@ export default function ToolTextInput({
.writeText(value)
.then(() => showSnackBar('Text copied', 'success'))
.catch((err) => {
showSnackBar('Failed to copy: ', 'error');
showSnackBar('Failed to copy: ', err);
});
};
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {

View File

@@ -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>
);
}

View File

@@ -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'))
});

View File

@@ -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);

View File

@@ -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];