Browse Source

Minor style fixes

pull/596/head
philon- 1 year ago
parent
commit
a02579d6dd
  1. 233
      src/components/Sidebar.tsx
  2. 14
      src/components/UI/Checkbox/index.tsx
  3. 38
      src/components/UI/Sidebar/SidebarSection.tsx

233
src/components/Sidebar.tsx

@ -46,26 +46,34 @@ const CollapseToggleButton = () => {
aria-label={buttonLabel} aria-label={buttonLabel}
onClick={toggleSidebar} onClick={toggleSidebar}
className={cn( className={cn(
'absolute top-20 right-0 z-10 p-0.5 rounded-full transform translate-x-1/2', "absolute top-20 right-0 z-10 p-0.5 rounded-full transform translate-x-1/2",
'transition-colors duration-300 ease-in-out', "transition-colors duration-300 ease-in-out",
'border border-slate-300 dark:border-slate-200', "border border-slate-300 dark:border-slate-200",
'text-slate-500 dark:text-slate-200 hover:text-slate-400 dark:hover:text-slate-400', "text-slate-500 dark:text-slate-200 hover:text-slate-400 dark:hover:text-slate-400",
'focus:outline-none focus:ring-2 focus:ring-accent transition-transform' "focus:outline-none focus:ring-2 focus:ring-accent transition-transform bg-background-primary",
)} )}
> >
<CircleChevronLeft <CircleChevronLeft
size={24} size={24}
className={cn( className={cn(
'transition-transform duration-300 ease-in-out', "transition-transform duration-300 ease-in-out",
isCollapsed && 'rotate-180' isCollapsed && "rotate-180",
)} )}
/> />
</button> </button>
); );
} };
export const Sidebar = ({ children }: SidebarProps) => { export const Sidebar = ({ children }: SidebarProps) => {
const { hardware, getNode, getNodesLength, metadata, activePage, setActivePage, setDialogOpen } = useDevice(); const {
hardware,
getNode,
getNodesLength,
metadata,
activePage,
setActivePage,
setDialogOpen,
} = useDevice();
const { setCommandPaletteOpen } = useAppStore(); const { setCommandPaletteOpen } = useAppStore();
const myNode = getNode(hardware.myNodeNum); const myNode = getNode(hardware.myNodeNum);
const { isCollapsed } = useSidebar(); const { isCollapsed } = useSidebar();
@ -86,19 +94,18 @@ export const Sidebar = ({ children }: SidebarProps) => {
return ( return (
<div <div
className={cn( className={cn(
'relative border-slate-300 dark:border-slate-700', "relative border-slate-300 dark:border-slate-700",
'transition-all duration-300 ease-in-out flex-shrink-0', "transition-all duration-300 ease-in-out flex-shrink-0",
isCollapsed ? 'w-24' : 'w-46 lg:w-64' isCollapsed ? "w-24" : "w-46 lg:w-64",
)} )}
> >
<CollapseToggleButton /> <CollapseToggleButton />
<div <div
className={cn( className={cn(
'h-14 flex mt-2 gap-2 items-center flex-shrink-0 transition-all duration-300 ease-in-out', "h-14 flex mt-2 gap-2 items-center flex-shrink-0 transition-all duration-300 ease-in-out",
'border-b-[0.5px] border-slate-300 dark:border-slate-700', "border-b-[0.5px] border-slate-300 dark:border-slate-700",
isCollapsed && 'justify-center px-0' isCollapsed && "justify-center px-0",
)} )}
> >
<img <img
@ -108,11 +115,11 @@ export const Sidebar = ({ children }: SidebarProps) => {
/> />
<h2 <h2
className={cn( className={cn(
'text-xl font-semibold text-gray-800 dark:text-gray-100 whitespace-nowrap', "text-xl font-semibold text-gray-800 dark:text-gray-100 whitespace-nowrap",
'transition-all duration-300 ease-in-out', "transition-all duration-300 ease-in-out",
isCollapsed isCollapsed
? 'opacity-0 max-w-0 invisible ml-0' ? "opacity-0 max-w-0 invisible ml-0"
: 'opacity-100 max-w-xs visible ml-2' : "opacity-100 max-w-xs visible ml-2",
)} )}
> >
Meshtastic Meshtastic
@ -136,106 +143,116 @@ export const Sidebar = ({ children }: SidebarProps) => {
))} ))}
</SidebarSection> </SidebarSection>
<div className={cn( <div
'flex-1 min-h-0', className={cn(
isCollapsed && 'overflow-hidden' "flex-1 min-h-0",
)} isCollapsed && "overflow-hidden",
)}
> >
{children} {children}
</div> </div>
<div className="pt-4 border-t-[0.5px] bg-background-primary border-slate-300 dark:border-slate-700 flex-shrink-0"> <div className="pt-4 border-t-[0.5px] bg-background-primary border-slate-300 dark:border-slate-700 flex-shrink-0">
{myNode === undefined ? ( {myNode === undefined
<div className="flex flex-col items-center justify-center py-6"> ? (
<Spinner /> <div className="flex flex-col items-center justify-center py-6">
<Subtle <Spinner />
className={cn( <Subtle
'mt-4 transition-opacity duration-300',
isCollapsed ? 'opacity-0 invisible' : 'opacity-100 visible'
)}
>
Loading...
</Subtle>
</div>
) : (
<>
<div
className={cn(
'flex place-items-center gap-2',
isCollapsed && 'justify-center'
)}
>
<Avatar
text={myNode.user?.shortName ?? myNode.num.toString()}
className={cn("flex-shrink-0 ml-2",
isCollapsed && "ml-0",
)}
size="sm"
/>
<p
className={cn( className={cn(
'max-w-[20ch] text-wrap text-sm font-medium', "mt-4 transition-opacity duration-300",
'transition-all duration-300 ease-in-out overflow-hidden', isCollapsed ? "opacity-0 invisible" : "opacity-100 visible",
isCollapsed
? 'opacity-0 max-w-0 invisible'
: 'opacity-100 max-w-full visible'
)} )}
> >
{myNode.user?.longName} Loading...
</p> </Subtle>
</div> </div>
)
<div : (
className={cn( <>
'flex flex-col gap-0.5 ml-2 mt-2', <div
'transition-all duration-300 ease-in-out', className={cn(
isCollapsed "flex place-items-center gap-2",
? 'opacity-0 max-w-0 h-0 invisible' isCollapsed && "justify-center",
: 'opacity-100 max-w-xs h-auto visible' )}
)} >
> <Avatar
<div className="inline-flex gap-2"> text={myNode.user?.shortName ?? myNode.num.toString()}
<BatteryStatus deviceMetrics={myNode.deviceMetrics} /> className={cn("flex-shrink-0 ml-2", isCollapsed && "ml-0")}
</div> size="sm"
<div className="inline-flex gap-2"> />
<ZapIcon size={18} className="text-gray-500 dark:text-gray-400 w-4 flex-shrink-0" /> <p
<Subtle>{myNode.deviceMetrics?.voltage?.toPrecision(3) ?? "UNK"} volts</Subtle> className={cn(
</div> "max-w-[20ch] text-wrap text-sm font-medium",
<div className="inline-flex gap-2"> "transition-all duration-300 ease-in-out overflow-hidden",
<CpuIcon size={18} className="text-gray-500 dark:text-gray-400 w-4 flex-shrink-0" /> isCollapsed
<Subtle>v{myMetadata?.firmwareVersion ?? "UNK"}</Subtle> ? "opacity-0 max-w-0 invisible"
: "opacity-100 max-w-full visible",
)}
>
{myNode.user?.longName}
</p>
</div> </div>
</div>
<div <div
className={cn( className={cn(
'flex items-center flex-shrink-0 ml-2', "flex flex-col gap-0.5 ml-2 mt-2",
'transition-all duration-300 ease-in-out', "transition-all duration-300 ease-in-out",
isCollapsed isCollapsed
? 'opacity-0 max-w-0 invisible pointer-events-none' ? "opacity-0 max-w-0 h-0 invisible"
: 'opacity-100 max-w-xs visible' : "opacity-100 max-w-xs h-auto visible",
)} )}
>
<button
type="button"
aria-label="Edit device name"
className="p-1 rounded transition-colors hover:text-accent"
onClick={() => setDialogOpen("deviceName", true)}
> >
<PenLine size={22} /> <div className="inline-flex gap-2">
</button> <BatteryStatus deviceMetrics={myNode.deviceMetrics} />
<ThemeSwitcher /> </div>
<button <div className="inline-flex gap-2">
type="button" <ZapIcon
className="transition-all hover:text-accent" size={18}
onClick={() => setCommandPaletteOpen(true)} className="text-gray-500 dark:text-gray-400 w-4 flex-shrink-0"
/>
<Subtle>
{myNode.deviceMetrics?.voltage?.toPrecision(3) ?? "UNK"}
{" "}
volts
</Subtle>
</div>
<div className="inline-flex gap-2">
<CpuIcon
size={18}
className="text-gray-500 dark:text-gray-400 w-4 flex-shrink-0"
/>
<Subtle>v{myMetadata?.firmwareVersion ?? "UNK"}</Subtle>
</div>
</div>
<div
className={cn(
"flex items-center flex-shrink-0 ml-2",
"transition-all duration-300 ease-in-out",
isCollapsed
? "opacity-0 max-w-0 invisible pointer-events-none"
: "opacity-100 max-w-xs visible",
)}
> >
<SearchIcon /> <button
</button> type="button"
</div> aria-label="Edit device name"
className="p-1 rounded transition-colors hover:text-accent"
</> onClick={() => setDialogOpen("deviceName", true)}
)} >
<PenLine size={22} />
</button>
<ThemeSwitcher />
<button
type="button"
className="transition-all hover:text-accent"
onClick={() => setCommandPaletteOpen(true)}
>
<SearchIcon />
</button>
</div>
</>
)}
</div> </div>
</div> </div>
); );
}; };

