Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create UI for already created tools (#35) #41

Merged
merged 8 commits into from
Mar 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .idea/workspace.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/components/ToolContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ interface ToolContentProps<T, I> extends ToolComponentProps {
// Tool info (optional)
toolInfo?: {
title: string;
description: string;
description?: string;
};

// Input value to pass to the compute function
Expand Down Expand Up @@ -66,7 +66,7 @@ export default function ToolContent<T extends FormikValues, I>({
validationSchema={validationSchema}
/>

{toolInfo && (
{toolInfo && toolInfo.title && toolInfo.description && (
<ToolInfo title={toolInfo.title} description={toolInfo.description} />
)}

Expand Down
53 changes: 28 additions & 25 deletions src/components/examples/ExampleCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,33 +60,36 @@ export default function ExampleCard<T>({
{description}
</Typography>

<Box
sx={{
display: 'flex',
zIndex: '2',
width: '100%',
height: '100%',
bgcolor: 'transparent',
padding: '5px 10px',
borderRadius: '5px',
boxShadow: 'inset 2px 2px 5px #b8b9be, inset -3px -3px 7px #fff;'
}}
>
<TextField
value={sampleText}
disabled
fullWidth
multiline
{sampleText && (
<Box
sx={{
'& .MuiOutlinedInput-root': {
zIndex: '-1',
'& fieldset': {
border: 'none'
}
}
display: 'flex',
zIndex: '2',
width: '100%',
height: '100%',
bgcolor: 'transparent',
padding: '5px 10px',
borderRadius: '5px',
boxShadow:
'inset 2px 2px 5px #b8b9be, inset -3px -3px 7px #fff;'
}}
/>
</Box>
>
<TextField
value={sampleText}
disabled
fullWidth
multiline
sx={{
'& .MuiOutlinedInput-root': {
zIndex: '-1',
'& fieldset': {
border: 'none'
}
}
}}
/>
</Box>
)}

<ArrowDownwardIcon />
<Box
Expand Down
84 changes: 44 additions & 40 deletions src/components/options/ToolOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@ interface FormikHelperProps<T> {
compute: (optionsValues: T, input: any) => void;
input: any;
children?: ReactNode;
getGroups: (
formikProps: FormikProps<T> & { updateField: UpdateField<T> }
) => ToolOptionGroup[];
getGroups:
| null
| ((
formikProps: FormikProps<T> & { updateField: UpdateField<T> }
) => ToolOptionGroup[]);
formikProps: FormikProps<T>;
}

Expand All @@ -63,7 +65,9 @@ const ToolBody = <T,>({
input={input}
initialValues={values}
/>
<ToolOptionGroups groups={getGroups({ ...formikProps, updateField })} />
<ToolOptionGroups
groups={getGroups?.({ ...formikProps, updateField }) ?? []}
/>
{children}
</Stack>
);
Expand All @@ -90,41 +94,41 @@ export default function ToolOptions<T extends FormikValues>({
formRef?: RefObject<FormikProps<T>>;
}) {
const theme = useTheme();
if (getGroups)
return (
<Box
sx={{
mb: 2,
borderRadius: 2,
padding: 2,
backgroundColor: theme.palette.background.default,
boxShadow: '2'
}}
mt={2}
>
<Stack direction={'row'} spacing={1} alignItems={'center'}>
<SettingsIcon />
<Typography fontSize={22}>Tool options</Typography>
</Stack>
<Box mt={2}>
<Formik
innerRef={formRef}
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={() => {}}
>
{(formikProps) => (
<ToolBody
compute={compute}
input={input}
getGroups={getGroups}
formikProps={formikProps}
>
{children}
</ToolBody>
)}
</Formik>
</Box>
return (
<Box
sx={{
mb: 2,
borderRadius: 2,
padding: 2,
backgroundColor: theme.palette.background.default,
boxShadow: '2',
display: getGroups ? 'block' : 'none'
}}
mt={2}
>
<Stack direction={'row'} spacing={1} alignItems={'center'}>
<SettingsIcon />
<Typography fontSize={22}>Tool options</Typography>
</Stack>
<Box mt={2}>
<Formik
innerRef={formRef}
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={() => {}}
>
{(formikProps) => (
<ToolBody
compute={compute}
input={input}
getGroups={getGroups}
formikProps={formikProps}
>
{children}
</ToolBody>
)}
</Formik>
</Box>
);
</Box>
);
}
4 changes: 3 additions & 1 deletion src/pages/tools/number/arithmetic-sequence/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
import { generateArithmeticSequence } from './service';
import * as Yup from 'yup';
import { CardExampleType } from '@components/examples/ToolExamples';
import { ToolComponentProps } from '@tools/defineTool';

type InitialValuesType = {
firstTerm: string;
Expand Down Expand Up @@ -68,11 +69,12 @@ const exampleCards: CardExampleType<InitialValuesType>[] = [
}
];

export default function ArithmeticSequence() {
export default function ArithmeticSequence({ title }: ToolComponentProps) {
const [result, setResult] = useState<string>('');

return (
<ToolContent
title={title}
inputComponent={null}
resultComponent={
<ToolTextResult title="Generated Sequence" value={result} />
Expand Down
122 changes: 112 additions & 10 deletions src/pages/tools/string/create-palindrome/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,113 @@
import { Box } from '@mui/material';
import React from 'react';
import * as Yup from 'yup';

const initialValues = {};
const validationSchema = Yup.object({
// splitSeparator: Yup.string().required('The separator is required')
});
export default function CreatePalindrome() {
return <Box>Lorem ipsum</Box>;
import React, { useState } from 'react';
import ToolTextInput from '@components/input/ToolTextInput';
import ToolTextResult from '@components/result/ToolTextResult';
import { GetGroupsType } from '@components/options/ToolOptions';
import { createPalindromeList } from './service';
import CheckboxWithDesc from '@components/options/CheckboxWithDesc';
import { CardExampleType } from '@components/examples/ToolExamples';
import { ToolComponentProps } from '@tools/defineTool';
import ToolContent from '@components/ToolContent';

const initialValues = {
lastChar: true,
multiLine: false
};

const exampleCards: CardExampleType<typeof initialValues>[] = [
{
title: 'Create Simple Palindrome',
description:
'Creates a palindrome by repeating the text in reverse order, including the last character.',
sampleText: 'level',
sampleResult: 'levellevel',
sampleOptions: {
...initialValues,
lastChar: true
}
},
{
title: 'Create Palindrome Without Last Character Duplication',
description:
'Creates a palindrome without repeating the last character in the reverse part.',
sampleText: 'radar',
sampleResult: 'radarada',
sampleOptions: {
...initialValues,
lastChar: false
}
},
{
title: 'Multi-line Palindrome Creation',
description: 'Creates palindromes for each line independently.',
sampleText: 'mom\ndad\nwow',
sampleResult: 'mommom\ndaddad\nwowwow',
sampleOptions: {
...initialValues,
lastChar: true,
multiLine: true
}
}
];

export default function CreatePalindrome({
title,
longDescription
}: ToolComponentProps) {
const [input, setInput] = useState<string>('');
const [result, setResult] = useState<string>('');

const computeExternal = (
optionsValues: typeof initialValues,
input: string
) => {
const { lastChar, multiLine } = optionsValues;
setResult(createPalindromeList(input, lastChar, multiLine));
};

const getGroups: GetGroupsType<typeof initialValues> = ({
values,
updateField
}) => [
{
title: 'Palindrome options',
component: [
<CheckboxWithDesc
key="lastChar"
checked={values.lastChar}
title="Include last character"
description="Repeat the last character in the reversed part"
onChange={(val) => updateField('lastChar', val)}
/>,
<CheckboxWithDesc
key="multiLine"
checked={values.multiLine}
title="Process multi-line text"
description="Create palindromes for each line independently"
onChange={(val) => updateField('multiLine', val)}
/>
]
}
];

return (
<ToolContent
title={title}
initialValues={initialValues}
getGroups={getGroups}
compute={computeExternal}
input={input}
setInput={setInput}
inputComponent={
<ToolTextInput title={'Input text'} value={input} onChange={setInput} />
}
resultComponent={
<ToolTextResult title={'Palindrome text'} value={result} />
}
toolInfo={{
title: 'What Is a String Palindrome Creator?',
description: longDescription
}}
exampleCards={exampleCards}
/>
);
}
9 changes: 6 additions & 3 deletions src/pages/tools/string/create-palindrome/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ import { lazy } from 'react';
export const tool = defineTool('string', {
name: 'Create palindrome',
path: 'create-palindrome',
icon: '',
description: '',
shortDescription: '',
icon: 'material-symbols-light:repeat',
description:
"World's simplest browser-based utility for creating palindromes from any text. Input text and instantly transform it into a palindrome that reads the same forward and backward. Perfect for word games, creating symmetrical text patterns, or exploring linguistic curiosities.",
shortDescription: 'Create text that reads the same forward and backward',
longDescription:
'This tool creates a palindrome from the given string. It does it by generating a copy of the string, reversing it, and appending it at the end of the original string. This method creates a palindrome with the last character duplicated twice. There is also another way to do it, which deletes the first letter of the reversed copy. In this case, when the string and the copy are joined together, you also get a palindrome but without the repeating last character. You can compare the two types of palindromes by switching between them in the options. You can also enable the multi-line mode that will create palindromes of every string on every line. Stringabulous!',
keywords: ['create', 'palindrome'],
component: lazy(() => import('./index'))
});
Loading