diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index e61652d..e50bab9 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,8 +4,10 @@
-
-
+
+
+
+
@@ -27,16 +29,37 @@
- {
- "history": [
+
+}]]>
+
{
"selectedUrlAndAccountId": {
"url": "https://github.com/iib0011/omni-tools.git",
@@ -61,51 +84,51 @@
- {
- "keyToString": {
- "ASKED_ADD_EXTERNAL_FILES": "true",
- "ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true",
- "Docker.Dockerfile build.executor": "Run",
- "Docker.Dockerfile.executor": "Run",
- "Playwright.JoinText Component.executor": "Run",
- "Playwright.JoinText Component.should merge text pieces with specified join character.executor": "Run",
- "RunOnceActivity.OpenProjectViewOnStart": "true",
- "RunOnceActivity.ShowReadmeOnStart": "true",
- "RunOnceActivity.git.unshallow": "true",
- "Vitest.compute function (1).executor": "Run",
- "Vitest.compute function.executor": "Run",
- "Vitest.mergeText.executor": "Run",
- "Vitest.mergeText.should merge lines and preserve blank lines when deleteBlankLines is false.executor": "Run",
- "Vitest.mergeText.should merge lines, preserve blank lines and trailing spaces when both deleteBlankLines and deleteTrailingSpaces are false.executor": "Run",
- "Vitest.removeDuplicateLines function.executor": "Run",
- "Vitest.removeDuplicateLines function.newlines option.executor": "Run",
- "Vitest.removeDuplicateLines function.newlines option.should filter newlines when newlines is set to filter.executor": "Run",
- "git-widget-placeholder": "main",
- "ignore.virus.scanning.warn.message": "true",
- "kotlin-language-version-configured": "true",
- "last_opened_file_path": "C:/Users/Ibrahima/IdeaProjects/omni-tools/public/assets",
- "node.js.detected.package.eslint": "true",
- "node.js.detected.package.tslint": "true",
- "node.js.selected.package.eslint": "(autodetect)",
- "node.js.selected.package.tslint": "(autodetect)",
- "nodejs_package_manager_path": "npm",
- "npm.build.executor": "Run",
- "npm.dev.executor": "Run",
- "npm.lint.executor": "Run",
- "npm.prebuild.executor": "Run",
- "npm.script:create:tool.executor": "Run",
- "npm.test.executor": "Run",
- "npm.test:e2e.executor": "Run",
- "npm.test:e2e:run.executor": "Run",
- "prettierjs.PrettierConfiguration.Package": "C:\\Users\\Ibrahima\\IdeaProjects\\omni-tools\\node_modules\\prettier",
- "project.structure.last.edited": "Problems",
- "project.structure.proportion": "0.0",
- "project.structure.side.proportion": "0.2",
- "settings.editor.selected.configurable": "settings.typescriptcompiler",
- "ts.external.directory.path": "C:\\Users\\Ibrahima\\IdeaProjects\\omni-tools\\node_modules\\typescript\\lib",
- "vue.rearranger.settings.migration": "true"
+
+}]]>
@@ -750,7 +775,6 @@
-
@@ -767,7 +791,8 @@
-
+
+
diff --git a/src/pages/tools/list/reverse/index.tsx b/src/pages/tools/list/reverse/index.tsx
index 2b50349..dce6d0e 100644
--- a/src/pages/tools/list/reverse/index.tsx
+++ b/src/pages/tools/list/reverse/index.tsx
@@ -1,14 +1,19 @@
import { Box } from '@mui/material';
-import React, { useState } from 'react';
+import React, { useRef, useState } from 'react';
import ToolTextInput from '@components/input/ToolTextInput';
import ToolTextResult from '@components/result/ToolTextResult';
-import ToolOptions from '@components/options/ToolOptions';
+import ToolOptions, { GetGroupsType } from '@components/options/ToolOptions';
import { reverseList, SplitOperatorType } from './service';
import ToolInputAndResult from '@components/ToolInputAndResult';
import SimpleRadio from '@components/options/SimpleRadio';
import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
-import { CardExampleType } from '@components/examples/ToolExamples';
+import ToolExamples, {
+ CardExampleType
+} from '@components/examples/ToolExamples';
import ToolInfo from '@components/ToolInfo';
+import { FormikProps } from 'formik';
+import Separator from '@components/Separator';
+import { ToolComponentProps } from '@tools/defineTool';
const initialValues = {
splitOperatorType: 'symbol' as SplitOperatorType,
@@ -37,12 +42,12 @@ const exampleCards: CardExampleType[] = [
{
title: 'Reverse a List of Digits',
description:
- "In this example, we load a list of digits in the input. The digits are separated by a mix of dot, comma, and semicolon characters, so we use the regular expression split mode and enter a regular expression that matches all these characters as the input item separator. In the output, we get a reversed list of digits that all use the semicolon as a separator.",
+ 'In this example, we load a list of digits in the input. The digits are separated by a mix of dot, comma, and semicolon characters, so we use the regular expression split mode and enter a regular expression that matches all these characters as the input item separator. In the output, we get a reversed list of digits that all use the semicolon as a separator.',
sampleText: `2, 9, 6; 3; 7. 4. 4. 2, 1; 4, 8. 4; 4. 8, 2, 5; 1; 7; 7. 0`,
sampleResult: `0; 7; 7; 1; 5; 2; 8; 4; 4; 8; 4; 1; 2; 4; 4; 7; 3; 6; 9; 2`,
sampleOptions: {
splitOperatorType: 'regex',
- splitSeparator: '/[;,.]\\s*/',
+ splitSeparator: '[;,.]\\s*',
joinSeparator: '; '
}
},
@@ -110,9 +115,56 @@ argument`,
}
];
-export default function Reverse() {
+export default function Reverse({ title }: ToolComponentProps) {
const [input, setInput] = useState('');
const [result, setResult] = useState('');
+ const formRef = useRef>(null);
+
+ const getGroups: GetGroupsType = ({
+ values,
+ updateField
+ }) => [
+ {
+ title: 'Splitter Mode',
+ component: (
+
+ {splitOperators.map(({ title, description, type }) => (
+ updateField('splitOperatorType', type)}
+ title={title}
+ description={description}
+ checked={values.splitOperatorType === type}
+ />
+ ))}
+
+ )
+ },
+ {
+ title: 'Item Separator',
+ component: (
+
+ updateField('splitSeparator', val)}
+ />
+
+ )
+ },
+ {
+ title: 'Output List Options',
+ component: (
+
+ updateField('joinSeparator', val)}
+ />
+
+ )
+ }
+ ];
const compute = (optionsValues: typeof initialValues, input: any) => {
const { splitOperatorType, splitSeparator, joinSeparator } = optionsValues;
@@ -134,56 +186,24 @@ export default function Reverse() {
result={}
/>
[
- {
- title: 'Splitter Mode',
- component: (
-
- {splitOperators.map(({ title, description, type }) => (
- updateField('splitOperatorType', type)}
- title={title}
- description={description}
- checked={values.splitOperatorType === type}
- />
- ))}
-
- )
- },
- {
- title: 'Item Separator',
- component: (
-
- updateField('splitSeparator', val)}
- />
-
- )
- },
- {
- title: 'Output List Options',
- component: (
-
- updateField('joinSeparator', val)}
- />
-
- )
- }
- ]}
+ getGroups={getGroups}
initialValues={initialValues}
input={input}
/>
+ title="What Is a List Reverser?"
+ description="With this utility, you can reverse the order of items in a list. The utility first splits the input list into individual items and then iterates through them from the last item to the first item, printing each item to the output during the iteration. The input list may contain anything that can be represented as textual data, which includes digits, numbers, strings, words, sentences, etc. The input item separator can also be a regular expression. For example, the regex /[;,]/ will allow you to use items that are either comma- or semicolon-separated. The input and output list items delimiters can be customized in the options. By default, both input and output lists are comma-separated. Listabulous!"
+ />
+
+
);
}
diff --git a/src/pages/tools/number/sum/index.tsx b/src/pages/tools/number/sum/index.tsx
index bc2ccdf..3c2b3e8 100644
--- a/src/pages/tools/number/sum/index.tsx
+++ b/src/pages/tools/number/sum/index.tsx
@@ -1,15 +1,20 @@
import { Box } from '@mui/material';
-import React, { useState } from 'react';
+import React, { useRef, useState } from 'react';
import ToolTextInput from '@components/input/ToolTextInput';
import ToolTextResult from '@components/result/ToolTextResult';
-import ToolOptions from '@components/options/ToolOptions';
+import ToolOptions, { GetGroupsType } from '@components/options/ToolOptions';
import { compute, NumberExtractionType } from './service';
import RadioWithTextField from '@components/options/RadioWithTextField';
import SimpleRadio from '@components/options/SimpleRadio';
import CheckboxWithDesc from '@components/options/CheckboxWithDesc';
import ToolInputAndResult from '@components/ToolInputAndResult';
-import { CardExampleType } from '@components/examples/ToolExamples';
+import ToolExamples, {
+ CardExampleType
+} from '@components/examples/ToolExamples';
import ToolInfo from '@components/ToolInfo';
+import Separator from '@components/Separator';
+import { ToolComponentProps } from '@tools/defineTool';
+import { FormikProps } from 'formik';
const initialValues = {
extractionType: 'smart' as NumberExtractionType,
@@ -44,7 +49,7 @@ const exampleCards: CardExampleType[] = [
{
title: 'Sum of Ten Positive Numbers',
description:
- "In this example, we calculate the sum of ten positive integers. These integers are listed as a column and their total sum equals 19494.",
+ 'In this example, we calculate the sum of ten positive integers. These integers are listed as a column and their total sum equals 19494.',
sampleText: `0
1
20
@@ -118,11 +123,57 @@ const exampleCards: CardExampleType[] = [
}
];
-
-export default function SplitText() {
+export default function SumNumbers({ title }: ToolComponentProps) {
const [input, setInput] = useState('');
const [result, setResult] = useState('');
+ const formRef = useRef>(null);
+ const getGroups: GetGroupsType = ({
+ values,
+ updateField
+ }) => [
+ {
+ title: 'Number extraction',
+ component: extractionTypes.map(
+ ({ title, description, type, withTextField, textValueAccessor }) =>
+ withTextField ? (
+ updateField('extractionType', type)}
+ onTextChange={(val) =>
+ textValueAccessor ? updateField(textValueAccessor, val) : null
+ }
+ />
+ ) : (
+ updateField('extractionType', type)}
+ checked={values.extractionType === type}
+ description={description}
+ title={title}
+ />
+ )
+ )
+ },
+ {
+ title: 'Running Sum',
+ component: (
+ updateField('printRunningSum', value)}
+ />
+ )
+ }
+ ];
return (
}
/>
[
- {
- title: 'Number extraction',
- component: extractionTypes.map(
- ({
- title,
- description,
- type,
- withTextField,
- textValueAccessor
- }) =>
- withTextField ? (
- updateField('extractionType', type)}
- onTextChange={(val) =>
- textValueAccessor
- ? updateField(textValueAccessor, val)
- : null
- }
- />
- ) : (
- updateField('extractionType', type)}
- checked={values.extractionType === type}
- description={description}
- title={title}
- />
- )
- )
- },
- {
- title: 'Running Sum',
- component: (
- updateField('printRunningSum', value)}
- />
- )
- }
- ]}
+ formRef={formRef}
+ getGroups={getGroups}
compute={(optionsValues, input) => {
const { extractionType, printRunningSum, separator } = optionsValues;
setResult(compute(input, extractionType, printRunningSum, separator));
@@ -190,10 +190,18 @@ export default function SplitText() {
initialValues={initialValues}
input={input}
/>
-
+
+
+
);
}