14
src/components/UI/Checkbox/index.tsx

@ -1,4 +1,4 @@
import { useState, useEffect, useId } from "react"; import { useEffect, useId, useState } from "react";
import { Check } from "lucide-react"; import { Check } from "lucide-react";
import { Label } from "@components/UI/Label.tsx"; import { Label } from "@components/UI/Label.tsx";
import { cn } from "@core/utils/cn.ts"; import { cn } from "@core/utils/cn.ts";
@ -65,13 +65,15 @@ export function Checkbox({
role="presentation" role="presentation"
className={cn( className={cn(
"w-6 h-6 border-2 border-gray-500 rounded-md flex items-center justify-center", "w-6 h-6 border-2 border-gray-500 rounded-md flex items-center justify-center",
disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2", disabled
isChecked ? "" : "" ? "opacity-50 cursor-not-allowed"
: "cursor-pointer focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2",
isChecked ? "" : "",
)} )}
> >
{isChecked && ( {isChecked && (
<div className="animate-fade-in scale-100 opacity-100"> <div className="animate-fade-in scale-100 opacity-100">
<Check className="w-4 h-4 text-slate-900 dark:text-slate-200" /> <Check className="w-4 h-4" />
</div> </div>
)} )}
</div> </div>
@ -85,7 +87,7 @@ export function Checkbox({
className={cn( className={cn(
"text-gray-900 dark:text-gray-900", "text-gray-900 dark:text-gray-900",
disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer", disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer",
labelClassName labelClassName,
)} )}
> >
{children} {children}
@ -95,4 +97,4 @@ export function Checkbox({
</div> </div>
</div> </div>
); );
} }

38
src/components/UI/Sidebar/SidebarSection.tsx

@ -16,27 +16,31 @@ export const SidebarSection = ({
}: SidebarSectionProps) => { }: SidebarSectionProps) => {
const { isCollapsed } = useSidebar(); const { isCollapsed } = useSidebar();
return ( return (
<div className={cn( <div
"py-2", className={cn(
isCollapsed ? 'px-0' : 'px-4', "py-2",
className, isCollapsed ? "px-0" : "px-4",
)}> className,
)}
<Heading as="h3" className={cn( >
'mb-2', <Heading
'uppercase tracking-wider text-md', as="h3"
'transition-all duration-300 ease-in-out', className={cn(
'whitespace-nowrap overflow-hidden', "mb-2",
isCollapsed "uppercase tracking-wider text-md",
? 'opacity-0 max-w-0 h-0 invisible px-0 mb-0' "transition-all duration-300 ease-in-out",
: 'opacity-100 max-w-xs h-auto visible px-1 mb-1' "whitespace-nowrap overflow-hidden",
)}> isCollapsed
? "opacity-0 max-w-0 h-0 invisible px-0 mb-0"
: "opacity-100 max-w-xs h-auto visible px-1 mb-1",
)}
>
{label} {label}
</Heading> </Heading>
<div className="space-y-0.5"> <div className="space-y-1">
{children} {children}
</div> </div>
</div> </div>
); );
}; };

Loading…
Cancel
Save