refact: examples

This commit is contained in:
Ibrahima G. Coulibaly
2025-02-27 01:47:44 +00:00
parent ff05de4ab6
commit f08bce84b0
6 changed files with 61 additions and 56 deletions

30
.idea/workspace.xml generated
View File

@@ -4,12 +4,12 @@
<option name="autoReloadType" value="SELECTIVE" /> <option name="autoReloadType" value="SELECTIVE" />
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="b30e2810-c4c1-4aad-b134-794e52cc1c7d" name="Changes" comment="chore: handle enter press on search"> <list default="true" id="b30e2810-c4c1-4aad-b134-794e52cc1c7d" name="Changes" comment="chore: show tooloptions in example">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/components/examples/ExampleCard.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/examples/ExampleCard.tsx" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/components/examples/ExampleCard.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/examples/ExampleCard.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/components/examples/Examples.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/examples/Examples.tsx" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/components/examples/Examples.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/examples/Examples.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/components/examples/RequiredOptions.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/examples/RequiredOptions.tsx" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/components/examples/RequiredOptions.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/examples/ExampleOptions.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/components/options/ToolOptions.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/options/ToolOptions.tsx" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/components/options/ToolOptionGroups.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/options/ToolOptionGroups.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/pages/tools/string/join/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/tools/string/join/index.tsx" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/pages/tools/string/join/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/tools/string/join/index.tsx" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
@@ -265,15 +265,7 @@
<workItem from="1740490890760" duration="1889000" /> <workItem from="1740490890760" duration="1889000" />
<workItem from="1740503199053" duration="4853000" /> <workItem from="1740503199053" duration="4853000" />
<workItem from="1740584243965" duration="17000" /> <workItem from="1740584243965" duration="17000" />
<workItem from="1740613094492" duration="6422000" /> <workItem from="1740613094492" duration="7661000" />
</task>
<task id="LOCAL-00078" summary="ci: run e2e tests">
<option name="closed" value="true" />
<created>1719587281298</created>
<option name="number" value="00078" />
<option name="presentableId" value="LOCAL-00078" />
<option name="project" value="LOCAL" />
<updated>1719587281298</updated>
</task> </task>
<task id="LOCAL-00079" summary="fix: ci"> <task id="LOCAL-00079" summary="fix: ci">
<option name="closed" value="true" /> <option name="closed" value="true" />
@@ -659,7 +651,15 @@
<option name="project" value="LOCAL" /> <option name="project" value="LOCAL" />
<updated>1740614957672</updated> <updated>1740614957672</updated>
</task> </task>
<option name="localTasksCounter" value="127" /> <task id="LOCAL-00127" summary="chore: show tooloptions in example">
<option name="closed" value="true" />
<created>1740619610168</created>
<option name="number" value="00127" />
<option name="presentableId" value="LOCAL-00127" />
<option name="project" value="LOCAL" />
<updated>1740619610169</updated>
</task>
<option name="localTasksCounter" value="128" />
<servers /> <servers />
</component> </component>
<component name="TypeScriptGeneratedFilesManager"> <component name="TypeScriptGeneratedFilesManager">
@@ -691,7 +691,6 @@
<option name="CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT" value="false" /> <option name="CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT" value="false" />
<option name="CHECK_NEW_TODO" value="false" /> <option name="CHECK_NEW_TODO" value="false" />
<option name="ADD_EXTERNAL_FILES_SILENTLY" value="true" /> <option name="ADD_EXTERNAL_FILES_SILENTLY" value="true" />
<MESSAGE value="feat: reverse list ui" />
<MESSAGE value="feat: self host" /> <MESSAGE value="feat: self host" />
<MESSAGE value="chore: format number" /> <MESSAGE value="chore: format number" />
<MESSAGE value="feat: rotate ui" /> <MESSAGE value="feat: rotate ui" />
@@ -716,7 +715,8 @@
<MESSAGE value="fix: bg" /> <MESSAGE value="fix: bg" />
<MESSAGE value="docs: readme" /> <MESSAGE value="docs: readme" />
<MESSAGE value="chore: handle enter press on search" /> <MESSAGE value="chore: handle enter press on search" />
<option name="LAST_COMMIT_MESSAGE" value="chore: handle enter press on search" /> <MESSAGE value="chore: show tooloptions in example" />
<option name="LAST_COMMIT_MESSAGE" value="chore: show tooloptions in example" />
</component> </component>
<component name="XSLT-Support.FileAssociations.UIState"> <component name="XSLT-Support.FileAssociations.UIState">
<expand /> <expand />

View File

