mirror of
https://github.com/iib0011/omni-tools.git
synced 2025-08-30 20:36:33 +02:00
adding text joiner
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"trailingComma": "none",
|
||||
"singleQuote": true
|
||||
"singleQuote": true,
|
||||
"endOfLine": "auto"
|
||||
}
|
||||
|
@@ -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>) => {
|
||||
|
181
src/pages/string/join/index.tsx
Normal file
181
src/pages/string/join/index.tsx
Normal 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>
|
||||
);
|
||||
}
|
13
src/pages/string/join/meta.ts
Normal file
13
src/pages/string/join/meta.ts
Normal 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'))
|
||||
});
|
29
src/pages/string/join/service.ts
Normal file
29
src/pages/string/join/service.ts
Normal 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);
|
@@ -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];
|
||||
|
Reference in New Issue
Block a user