mirror of
https://github.com/ershisan99/DevToysWeb.git
synced 2025-12-16 20:49:23 +00:00
refactor: rename, reorder, etc.
This commit is contained in:
@@ -7,18 +7,8 @@ import { toolGroups } from "@/config/tools";
|
||||
import { safeJsonParse } from "@/lib/json";
|
||||
import { safeYamlParse } from "@/lib/yaml";
|
||||
import { Editor, EditorProps } from "@/components/ui/editor";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectProps,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { ClearButton } from "@/components/buttons/clear";
|
||||
import { CopyButton } from "@/components/buttons/copy";
|
||||
import { FileButton } from "@/components/buttons/file";
|
||||
import { PasteButton } from "@/components/buttons/paste";
|
||||
import * as Select from "@/components/ui/select";
|
||||
import * as Button from "@/components/buttons";
|
||||
import { Configuration } from "@/components/configuration";
|
||||
import { Configurations } from "@/components/configurations";
|
||||
import { ControlMenu } from "@/components/control-menu";
|
||||
@@ -38,41 +28,44 @@ export default function Page() {
|
||||
yaml: "foo: bar",
|
||||
});
|
||||
|
||||
const setJsonReactively = useCallback((text: string) => {
|
||||
const parsed = safeJsonParse(text);
|
||||
|
||||
const setFormByJson = useCallback((text: string) => {
|
||||
setForm(prev => ({
|
||||
...prev,
|
||||
json: text,
|
||||
yaml: parsed.isErr()
|
||||
? ""
|
||||
: yaml.dump(parsed.value, { indent: prev.indentation.length, quotingType: '"' }),
|
||||
yaml: safeJsonParse(text)
|
||||
.map(x => yaml.dump(x, { indent: prev.indentation.length, quotingType: '"' }))
|
||||
.unwrapOr(""),
|
||||
}));
|
||||
}, []);
|
||||
|
||||
const setYamlReactively = useCallback((text: string) => {
|
||||
const parsed = safeYamlParse(text);
|
||||
|
||||
const setFormByYaml = useCallback((text: string) => {
|
||||
setForm(prev => ({
|
||||
...prev,
|
||||
json: safeYamlParse(text)
|
||||
.map(x => JSON.stringify(x, null, prev.indentation))
|
||||
.unwrapOr(""),
|
||||
yaml: text,
|
||||
json: parsed.isErr() ? "" : JSON.stringify(parsed.value, null, prev.indentation),
|
||||
}));
|
||||
}, []);
|
||||
|
||||
const clearBoth = useCallback(() => {
|
||||
setForm(prev => ({ ...prev, json: "", yaml: "" }));
|
||||
setForm(prev => ({
|
||||
...prev,
|
||||
json: "",
|
||||
yaml: "",
|
||||
}));
|
||||
}, []);
|
||||
|
||||
const onIndentationChange: SelectProps["onValueChange"] = value => {
|
||||
const parsed = safeJsonParse(form.json);
|
||||
|
||||
const jsonYaml = parsed.isErr()
|
||||
? { json: "", yaml: "" }
|
||||
: {
|
||||
json: JSON.stringify(parsed.value, null, value),
|
||||
yaml: yaml.dump(parsed.value, { indent: value.length, quotingType: '"' }),
|
||||
};
|
||||
const onIndentationChange: Select.Props["onValueChange"] = value => {
|
||||
const jsonYaml = safeJsonParse(form.json)
|
||||
.map(x => ({
|
||||
json: JSON.stringify(x, null, value),
|
||||
yaml: yaml.dump(x, { indent: value.length, quotingType: '"' }),
|
||||
}))
|
||||
.unwrapOr({
|
||||
json: "",
|
||||
yaml: "",
|
||||
});
|
||||
|
||||
setForm({
|
||||
indentation: value,
|
||||
@@ -80,59 +73,55 @@ export default function Page() {
|
||||
});
|
||||
};
|
||||
|
||||
const onJsonChange: EditorProps["onChange"] = value => setJsonReactively(value ?? "");
|
||||
const onYamlChange: EditorProps["onChange"] = value => setYamlReactively(value ?? "");
|
||||
const onJsonChange: EditorProps["onChange"] = value => setFormByJson(value ?? "");
|
||||
const onYamlChange: EditorProps["onChange"] = value => setFormByYaml(value ?? "");
|
||||
|
||||
const indentationConfig = (
|
||||
<Configuration
|
||||
icon={<icons.Space size={24} className="-translate-y-1.5" />}
|
||||
title="Indentation"
|
||||
control={
|
||||
<Select value={form.indentation} onValueChange={onIndentationChange}>
|
||||
<SelectTrigger
|
||||
<Select.Root value={form.indentation} onValueChange={onIndentationChange}>
|
||||
<Select.Trigger
|
||||
className="w-28"
|
||||
aria-label="toggle open/close state of indentation selection"
|
||||
>
|
||||
<SelectValue placeholder={form.indentation} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value={indentations.two}>2 spaces</SelectItem>
|
||||
<SelectItem value={indentations.four}>4 spaces</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Select.Value placeholder={form.indentation} />
|
||||
</Select.Trigger>
|
||||
<Select.Content>
|
||||
<Select.Item value={indentations.two}>2 spaces</Select.Item>
|
||||
<Select.Item value={indentations.four}>4 spaces</Select.Item>
|
||||
</Select.Content>
|
||||
</Select.Root>
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
const jsonPasteButton = <PasteButton onClipboardRead={setJsonReactively} />;
|
||||
const yamlPasteButton = <PasteButton onClipboardRead={setYamlReactively} />;
|
||||
const jsonPasteButton = <Button.Paste onClipboardRead={setFormByJson} />;
|
||||
const yamlPasteButton = <Button.Paste onClipboardRead={setFormByYaml} />;
|
||||
|
||||
const jsonFileButton = (
|
||||
<FileButton
|
||||
accept=".json"
|
||||
onFileRead={setJsonReactively}
|
||||
iconOnly
|
||||
aria-label="load a json file"
|
||||
/>
|
||||
<Button.File accept=".json" onFileRead={setFormByJson} iconOnly aria-label="load a json file" />
|
||||
);
|
||||
const yamlFileButton = (
|
||||
<FileButton
|
||||
<Button.File
|
||||
accept=".yml,.yaml"
|
||||
onFileRead={setYamlReactively}
|
||||
onFileRead={setFormByYaml}
|
||||
iconOnly
|
||||
aria-label="load a yaml file"
|
||||
/>
|
||||
);
|
||||
|
||||
const jsonCopyButton = <CopyButton text={form.json} />;
|
||||
const yamlCopyButton = <CopyButton text={form.yaml} />;
|
||||
const jsonCopyButton = <Button.Copy text={form.json} />;
|
||||
const yamlCopyButton = <Button.Copy text={form.yaml} />;
|
||||
|
||||
const clearButton = <ClearButton onClick={clearBoth} iconOnly aria-label="clear json and yaml" />;
|
||||
const clearButton = (
|
||||
<Button.Clear onClick={clearBoth} iconOnly aria-label="clear json and yaml" />
|
||||
);
|
||||
|
||||
const jsonControl = (
|
||||
<ControlMenu list={[jsonPasteButton, jsonFileButton, jsonCopyButton, clearButton]} />
|
||||
);
|
||||
|
||||
const yamlControl = (
|
||||
<ControlMenu list={[yamlPasteButton, yamlFileButton, yamlCopyButton, clearButton]} />
|
||||
);
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useCallback, useState } from "react";
|
||||
import { toolGroups } from "@/config/tools";
|
||||
import * as baselib from "@/lib/base";
|
||||
import { Input, InputProps } from "@/components/ui/input";
|
||||
import { PasteButton } from "@/components/buttons/paste";
|
||||
import * as Button from "@/components/buttons";
|
||||
import { Configuration } from "@/components/configuration";
|
||||
import { Configurations } from "@/components/configurations";
|
||||
import { ControlMenu } from "@/components/control-menu";
|
||||
@@ -53,10 +53,10 @@ export default function Page() {
|
||||
const trySetOct = useCallback((value: string) => trySetInt(8)(value), []);
|
||||
const trySetBin = useCallback((value: string) => trySetInt(2)(value), []);
|
||||
|
||||
const onDecChange: InputProps["onChange"] = ({ currentTarget: { value } }) => trySetDec(value);
|
||||
const onHexChange: InputProps["onChange"] = ({ currentTarget: { value } }) => trySetHex(value);
|
||||
const onOctChange: InputProps["onChange"] = ({ currentTarget: { value } }) => trySetOct(value);
|
||||
const onBinChange: InputProps["onChange"] = ({ currentTarget: { value } }) => trySetBin(value);
|
||||
const onDecChange: InputProps["onChange"] = e => trySetDec(e.currentTarget.value);
|
||||
const onHexChange: InputProps["onChange"] = e => trySetHex(e.currentTarget.value);
|
||||
const onOctChange: InputProps["onChange"] = e => trySetOct(e.currentTarget.value);
|
||||
const onBinChange: InputProps["onChange"] = e => trySetBin(e.currentTarget.value);
|
||||
|
||||
const formatNumberConfig = (
|
||||
<Configuration
|
||||
@@ -73,10 +73,10 @@ export default function Page() {
|
||||
}
|
||||
/>
|
||||
);
|
||||
const decPasteButton = <PasteButton onClipboardRead={trySetDec} />;
|
||||
const hexPasteButton = <PasteButton onClipboardRead={trySetHex} />;
|
||||
const octPasteButton = <PasteButton onClipboardRead={trySetOct} />;
|
||||
const binPasteButton = <PasteButton onClipboardRead={trySetBin} />;
|
||||
const decPasteButton = <Button.Paste onClipboardRead={trySetDec} />;
|
||||
const hexPasteButton = <Button.Paste onClipboardRead={trySetHex} />;
|
||||
const octPasteButton = <Button.Paste onClipboardRead={trySetOct} />;
|
||||
const binPasteButton = <Button.Paste onClipboardRead={trySetBin} />;
|
||||
|
||||
const decControl = <ControlMenu list={[decPasteButton]} />;
|
||||
const hexControl = <ControlMenu list={[hexPasteButton]} />;
|
||||
|
||||
@@ -5,10 +5,7 @@ import { decode, encode, isValid } from "js-base64";
|
||||
|
||||
import { toolGroups } from "@/config/tools";
|
||||
import { Textarea, TextareaProps } from "@/components/ui/textarea";
|
||||
import { ClearButton } from "@/components/buttons/clear";
|
||||
import { CopyButton } from "@/components/buttons/copy";
|
||||
import { FileButton } from "@/components/buttons/file";
|
||||
import { PasteButton } from "@/components/buttons/paste";
|
||||
import * as Button from "@/components/buttons";
|
||||
import { ControlMenu } from "@/components/control-menu";
|
||||
import { PageRootSection } from "@/components/page-root-section";
|
||||
import { PageSection } from "@/components/page-section";
|
||||
@@ -19,19 +16,19 @@ export default function Page() {
|
||||
encoded: "8J+YgPCfmILwn6Sj",
|
||||
});
|
||||
|
||||
const setDecodedReactively = useCallback((text: string) => {
|
||||
const setFormByDecoded = useCallback((text: string) => {
|
||||
setForm({
|
||||
decoded: text,
|
||||
encoded: encode(text),
|
||||
});
|
||||
}, []);
|
||||
|
||||
const setEncodedReactively = useCallback((text: string) => {
|
||||
const setFormByEncoded = useCallback((text: string) => {
|
||||
const newDecoded = decode(text);
|
||||
|
||||
setForm({
|
||||
encoded: text,
|
||||
decoded: isValid(text) && !newDecoded.includes("<22>") ? newDecoded : "",
|
||||
encoded: text,
|
||||
});
|
||||
}, []);
|
||||
|
||||
@@ -42,33 +39,29 @@ export default function Page() {
|
||||
});
|
||||
}, []);
|
||||
|
||||
const onDecodedChange: TextareaProps["onChange"] = ({ currentTarget: { value } }) =>
|
||||
setDecodedReactively(value);
|
||||
const onDecodedChange: TextareaProps["onChange"] = e => setFormByDecoded(e.currentTarget.value);
|
||||
const onEncodedChange: TextareaProps["onChange"] = e => setFormByEncoded(e.currentTarget.value);
|
||||
|
||||
const onEncodedChange: TextareaProps["onChange"] = ({ currentTarget: { value } }) =>
|
||||
setEncodedReactively(value);
|
||||
|
||||
const decodedPasteButton = <PasteButton onClipboardRead={setDecodedReactively} />;
|
||||
const encodedPasteButton = <PasteButton onClipboardRead={setEncodedReactively} />;
|
||||
const decodedPasteButton = <Button.Paste onClipboardRead={setFormByDecoded} />;
|
||||
const encodedPasteButton = <Button.Paste onClipboardRead={setFormByEncoded} />;
|
||||
|
||||
const decodedFileButton = (
|
||||
<FileButton onFileRead={setDecodedReactively} iconOnly aria-label="load a decoded file" />
|
||||
<Button.File onFileRead={setFormByDecoded} iconOnly aria-label="load a decoded file" />
|
||||
);
|
||||
const encodedFileButton = (
|
||||
<FileButton onFileRead={setEncodedReactively} iconOnly aria-label="load a encoded file" />
|
||||
<Button.File onFileRead={setFormByEncoded} iconOnly aria-label="load a encoded file" />
|
||||
);
|
||||
|
||||
const decodedCopyButton = <CopyButton text={form.decoded} />;
|
||||
const encodedCopyButton = <CopyButton text={form.encoded} />;
|
||||
const decodedCopyButton = <Button.Copy text={form.decoded} />;
|
||||
const encodedCopyButton = <Button.Copy text={form.encoded} />;
|
||||
|
||||
const clearButton = (
|
||||
<ClearButton onClick={clearBoth} iconOnly aria-label="clear decoded and encoded" />
|
||||
<Button.Clear onClick={clearBoth} iconOnly aria-label="clear decoded and encoded" />
|
||||
);
|
||||
|
||||
const decodedControl = (
|
||||
<ControlMenu list={[decodedPasteButton, decodedFileButton, decodedCopyButton, clearButton]} />
|
||||
);
|
||||
|
||||
const encodedControl = (
|
||||
<ControlMenu list={[encodedPasteButton, encodedFileButton, encodedCopyButton, clearButton]} />
|
||||
);
|
||||
|
||||
@@ -5,10 +5,7 @@ import { escape, unescape } from "html-escaper";
|
||||
|
||||
import { toolGroups } from "@/config/tools";
|
||||
import { Textarea, TextareaProps } from "@/components/ui/textarea";
|
||||
import { ClearButton } from "@/components/buttons/clear";
|
||||
import { CopyButton } from "@/components/buttons/copy";
|
||||
import { FileButton } from "@/components/buttons/file";
|
||||
import { PasteButton } from "@/components/buttons/paste";
|
||||
import * as Button from "@/components/buttons";
|
||||
import { ControlMenu } from "@/components/control-menu";
|
||||
import { PageRootSection } from "@/components/page-root-section";
|
||||
import { PageSection } from "@/components/page-section";
|
||||
@@ -19,17 +16,17 @@ export default function Page() {
|
||||
encoded: "> It's "HTML escaping".",
|
||||
});
|
||||
|
||||
const setDecodedReactively = useCallback((text: string) => {
|
||||
const setFormByDecoded = useCallback((text: string) => {
|
||||
setForm({
|
||||
decoded: text,
|
||||
encoded: escape(text),
|
||||
});
|
||||
}, []);
|
||||
|
||||
const setEncodedReactively = useCallback((text: string) => {
|
||||
const setFormByEncoded = useCallback((text: string) => {
|
||||
setForm({
|
||||
encoded: text,
|
||||
decoded: unescape(text),
|
||||
encoded: text,
|
||||
});
|
||||
}, []);
|
||||
|
||||
@@ -40,33 +37,29 @@ export default function Page() {
|
||||
});
|
||||
}, []);
|
||||
|
||||
const onDecodedChange: TextareaProps["onChange"] = ({ currentTarget: { value } }) =>
|
||||
setDecodedReactively(value);
|
||||
const onDecodedChange: TextareaProps["onChange"] = e => setFormByDecoded(e.currentTarget.value);
|
||||
const onEncodedChange: TextareaProps["onChange"] = e => setFormByEncoded(e.currentTarget.value);
|
||||
|
||||
const onEncodedChange: TextareaProps["onChange"] = ({ currentTarget: { value } }) =>
|
||||
setEncodedReactively(value);
|
||||
|
||||
const decodedPasteButton = <PasteButton onClipboardRead={setDecodedReactively} />;
|
||||
const encodedPasteButton = <PasteButton onClipboardRead={setEncodedReactively} />;
|
||||
const decodedPasteButton = <Button.Paste onClipboardRead={setFormByDecoded} />;
|
||||
const encodedPasteButton = <Button.Paste onClipboardRead={setFormByEncoded} />;
|
||||
|
||||
const decodedFileButton = (
|
||||
<FileButton onFileRead={setDecodedReactively} iconOnly aria-label="load a decoded file" />
|
||||
<Button.File onFileRead={setFormByDecoded} iconOnly aria-label="load a decoded file" />
|
||||
);
|
||||
const encodedFileButton = (
|
||||
<FileButton onFileRead={setEncodedReactively} iconOnly aria-label="load a encoded file" />
|
||||
<Button.File onFileRead={setFormByEncoded} iconOnly aria-label="load a encoded file" />
|
||||
);
|
||||
|
||||
const decodedCopyButton = <CopyButton text={form.decoded} />;
|
||||
const encodedCopyButton = <CopyButton text={form.encoded} />;
|
||||
const decodedCopyButton = <Button.Copy text={form.decoded} />;
|
||||
const encodedCopyButton = <Button.Copy text={form.encoded} />;
|
||||
|
||||
const clearButton = (
|
||||
<ClearButton onClick={clearBoth} iconOnly aria-label="clear decoded and encoded" />
|
||||
<Button.Clear onClick={clearBoth} iconOnly aria-label="clear decoded and encoded" />
|
||||
);
|
||||
|
||||
const decodedControl = (
|
||||
<ControlMenu list={[decodedPasteButton, decodedFileButton, decodedCopyButton, clearButton]} />
|
||||
);
|
||||
|
||||
const encodedControl = (
|
||||
<ControlMenu list={[encodedPasteButton, encodedFileButton, encodedCopyButton, clearButton]} />
|
||||
);
|
||||
|
||||
@@ -6,10 +6,7 @@ import { toolGroups } from "@/config/tools";
|
||||
import { decode } from "@/lib/jwt";
|
||||
import { Editor } from "@/components/ui/editor";
|
||||
import { Textarea, TextareaProps } from "@/components/ui/textarea";
|
||||
import { ClearButton } from "@/components/buttons/clear";
|
||||
import { CopyButton } from "@/components/buttons/copy";
|
||||
import { FileButton } from "@/components/buttons/file";
|
||||
import { PasteButton } from "@/components/buttons/paste";
|
||||
import * as Button from "@/components/buttons";
|
||||
import { ControlMenu } from "@/components/control-menu";
|
||||
import { PageRootSection } from "@/components/page-root-section";
|
||||
import { PageSection } from "@/components/page-section";
|
||||
@@ -20,23 +17,23 @@ export default function Page() {
|
||||
);
|
||||
|
||||
const { header: h, payload: p } = decode(jwt);
|
||||
const header = h.isErr() ? "" : JSON.stringify(h.value, null, 2);
|
||||
const payload = p.isErr() ? "" : JSON.stringify(p.value, null, 2);
|
||||
const header = h.map(x => JSON.stringify(x, null, 2)).unwrapOr("");
|
||||
const payload = p.map(x => JSON.stringify(x, null, 2)).unwrapOr("");
|
||||
|
||||
const clearJwt = useCallback(() => setJwt(""), []);
|
||||
|
||||
const onJwtChange: TextareaProps["onChange"] = ({ currentTarget: { value } }) => setJwt(value);
|
||||
const onJwtChange: TextareaProps["onChange"] = e => setJwt(e.currentTarget.value);
|
||||
|
||||
const jwtTokenPasteButton = <PasteButton onClipboardRead={setJwt} />;
|
||||
const jwtTokenPasteButton = <Button.Paste onClipboardRead={setJwt} />;
|
||||
|
||||
const jwtTokenFileButton = (
|
||||
<FileButton onFileRead={setJwt} iconOnly aria-label="load a token file" />
|
||||
<Button.File onFileRead={setJwt} iconOnly aria-label="load a token file" />
|
||||
);
|
||||
|
||||
const jwtTokenClearButton = <ClearButton onClick={clearJwt} iconOnly aria-label="clear token" />;
|
||||
const jwtTokenClearButton = <Button.Clear onClick={clearJwt} iconOnly aria-label="clear token" />;
|
||||
|
||||
const heaederCopyButton = <CopyButton text={header} />;
|
||||
const payloadCopyButton = <CopyButton text={payload} />;
|
||||
const heaederCopyButton = <Button.Copy text={header} />;
|
||||
const payloadCopyButton = <Button.Copy text={payload} />;
|
||||
|
||||
const jwtTokenControl = (
|
||||
<ControlMenu list={[jwtTokenPasteButton, jwtTokenFileButton, jwtTokenClearButton]} />
|
||||
|
||||
@@ -5,10 +5,7 @@ import { useCallback, useState } from "react";
|
||||
import { toolGroups } from "@/config/tools";
|
||||
import { safeDecodeURIComponent, safeEncodeURIComponent } from "@/lib/uri";
|
||||
import { Textarea, TextareaProps } from "@/components/ui/textarea";
|
||||
import { ClearButton } from "@/components/buttons/clear";
|
||||
import { CopyButton } from "@/components/buttons/copy";
|
||||
import { FileButton } from "@/components/buttons/file";
|
||||
import { PasteButton } from "@/components/buttons/paste";
|
||||
import * as Button from "@/components/buttons";
|
||||
import { ControlMenu } from "@/components/control-menu";
|
||||
import { PageRootSection } from "@/components/page-root-section";
|
||||
import { PageSection } from "@/components/page-section";
|
||||
@@ -19,17 +16,17 @@ export default function Page() {
|
||||
encoded: "%3E%20It's%20%22URL%20encoding%22%3F",
|
||||
});
|
||||
|
||||
const setDecodedReactively = useCallback((text: string) => {
|
||||
const setFormByDecoded = useCallback((text: string) => {
|
||||
setForm({
|
||||
decoded: text,
|
||||
encoded: safeEncodeURIComponent(text).unwrapOr(""),
|
||||
});
|
||||
}, []);
|
||||
|
||||
const setEncodedReactively = useCallback((text: string) => {
|
||||
const setFormByEncoded = useCallback((text: string) => {
|
||||
setForm({
|
||||
encoded: text,
|
||||
decoded: safeDecodeURIComponent(text).unwrapOr(""),
|
||||
encoded: text,
|
||||
});
|
||||
}, []);
|
||||
|
||||
@@ -40,33 +37,29 @@ export default function Page() {
|
||||
});
|
||||
}, []);
|
||||
|
||||
const onDecodedChange: TextareaProps["onChange"] = ({ currentTarget: { value } }) =>
|
||||
setDecodedReactively(value);
|
||||
const onDecodedChange: TextareaProps["onChange"] = e => setFormByDecoded(e.currentTarget.value);
|
||||
const onEncodedChange: TextareaProps["onChange"] = e => setFormByEncoded(e.currentTarget.value);
|
||||
|
||||
const onEncodedChange: TextareaProps["onChange"] = ({ currentTarget: { value } }) =>
|
||||
setEncodedReactively(value);
|
||||
|
||||
const decodedPasteButton = <PasteButton onClipboardRead={setDecodedReactively} />;
|
||||
const encodedPasteButton = <PasteButton onClipboardRead={setEncodedReactively} />;
|
||||
const decodedPasteButton = <Button.Paste onClipboardRead={setFormByDecoded} />;
|
||||
const encodedPasteButton = <Button.Paste onClipboardRead={setFormByEncoded} />;
|
||||
|
||||
const decodedFileButton = (
|
||||
<FileButton onFileRead={setDecodedReactively} iconOnly aria-label="load a decoded file" />
|
||||
<Button.File onFileRead={setFormByDecoded} iconOnly aria-label="load a decoded file" />
|
||||
);
|
||||
const encodedFileButton = (
|
||||
<FileButton onFileRead={setEncodedReactively} iconOnly aria-label="load a encoded file" />
|
||||
<Button.File onFileRead={setFormByEncoded} iconOnly aria-label="load a encoded file" />
|
||||
);
|
||||
|
||||
const decodedCopyButton = <CopyButton text={form.decoded} />;
|
||||
const encodedCopyButton = <CopyButton text={form.encoded} />;
|
||||
const decodedCopyButton = <Button.Copy text={form.decoded} />;
|
||||
const encodedCopyButton = <Button.Copy text={form.encoded} />;
|
||||
|
||||
const clearButton = (
|
||||
<ClearButton onClick={clearBoth} iconOnly aria-label="clear decoded and encoded" />
|
||||
<Button.Clear onClick={clearBoth} iconOnly aria-label="clear decoded and encoded" />
|
||||
);
|
||||
|
||||
const decodedControl = (
|
||||
<ControlMenu list={[decodedPasteButton, decodedFileButton, decodedCopyButton, clearButton]} />
|
||||
);
|
||||
|
||||
const encodedControl = (
|
||||
<ControlMenu list={[encodedPasteButton, encodedFileButton, encodedCopyButton, clearButton]} />
|
||||
);
|
||||
|
||||
@@ -5,17 +5,8 @@ import { useCallback, useState } from "react";
|
||||
import { toolGroups } from "@/config/tools";
|
||||
import { safeJsonParse } from "@/lib/json";
|
||||
import { Editor, EditorProps } from "@/components/ui/editor";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { ClearButton } from "@/components/buttons/clear";
|
||||
import { CopyButton } from "@/components/buttons/copy";
|
||||
import { FileButton } from "@/components/buttons/file";
|
||||
import { PasteButton } from "@/components/buttons/paste";
|
||||
import * as Select from "@/components/ui/select";
|
||||
import * as Button from "@/components/buttons";
|
||||
import { Configuration } from "@/components/configuration";
|
||||
import { Configurations } from "@/components/configurations";
|
||||
import { ControlMenu } from "@/components/control-menu";
|
||||
@@ -35,7 +26,7 @@ export default function Page() {
|
||||
const [input, setInput] = useState('{\n"foo":"bar"\n}');
|
||||
|
||||
const parsed = safeJsonParse(input);
|
||||
const output = parsed.isErr() ? "" : JSON.stringify(parsed.value, null, indentation);
|
||||
const output = parsed.map(x => JSON.stringify(x, null, indentation)).unwrapOr("");
|
||||
|
||||
const clearInput = useCallback(() => setInput(""), []);
|
||||
|
||||
@@ -46,33 +37,33 @@ export default function Page() {
|
||||
icon={<icons.Space size={24} className="-translate-y-1.5" />}
|
||||
title="Indentation"
|
||||
control={
|
||||
<Select value={indentation} onValueChange={setIndentation}>
|
||||
<SelectTrigger
|
||||
<Select.Root value={indentation} onValueChange={setIndentation}>
|
||||
<Select.Trigger
|
||||
className="w-28"
|
||||
aria-label="toggle open/close state of indentation selection"
|
||||
>
|
||||
<SelectValue placeholder={indentation} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value={indentations.two}>2 spaces</SelectItem>
|
||||
<SelectItem value={indentations.four}>4 spaces</SelectItem>
|
||||
<SelectItem value={indentations.tab}>1 tab</SelectItem>
|
||||
<SelectItem value={indentations.zero}>minified</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Select.Value placeholder={indentation} />
|
||||
</Select.Trigger>
|
||||
<Select.Content>
|
||||
<Select.Item value={indentations.two}>2 spaces</Select.Item>
|
||||
<Select.Item value={indentations.four}>4 spaces</Select.Item>
|
||||
<Select.Item value={indentations.tab}>1 tab</Select.Item>
|
||||
<Select.Item value={indentations.zero}>minified</Select.Item>
|
||||
</Select.Content>
|
||||
</Select.Root>
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
const inputPasteButton = <PasteButton onClipboardRead={setInput} />;
|
||||
const inputPasteButton = <Button.Paste onClipboardRead={setInput} />;
|
||||
|
||||
const inputFileButton = (
|
||||
<FileButton accept=".json" onFileRead={setInput} iconOnly aria-label="load a json file" />
|
||||
<Button.File accept=".json" onFileRead={setInput} iconOnly aria-label="load a json file" />
|
||||
);
|
||||
|
||||
const inputClearButton = <ClearButton onClick={clearInput} iconOnly aria-label="clear json" />;
|
||||
const inputClearButton = <Button.Clear onClick={clearInput} iconOnly aria-label="clear json" />;
|
||||
|
||||
const outputCopyButton = <CopyButton text={output} />;
|
||||
const outputCopyButton = <Button.Copy text={output} />;
|
||||
|
||||
const inputControl = <ControlMenu list={[inputPasteButton, inputFileButton, inputClearButton]} />;
|
||||
const outputControl = <ControlMenu list={[outputCopyButton]} />;
|
||||
|
||||
@@ -6,10 +6,7 @@ import createHash from "create-hash";
|
||||
import { toolGroups } from "@/config/tools";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Textarea, TextareaProps } from "@/components/ui/textarea";
|
||||
import { ClearButton } from "@/components/buttons/clear";
|
||||
import { CopyButton } from "@/components/buttons/copy";
|
||||
import { FileButton } from "@/components/buttons/file";
|
||||
import { PasteButton } from "@/components/buttons/paste";
|
||||
import * as Button from "@/components/buttons";
|
||||
import { Configuration } from "@/components/configuration";
|
||||
import { Configurations } from "@/components/configurations";
|
||||
import { ControlMenu } from "@/components/control-menu";
|
||||
@@ -34,8 +31,7 @@ export default function Page() {
|
||||
|
||||
const clearInput = useCallback(() => setInput(""), []);
|
||||
|
||||
const onInputChange: TextareaProps["onChange"] = ({ currentTarget: { value } }) =>
|
||||
setInput(value);
|
||||
const onInputChange: TextareaProps["onChange"] = e => setInput(e.currentTarget.value);
|
||||
|
||||
const uppercaseConfig = (
|
||||
<Configuration
|
||||
@@ -53,16 +49,20 @@ export default function Page() {
|
||||
/>
|
||||
);
|
||||
|
||||
const inputPasteButton = <PasteButton onClipboardRead={setInput} />;
|
||||
const inputFileButton = <FileButton onFileRead={setInput} iconOnly aria-label="load a file" />;
|
||||
const inputClearButton = <ClearButton onClick={clearInput} iconOnly aria-label="clear input" />;
|
||||
const inputPasteButton = <Button.Paste onClipboardRead={setInput} />;
|
||||
const inputFileButton = <Button.File onFileRead={setInput} iconOnly aria-label="load a file" />;
|
||||
const inputClearButton = <Button.Clear onClick={clearInput} iconOnly aria-label="clear input" />;
|
||||
|
||||
const inputControl = <ControlMenu list={[inputPasteButton, inputFileButton, inputClearButton]} />;
|
||||
|
||||
const md5CopyButton = <CopyButton text={md5} iconOnly aria-label="copy generated md5" />;
|
||||
const sha1CopyButton = <CopyButton text={sha1} iconOnly aria-label="copy generated sha1" />;
|
||||
const sha256CopyButton = <CopyButton text={sha256} iconOnly aria-label="copy generated sha256" />;
|
||||
const sha512CopyButton = <CopyButton text={sha512} iconOnly aria-label="copy generated sha512" />;
|
||||
const md5CopyButton = <Button.Copy text={md5} iconOnly aria-label="copy generated md5" />;
|
||||
const sha1CopyButton = <Button.Copy text={sha1} iconOnly aria-label="copy generated sha1" />;
|
||||
const sha256CopyButton = (
|
||||
<Button.Copy text={sha256} iconOnly aria-label="copy generated sha256" />
|
||||
);
|
||||
const sha512CopyButton = (
|
||||
<Button.Copy text={sha512} iconOnly aria-label="copy generated sha512" />
|
||||
);
|
||||
|
||||
return (
|
||||
<PageRootSection title={toolGroups.generators.tools.hash.longTitle}>
|
||||
|
||||
@@ -9,17 +9,10 @@ import { uuid } from "@/lib/uuid";
|
||||
import { useScrollFollow } from "@/hooks/useScrollFollow";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input, InputProps } from "@/components/ui/input";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectProps,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import * as Select from "@/components/ui/select";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { ClearButton } from "@/components/buttons/clear";
|
||||
import { CopyButton } from "@/components/buttons/copy";
|
||||
import { Clear } from "@/components/buttons/clear";
|
||||
import { Copy } from "@/components/buttons/copy";
|
||||
import { Configuration } from "@/components/configuration";
|
||||
import { Configurations } from "@/components/configurations";
|
||||
import { ControlMenu } from "@/components/control-menu";
|
||||
@@ -48,22 +41,19 @@ export default function Page() {
|
||||
|
||||
const clearUuids = useCallback(() => setUuids([]), []);
|
||||
|
||||
const onUuidVersionChange: NonNullable<SelectProps["onValueChange"]> = useCallback(value => {
|
||||
const onUuidVersionChange: NonNullable<Select.Props["onValueChange"]> = useCallback(value => {
|
||||
if (uuidVersions.is(value)) {
|
||||
setUuidVersion(value);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const onGeneratesChange: NonNullable<InputProps["onChange"]> = useCallback(
|
||||
({ currentTarget: { value } }) => {
|
||||
const newGenerates = Number(value);
|
||||
const onGeneratesChange: NonNullable<InputProps["onChange"]> = useCallback(e => {
|
||||
const newGenerates = Number(e.currentTarget.value);
|
||||
|
||||
if (newGenerates >= 1 && newGenerates <= 1000) {
|
||||
setGenerates(newGenerates);
|
||||
}
|
||||
},
|
||||
[]
|
||||
);
|
||||
if (newGenerates >= 1 && newGenerates <= 1000) {
|
||||
setGenerates(newGenerates);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const onGenerateClick = () => {
|
||||
const newUuids = range(1, generates).map(_ => uuid(uuidVersion, hyphens, uppercase));
|
||||
@@ -108,24 +98,24 @@ export default function Page() {
|
||||
title="UUID version"
|
||||
description="Choose the version of UUID to generate"
|
||||
control={
|
||||
<Select value={uuidVersion} onValueChange={onUuidVersionChange}>
|
||||
<SelectTrigger
|
||||
<Select.Root value={uuidVersion} onValueChange={onUuidVersionChange}>
|
||||
<Select.Trigger
|
||||
className="w-28"
|
||||
aria-label="toggle open/close state of uuid version selection"
|
||||
>
|
||||
<SelectValue placeholder={uuidVersion} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value={versions.v1}>1</SelectItem>
|
||||
<SelectItem value={versions.v4}>4 (GUID)</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Select.Value placeholder={uuidVersion} />
|
||||
</Select.Trigger>
|
||||
<Select.Content>
|
||||
<Select.Item value={versions.v1}>1</Select.Item>
|
||||
<Select.Item value={versions.v4}>4 (GUID)</Select.Item>
|
||||
</Select.Content>
|
||||
</Select.Root>
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
const uuidsCopyButton = <CopyButton text={uuidsString} />;
|
||||
const uuidsClearButton = <ClearButton onClick={clearUuids} iconOnly aria-label="clear uuids" />;
|
||||
const uuidsCopyButton = <Copy text={uuidsString} />;
|
||||
const uuidsClearButton = <Clear onClick={clearUuids} iconOnly aria-label="clear uuids" />;
|
||||
|
||||
const uuidsControl = <ControlMenu list={[uuidsCopyButton, uuidsClearButton]} />;
|
||||
|
||||
|
||||
@@ -3,13 +3,7 @@
|
||||
import { useTheme } from "next-themes";
|
||||
|
||||
import { singleTools } from "@/config/tools";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import * as Select from "@/components/ui/select";
|
||||
import { Configuration } from "@/components/configuration";
|
||||
import { Configurations } from "@/components/configurations";
|
||||
import { icons } from "@/components/icons";
|
||||
@@ -25,19 +19,19 @@ export default function Page() {
|
||||
title="App theme"
|
||||
description="Select which app theme to display"
|
||||
control={
|
||||
<Select value={theme} onValueChange={setTheme}>
|
||||
<SelectTrigger
|
||||
<Select.Root value={theme} onValueChange={setTheme}>
|
||||
<Select.Trigger
|
||||
className="w-28"
|
||||
aria-label="toggle open/close state of app theme selection"
|
||||
>
|
||||
<SelectValue placeholder={theme} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="light">Light</SelectItem>
|
||||
<SelectItem value="dark">Dark</SelectItem>
|
||||
<SelectItem value="system">System</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Select.Value placeholder={theme} />
|
||||
</Select.Trigger>
|
||||
<Select.Content>
|
||||
<Select.Item value="light">Light</Select.Item>
|
||||
<Select.Item value="dark">Dark</Select.Item>
|
||||
<Select.Item value="system">System</Select.Item>
|
||||
</Select.Content>
|
||||
</Select.Root>
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user