Browse Source

Merge pull request #596 from philon-/style-fixes

Minor style fixes
pull/599/head
Dan Ditomaso 1 year ago
committed by GitHub
parent
commit
cfcc9f82d8
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  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}
onClick={toggleSidebar}
className={cn(
'absolute top-20 right-0 z-10 p-0.5 rounded-full transform translate-x-1/2',
'transition-colors duration-300 ease-in-out',
'border border-slate-300 dark:border-slate-200',
'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'
"absolute top-20 right-0 z-10 p-0.5 rounded-full transform translate-x-1/2",
"transition-colors duration-300 ease-in-out",
"border border-slate-300 dark:border-slate-200",
"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 bg-background-primary",
)}
>
<CircleChevronLeft
size={24}
className={cn(
'transition-transform duration-300 ease-in-out',
isCollapsed && 'rotate-180'
"transition-transform duration-300 ease-in-out",
isCollapsed && "rotate-180",
)}
/>
</button>
);
}
};
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 myNode = getNode(hardware.myNodeNum);
const { isCollapsed } = useSidebar();
@ -86,19 +94,18 @@ export const Sidebar = ({ children }: SidebarProps) => {
return (
<div
className={cn(
'relative border-slate-300 dark:border-slate-700',
'transition-all duration-300 ease-in-out flex-shrink-0',
isCollapsed ? 'w-24' : 'w-46 lg:w-64'
"relative border-slate-300 dark:border-slate-700",
"transition-all duration-300 ease-in-out flex-shrink-0",
isCollapsed ? "w-24" : "w-46 lg:w-64",
)}
>
<CollapseToggleButton />
<div
className={cn(
'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',
isCollapsed && 'justify-center px-0'
"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",
isCollapsed && "justify-center px-0",
)}
>
<img
@ -108,11 +115,11 @@ export const Sidebar = ({ children }: SidebarProps) => {
/>
<h2
className={cn(
'text-xl font-semibold text-gray-800 dark:text-gray-100 whitespace-nowrap',
'transition-all duration-300 ease-in-out',
"text-xl font-semibold text-gray-800 dark:text-gray-100 whitespace-nowrap",
"transition-all duration-300 ease-in-out",
isCollapsed
? 'opacity-0 max-w-0 invisible ml-0'
: 'opacity-100 max-w-xs visible ml-2'
? "opacity-0 max-w-0 invisible ml-0"
: "opacity-100 max-w-xs visible ml-2",
)}
>
Meshtastic
@ -136,106 +143,116 @@ export const Sidebar = ({ children }: SidebarProps) => {
))}
</SidebarSection>
<div className={cn(
'flex-1 min-h-0',
isCollapsed && 'overflow-hidden'
)}
<div
className={cn(
"flex-1 min-h-0",
isCollapsed && "overflow-hidden",
)}
>
{children}
</div>
<div className="pt-4 border-t-[0.5px] bg-background-primary border-slate-300 dark:border-slate-700 flex-shrink-0">
{myNode === undefined ? (
<div className="flex flex-col items-center justify-center py-6">
<Spinner />
<Subtle
className={cn(
'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
{myNode === undefined
? (
<div className="flex flex-col items-center justify-center py-6">
<Spinner />
<Subtle
className={cn(
'max-w-[20ch] text-wrap text-sm font-medium',
'transition-all duration-300 ease-in-out overflow-hidden',
isCollapsed
? 'opacity-0 max-w-0 invisible'
: 'opacity-100 max-w-full visible'
"mt-4 transition-opacity duration-300",
isCollapsed ? "opacity-0 invisible" : "opacity-100 visible",
)}
>
{myNode.user?.longName}
</p>
Loading...
</Subtle>
</div>
<div
className={cn(
'flex flex-col gap-0.5 ml-2 mt-2',
'transition-all duration-300 ease-in-out',
isCollapsed
? 'opacity-0 max-w-0 h-0 invisible'
: 'opacity-100 max-w-xs h-auto visible'
)}
>
<div className="inline-flex gap-2">
<BatteryStatus deviceMetrics={myNode.deviceMetrics} />
</div>
<div className="inline-flex gap-2">
<ZapIcon size={18} 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
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(
"max-w-[20ch] text-wrap text-sm font-medium",
"transition-all duration-300 ease-in-out overflow-hidden",
isCollapsed
? "opacity-0 max-w-0 invisible"
: "opacity-100 max-w-full visible",
)}
>
{myNode.user?.longName}
</p>
</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'
)}
>
<button
type="button"
aria-label="Edit device name"
className="p-1 rounded transition-colors hover:text-accent"
onClick={() => setDialogOpen("deviceName", true)}
<div
className={cn(
"flex flex-col gap-0.5 ml-2 mt-2",
"transition-all duration-300 ease-in-out",
isCollapsed
? "opacity-0 max-w-0 h-0 invisible"
: "opacity-100 max-w-xs h-auto visible",
)}
>
<PenLine size={22} />
</button>
<ThemeSwitcher />
<button
type="button"
className="transition-all hover:text-accent"
onClick={() => setCommandPaletteOpen(true)}
<div className="inline-flex gap-2">
<BatteryStatus deviceMetrics={myNode.deviceMetrics} />
</div>
<div className="inline-flex gap-2">
<ZapIcon
size={18}
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>
</div>
</>
)}
<button
type="button"
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>
);
};
};

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 { Label } from "@components/UI/Label.tsx";
import { cn } from "@core/utils/cn.ts";
@ -65,13 +65,15 @@ export function Checkbox({
role="presentation"
className={cn(
"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",
isChecked ? "" : ""
disabled
? "opacity-50 cursor-not-allowed"
: "cursor-pointer focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2",
isChecked ? "" : "",
)}
>
{isChecked && (
<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>
@ -85,7 +87,7 @@ export function Checkbox({
className={cn(
"text-gray-900 dark:text-gray-900",
disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer",
labelClassName
labelClassName,
)}
>
{children}
@ -95,4 +97,4 @@ export function Checkbox({
</div>
</div>
);
}
}

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

@ -16,27 +16,31 @@ export const SidebarSection = ({
}: SidebarSectionProps) => {
const { isCollapsed } = useSidebar();
return (
<div className={cn(
"py-2",
isCollapsed ? 'px-0' : 'px-4',
className,
)}>
<Heading as="h3" className={cn(
'mb-2',
'uppercase tracking-wider text-md',
'transition-all duration-300 ease-in-out',
'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'
)}>
<div
className={cn(
"py-2",
isCollapsed ? "px-0" : "px-4",
className,
)}
>
<Heading
as="h3"
className={cn(
"mb-2",
"uppercase tracking-wider text-md",
"transition-all duration-300 ease-in-out",
"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}
</Heading>
<div className="space-y-0.5">
<div className="space-y-1">
{children}
</div>
</div>
);
};
};

Loading…
Cancel
Save