mirror of
https://github.com/ershisan99/DevToysWeb.git
synced 2025-12-16 12:32:48 +00:00
refactor: clean some codes
This commit is contained in:
@@ -5,7 +5,7 @@ import { range } from "fp-ts/NonEmptyArray";
|
|||||||
|
|
||||||
import { toolGroups } from "@/config/tools";
|
import { toolGroups } from "@/config/tools";
|
||||||
import { uuid } from "@/lib/uuid";
|
import { uuid } from "@/lib/uuid";
|
||||||
import { useScrollFollow } from "@/hooks/useScrollFollow";
|
import { useAutoScroll } from "@/hooks/useAutoScroll";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input, InputProps } from "@/components/ui/input";
|
import { Input, InputProps } from "@/components/ui/input";
|
||||||
import * as Select from "@/components/ui/select";
|
import * as Select from "@/components/ui/select";
|
||||||
@@ -37,7 +37,7 @@ export default function Page() {
|
|||||||
const [uuidVersion, setUuidVersion] = useState<UuidVersion>("4");
|
const [uuidVersion, setUuidVersion] = useState<UuidVersion>("4");
|
||||||
const [generates, setGenerates] = useState(1);
|
const [generates, setGenerates] = useState(1);
|
||||||
const [uuids, setUuids] = useState<string[]>([]);
|
const [uuids, setUuids] = useState<string[]>([]);
|
||||||
const ref = useScrollFollow<HTMLTextAreaElement>([uuids]);
|
const ref = useAutoScroll<HTMLTextAreaElement>([uuids]);
|
||||||
|
|
||||||
const uuidsString = uuids.join("\n");
|
const uuidsString = uuids.join("\n");
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import { Configuration } from "@/components/configuration";
|
|||||||
import { Configurations } from "@/components/configurations";
|
import { Configurations } from "@/components/configurations";
|
||||||
import { icons } from "@/components/icons";
|
import { icons } from "@/components/icons";
|
||||||
import { PageRootSection } from "@/components/page-root-section";
|
import { PageRootSection } from "@/components/page-root-section";
|
||||||
import { PageSection } from "@/components/page-section";
|
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
const { theme = "system", setTheme } = useTheme();
|
const { theme = "system", setTheme } = useTheme();
|
||||||
@@ -38,9 +37,7 @@ export default function Page() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<PageRootSection title={singleTools.settings.longTitle}>
|
<PageRootSection title={singleTools.settings.longTitle}>
|
||||||
<PageSection>
|
<Configurations list={[appThemeConfig]} />
|
||||||
<Configurations list={[appThemeConfig]} />
|
|
||||||
</PageSection>
|
|
||||||
</PageRootSection>
|
</PageRootSection>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export type BaseProps = ButtonProps & {
|
|||||||
|
|
||||||
export function Base({ icon, iconOnly, labelText, ...props }: BaseProps) {
|
export function Base({ icon, iconOnly, labelText, ...props }: BaseProps) {
|
||||||
const button = (
|
const button = (
|
||||||
<Button className="w-fit border" {...props}>
|
<Button className="border" {...props}>
|
||||||
{icon}
|
{icon}
|
||||||
{!iconOnly && <span className="ml-1">{labelText}</span>}
|
{!iconOnly && <span className="ml-1">{labelText}</span>}
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -3,22 +3,21 @@ import { cn } from "@/lib/style";
|
|||||||
type Props = {
|
type Props = {
|
||||||
className?: string;
|
className?: string;
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
title?: string;
|
title: string;
|
||||||
control?: React.ReactNode;
|
control?: React.ReactNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function PageSection({ className, children, title, control }: Props) {
|
export function PageSection({ className, children, title, control }: Props) {
|
||||||
return (
|
return (
|
||||||
<section className={cn("mt-3 flex flex-col", className)}>
|
<section className={cn("mt-3 flex flex-col", className)}>
|
||||||
{title &&
|
{control ? (
|
||||||
(control ? (
|
<div className="mb-1.5 flex w-full items-end">
|
||||||
<div className="mb-1.5 flex w-full items-end">
|
<h2 className="text-base">{title}</h2>
|
||||||
<h2 className="text-base">{title}</h2>
|
<div className="ml-auto">{control}</div>
|
||||||
<div className="ml-auto">{control}</div>
|
</div>
|
||||||
</div>
|
) : (
|
||||||
) : (
|
<h2 className="mb-1.5 text-base">{title}</h2>
|
||||||
<h2 className="mb-1.5 text-base">{title}</h2>
|
)}
|
||||||
))}
|
|
||||||
{children}
|
{children}
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -41,10 +41,10 @@ export function SearchBar() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative flex w-full items-center">
|
<div className="relative flex items-center">
|
||||||
<Input
|
<Input
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
className="flex-1 pr-16 font-sans"
|
className="w-full pr-16 font-sans"
|
||||||
value={text}
|
value={text}
|
||||||
onChange={changeText}
|
onChange={changeText}
|
||||||
onKeyDown={searchIfEnter}
|
onKeyDown={searchIfEnter}
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ type Props = IToolGroup & {
|
|||||||
isOpend: boolean;
|
isOpend: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME: css outline messed up
|
|
||||||
export function ToolGroup({ Icon, title, href, tools, isOpend }: Props) {
|
export function ToolGroup({ Icon, title, href, tools, isOpend }: Props) {
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
const triggerRef = useRef<HTMLButtonElement>(null);
|
const triggerRef = useRef<HTMLButtonElement>(null);
|
||||||
@@ -25,18 +24,19 @@ export function ToolGroup({ Icon, title, href, tools, isOpend }: Props) {
|
|||||||
<Accordion.AccordionItem value={href}>
|
<Accordion.AccordionItem value={href}>
|
||||||
<Accordion.Header asChild>
|
<Accordion.Header asChild>
|
||||||
<div className="relative flex">
|
<div className="relative flex">
|
||||||
<ToolLink
|
<div className="flex-1">
|
||||||
className="flex-1"
|
<ToolLink
|
||||||
{...{ Icon, href, onClick }}
|
{...{ Icon, href, onClick }}
|
||||||
shortTitle={title}
|
shortTitle={title}
|
||||||
highlight={
|
highlight={
|
||||||
pathname === href
|
pathname === href
|
||||||
? "both"
|
? "both"
|
||||||
: !isOpend && pathname.startsWith(`${href}/`)
|
: !isOpend && pathname.startsWith(`${href}/`)
|
||||||
? "indicatorOnly"
|
? "indicatorOnly"
|
||||||
: "none"
|
: "none"
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
<Accordion.Trigger
|
<Accordion.Trigger
|
||||||
ref={triggerRef}
|
ref={triggerRef}
|
||||||
className={cn(
|
className={cn(
|
||||||
@@ -61,10 +61,9 @@ export function ToolGroup({ Icon, title, href, tools, isOpend }: Props) {
|
|||||||
{Object.values(tools).map(tool => (
|
{Object.values(tools).map(tool => (
|
||||||
<li className="mt-1" key={tool.href}>
|
<li className="mt-1" key={tool.href}>
|
||||||
<ToolLink
|
<ToolLink
|
||||||
// -outline-offset-1: ugly hack for Chrome outlines
|
|
||||||
className="pl-8 -outline-offset-1"
|
|
||||||
{...tool}
|
{...tool}
|
||||||
highlight={isOpend && pathname === tool.href ? "both" : "none"}
|
highlight={isOpend && pathname === tool.href ? "both" : "none"}
|
||||||
|
grouped
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -8,22 +8,24 @@ import { cn } from "@/lib/style";
|
|||||||
import { Indicator } from "@/components/indicator";
|
import { Indicator } from "@/components/indicator";
|
||||||
|
|
||||||
type Props = Pick<Tool, "Icon" | "shortTitle"> &
|
type Props = Pick<Tool, "Icon" | "shortTitle"> &
|
||||||
Pick<LinkProps<unknown>, "className" | "href" | "onClick"> & {
|
Pick<LinkProps<unknown>, "href" | "onClick"> & {
|
||||||
highlight: "both" | "indicatorOnly" | "none";
|
highlight: "both" | "indicatorOnly" | "none";
|
||||||
|
grouped?: true;
|
||||||
};
|
};
|
||||||
|
|
||||||
function RawToolLink({ Icon, shortTitle: title, href, onClick, className, highlight }: Props) {
|
// FIXME: css outline messed up
|
||||||
|
function RawToolLink({ Icon, shortTitle: title, href, onClick, highlight, grouped }: Props) {
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex h-10 items-center gap-3 rounded",
|
"flex h-10 items-center gap-3 rounded",
|
||||||
highlight === "both" && "bg-accent",
|
highlight === "both" && "bg-accent",
|
||||||
"hover:bg-accent",
|
grouped && "pl-8 -outline-offset-1", // -outline-offset-1: ugly hack for Chrome outlines
|
||||||
className
|
"hover:bg-accent"
|
||||||
)}
|
)}
|
||||||
{...{ href, onClick }}
|
{...{ href, onClick }}
|
||||||
>
|
>
|
||||||
<span className={cn("invisible flex items-center", highlight !== "none" && "visible")}>
|
<span className={cn("flex items-center", highlight === "none" && "invisible")}>
|
||||||
<Indicator />
|
<Indicator />
|
||||||
</span>
|
</span>
|
||||||
<span className="flex select-none items-center gap-4">
|
<span className="flex select-none items-center gap-4">
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const RawInput = React.forwardRef<HTMLInputElement, InputProps>(({ className, ..
|
|||||||
<input
|
<input
|
||||||
{...{ ref }}
|
{...{ ref }}
|
||||||
className={cn(
|
className={cn(
|
||||||
"border-b-1 flex h-9 w-full rounded border border-b-muted-foreground bg-input px-3 py-2 font-mono outline-none",
|
"border-b-1 h-9 rounded border border-b-muted-foreground bg-input px-3 py-2 font-mono outline-none",
|
||||||
"placeholder:text-muted-foreground",
|
"placeholder:text-muted-foreground",
|
||||||
"hover:bg-input-hover",
|
"hover:bg-input-hover",
|
||||||
"focus:border-b-2 focus:border-b-indicator focus:bg-input-focus focus:pb-[7px]",
|
"focus:border-b-2 focus:border-b-indicator focus:bg-input-focus focus:pb-[7px]",
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export const RawTextarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
|
|||||||
<textarea
|
<textarea
|
||||||
{...{ ref }}
|
{...{ ref }}
|
||||||
className={cn(
|
className={cn(
|
||||||
"border-b-1 flex w-full resize-none rounded border border-b-muted-foreground bg-textarea px-3 py-2 font-mono outline-none",
|
"border-b-1 resize-none rounded border border-b-muted-foreground bg-textarea px-3 py-2 font-mono outline-none",
|
||||||
"placeholder:text-muted-foreground",
|
"placeholder:text-muted-foreground",
|
||||||
"hover:bg-textarea-hover",
|
"hover:bg-textarea-hover",
|
||||||
"focus:border-b-2 focus:border-b-indicator focus:bg-textarea-focus focus:pb-[7px]",
|
"focus:border-b-2 focus:border-b-indicator focus:bg-textarea-focus focus:pb-[7px]",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { DependencyList, useEffect, useRef } from "react";
|
import { DependencyList, useEffect, useRef } from "react";
|
||||||
|
|
||||||
export const useScrollFollow = <T extends HTMLElement = HTMLElement>(
|
export const useAutoScroll = <T extends HTMLElement = HTMLElement>(
|
||||||
deps: DependencyList,
|
deps: DependencyList,
|
||||||
behavior: ScrollBehavior = "smooth"
|
behavior: ScrollBehavior = "smooth"
|
||||||
) => {
|
) => {
|
||||||
Reference in New Issue
Block a user