From eb9e3cbdf9dd4ee24bba135858b240fe3ef28e50 Mon Sep 17 00:00:00 2001 From: EugSh <127679450+EugSh1@users.noreply.github.com> Date: Fri, 7 Mar 2025 15:26:04 +0300 Subject: [PATCH 1/2] feat: add text repeat tool - Added text repeat tool to repeat input text multiple times with optional delimiter. - Included functionality for custom repetition amounts and delimiters. --- src/pages/tools/string/index.ts | 4 +- src/pages/tools/string/repeat/index.tsx | 114 ++++++++++++++++++ .../tools/string/repeat/initialValues.ts | 11 ++ src/pages/tools/string/repeat/meta.ts | 13 ++ .../string/repeat/repeatText.service.test.ts | 55 +++++++++ src/pages/tools/string/repeat/service.ts | 9 ++ 6 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 src/pages/tools/string/repeat/index.tsx create mode 100644 src/pages/tools/string/repeat/initialValues.ts create mode 100644 src/pages/tools/string/repeat/meta.ts create mode 100644 src/pages/tools/string/repeat/repeatText.service.test.ts create mode 100644 src/pages/tools/string/repeat/service.ts diff --git a/src/pages/tools/string/index.ts b/src/pages/tools/string/index.ts index ee02eba..c3c97ce 100644 --- a/src/pages/tools/string/index.ts +++ b/src/pages/tools/string/index.ts @@ -9,13 +9,15 @@ import { tool as stringToMorse } from './to-morse/meta'; import { tool as stringSplit } from './split/meta'; import { tool as stringJoin } from './join/meta'; import { tool as stringReplace } from './text-replacer/meta'; +import { tool as stringRepeat } from './repeat/meta'; export const stringTools = [ stringSplit, stringJoin, stringRemoveDuplicateLines, stringToMorse, - stringReplace + stringReplace, + stringRepeat // stringReverse, // stringRandomizeCase, // stringUppercase, diff --git a/src/pages/tools/string/repeat/index.tsx b/src/pages/tools/string/repeat/index.tsx new file mode 100644 index 0000000..78e5f08 --- /dev/null +++ b/src/pages/tools/string/repeat/index.tsx @@ -0,0 +1,114 @@ +import { Box } from '@mui/material'; +import { useState } from 'react'; +import ToolTextResult from '@components/result/ToolTextResult'; +import { GetGroupsType } from '@components/options/ToolOptions'; +import { repeatText } from './service'; +import TextFieldWithDesc from '@components/options/TextFieldWithDesc'; +import ToolTextInput from '@components/input/ToolTextInput'; +import { initialValues, InitialValuesType } from './initialValues'; +import ToolContent from '@components/ToolContent'; +import { CardExampleType } from '@components/examples/ToolExamples'; +import { ToolComponentProps } from '@tools/defineTool'; + +const exampleCards: CardExampleType[] = [ + { + title: 'Repeat word five times', + description: 'Repeats "Hello!" five times without any delimiter.', + sampleText: 'Hello! ', + sampleResult: 'Hello! Hello! Hello! Hello! Hello! ', + sampleOptions: { + textToRepeat: 'Hello! ', + repeatAmount: '5', + delimiter: '' + } + }, + { + title: 'Repeat phrase with comma', + description: + 'Repeats "Good job" three times, separated by commas and spaces.', + sampleText: 'Good job', + sampleResult: 'Good job, Good job, Good job', + sampleOptions: { + textToRepeat: 'Good job', + repeatAmount: '3', + delimiter: ', ' + } + }, + { + title: 'Repeat number with space', + description: 'Repeats the number "42" four times, separated by spaces.', + sampleText: '42', + sampleResult: '42 42 42 42', + sampleOptions: { + textToRepeat: '42', + repeatAmount: '4', + delimiter: ' ' + } + } +]; + +export default function Replacer({ title }: ToolComponentProps) { + const [input, setInput] = useState(''); + const [result, setResult] = useState(''); + + function compute(optionsValues: InitialValuesType, input: string) { + setResult(repeatText(optionsValues, input)); + } + + const getGroups: GetGroupsType = ({ + values, + updateField + }) => [ + { + title: 'Text Repetitions', + component: ( + + updateField('repeatAmount', val)} + type={'number'} + /> + + ) + }, + { + title: 'Repetitions Delimiter', + component: ( + + updateField('delimiter', val)} + type={'text'} + /> + + ) + } + ]; + + return ( + + } + resultComponent={ + + } + toolInfo={{ + title: 'Text Replacer', + description: + 'This tool allows you to repeat a given text multiple times with an optional separator.' + }} + exampleCards={exampleCards} + /> + ); +} diff --git a/src/pages/tools/string/repeat/initialValues.ts b/src/pages/tools/string/repeat/initialValues.ts new file mode 100644 index 0000000..9e543be --- /dev/null +++ b/src/pages/tools/string/repeat/initialValues.ts @@ -0,0 +1,11 @@ +export type InitialValuesType = { + textToRepeat: string; + repeatAmount: string; + delimiter: string; +}; + +export const initialValues: InitialValuesType = { + textToRepeat: '', + repeatAmount: '5', + delimiter: '' +}; diff --git a/src/pages/tools/string/repeat/meta.ts b/src/pages/tools/string/repeat/meta.ts new file mode 100644 index 0000000..563b2f2 --- /dev/null +++ b/src/pages/tools/string/repeat/meta.ts @@ -0,0 +1,13 @@ +import { defineTool } from '@tools/defineTool'; +import { lazy } from 'react'; + +export const tool = defineTool('string', { + name: 'Repeat text', + path: 'repeat', + shortDescription: 'Repeat text multiple times.', + icon: 'material-symbols-light:replay', + description: + 'This tool allows you to repeat a given text multiple times with an optional separator.', + keywords: ['text', 'repeat'], + component: lazy(() => import('./index')) +}); diff --git a/src/pages/tools/string/repeat/repeatText.service.test.ts b/src/pages/tools/string/repeat/repeatText.service.test.ts new file mode 100644 index 0000000..6a8a0c1 --- /dev/null +++ b/src/pages/tools/string/repeat/repeatText.service.test.ts @@ -0,0 +1,55 @@ +import { describe, expect, it } from 'vitest'; +import { repeatText } from './service'; +import { initialValues } from './initialValues'; + +describe('repeatText function', () => { + it('should repeat the letter correctly', () => { + const text = 'i'; + const repeatAmount = '5'; + const result = repeatText({ ...initialValues, repeatAmount }, text); + expect(result).toBe('iiiii'); + }); + + it('should repeat the word correctly', () => { + const text = 'hello'; + const repeatAmount = '3'; + const result = repeatText({ ...initialValues, repeatAmount }, text); + expect(result).toBe('hellohellohello'); + }); + + it('should repeat the word with a space delimiter correctly', () => { + const text = 'word'; + const repeatAmount = '3'; + const delimiter = ' '; + const result = repeatText( + { ...initialValues, repeatAmount, delimiter }, + text + ); + expect(result).toBe('word word word'); + }); + + it('should repeat the word with a space and a comma delimiter correctly', () => { + const text = 'test'; + const repeatAmount = '3'; + const delimiter = ', '; + const result = repeatText( + { ...initialValues, repeatAmount, delimiter }, + text + ); + expect(result).toBe('test, test, test'); + }); + + it('Should not repeat text if repeatAmount is zero', () => { + const text = 'something'; + const repeatAmount = '0'; + const result = repeatText({ ...initialValues, repeatAmount }, text); + expect(result).toBe(''); + }); + + it('Should not repeat text if repeatAmount is not entered', () => { + const text = 'something'; + const repeatAmount = ''; + const result = repeatText({ ...initialValues, repeatAmount }, text); + expect(result).toBe(''); + }); +}); diff --git a/src/pages/tools/string/repeat/service.ts b/src/pages/tools/string/repeat/service.ts new file mode 100644 index 0000000..a45130e --- /dev/null +++ b/src/pages/tools/string/repeat/service.ts @@ -0,0 +1,9 @@ +import { InitialValuesType } from './initialValues'; + +export function repeatText(options: InitialValuesType, text: string) { + const { repeatAmount, delimiter } = options; + + const parsedAmount = parseInt(repeatAmount) || 0; + + return Array(parsedAmount).fill(text).join(delimiter); +} From b960db9e791d7820f587453feea181343535cc31 Mon Sep 17 00:00:00 2001 From: EugSh <127679450+EugSh1@users.noreply.github.com> Date: Fri, 7 Mar 2025 15:32:15 +0300 Subject: [PATCH 2/2] fix: update title and remove unnecessary period from short description --- src/pages/tools/string/repeat/index.tsx | 2 +- src/pages/tools/string/repeat/meta.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/tools/string/repeat/index.tsx b/src/pages/tools/string/repeat/index.tsx index 78e5f08..0a954e2 100644 --- a/src/pages/tools/string/repeat/index.tsx +++ b/src/pages/tools/string/repeat/index.tsx @@ -104,7 +104,7 @@ export default function Replacer({ title }: ToolComponentProps) { } toolInfo={{ - title: 'Text Replacer', + title: 'Repeat text', description: 'This tool allows you to repeat a given text multiple times with an optional separator.' }} diff --git a/src/pages/tools/string/repeat/meta.ts b/src/pages/tools/string/repeat/meta.ts index 563b2f2..69f5d79 100644 --- a/src/pages/tools/string/repeat/meta.ts +++ b/src/pages/tools/string/repeat/meta.ts @@ -4,7 +4,7 @@ import { lazy } from 'react'; export const tool = defineTool('string', { name: 'Repeat text', path: 'repeat', - shortDescription: 'Repeat text multiple times.', + shortDescription: 'Repeat text multiple times', icon: 'material-symbols-light:replay', description: 'This tool allows you to repeat a given text multiple times with an optional separator.',