mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2026-04-20 06:28:14 -04:00
refactor progress
This commit is contained in:
@@ -20,9 +20,9 @@ export function AppLayout() {
|
||||
<div
|
||||
className={clsx(
|
||||
// App level styles
|
||||
'flex flex-row overflow-hidden text-ink select-none cursor-default',
|
||||
os === 'macOS' && 'rounded-xl has-blur-effects',
|
||||
os !== 'browser' && os !== 'windows' && 'border border-app-divider'
|
||||
'flex overflow-hidden text-ink select-none cursor-default',
|
||||
os === 'macOS' && 'rounded-[10px] has-blur-effects',
|
||||
os !== 'browser' && os !== 'windows' && 'border border-app-divider/30'
|
||||
)}
|
||||
onContextMenu={(e) => {
|
||||
// TODO: allow this on some UI text at least / disable default browser context menu
|
||||
@@ -31,7 +31,7 @@ export function AppLayout() {
|
||||
}}
|
||||
>
|
||||
<Sidebar />
|
||||
<div className="relative flex w-full h-screen max-h-screen">
|
||||
<div className="relative flex w-full">
|
||||
<Suspense>
|
||||
<Outlet />
|
||||
</Suspense>
|
||||
|
||||
@@ -35,10 +35,10 @@ export default function Explorer(props: Props) {
|
||||
return (
|
||||
<div className="relative">
|
||||
<ExplorerContextMenu>
|
||||
<div className="relative flex flex-col w-full bg-app">
|
||||
<div className="relative flex flex-col w-full">
|
||||
<TopBar showSeparator={separateTopBar} />
|
||||
|
||||
<div className="relative flex flex-row w-full max-h-full app-bg">
|
||||
<div className="relative flex flex-row w-full max-h-full app-background">
|
||||
{props.data && (
|
||||
<VirtualizedList
|
||||
data={props.data.items || []}
|
||||
|
||||
@@ -4,11 +4,11 @@ import { PropsWithChildren, useState } from 'react';
|
||||
import Slider from '../primitive/Slider';
|
||||
|
||||
function Heading({ children }: PropsWithChildren) {
|
||||
return <div className="text-xs font-semibold text-gray-300">{children}</div>;
|
||||
return <div className="text-xs font-semibold text-ink-dull">{children}</div>;
|
||||
}
|
||||
|
||||
function SubHeading({ children }: PropsWithChildren) {
|
||||
return <div className="mb-1 text-xs font-medium text-gray-300">{children}</div>;
|
||||
return <div className="mb-1 text-xs font-medium text-ink-dull">{children}</div>;
|
||||
}
|
||||
|
||||
export function ExplorerOptionsPanel() {
|
||||
|
||||
@@ -51,17 +51,16 @@ const TopBarButton = forwardRef<HTMLButtonElement, TopBarButtonProps>(
|
||||
{...props}
|
||||
ref={ref}
|
||||
className={clsx(
|
||||
'mr-[1px] flex py-0.5 px-0.5 text-md font-medium hover:bg-gray-150 dark:transparent dark:hover:bg-gray-550 rounded-md open:dark:bg-gray-550 transition-colors duration-100 outline-none !cursor-normal',
|
||||
'mr-[1px] flex py-0.5 px-0.5 text-md font-medium rounded-md open:bg-selected transition-colors duration-100 outline-none !cursor-normal',
|
||||
{
|
||||
'rounded-r-none rounded-l-none': group && !left && !right,
|
||||
'rounded-r-none': group && left,
|
||||
'rounded-l-none': group && right,
|
||||
'dark:bg-gray-550': active
|
||||
'rounded-l-none': group && right
|
||||
},
|
||||
className
|
||||
)}
|
||||
>
|
||||
<Icon weight={'regular'} className="m-0.5 w-5 h-5 text-gray-450 dark:text-gray-150" />
|
||||
<Icon weight={'regular'} className="m-0.5 w-5 h-5 text-ink-dull" />
|
||||
</button>
|
||||
);
|
||||
}
|
||||
@@ -95,7 +94,7 @@ const SearchBar = forwardRef<HTMLInputElement, DefaultProps>((props, forwardedRe
|
||||
else if (forwardedRef) forwardedRef.current = el;
|
||||
}}
|
||||
placeholder="Search"
|
||||
className="peer w-32 h-[30px] focus:w-52 text-sm p-3 rounded-lg outline-none focus:ring-2 placeholder-gray-400 dark:placeholder-gray-450 bg-[#F6F2F6] border border-gray-50 shadow dark:shadow-gray-900/30 dark:bg-gray-600/70 dark:border-gray-550 focus:ring-gray-100 dark:focus:ring-gray-550 dark:focus:bg-gray-800 transition-all"
|
||||
className="peer w-32 h-[30px] focus:w-52 text-sm p-3 rounded-lg outline-none focus:ring-2 border shadow transition-all bg-app-input border-app-border"
|
||||
{...searchField}
|
||||
/>
|
||||
|
||||
@@ -219,7 +218,7 @@ export const TopBar: React.FC<TopBarProps> = (props) => {
|
||||
// in case you wanna turn it back on
|
||||
// honestly its just work to revert
|
||||
className={clsx(
|
||||
'flex h-[2.95rem] -mt-0.5 max-w z-10 pl-3 flex-shrink-0 items-center border-transparent border-b app-bg overflow-hidden rounded-tl-md transition-[background-color] transition-[border-color] duration-250 ease-out',
|
||||
'flex h-[2.95rem] -mt-0.5 max-w z-10 pl-3 flex-shrink-0 items-center border-transparent border-b app-background overflow-hidden rounded-tl-md transition-[background-color] transition-[border-color] duration-250 ease-out',
|
||||
props.showSeparator && 'top-bar-blur'
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -40,7 +40,7 @@ function FileItem({ data, selected, index, ...rest }: Props) {
|
||||
className={clsx(
|
||||
'border-2 border-transparent rounded-lg text-center mb-1 active:translate-y-[1px]',
|
||||
{
|
||||
'bg-gray-50 dark:bg-gray-750/50': selected
|
||||
'bg-app-selected/30': selected
|
||||
}
|
||||
)}
|
||||
>
|
||||
@@ -51,15 +51,15 @@ function FileItem({ data, selected, index, ...rest }: Props) {
|
||||
>
|
||||
<FileThumb
|
||||
className={clsx(
|
||||
'border-4 border-gray-250 shadow shadow-gray-750 object-cover max-w-full max-h-full w-auto overflow-hidden',
|
||||
isVid && 'border-gray-950 rounded border-x-0 border-y-[9px]'
|
||||
'border-4 border-gray-250 shadow shadow-black/40 object-cover max-w-full max-h-full w-auto overflow-hidden',
|
||||
isVid && 'border-black rounded border-x-0 border-y-[9px]'
|
||||
)}
|
||||
data={data}
|
||||
kind={data.extension === 'zip' ? 'zip' : isVid ? 'video' : 'other'}
|
||||
size={getExplorerStore().gridItemSize}
|
||||
/>
|
||||
{data?.extension && isVid && (
|
||||
<div className="absolute bottom-4 font-semibold opacity-70 right-2 py-0.5 px-1 text-[9px] uppercase bg-gray-800 rounded">
|
||||
<div className="absolute bottom-4 font-semibold opacity-70 right-2 py-0.5 px-1 text-[9px] uppercase bg-black/60 rounded">
|
||||
{data.extension}
|
||||
</div>
|
||||
)}
|
||||
@@ -68,9 +68,9 @@ function FileItem({ data, selected, index, ...rest }: Props) {
|
||||
<div className="flex justify-center">
|
||||
<span
|
||||
className={clsx(
|
||||
'px-1.5 py-[1px] truncate text-center rounded-md text-xs font-medium text-gray-550 dark:text-gray-300 cursor-default ',
|
||||
'px-1.5 py-[1px] truncate text-center rounded-md text-xs font-medium text-gray-550 cursor-default ',
|
||||
{
|
||||
'bg-primary !text-white': selected
|
||||
'bg-accent !text-white': selected
|
||||
}
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -16,7 +16,7 @@ function FileRow({ data, index, selected, ...props }: Props) {
|
||||
{...props}
|
||||
className={clsx(
|
||||
'table-body-row mr-2 flex w-full flex-row rounded-lg border-2',
|
||||
selected ? 'border-primary-500' : 'border-transparent',
|
||||
selected ? 'border-accent' : 'border-transparent',
|
||||
index % 2 == 0 && 'bg-[#00000006] dark:bg-[#00000030]'
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -78,11 +78,11 @@ export default function FileThumb({ data, ...props }: Props) {
|
||||
>
|
||||
<svg
|
||||
// BACKGROUND
|
||||
className="absolute -translate-x-1/2 -translate-y-1/2 pointer-events-none top-1/2 left-1/2 fill-gray-150 dark:fill-gray-550"
|
||||
className="absolute -translate-x-1/2 -translate-y-1/2 pointer-events-none top-1/2 left-1/2 fill-app-box"
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 65 81"
|
||||
style={{ filter: 'drop-shadow(0px 5px 2px rgb(0 0 0 / 0.05))' }}
|
||||
style={{ filter: 'drop-shadow(0px 2px 1px rgb(0 0 0 / 0.15))' }}
|
||||
>
|
||||
<path d="M0 8C0 3.58172 3.58172 0 8 0H39.6863C41.808 0 43.8429 0.842855 45.3431 2.34315L53.5 10.5L62.6569 19.6569C64.1571 21.1571 65 23.192 65 25.3137V73C65 77.4183 61.4183 81 57 81H8C3.58172 81 0 77.4183 0 73V8Z" />
|
||||
</svg>
|
||||
@@ -103,8 +103,9 @@ export default function FileThumb({ data, ...props }: Props) {
|
||||
// PEEL
|
||||
width="28%"
|
||||
height="28%"
|
||||
className="absolute top-0 right-0 -translate-x-[35%] z-0 pointer-events-none fill-gray-50 dark:fill-gray-500"
|
||||
viewBox="0 0 41 41"
|
||||
className="absolute top-0 right-0 -translate-x-[40%] z-0 pointer-events-none fill-app-selected"
|
||||
viewBox="0 0 40 40"
|
||||
style={{ filter: 'drop-shadow(-3px 1px 1px rgb(0 0 0 / 0.05))' }}
|
||||
>
|
||||
<path d="M41.4116 40.5577H11.234C5.02962 40.5577 0 35.5281 0 29.3238V0L41.4116 40.5577Z" />
|
||||
</svg>
|
||||
|
||||
@@ -67,7 +67,7 @@ export const Inspector = (props: Props) => {
|
||||
data={props.data}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col w-full pt-0.5 pb-1 overflow-hidden bg-white rounded-lg shadow select-text dark:shadow-gray-800/40 dark:bg-gray-550 dark:bg-opacity-40 border border-gray-550/70">
|
||||
<div className="flex flex-col w-full pt-0.5 pb-1 overflow-hidden bg-app-box/50 rounded-lg shadow select-text shadow-black/40 border border-app-border/30">
|
||||
<h3 className="pt-2 pb-1 pl-3 text-base font-bold">
|
||||
{props.data?.name}
|
||||
{props.data?.extension && `.${props.data.extension}`}
|
||||
|
||||
@@ -1 +1 @@
|
||||
export const Divider = () => <div className="w-full my-1 h-[1px] bg-gray-100 dark:bg-gray-550" />;
|
||||
export const Divider = () => <div className="w-full my-1 h-[1px] bg-app-border" />;
|
||||
|
||||
@@ -8,7 +8,7 @@ export const MetaItem = (props: MetaItemProps) => {
|
||||
<div data-tip={props.value} className="flex flex-col px-4 py-1.5 meta-item">
|
||||
{!!props.title && <h5 className="text-xs font-bold">{props.title}</h5>}
|
||||
{typeof props.value === 'string' ? (
|
||||
<p className="text-xs text-gray-600 break-all truncate dark:text-gray-300">{props.value}</p>
|
||||
<p className="text-xs break-all truncate">{props.value}</p>
|
||||
) : (
|
||||
props.value
|
||||
)}
|
||||
|
||||
@@ -49,11 +49,7 @@ export const Key: React.FC<{ data: Key; index: number }> = ({ data, index }) =>
|
||||
<KeyIcon
|
||||
className={clsx(
|
||||
'w-5 h-5 ml-1 mr-3',
|
||||
data.mounted
|
||||
? data.locked
|
||||
? 'text-primary-600'
|
||||
: 'text-primary-600'
|
||||
: 'text-gray-400/80'
|
||||
data.mounted ? (data.locked ? 'text-accent' : 'text-accent') : 'text-gray-400/80'
|
||||
)}
|
||||
/>
|
||||
<div className="flex flex-col ">
|
||||
|
||||
@@ -2,10 +2,18 @@ import { CogIcon, LockClosedIcon, PhotoIcon } from '@heroicons/react/24/outline'
|
||||
import { PlusIcon } from '@heroicons/react/24/solid';
|
||||
import { useCurrentLibrary, useLibraryMutation, useLibraryQuery, usePlatform } from '@sd/client';
|
||||
import { LocationCreateArgs } from '@sd/client';
|
||||
import { Button, CategoryHeading, Dropdown, OverlayPanel } from '@sd/ui';
|
||||
import { Button, CategoryHeading, Dropdown, OverlayPanel, cva } from '@sd/ui';
|
||||
import { restyle } from '@sd/ui';
|
||||
import { tw } from '@sd/ui';
|
||||
import clsx from 'clsx';
|
||||
import { CheckCircle, CirclesFour, Planet, WaveTriangle } from 'phosphor-react';
|
||||
import {
|
||||
CheckCircle,
|
||||
CirclesFour,
|
||||
Hexagon,
|
||||
Planet,
|
||||
ShareNetwork,
|
||||
WaveTriangle
|
||||
} from 'phosphor-react';
|
||||
import { PropsWithChildren, forwardRef } from 'react';
|
||||
import { NavLink, NavLinkProps, useNavigate } from 'react-router-dom';
|
||||
|
||||
@@ -16,18 +24,21 @@ import { JobsManager } from '../jobs/JobManager';
|
||||
import RunningJobsWidget from '../jobs/RunningJobsWidget';
|
||||
import { MacTrafficLights } from '../os/TrafficLights';
|
||||
|
||||
const sidebarItemClass = cva(
|
||||
'max-w mb-[2px] rounded px-2 py-1 gap-0.5 flex flex-row flex-grow items-center font-medium truncate text-sm',
|
||||
{
|
||||
variants: {
|
||||
isActive: {
|
||||
true: 'bg-sidebar-selected/60'
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
export const SidebarLink = (props: PropsWithChildren<NavLinkProps>) => (
|
||||
<NavLink {...props}>
|
||||
{({ isActive }) => (
|
||||
<span
|
||||
className={clsx(
|
||||
'max-w mb-[2px] text-gray-550 rounded px-2 py-1 flex flex-row flex-grow items-center font-medium text-sm',
|
||||
{
|
||||
'bg-sidebar-selected': isActive
|
||||
},
|
||||
props.className
|
||||
)}
|
||||
>
|
||||
<span className={clsx(sidebarItemClass({ isActive }), props.className)}>
|
||||
{props.children}
|
||||
</span>
|
||||
)}
|
||||
@@ -58,6 +69,8 @@ function WindowControls() {
|
||||
return null;
|
||||
}
|
||||
|
||||
const SidebarCategoryHeading = tw(CategoryHeading)`mt-5 mb-1 ml-1`;
|
||||
|
||||
function LibraryScopedSection() {
|
||||
const os = useOperatingSystem();
|
||||
const platform = usePlatform();
|
||||
@@ -68,7 +81,7 @@ function LibraryScopedSection() {
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<CategoryHeading className="mt-5">Locations</CategoryHeading>
|
||||
<SidebarCategoryHeading>Locations</SidebarCategoryHeading>
|
||||
{locations?.map((location) => {
|
||||
return (
|
||||
<div key={location.id} className="flex flex-row items-center">
|
||||
@@ -79,12 +92,8 @@ function LibraryScopedSection() {
|
||||
}}
|
||||
>
|
||||
{({ isActive }) => (
|
||||
<span
|
||||
className={clsx(
|
||||
'max-w mb-[2px] rounded px-2 py-1 gap-2 flex flex-row flex-grow items-center truncate text-sm'
|
||||
)}
|
||||
>
|
||||
<div className="-mt-0.5 flex-grow-0 flex-shrink-0">
|
||||
<span className={sidebarItemClass({ isActive })}>
|
||||
<div className="-mt-0.5 mr-1 flex-grow-0 flex-shrink-0">
|
||||
<Folder size={18} />
|
||||
</div>
|
||||
|
||||
@@ -114,7 +123,7 @@ function LibraryScopedSection() {
|
||||
});
|
||||
}}
|
||||
className={clsx(
|
||||
'w-full px-2 py-1.5 mt-1 text-xs font-bold text-center text-ink-faint border border-dashed rounded border-sidebar-box cursor-normal transition'
|
||||
'w-full px-2 py-1.5 mt-1 text-xs font-bold text-center text-ink-faint border border-dashed rounded border-sidebar-border cursor-normal transition'
|
||||
// os === 'macOS'
|
||||
// ? 'dark:text-gray-450 dark:border-gray-450 hover:dark:border-gray-400 dark:border-opacity-60'
|
||||
// : 'dark:text-gray-450 dark:border-gray-550 hover:dark:border-gray-500'
|
||||
@@ -126,15 +135,15 @@ function LibraryScopedSection() {
|
||||
</div>
|
||||
{tags?.length ? (
|
||||
<div>
|
||||
<CategoryHeading className="mt-5">Tags</CategoryHeading>
|
||||
<div className="mb-2">
|
||||
<SidebarCategoryHeading>Tags</SidebarCategoryHeading>
|
||||
<div className="mt-1 mb-2">
|
||||
{tags?.slice(0, 6).map((tag, index) => (
|
||||
<SidebarLink key={index} to={`tag/${tag.id}`} className="">
|
||||
<div
|
||||
className="w-[12px] h-[12px] rounded-full"
|
||||
style={{ backgroundColor: tag.color || '#efefef' }}
|
||||
/>
|
||||
<span className="ml-2 text-sm">{tag.name}</span>
|
||||
<span className="ml-1.5 text-sm">{tag.name}</span>
|
||||
</SidebarLink>
|
||||
))}
|
||||
</div>
|
||||
@@ -151,44 +160,41 @@ export function Sidebar() {
|
||||
const os = useOperatingSystem();
|
||||
const { library, libraries, isLoading: isLoadingLibraries, switchLibrary } = useCurrentLibrary();
|
||||
|
||||
const itemStyles = macOnly(os, 'dark:hover:bg-gray-550 dark:hover:bg-opacity-50');
|
||||
// const itemStyles = macOnly(os, 'dark:hover:bg-gray-550 dark:hover:bg-opacity-50');
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
'flex flex-col flex-grow-0 flex-shrink-0 w-48 min-h-full px-2.5 overflow-x-hidden overflow-y-scroll border-r border-sidebar-divider no-scrollbar bg-sidebar/100'
|
||||
// macOnly(os, 'bg-sidebar/30')
|
||||
'flex flex-col flex-grow-0 flex-shrink-0 w-44 min-h-full px-2.5 overflow-x-hidden overflow-y-scroll border-r border-sidebar-divider no-scrollbar bg-sidebar/100',
|
||||
macOnly(os, 'bg-sidebar/80')
|
||||
)}
|
||||
>
|
||||
<WindowControls />
|
||||
|
||||
<Dropdown.Root
|
||||
className="mt-2"
|
||||
itemsClassName="bg-app-box border-sidebar-border"
|
||||
button={
|
||||
<Dropdown.Button
|
||||
variant="gray"
|
||||
className={clsx(
|
||||
`flex w-full text-left max-w-full mb-1 mt-1 -mr-0.5 shadow-xs rounded !bg-gray-50 border-gray-150 hover:!bg-gray-1000 dark:!bg-gray-500 dark:hover:!bg-gray-500 dark:!border-gray-550 dark:hover:!border-gray-500`,
|
||||
(library === null || isLoadingLibraries) && 'text-gray-300',
|
||||
macOnly(
|
||||
os,
|
||||
'dark:!bg-opacity-40 dark:hover:!bg-opacity-70 dark:!border-[#333949] dark:hover:!border-[#394052]'
|
||||
)
|
||||
`w-full mb-1 mt-1 -mr-0.5 shadow-xs rounded`,
|
||||
`!bg-sidebar-box !border-sidebar-border hover:!border-sidebar-selected !text-ink`,
|
||||
(library === null || isLoadingLibraries) && '!text-ink-faint',
|
||||
macOnly(os, '!bg-opacity-80 !border-opacity-40')
|
||||
)}
|
||||
>
|
||||
{/* this shouldn't default to "My Library", it is only this way for landing demo */}
|
||||
<span className="w-32 truncate">
|
||||
<span className="truncate">
|
||||
{isLoadingLibraries ? 'Loading...' : library ? library.config.name : ' '}
|
||||
</span>
|
||||
</Dropdown.Button>
|
||||
}
|
||||
// to support the transparent sidebar on macOS we use slightly adjusted styles
|
||||
itemsClassName={macOnly(os, 'dark:bg-gray-800 dark:divide-gray-600')}
|
||||
// itemsClassName={macOnly(os, 'bg-app/60')}
|
||||
>
|
||||
<Dropdown.Section>
|
||||
{libraries?.map((lib) => (
|
||||
<Dropdown.Item
|
||||
className={itemStyles}
|
||||
selected={lib.uuid === library?.uuid}
|
||||
key={lib.uuid}
|
||||
onClick={() => switchLibrary(lib.uuid)}
|
||||
@@ -198,19 +204,13 @@ export function Sidebar() {
|
||||
))}
|
||||
</Dropdown.Section>
|
||||
<Dropdown.Section>
|
||||
<Dropdown.Item className={itemStyles} icon={CogIcon} to="settings/library">
|
||||
<Dropdown.Item icon={CogIcon} to="settings/library">
|
||||
Library Settings
|
||||
</Dropdown.Item>
|
||||
<CreateLibraryDialog>
|
||||
<Dropdown.Item className={itemStyles} icon={PlusIcon}>
|
||||
Add Library
|
||||
</Dropdown.Item>
|
||||
<Dropdown.Item icon={PlusIcon}>Add Library</Dropdown.Item>
|
||||
</CreateLibraryDialog>
|
||||
<Dropdown.Item
|
||||
className={itemStyles}
|
||||
icon={LockClosedIcon}
|
||||
onClick={() => alert('TODO: Not implemented yet!')}
|
||||
>
|
||||
<Dropdown.Item icon={LockClosedIcon} onClick={() => alert('TODO: Not implemented yet!')}>
|
||||
Lock
|
||||
</Dropdown.Item>
|
||||
</Dropdown.Section>
|
||||
@@ -220,14 +220,14 @@ export function Sidebar() {
|
||||
<Icon component={Planet} />
|
||||
Overview
|
||||
</SidebarLink>
|
||||
<SidebarLink to="photos">
|
||||
<Icon component={ShareNetwork} />
|
||||
Nodes
|
||||
</SidebarLink>
|
||||
<SidebarLink to="content">
|
||||
<Icon component={CirclesFour} />
|
||||
Spaces
|
||||
</SidebarLink>
|
||||
<SidebarLink to="photos">
|
||||
<Icon component={PhotoIcon} />
|
||||
Photos
|
||||
</SidebarLink>
|
||||
</div>
|
||||
|
||||
{library && <LibraryScopedSection />}
|
||||
|
||||
@@ -55,7 +55,7 @@ export default function Listbox(props: { options: ListboxOption[]; className?: s
|
||||
className={({ active }) =>
|
||||
`cursor-default select-none relative rounded m-1 py-2 pl-8 pr-4 dark:text-white focus:outline-none ${
|
||||
active
|
||||
? 'text-primary-900 bg-primary-600'
|
||||
? 'text-accent bg-accent'
|
||||
: 'text-gray-900 dark:hover:bg-gray-600 dark:hover:bg-opacity-20'
|
||||
}`
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ const ProgressBar = (props: Props) => {
|
||||
>
|
||||
<ProgressPrimitive.Indicator
|
||||
style={{ width: `${percentage}%` }}
|
||||
className="h-full duration-300 ease-in-out bg-primary "
|
||||
className="h-full duration-300 ease-in-out bg-accent "
|
||||
/>
|
||||
</ProgressPrimitive.Root>
|
||||
);
|
||||
|
||||
@@ -7,10 +7,10 @@ const Slider = (props: SliderPrimitive.SliderProps) => (
|
||||
className={clsx('relative flex items-center w-full h-6 select-none', props.className)}
|
||||
>
|
||||
<SliderPrimitive.Track className="relative flex-grow h-2 bg-gray-500 rounded-full outline-none">
|
||||
<SliderPrimitive.Range className="absolute h-full rounded-full outline-none bg-primary-500" />
|
||||
<SliderPrimitive.Range className="absolute h-full rounded-full outline-none bg-accent" />
|
||||
</SliderPrimitive.Track>
|
||||
<SliderPrimitive.Thumb
|
||||
className="z-50 block w-5 h-5 font-bold transition rounded-full shadow-lg outline-none shadow-black/50 bg-primary-500 ring-primary-500 ring-opacity-30 focus:ring-4"
|
||||
className="z-50 block w-5 h-5 font-bold transition rounded-full shadow-lg outline-none shadow-black/50 bg-accent ring-accent ring-opacity-30 focus:ring-4"
|
||||
data-tip="1.0"
|
||||
/>
|
||||
</SliderPrimitive.Root>
|
||||
|
||||
@@ -23,7 +23,7 @@ export function Toasts() {
|
||||
'radix-swipe-end:animate-toast-swipe-out',
|
||||
'translate-x-radix-toast-swipe-move-x',
|
||||
'radix-swipe-cancel:translate-x-0 radix-swipe-cancel:duration-200 radix-swipe-cancel:ease-[ease]',
|
||||
'focus:outline-none focus-visible:ring focus-visible:ring-primary focus-visible:ring-opacity-75 border-white/10 border-2 shadow-2xl'
|
||||
'focus:outline-none focus-visible:ring focus-visible:ring-accent focus-visible:ring-opacity-75 border-white/10 border-2 shadow-2xl'
|
||||
)}
|
||||
>
|
||||
<div className="flex">
|
||||
@@ -45,7 +45,7 @@ export function Toasts() {
|
||||
{toast.actionButton && (
|
||||
<ToastPrimitive.Action
|
||||
altText="view now"
|
||||
className="flex items-center justify-center w-full px-3 py-2 text-sm font-medium border border-transparent rounded-lg text-accent hover:bg-white/10 focus:z-10 focus:outline-none focus-visible:ring focus-visible:ring-primary focus-visible:ring-opacity-75"
|
||||
className="flex items-center justify-center w-full px-3 py-2 text-sm font-medium border border-transparent rounded-lg text-accent hover:bg-white/10 focus:z-10 focus:outline-none focus-visible:ring focus-visible:ring-accent focus-visible:ring-opacity-75"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
toast.actionButton?.onClick();
|
||||
@@ -57,7 +57,7 @@ export function Toasts() {
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-1 h-0">
|
||||
<ToastPrimitive.Close className="flex items-center justify-center w-full px-3 py-2 text-sm font-medium border border-transparent rounded-lg text-ink-faint hover:bg-white/10 focus:z-10 focus:outline-none focus-visible:ring focus-visible:ring-primary focus-visible:ring-opacity-75">
|
||||
<ToastPrimitive.Close className="flex items-center justify-center w-full px-3 py-2 text-sm font-medium border border-transparent rounded-lg text-ink-faint hover:bg-white/10 focus:z-10 focus:outline-none focus-visible:ring focus-visible:ring-accent focus-visible:ring-opacity-75">
|
||||
Dismiss
|
||||
</ToastPrimitive.Close>
|
||||
</div>
|
||||
|
||||
@@ -19,7 +19,7 @@ export const Toggle: React.FC<ToggleProps> = (props) => {
|
||||
'transition relative flex-shrink-0 inline-flex items-center h-6 w-11 rounded-full bg-gray-200 dark:bg-gray-550',
|
||||
props.className,
|
||||
{
|
||||
'!bg-primary-500 dark:!bg-primary-500': isEnabled,
|
||||
'!bg-accent dark:!bg-accent': isEnabled,
|
||||
'h-[20px] w-[35px]': size === 'sm',
|
||||
'h-8 w-[55px]': size === 'md'
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
interface StyleState {
|
||||
active: string[];
|
||||
hover: string[];
|
||||
normal: string[];
|
||||
}
|
||||
|
||||
interface Variant {
|
||||
base: string;
|
||||
light: StyleState;
|
||||
dark: StyleState;
|
||||
}
|
||||
|
||||
function tw(variant: Variant): string {
|
||||
return `${variant.base} ${variant.light}`;
|
||||
}
|
||||
|
||||
const variants: Record<string, string> = {
|
||||
default: tw({
|
||||
base: 'shadow-sm',
|
||||
light: {
|
||||
normal: ['bg-gray-50', 'border-gray-100', 'text-gray-700'],
|
||||
hover: ['bg-gray-100', 'border-gray-200', 'text-gray-900'],
|
||||
active: ['bg-gray-50', 'border-gray-200', 'text-gray-600']
|
||||
},
|
||||
dark: {
|
||||
normal: ['bg-gray-800 ', 'border-gray-100', ' text-gray-200'],
|
||||
active: ['bg-gray-700 ', 'border-gray-200 ', 'text-white'],
|
||||
hover: ['bg-gray-700 ', 'border-gray-600 ', 'text-white']
|
||||
}
|
||||
})
|
||||
};
|
||||
@@ -16,7 +16,7 @@ export default function DebugScreen() {
|
||||
// });
|
||||
const { mutate: identifyFiles } = useLibraryMutation('jobs.identifyUniqueFiles');
|
||||
return (
|
||||
<div className="flex flex-col w-full h-screen custom-scroll page-scroll app-bg">
|
||||
<div className="flex flex-col w-full h-screen custom-scroll page-scroll app-background">
|
||||
<div data-tauri-drag-region className="flex flex-shrink-0 w-full h-5" />
|
||||
<div className="flex flex-col p-5 pt-2 space-y-5 pb-7">
|
||||
<h1 className="text-lg font-bold ">Developer Debugger</h1>
|
||||
|
||||
@@ -92,7 +92,7 @@ const StatItem: React.FC<StatItemProps> = (props) => {
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
'flex flex-col flex-shrink-0 w-32 px-4 py-3 duration-75 transform rounded-md cursor-default hover:bg-gray-50 hover:dark:bg-gray-600',
|
||||
'flex flex-col flex-shrink-0 w-32 px-4 py-3 duration-75 transform rounded-md cursor-default ',
|
||||
!+bytes && 'hidden'
|
||||
)}
|
||||
>
|
||||
@@ -139,7 +139,7 @@ export default function OverviewScreen() {
|
||||
console.log(overviewStats);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col w-full h-screen overflow-x-hidden custom-scroll page-scroll app-bg">
|
||||
<div className="flex flex-col w-full h-screen overflow-x-hidden custom-scroll page-scroll app-background">
|
||||
<div data-tauri-drag-region className="flex flex-shrink-0 w-full h-5" />
|
||||
{/* PAGE */}
|
||||
|
||||
@@ -165,7 +165,7 @@ export default function OverviewScreen() {
|
||||
<div className="flex-grow" />
|
||||
<div className="flex items-center h-full space-x-2">
|
||||
<div>
|
||||
<Dialog
|
||||
{/* <Dialog
|
||||
title="Add Device"
|
||||
description="Connect a new device to your library. Either enter another device's code or copy this one."
|
||||
// ctaAction={() => {}}
|
||||
@@ -191,7 +191,7 @@ export default function OverviewScreen() {
|
||||
<Input value="" />
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Dialog>*/}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
export default function PhotosScreen() {
|
||||
return (
|
||||
<div className="flex flex-col w-full h-screen p-5 custom-scroll page-scroll app-bg">
|
||||
<div className="flex flex-col w-full h-screen p-5 custom-scroll page-scroll app-background">
|
||||
<div className="flex flex-col space-y-5 pb-7">
|
||||
<p className="px-5 py-3 mb-3 text-sm text-gray-400 rounded-md bg-gray-50 dark:text-gray-400 dark:bg-gray-600">
|
||||
<p className="px-5 py-3 mb-3 text-sm border rounded-md border-app-border bg-app-box ">
|
||||
<b>Note: </b>This is a pre-alpha build of Spacedrive, many features are yet to be
|
||||
functional.
|
||||
</p>
|
||||
|
||||
@@ -5,7 +5,7 @@ import { SettingsSidebar } from '../../components/settings/SettingsSidebar';
|
||||
|
||||
export default function SettingsScreen() {
|
||||
return (
|
||||
<div className="flex flex-row w-full app-bg">
|
||||
<div className="flex flex-row w-full app-background">
|
||||
<SettingsSidebar />
|
||||
<div className="w-full">
|
||||
<div data-tauri-drag-region className="w-full h-7" />
|
||||
|
||||
@@ -28,7 +28,7 @@ export default function GeneralSettings() {
|
||||
<span className="font-semibold">Connected Node</span>
|
||||
<div className="grid grid-cols-2 gap-1">
|
||||
<NodePill>0 Peers</NodePill>
|
||||
<NodePill className="bg-primary-600">Running</NodePill>
|
||||
<NodePill className="bg-accent">Running</NodePill>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ export default function P2PSettings() {
|
||||
<div className="flex flex-col mt-1">
|
||||
<Input className="flex-grow" disabled defaultValue="https://p2p.spacedrive.com" />
|
||||
<div className="flex justify-end mt-1">
|
||||
<a className="p-1 text-sm font-bold text-primary-500 hover:text-primary-400">Change</a>
|
||||
<a className="p-1 text-sm font-bold text-accent hover:text-accent">Change</a>
|
||||
</div>
|
||||
</div>
|
||||
</InputContainer>
|
||||
|
||||
@@ -4,15 +4,15 @@ button {
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'InterVariable', sans-serif;
|
||||
// font-family: 'InterVariable', sans-serif;
|
||||
}
|
||||
|
||||
.app-bg {
|
||||
.app-background {
|
||||
@apply bg-app;
|
||||
}
|
||||
|
||||
.has-blur-effects {
|
||||
.app-bg {
|
||||
.app-background {
|
||||
@apply bg-app/90;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ const styles = cva(
|
||||
},
|
||||
size: {
|
||||
md: 'py-1 px-3 text-md font-medium',
|
||||
sm: 'py-1 px-2 text-xs font-medium'
|
||||
sm: 'py-1 px-2 text-sm font-medium'
|
||||
},
|
||||
justify: {
|
||||
left: 'justify-left',
|
||||
@@ -49,17 +49,13 @@ const styles = cva(
|
||||
},
|
||||
variant: {
|
||||
default: [
|
||||
'bg-gray-50 shadow-sm hover:bg-gray-100 active:bg-gray-50 dark:bg-transparent',
|
||||
'dark:active:bg-gray-600 dark:hover:bg-gray-550 dark:active:opacity-80',
|
||||
'border-gray-100 hover:border-gray-200 active:border-gray-200',
|
||||
'dark:border-transparent dark:active:border-gray-600 dark:hover:border-gray-500',
|
||||
'text-gray-700 hover:text-gray-900 active:text-gray-600',
|
||||
'dark:text-gray-200 dark:active:text-white dark:hover:text-white'
|
||||
'bg-app-button bg-transparent active:bg-app-selected hover:bg-app-hover',
|
||||
'border-transparent hover:border-app-border active:border-app-border'
|
||||
],
|
||||
gray: [
|
||||
'bg-gray-100 shadow-sm hover:bg-gray-200 active:bg-gray-100 dark:bg-gray-500 dark:hover:bg-gray-500 dark:bg-opacity-80 dark:hover:bg-opacity-100 dark:active:opacity-80',
|
||||
'border-gray-200 hover:border-gray-300 active:border-gray-200 dark:border-gray-500 dark:hover:border-gray-500',
|
||||
'text-gray-700 hover:text-gray-900 active:text-gray-600 dark:text-gray-200 dark:active:text-white dark:hover:text-white'
|
||||
'bg-gray-100 shadow-sm hover:bg-gray-200 active:bg-gray-100',
|
||||
'border-gray-200 hover:border-app-border active:border-gray-200',
|
||||
'text-gray-700 hover:text-gray-900 active:text-gray-600'
|
||||
],
|
||||
primary: [
|
||||
'bg-primary-600 text-white shadow-sm active:bg-primary-600 hover:bg-primary border-primary-500 hover:border-primary-500 active:border-primary-700'
|
||||
|
||||
@@ -11,11 +11,13 @@ import { tw } from './utils';
|
||||
export const Section = tw.div`px-1 py-1 space-y-[2px]`;
|
||||
|
||||
const itemStyles = cva(
|
||||
'text-sm group flex grow shrink-0 rounded items-center w-full whitespace-nowrap px-2 py-1 mb-[2px] dark:hover:bg-gray-650 disabled:opacity-50 disabled:cursor-not-allowed',
|
||||
'text-sm group flex grow shrink-0 rounded items-center w-full whitespace-nowrap px-2 py-1 mb-[2px] disabled:opacity-50 disabled:cursor-not-allowed',
|
||||
{
|
||||
variants: {
|
||||
selected: {
|
||||
true: 'bg-gray-300 dark:bg-primary dark:hover:bg-primary'
|
||||
true: 'bg-app-selected hover:bg-app-selected',
|
||||
undefined: 'hover:bg-app-selected/50',
|
||||
false: 'hover:bg-app-selected/50'
|
||||
},
|
||||
active: {
|
||||
true: ''
|
||||
@@ -27,10 +29,10 @@ const itemStyles = cva(
|
||||
|
||||
const itemIconStyles = cva('mr-2 w-4 h-4', {
|
||||
variants: {
|
||||
active: {
|
||||
true: 'dark:text-gray-100',
|
||||
false: 'text-gray-600 dark:text-gray-200'
|
||||
}
|
||||
// active: {
|
||||
// // true: 'dark:text-ink-dull'
|
||||
// // false: 'text-gray-600 dark:text-gray-200'
|
||||
// }
|
||||
}
|
||||
});
|
||||
|
||||
@@ -62,15 +64,12 @@ export const Item = ({ to, className, icon: Icon, children, ...props }: Dropdown
|
||||
);
|
||||
};
|
||||
|
||||
export const Button = ({ children, ...props }: UI.ButtonProps) => {
|
||||
export const Button = ({ children, className, ...props }: UI.ButtonProps) => {
|
||||
return (
|
||||
<UI.Button size="sm" {...props}>
|
||||
<UI.Button size="sm" {...props} className={clsx('flex text-left', className)}>
|
||||
{children}
|
||||
<div className="flex-grow" />
|
||||
<ChevronDownIcon
|
||||
className="w-5 h-5 ml-2 -mr-1 text-violet-200 hover:text-violet-100"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<span className="flex-grow" />
|
||||
<ChevronDownIcon className="w-5 h-5" aria-hidden="true" />
|
||||
</UI.Button>
|
||||
);
|
||||
};
|
||||
@@ -100,7 +99,7 @@ export const Root = (props: PropsWithChildren<DropdownRootProps>) => {
|
||||
>
|
||||
<Menu.Items
|
||||
className={clsx(
|
||||
'absolute z-50 min-w-fit w-full bg-white border divide-y divide-gray-100 rounded shadow-xl top-full dark:bg-gray-550 dark:divide-gray-500 dark:border-gray-600 ring-1 ring-black ring-opacity-5 focus:outline-none',
|
||||
'absolute z-50 min-w-fit w-full border divide-y divide-app-border/50 rounded shadow-xl top-full ring-1 ring-black ring-opacity-5 focus:outline-none bg-app-box border-app-border',
|
||||
props.itemsClassName,
|
||||
{ 'left-0': props.align === 'left' },
|
||||
{ 'right-0': props.align === 'right' }
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import { tw } from './utils';
|
||||
|
||||
export const CategoryHeading = tw.h3`mt-1 mb-1 text-xs font-semibold text-ink-dull`;
|
||||
export const CategoryHeading = tw.h3`text-xs font-semibold text-ink-dull`;
|
||||
|
||||
@@ -2,66 +2,69 @@
|
||||
|
||||
// Notes
|
||||
// shadow should be used as shadow-black/40
|
||||
.vanilla-dark {
|
||||
// global
|
||||
--color-black: 0, 0, 0;
|
||||
--color-white: 255, 255, 255;
|
||||
// accent theme colors
|
||||
--color-accent: 0, 0, 0;
|
||||
--color-accent-faint: 0, 0, 0;
|
||||
--color-accent-deep: 0, 0, 0;
|
||||
// text
|
||||
--color-ink: 255, 255, 255;
|
||||
--color-ink-dull: 190, 190, 190;
|
||||
--color-ink-faint: 150, 150, 150;
|
||||
// sidebar
|
||||
--color-sidebar: 13, 17, 23;
|
||||
--color-sidebar-box: 48,53,68;
|
||||
--color-sidebar-border: 48,53,68;
|
||||
--color-sidebar-divider: 48,53,68;
|
||||
--color-sidebar-button: 48,53,68;
|
||||
--color-sidebar-selected: 48,53,68;
|
||||
--color-sidebar-separator: 48,53,68;
|
||||
// main
|
||||
--color-app: 0, 0, 0;
|
||||
--color-app-box: 0, 0, 0;
|
||||
--color-app-input: 0, 0, 0;
|
||||
--color-app-border: 0, 0, 0;
|
||||
--color-app-button: 0, 0, 0;
|
||||
--color-app-divider: 0, 0, 0;
|
||||
--color-app-selected: 0, 0, 0;
|
||||
--color-app-hover: 0, 0, 0;
|
||||
--color-app-separator: 0, 0, 0;
|
||||
}
|
||||
|
||||
.vanilla-light {
|
||||
// global
|
||||
--color-black: 0,0,0;
|
||||
--color-white: 255,255,255;
|
||||
--color-black: 0, 0%, 0%;
|
||||
--color-white: 0, 0%, 100%;
|
||||
// accent theme colors
|
||||
--color-accent: 0,0,0;
|
||||
--color-accent-faint: 0,0,0;
|
||||
--color-accent-deep: 0,0,0;
|
||||
--color-accent: 208, 100%, 57%;
|
||||
--color-accent-faint: 208, 100%, 67%;
|
||||
--color-accent-deep: 208, 100%, 47%;
|
||||
// text
|
||||
--color-ink: 0,0,0;
|
||||
--color-ink-dull: 35,35,35;
|
||||
--color-ink-faint: 55,55,55;
|
||||
--color-ink: 215, 5%, 20%;
|
||||
--color-ink-dull: 215, 5%, 30%;
|
||||
--color-ink-faint: 215, 5%, 60%;
|
||||
// sidebar
|
||||
--color-sidebar: 255,255,255;
|
||||
--color-sidebar-box: 233,237,253;
|
||||
--color-sidebar-border: 233,237,253;
|
||||
--color-sidebar-divider: 233,237,253;
|
||||
--color-sidebar-button: 233,237,253;
|
||||
--color-sidebar-selected: 233,237,253;
|
||||
--color-sidebar-separator: 233,237,253;
|
||||
--color-sidebar: 215, 5%, 98%;
|
||||
--color-sidebar-box: 215, 5%, 100%;
|
||||
--color-sidebar-border: 215, 10%, 85%;
|
||||
--color-sidebar-divider: 215, 15%, 90%;
|
||||
--color-sidebar-button: 215, 15%, 100%;
|
||||
--color-sidebar-selected: 215, 10%, 90%;
|
||||
--color-sidebar-separator: 215, 15%, 100%;
|
||||
// main
|
||||
--color-app: 0,0,0;
|
||||
--color-app-box: 0,0,0;
|
||||
--color-app-input: 0,0,0;
|
||||
--color-app-border: 0,0,0;
|
||||
--color-app-button: 0,0,0;
|
||||
--color-app-divider: 0,0,0;
|
||||
--color-app-selected: 0,0,0;
|
||||
--color-app-hover: 0,0,0;
|
||||
--color-app-separator: 0,0,0;
|
||||
--color-app: 215, 5%, 100%;
|
||||
--color-app-box: 215, 5%, 98%;
|
||||
--color-app-input: 215, 5%, 100%;
|
||||
--color-app-border: 215, 5%, 94%;
|
||||
--color-app-button: 215, 5%, 100%;
|
||||
--color-app-divider: 215, 5%, 100%;
|
||||
--color-app-selected: 215, 5%, 80%;
|
||||
--color-app-hover: 215, 5%, 100%;
|
||||
--color-app-separator: 215, 5%, 100%;
|
||||
}
|
||||
|
||||
|
||||
.vanilla-dark {
|
||||
// global
|
||||
--color-black: 0, 0%, 0%;
|
||||
--color-white: 0, 0%, 100%;
|
||||
// accent theme colors
|
||||
--color-accent: 208, 100%, 57%;
|
||||
--color-accent-faint: 208, 100%, 67%;
|
||||
--color-accent-deep: 208, 100%, 47%;
|
||||
// text
|
||||
--color-ink: 215, 0%, 100%;
|
||||
--color-ink-dull: 215, 10%, 70%;
|
||||
--color-ink-faint: 215, 10%, 25%;
|
||||
// sidebar
|
||||
--color-sidebar: 215, 15%, 7%;
|
||||
--color-sidebar-box: 215, 15%, 13%;
|
||||
--color-sidebar-border: 215, 15%, 23%;
|
||||
--color-sidebar-divider: 215, 15%, 23%;
|
||||
--color-sidebar-button: 215, 15%, 23%;
|
||||
--color-sidebar-selected: 215, 15%, 16%;
|
||||
--color-sidebar-separator: 215, 15%, 23%;
|
||||
// main
|
||||
--color-app: 215, 15%, 13%;
|
||||
--color-app-box: 215, 15%, 20%;
|
||||
--color-app-input: 215, 15%, 23%;
|
||||
--color-app-border: 215, 15%, 30%;
|
||||
--color-app-button: 215, 15%, 23%;
|
||||
--color-app-divider: 215, 15%, 23%;
|
||||
--color-app-selected: 215, 15%, 23%;
|
||||
--color-app-hover: 215, 15%, 23%;
|
||||
--color-app-separator: 215, 15%, 23%;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ const defaultTheme = require('tailwindcss/defaultTheme');
|
||||
function alpha(variableName) {
|
||||
// some tailwind magic to allow us to specify opacity with CSS variables (eg: bg-app/80)
|
||||
// https://tailwindcss.com/docs/customizing-colors#using-css-variables
|
||||
return `rgba(var(${variableName}), <alpha-value>)`;
|
||||
return `hsla(var(${variableName}), <alpha-value>)`;
|
||||
}
|
||||
|
||||
module.exports = function (app, options) {
|
||||
@@ -24,7 +24,7 @@ module.exports = function (app, options) {
|
||||
fontSize: {
|
||||
'tiny': '.65rem',
|
||||
'xs': '.75rem',
|
||||
'sm': '.84rem',
|
||||
'sm': '.80rem',
|
||||
'base': '1rem',
|
||||
'lg': '1.125rem',
|
||||
'xl': '1.25rem',
|
||||
|
||||
Reference in New Issue
Block a user