@@ -1,4 +1,3 @@
import { ExampleCardProps } from './Examples';
import { import {
Box, Box,
Card, Card,
@@ -9,14 +8,25 @@ import {
useTheme useTheme
} from '@mui/material'; } from '@mui/material';
import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward'; import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';
import RequiredOptions from './RequiredOptions'; import ExampleOptions from './ExampleOptions';
import { GetGroupsType } from '@components/options/ToolOptions';
export interface ExampleCardProps<T> {
title: string;
description: string;
sampleText: string;
sampleResult: string;
sampleOptions: T;
changeInputResult: (newOptions: T) => void;
getGroups: GetGroupsType<T>;
}
export default function ExampleCard<T>({ export default function ExampleCard<T>({
title, title,
description, description,
sampleText, sampleText,
sampleResult, sampleResult,
requiredOptions, sampleOptions,
changeInputResult, changeInputResult,
getGroups getGroups
}: ExampleCardProps<T>) { }: ExampleCardProps<T>) {
@@ -25,7 +35,7 @@ export default function ExampleCard<T>({
<Card <Card
raised raised
onClick={() => { onClick={() => {
changeInputResult(sampleText, sampleResult); changeInputResult(sampleOptions);
}} }}
sx={{ sx={{
bgcolor: theme.palette.background.default, bgcolor: theme.palette.background.default,
@@ -108,7 +118,7 @@ export default function ExampleCard<T>({
/> />
</Box> </Box>
<RequiredOptions options={requiredOptions} getGroups={getGroups} /> <ExampleOptions options={sampleOptions} getGroups={getGroups} />
</Stack> </Stack>
</CardContent> </CardContent>
</Card> </Card>

View File

@@ -2,12 +2,18 @@ import ToolOptionGroups from '@components/options/ToolOptionGroups';
import { GetGroupsType } from '@components/options/ToolOptions'; import { GetGroupsType } from '@components/options/ToolOptions';
import React from 'react'; import React from 'react';
export default function RequiredOptions<T>({ export default function ExampleOptions<T>({
options, options,
getGroups getGroups
}: { }: {
options: T; options: T;
getGroups: GetGroupsType<T>; getGroups: GetGroupsType<T>;
}) { }) {
return <ToolOptionGroups groups={getGroups({ values: options })} />; return (
<ToolOptionGroups
// @ts-ignore
groups={getGroups({ values: options })}
vertical
/>
);
} }

View File

@@ -1,24 +1,14 @@
import { Box, Grid, Stack, Typography } from '@mui/material'; import { Box, Grid, Stack, Typography } from '@mui/material';
import ExampleCard from './ExampleCard'; import ExampleCard, { ExampleCardProps } from './ExampleCard';
import React from 'react'; import React from 'react';
import { GetGroupsType } from '@components/options/ToolOptions'; import { GetGroupsType } from '@components/options/ToolOptions';
export interface ExampleCardProps<T> {
title: string;
description: string;
sampleText: string;
sampleResult: string;
requiredOptions: T;
changeInputResult: (input: string, result: string) => void;
getGroups: GetGroupsType<T>;
}
interface ExampleProps<T> { interface ExampleProps<T> {
title: string; title: string;
subtitle: string; subtitle: string;
exampleCards: ExampleCardProps<T>[]; exampleCards: Omit<ExampleCardProps<T>, 'getGroups' | 'changeInputResult'>[];
getGroups: GetGroupsType<T>; getGroups: GetGroupsType<T>;
changeInputResult: (input: string, result: string) => void; changeInputResult: (newOptions: T) => void;
} }
export default function Examples<T>({ export default function Examples<T>({
@@ -48,7 +38,7 @@ export default function Examples<T>({
description={card.description} description={card.description}
sampleText={card.sampleText} sampleText={card.sampleText}
sampleResult={card.sampleResult} sampleResult={card.sampleResult}
requiredOptions={card.requiredOptions} sampleOptions={card.sampleOptions}
getGroups={getGroups} getGroups={getGroups}
changeInputResult={changeInputResult} changeInputResult={changeInputResult}
/> />

View File

@@ -8,14 +8,16 @@ export interface ToolOptionGroup {
} }
export default function ToolOptionGroups({ export default function ToolOptionGroups({
groups groups,
vertical
}: { }: {
groups: ToolOptionGroup[]; groups: ToolOptionGroup[];
vertical?: boolean;
}) { }) {
return ( return (
<Grid container spacing={2}> <Grid container spacing={2}>
{groups.map((group) => ( {groups.map((group) => (
<Grid item xs={12} md={4} key={group.title}> <Grid item xs={12} md={vertical ? 12 : 4} key={group.title}>
<Typography mb={1} fontSize={22}> <Typography mb={1} fontSize={22}>
{group.title} {group.title}
</Typography> </Typography>

View File

@@ -1,5 +1,5 @@
import { Box } from '@mui/material'; import { Box } from '@mui/material';
import React, { useState } from 'react'; import React, { useRef, useState } from 'react';
import * as Yup from 'yup'; import * as Yup from 'yup';
import ToolTextInput from '@components/input/ToolTextInput'; import ToolTextInput from '@components/input/ToolTextInput';
import ToolTextResult from '@components/result/ToolTextResult'; import ToolTextResult from '@components/result/ToolTextResult';
@@ -12,13 +12,14 @@ import ToolInputAndResult from '@components/ToolInputAndResult';
import ToolInfo from '@components/ToolInfo'; import ToolInfo from '@components/ToolInfo';
import Separator from '@components/Separator'; import Separator from '@components/Separator';
import Examples from '@components/examples/Examples'; import Examples from '@components/examples/Examples';
import { FormikProps } from 'formik';
const initialValues = { const initialValues = {
joinCharacter: '', joinCharacter: '',
deleteBlank: true, deleteBlank: true,
deleteTrailing: true deleteTrailing: true
}; };
type InitialValuesType = typeof initialValues;
const validationSchema = Yup.object().shape({ const validationSchema = Yup.object().shape({
joinCharacter: Yup.string().required('Join character is required'), joinCharacter: Yup.string().required('Join character is required'),
deleteBlank: Yup.boolean().required('Delete blank is required'), deleteBlank: Yup.boolean().required('Delete blank is required'),
@@ -29,13 +30,13 @@ const mergeOptions = {
placeholder: 'Join Character', placeholder: 'Join Character',
description: description:
'Symbol that connects broken\n' + 'pieces of text. (Space by default.)\n', 'Symbol that connects broken\n' + 'pieces of text. (Space by default.)\n',
accessor: 'joinCharacter' as keyof typeof initialValues accessor: 'joinCharacter' as keyof InitialValuesType
}; };
const blankTrailingOptions: { const blankTrailingOptions: {
title: string; title: string;
description: string; description: string;
accessor: keyof typeof initialValues; accessor: keyof InitialValuesType;
}[] = [ }[] = [
{ {
title: 'Delete Blank Lines', title: 'Delete Blank Lines',
@@ -62,7 +63,7 @@ feed the cat
make dinner make dinner
build a rocket ship and fly away`, build a rocket ship and fly away`,
sampleResult: `clean the house and go shopping and feed the cat and make dinner and build a rocket ship and fly away`, sampleResult: `clean the house and go shopping and feed the cat and make dinner and build a rocket ship and fly away`,
requiredOptions: { sampleOptions: {
joinCharacter: 'and', joinCharacter: 'and',
deleteBlank: true, deleteBlank: true,
deleteTrailing: true deleteTrailing: true
@@ -78,7 +79,7 @@ processor
mouse mouse
keyboard`, keyboard`,
sampleResult: `computer, memory, processor, mouse, keyboard`, sampleResult: `computer, memory, processor, mouse, keyboard`,
requiredOptions: { sampleOptions: {
joinCharacter: ',', joinCharacter: ',',
deleteBlank: false, deleteBlank: false,
deleteTrailing: false deleteTrailing: false
@@ -101,7 +102,7 @@ u
s s
!`, !`,
sampleResult: `Textabulous!`, sampleResult: `Textabulous!`,
requiredOptions: { sampleOptions: {
joinCharacter: '', joinCharacter: '',
deleteBlank: false, deleteBlank: false,
deleteTrailing: false deleteTrailing: false
@@ -112,15 +113,14 @@ s
export default function JoinText() { export default function JoinText() {
const [input, setInput] = useState<string>(''); const [input, setInput] = useState<string>('');
const [result, setResult] = useState<string>(''); const [result, setResult] = useState<string>('');
const optionsFormRef = useRef<FormikProps<InitialValuesType>>(null);
const compute = (optionsValues: typeof initialValues, input: any) => { const compute = (optionsValues: InitialValuesType, input: any) => {
const { joinCharacter, deleteBlank, deleteTrailing } = optionsValues; const { joinCharacter, deleteBlank, deleteTrailing } = optionsValues;
setResult(mergeText(input, deleteBlank, deleteTrailing, joinCharacter)); setResult(mergeText(input, deleteBlank, deleteTrailing, joinCharacter));
}; };
function changeInputResult(input: string, result: string) { function changeInputResult(newOptions: InitialValuesType) {
setInput(input); optionsFormRef.current?.setValues(newOptions);
setResult(result);
const toolsElement = document.getElementById('tool'); const toolsElement = document.getElementById('tool');
if (toolsElement) { if (toolsElement) {
@@ -128,7 +128,7 @@ export default function JoinText() {
} }
} }
const getGroups: GetGroupsType<typeof initialValues> = ({ const getGroups: GetGroupsType<InitialValuesType> = ({
values, values,
updateField updateField
}) => [ }) => [
@@ -169,6 +169,7 @@ export default function JoinText() {
result={<ToolTextResult title={'Joined Text'} value={result} />} result={<ToolTextResult title={'Joined Text'} value={result} />}
/> />
<ToolOptions <ToolOptions
formRef={optionsFormRef}
compute={compute} compute={compute}
getGroups={getGroups} getGroups={getGroups}
initialValues={initialValues} initialValues={initialValues}
@@ -182,11 +183,7 @@ export default function JoinText() {
<Examples <Examples
title="Text Joiner Examples" title="Text Joiner Examples"
subtitle="Click to try!" subtitle="Click to try!"
exampleCards={exampleCards.map((card) => ({ exampleCards={exampleCards}
...card,
changeInputResult,
getGroups
}))}
getGroups={getGroups} getGroups={getGroups}
changeInputResult={changeInputResult} changeInputResult={changeInputResult}
/> />