mirror of
https://github.com/dsprenkels/backpack.git
synced 2026-01-12 05:17:57 -05:00
70 lines
2.1 KiB
TypeScript
70 lines
2.1 KiB
TypeScript
import { NavLink } from "react-router-dom";
|
|
|
|
const HEADER_PLACEHOLDER = "untitled list"
|
|
const HEADER_MIN_WIDTH = 20
|
|
const HEADER_MAX_WIDTH = 50
|
|
|
|
export function AppContainer(props: {
|
|
children: React.ReactNode,
|
|
}) {
|
|
return <div className="items-center container mx-auto max-w-4xl font-mono text-sm not-print:text-zinc-800 dark:not-print:text-zinc-100">
|
|
{props.children}
|
|
</div>
|
|
}
|
|
|
|
export function HeadNav(props: {
|
|
header: string,
|
|
setHeader: (header: string) => void,
|
|
}) {
|
|
return <div className="flex flex-col items-center">
|
|
<Header header={props.header} setHeader={props.setHeader} />
|
|
<Nav />
|
|
</div>
|
|
}
|
|
|
|
function Header(props: {
|
|
header: string,
|
|
setHeader: (header: string) => void,
|
|
}) {
|
|
const inputFieldGrowPadding = 2
|
|
const border = props.header === "" ? "not-print:border-1 border-gray-400 dark:border-zinc-500" : ""
|
|
return (
|
|
<header className="text-4xl font-bold m-6">
|
|
<input
|
|
className={`text-center p-1 ${border}`}
|
|
size={clamp(HEADER_MIN_WIDTH, props.header.length + inputFieldGrowPadding, HEADER_MAX_WIDTH)}
|
|
value={props.header}
|
|
placeholder={HEADER_PLACEHOLDER}
|
|
onChange={(event) => props.setHeader(event.target.value)}
|
|
/>
|
|
</header>
|
|
)
|
|
}
|
|
|
|
function Nav() {
|
|
const baseClass = "hover:underline text-blue-700 dark:text-blue-300";
|
|
const activeClass = "font-bold";
|
|
const inactiveClass = "";
|
|
const className = ({ isActive }: { isActive: boolean }) =>
|
|
`${baseClass} ${isActive ? activeClass : inactiveClass}`
|
|
|
|
return (
|
|
<nav className="flex justify-center items-center space-x-6 text-lg print:hidden">
|
|
<NavLink
|
|
to="/view"
|
|
className={className}>
|
|
View list
|
|
</NavLink>
|
|
<NavLink
|
|
to="/edit"
|
|
className={className}>
|
|
Edit list
|
|
</NavLink>
|
|
</nav>
|
|
);
|
|
}
|
|
|
|
function clamp(lo: number, x: number, hi: number): number {
|
|
return Math.max(Math.min(x, hi), lo)
|
|
}
|