mirror of
https://github.com/SrIzan10/spongebin.git
synced 2026-05-01 11:05:09 +00:00
121 lines
3.7 KiB
TypeScript
121 lines
3.7 KiB
TypeScript
"use client";
|
|
|
|
import { WrapText } from "lucide-react";
|
|
import Link from "next/link";
|
|
import { useEditor } from "./editor-provider";
|
|
import { EditorTabs } from "./editor-tabs";
|
|
import { Button, buttonVariants } from "~/components/ui/button";
|
|
import { SearchableSelect } from "./searchable-select";
|
|
import { LANGUAGES, LANGUAGES_SET, type LanguageName } from "~/utils/languages";
|
|
import { THEME_MAP } from "~/utils/themes";
|
|
import { SaveButton } from "./save-button";
|
|
import { Icons } from "./icons";
|
|
import { cn } from "~/utils/cn";
|
|
|
|
function LanguageThemeControls() {
|
|
const { activeTab, theme, updateActiveTabLanguage, setTheme } = useEditor();
|
|
|
|
const setLanguage = (language: string) => {
|
|
if (LANGUAGES_SET.has(language as LanguageName))
|
|
updateActiveTabLanguage(language as LanguageName);
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<SearchableSelect
|
|
options={LANGUAGES.map((language) => ({
|
|
value: language,
|
|
label: language,
|
|
}))}
|
|
placeholder="language"
|
|
value={activeTab.language}
|
|
onValueChange={setLanguage}
|
|
onPreview={setLanguage}
|
|
className="w-full min-w-0 sm:w-40"
|
|
/>
|
|
|
|
<SearchableSelect
|
|
options={Object.keys(THEME_MAP).map((currentTheme) => ({
|
|
value: currentTheme,
|
|
label: currentTheme,
|
|
}))}
|
|
placeholder="theme"
|
|
value={theme}
|
|
onValueChange={setTheme}
|
|
onPreview={setTheme}
|
|
className="w-full min-w-0 sm:w-52"
|
|
/>
|
|
</>
|
|
);
|
|
}
|
|
|
|
export function Header() {
|
|
const { tabs, theme, wordWrap, setWordWrap } = useEditor();
|
|
|
|
return (
|
|
<>
|
|
<header className="border-border/70 bg-background shrink-0 border-b">
|
|
<div className="flex flex-col gap-2 px-4 py-2 sm:flex-row sm:items-center sm:py-3">
|
|
<div className="grid w-full grid-cols-6 gap-2 sm:flex sm:w-auto sm:shrink-0">
|
|
<Link
|
|
className={cn(
|
|
buttonVariants({ variant: "outline" }),
|
|
"col-span-1 p-2 sm:w-auto",
|
|
)}
|
|
href="https://github.com/durocodes/spongebin"
|
|
>
|
|
<Icons.GitHub className="mx-auto h-4 w-4" />
|
|
</Link>
|
|
|
|
<Button
|
|
type="button"
|
|
variant="outline"
|
|
onClick={() => setWordWrap(!wordWrap)}
|
|
className={cn(
|
|
"col-span-1 p-2 sm:w-auto",
|
|
wordWrap &&
|
|
"bg-accent text-accent-foreground hover:bg-accent hover:text-accent-foreground",
|
|
)}
|
|
aria-pressed={wordWrap}
|
|
aria-label={wordWrap ? "Disable word wrap" : "Enable word wrap"}
|
|
title="Word wrap"
|
|
>
|
|
<WrapText className="mx-auto h-4 w-4" />
|
|
</Button>
|
|
|
|
<Button
|
|
variant="outline"
|
|
onClick={() => (location.href = "/")}
|
|
className="col-span-2 sm:w-auto"
|
|
>
|
|
new
|
|
</Button>
|
|
|
|
<SaveButton
|
|
tabs={tabs}
|
|
theme={theme}
|
|
className="col-span-2 sm:w-auto"
|
|
/>
|
|
</div>
|
|
|
|
<div className="w-full min-w-0 sm:flex-1">
|
|
<EditorTabs />
|
|
</div>
|
|
|
|
<div className="hidden sm:ml-2 sm:flex sm:w-auto sm:shrink-0 sm:gap-2">
|
|
<LanguageThemeControls />
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<div
|
|
className="fixed bottom-0 left-0 right-0 z-40 grid grid-cols-2 gap-2 border-t border-border/70 bg-background/95 px-4 pt-2 pb-[max(0.5rem,env(safe-area-inset-bottom))] backdrop-blur supports-[backdrop-filter]:bg-background/80 sm:hidden"
|
|
role="region"
|
|
aria-label="Language and theme"
|
|
>
|
|
<LanguageThemeControls />
|
|
</div>
|
|
</>
|
|
);
|
|
}
|