Tailwind Prettier Plugin (#557)

* add tailwind prettier plugin + run prettier

* add eslint tailwind plugin and eslint fix to turbo

* Ran eslint fix + fixed every other lint issues

* twStyle and lint stuff

* remove auto lint as it's buggy

* update eslint & add twStyle to tailwind regex

* Fix auto lint + config inconsistencies

* Add tailwind config to prettier config

* run lint:fix

---------

Co-authored-by: Brendan Allan <brendonovich@outlook.com>
This commit is contained in:
Utku 2023-02-16 10:04:19 +03:00 committed by GitHub
parent a9fceae819
commit b856f15b22
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
160 changed files with 1081 additions and 984 deletions

View file

@ -1,84 +1,84 @@
pnpm
titlebar
consts
pallete
unlisten
svgr
middlewares
clsx
SDWEB
tryghost
tsparticles
Opencollective
Waitlist
heroicons
roadmap
semibold
noreferer
Rescan
subpackage
photoslibrary
fontsource
audiomp
audioogg
audiowav
browserslist
bsconfig
cheader
classname
clsx
compodoc
consts
cssmap
dartlang
dockerdebug
falsey
folderlight
folderopen
fontotf
fontsource
fontttf
fontwoff
gopackage
haml
headlessui
heroicons
imagegif
imageico
imagejpg
imagepng
imagewebp
immer
ipynb
jsmap
lacie
lighteditorconfig
nestjscontroller
middlewares
moti
nestjs
nestjscontroller
nestjsdecorator
nestjsfilter
nestjsguard
nestjsmodule
nestjsservice
noreferer
npmlock
nums
nuxt
Opencollective
opengl
overscan
pallete
photoshop
photoslibrary
pnpm
postcssconfig
powershelldata
reactjs
rjson
symfony
testjs
tmpl
typescriptdef
windi
yarnerror
unlisten
imagewebp
powershellmodule
pressable
reactjs
reactts
testts
zustand
overscan
webp
headlessui
falsey
nums
lacie
classname
wunsub
immer
Rescan
rjson
roadmap
SDWEB
semibold
subpackage
svgr
swipeable
symfony
tada
moti
pressable
testjs
testts
titlebar
tmpl
tryghost
tsparticles
typescriptdef
unlisten
Waitlist
webp
windi
wunsub
yarnerror
zustand

View file

@ -21,6 +21,7 @@ module.exports = {
],
importOrderSortSpecifiers: true,
importOrderParserPlugins: ['importAssertions', 'typescript', 'jsx'],
pluginSearchDirs: ['.'],
plugins: ['@trivago/prettier-plugin-sort-imports']
pluginSearchDirs: false,
plugins: ['@trivago/prettier-plugin-sort-imports', 'prettier-plugin-tailwindcss'],
tailwindConfig: 'packages/ui/tailwind.config.js'
};

13
.vscode/settings.json vendored
View file

@ -2,6 +2,7 @@
"cSpell.words": [
"actix",
"bpfrpt",
"callees",
"consts",
"countup",
"creationdate",
@ -41,7 +42,8 @@
"tw`([^`]*)",
"tw\\.[^`]+`([^`]*)`",
"tw\\(.*?\\).*?`([^`]*)",
"tw\\.style\\(([^)]*)\\)"
"tw\\.style\\(([^)]*)\\)",
"twStyle\\(([^)]*)\\)"
],
"search.exclude": {
"**/node_modules": true,
@ -50,5 +52,12 @@
// Hiding these folders bcs they create a lot of noise in the search results
"apps/mobile/android": true,
"apps/mobile/ios": true
}
},
"eslint.workingDirectories": [
"apps/landing",
"apps/mobile",
"packages/ui",
"packages/client",
"packages/interface"
]
}

View file

@ -25,7 +25,7 @@ export default function App({
<>
<NavBar />
<div className="dark dark:bg-black dark:text-white z-10 max-w-[100rem] m-auto">
<div className="dark z-10 m-auto max-w-[100rem] dark:bg-black dark:text-white">
{children}
</div>
<Footer />

View file

@ -59,18 +59,18 @@ const AppEmbed = () => {
return (
<div className="w-screen">
{renderBloom && (
<div className="relative max-w-full sm:w-full sm:max-w-[1400px] mx-auto">
<div className="relative mx-auto max-w-full sm:w-full sm:max-w-[1400px]">
<div className="bloom burst bloom-one" />
<div className="bloom burst bloom-three" />
<div className="bloom burst bloom-two" />
</div>
)}
<div className="relative z-30 h-[255px] px-1 sm:h-[428px] md:h-[428px] lg:h-[628px] mt-8 sm:mt-16">
<div className="relative z-30 mt-8 h-[255px] px-1 sm:mt-16 sm:h-[428px] md:h-[428px] lg:h-[628px]">
<div
className={clsx(
'relative h-full m-auto border rounded-lg max-w-7xl transition-opacity border-gray-550 opacity-0',
'border-gray-550 relative m-auto h-full max-w-7xl rounded-lg border opacity-0 transition-opacity',
renderBloom && '!opacity-100',
renderImage && 'bg-transparent border-none'
renderImage && 'border-none bg-transparent'
)}
>
{showApp && !forceImg && (
@ -78,8 +78,8 @@ const AppEmbed = () => {
ref={iFrame}
referrerPolicy="origin-when-cross-origin"
className={clsx(
'w-full h-full z-30 rounded-lg shadow-iframe inset-center bg-gray-850',
iFrameAppReady ? 'fade-in-app-embed opacity-100' : 'opacity-0 -ml-[10000px]'
'shadow-iframe inset-center bg-gray-850 z-30 h-full w-full rounded-lg',
iFrameAppReady ? 'fade-in-app-embed opacity-100' : 'ml-[-10000px] opacity-0'
)}
src={`${
import.meta.env.VITE_SDWEB_BASE_URL || 'http://localhost:8002'
@ -87,7 +87,7 @@ const AppEmbed = () => {
/>
)}
{renderImage && <div className="z-40 h-full w-auto fade-in-app-embed landing-img" />}
{renderImage && <div className="fade-in-app-embed landing-img z-40 h-full w-auto" />}
</div>
</div>
</div>
@ -96,7 +96,7 @@ const AppEmbed = () => {
export const AppEmbedPlaceholder = () => {
return (
<div className="w-screen relative z-30 h-[228px] px-5 sm:h-[428px] md:h-[428px] lg:h-[628px] mt-8 sm:mt-16" />
<div className="relative z-30 mt-8 h-[228px] w-screen px-5 sm:mt-16 sm:h-[428px] md:h-[428px] lg:h-[628px]" />
);
};

View file

@ -7,7 +7,7 @@ export interface BlogTagProps {
export const BlogTag = (props: BlogTagProps) => {
return (
<span
className={`px-2 py-0.5 rounded-md text-gray-500 text-sm bg-gray-550`}
className={`bg-gray-550 rounded-md px-2 py-0.5 text-sm text-gray-500`}
style={{
backgroundColor: props.tag.accent_color + '' ?? '',
color: parseInt(props.tag.accent_color?.slice(1) ?? '', 16) > 0xffffff / 2 ? '#000' : '#fff'

View file

@ -17,7 +17,7 @@ export default function DocsLayout(props: Props) {
const [menuOpen, setMenuOpen] = useState(false);
return (
<div className="flex flex-col items-start w-full sm:flex-row">
<div className="flex w-full flex-col items-start sm:flex-row">
<Menu
onClose={() => setMenuOpen(false)}
customBurgerIcon={false}
@ -25,33 +25,33 @@ export default function DocsLayout(props: Props) {
pageWrapId="page-container"
className="shadow-2xl shadow-black"
>
<div className="visible h-screen pb-20 overflow-x-hidden custom-scroll doc-sidebar-scroll bg-gray-650 pt-7 px-7 sm:invisible">
<div className="custom-scroll doc-sidebar-scroll bg-gray-650 visible h-screen overflow-x-hidden px-7 pb-20 pt-7 sm:invisible">
<Button
onClick={() => setMenuOpen(!menuOpen)}
className="!px-1 -ml-0.5 mb-3 !border-none"
className="-ml-0.5 mb-3 !border-none !px-1"
>
<X weight="bold" className="w-6 h-6" />
<X weight="bold" className="h-6 w-6" />
</Button>
<DocsSidebar activePath={props?.doc?.url} navigation={props.navigation} />
</div>
</Menu>
<aside className="sticky hidden px-5 mt-32 mb-20 ml-2 mr-0 lg:mr-4 top-32 sm:inline">
<aside className="sticky top-32 mt-32 mb-20 ml-2 mr-0 hidden px-5 sm:inline lg:mr-4">
<DocsSidebar activePath={props?.doc?.url} navigation={props.navigation} />
</aside>
<div className="flex flex-col w-full sm:flex-row" id="page-container">
<div className="h-12 px-5 flex w-full border-t border-gray-600 border-b mt-[65px] sm:hidden items-center ">
<div className="flex w-full flex-col sm:flex-row" id="page-container">
<div className="mt-[65px] flex h-12 w-full items-center border-y border-gray-600 px-5 sm:hidden">
<div className="flex sm:hidden">
<Button onClick={() => setMenuOpen(!menuOpen)} className="!px-2 ml-1 !border-none">
<List weight="bold" className="w-6 h-6" />
<Button onClick={() => setMenuOpen(!menuOpen)} className="ml-1 !border-none !px-2">
<List weight="bold" className="h-6 w-6" />
</Button>
</div>
{props.doc?.url.split('/').map((item, index) => {
if (index === 2) return null;
return (
<div key={index} className="flex flex-row items-center ml-2">
<div key={index} className="ml-2 flex flex-row items-center">
<a className="px-1 text-sm">{toTitleCase(item)}</a>
{index < 1 && <CaretRight className="w-4 h-4 ml-1 -mr-2" />}
{index < 1 && <CaretRight className="ml-1 -mr-2 h-4 w-4" />}
</div>
);
})}

View file

@ -15,13 +15,13 @@ export default function DocsSidebar(props: Props) {
const activeSectionData = props.navigation.find((section) => section.slug === activeSection);
return (
<nav className="flex flex-col w-full mr-8 sm:w-52">
<nav className="mr-8 flex w-full flex-col sm:w-52">
<div onClick={() => alert('Search coming soon...')} className="relative w-full">
<MagnifyingGlass weight="bold" className="absolute top-3 left-3" />
<Input className="w-full mb-5 pointer-events-none pl-9" placeholder="Search" />
<span className="absolute text-sm font-semibold text-gray-400 right-3 top-[9px]">K</span>
<Input className="pointer-events-none mb-5 w-full pl-9" placeholder="Search" />
<span className="absolute right-3 top-[9px] text-sm font-semibold text-gray-400">K</span>
</div>
<div className="flex flex-col mb-6">
<div className="mb-6 flex flex-col">
{props.navigation.map((section) => {
const isActive = section.slug === activeSection;
const Icon = config.sections.find((s) => s.slug === section.slug)?.icon;
@ -30,13 +30,13 @@ export default function DocsSidebar(props: Props) {
href={`/docs/${section.section[0].category[0].url}`}
key={section.slug}
className={clsx(
`flex font-semibold text-[14px] items-center py-1.5 doc-sidebar-button`,
`doc-sidebar-button flex items-center py-1.5 text-[14px] font-semibold`,
section.slug,
isActive && 'nav-active'
)}
>
<div className={clsx(`p-1 mr-4 bg-gray-500 border-t rounded-lg border-gray-400/20`)}>
<Icon weight="bold" className="w-4 h-4 text-white opacity-80" />
<div className={clsx(`mr-4 rounded-lg border-t border-gray-400/20 bg-gray-500 p-1`)}>
<Icon weight="bold" className="h-4 w-4 text-white opacity-80" />
</div>
{section.title}
</a>
@ -54,15 +54,15 @@ export default function DocsSidebar(props: Props) {
<li
className={clsx(
'flex border-l border-gray-600',
active && 'border-l-2 border-primary'
active && 'border-primary border-l-2'
)}
key={page.title}
>
<a
href={`/docs/${page.url}`}
className={clsx(
'font-normal w-full rounded px-3 py-1 hover:text-gray-50 no-underline text-[14px] text-gray-350',
active && '!text-white !font-medium '
'text-gray-350 w-full rounded px-3 py-1 text-[14px] font-normal no-underline hover:text-gray-50',
active && '!font-medium !text-white '
)}
>
{page.title}

View file

@ -24,16 +24,16 @@ function FooterLink(props: PropsWithChildren<{ link: string; blank?: boolean }>)
export function Footer() {
return (
<footer id="footer" className="z-50 w-screen pt-3 border-t border-gray-550 bg-gray-850">
<div className="max-w-[100rem] mx-auto grid grid-cols-2 gap-6 p-8 pt-10 pb-20 m-auto text-white min-h-64 sm:grid-cols-2 lg:grid-cols-6">
<footer id="footer" className="border-gray-550 bg-gray-850 z-50 w-screen border-t pt-3">
<div className="min-h-64 m-auto grid max-w-[100rem] grid-cols-2 gap-6 p-8 pt-10 pb-20 text-white sm:grid-cols-2 lg:grid-cols-6">
<div className="col-span-2">
<img src={AppLogo} className="w-10 h-10 mb-5" />
<img src={AppLogo} className="mb-5 h-10 w-10" />
<h3 className="mb-1 text-xl font-bold">Spacedrive</h3>
<p className="text-sm text-gray-350">
<p className="text-gray-350 text-sm">
&copy; Copyright {new Date().getFullYear()} Spacedrive Technology Inc.
</p>
<div className="flex flex-row mt-6 mb-10 space-x-3">
<div className="mt-6 mb-10 flex flex-row space-x-3">
<FooterLink link="https://twitter.com/spacedriveapp">
<Twitter />
</FooterLink>
@ -55,7 +55,7 @@ export function Footer() {
</div>
</div>
<div className="flex flex-col col-span-1 space-y-2">
<div className="col-span-1 flex flex-col space-y-2">
<h3 className="mb-1 text-xs font-bold uppercase ">About</h3>
<FooterLink link="/team">Team</FooterLink>
@ -64,15 +64,15 @@ export function Footer() {
<FooterLink link="/docs/changelog/beta/0.1.0">Changelog</FooterLink>
<FooterLink link="/blog">Blog</FooterLink>
</div>
<div className="flex flex-col col-span-1 space-y-2 pointer-events-none">
<div className="pointer-events-none col-span-1 flex flex-col space-y-2">
<h3 className="mb-1 text-xs font-bold uppercase">Downloads</h3>
<div className="flex flex-col col-span-1 space-y-2 opacity-50">
<div className="col-span-1 flex flex-col space-y-2 opacity-50">
<FooterLink link="#">macOS</FooterLink>
<FooterLink link="#">Windows</FooterLink>
<FooterLink link="#">Linux</FooterLink>
</div>
</div>
<div className="flex flex-col col-span-1 space-y-2">
<div className="col-span-1 flex flex-col space-y-2">
<h3 className="mb-1 text-xs font-bold uppercase ">Developers</h3>
<FooterLink blank link="https://github.com/spacedriveapp/spacedrive/tree/main/docs">
Documentation
@ -83,14 +83,14 @@ export function Footer() {
>
Contribute
</FooterLink>
<div className="opacity-50 pointer-events-none">
<div className="pointer-events-none opacity-50">
<FooterLink link="#">Extensions</FooterLink>
</div>
<div className="opacity-50 pointer-events-none">
<div className="pointer-events-none opacity-50">
<FooterLink link="#">Self Host</FooterLink>
</div>
</div>
<div className="flex flex-col col-span-1 space-y-2">
<div className="col-span-1 flex flex-col space-y-2">
<h3 className="mb-1 text-xs font-bold uppercase ">Org</h3>
<FooterLink blank link="https://opencollective.com/spacedrive">
Open Collective

View file

@ -81,12 +81,12 @@ export function HomeCTA() {
useWorker
zIndex={-1}
/> */}
<div className="z-30 flex flex-row items-center h-10 space-x-4 animation-delay-2 fade-in">
<div className="animation-delay-2 fade-in z-30 flex h-10 flex-row items-center space-x-4">
{!showWaitlistInput ? (
<>
<Button
onClick={() => setShowWaitlistInput(true)}
className="z-30 border-0 cursor-pointer"
className="z-30 cursor-pointer border-0"
variant="gray"
>
Join Waitlist
@ -97,7 +97,7 @@ export function HomeCTA() {
className="z-30 cursor-pointer"
variant="accent"
>
<Github className="inline w-5 h-5 -mt-[4px] -ml-1 mr-2" fill="white" />
<Github className="mt-[-4px] -ml-1 mr-2 inline h-5 w-5" fill="white" />
Star on GitHub
</Button>
</>
@ -107,16 +107,16 @@ export function HomeCTA() {
{(waitlistError || waitlistSubmitted) && (
<div
className={clsx({
'flex flex-row items-center bg-opacity-20 border-2 my-2 px-2 rounded-md': true,
'bg-red-800 border-red-900': waitlistError,
'bg-green-800 border-green-900': !waitlistError,
'bg-opacity/20 my-2 flex flex-row items-center rounded-md border-2 px-2': true,
'border-red-900 bg-red-800': waitlistError,
'border-green-900 bg-green-800': !waitlistError,
'-mt-2': waitlistSubmitted
})}
>
{waitlistError ? (
<Alert className="w-5 mr-1 fill-red-500" />
<Alert className="mr-1 w-5 fill-red-500" />
) : (
<Info className="w-5 mr-1 fill-green-500" />
<Info className="mr-1 w-5 fill-green-500" />
)}
<p
className={clsx({
@ -145,15 +145,15 @@ export function HomeCTA() {
{!waitlistSubmitted && (
<Button
onClick={() => setShowWaitlistInput(true)}
className={clsx('z-30 border-0 rounded-l-none cursor-pointer', {
'opacity-50 cursor-default': loading
className={clsx('z-30 cursor-pointer rounded-l-none border-0', {
'cursor-default opacity-50': loading
})}
disabled={loading}
variant="accent"
type="submit"
>
{loading ? (
<Spinner className="w-6 h-6 text-white text-opacity-40 animate-spin fill-white" />
<Spinner className="h-6 w-6 animate-spin fill-white text-white text-opacity-40" />
) : (
'Submit'
)}
@ -165,7 +165,7 @@ export function HomeCTA() {
)}
</div>
<p
className={clsx('z-30 px-6 text-sm text-center text-gray-450 animation-delay-3 fade-in', {
className={clsx('animation-delay-3 fade-in text-gray-450 z-30 px-6 text-center text-sm', {
'mt-10': waitlistError,
'mt-3': !waitlistError
})}

View file

@ -16,11 +16,11 @@ function MarkdownPage(props: PropsWithChildren<MarkdownPageProps>) {
}, []);
return (
<div className={clsx('p-4 mb-10', props.classNames)}>
<div className={clsx('mb-10 p-4', props.classNames)}>
<article
id="content"
className={clsx(
'prose text-[15px] sm:text-[16px] prose-img:rounded prose-code:text-gray-400 prose-code:font-normal prose-code:before:hidden prose-code:p-1 prose-code:bg-gray-650 prose-code:rounded-md prose-code:after:hidden prose-h1:text-[3.25em] prose-blockquote:bg-gray-600 prose-blockquote:rounded prose-a:text-primary prose-a:no-underline lg:prose-xs dark:prose-invert prose-td:p-2 prose-th:p-2 prose-td:border-l prose-td:border-gray-500 prose-td:last:border-r prose-table:border-b prose-table:border-gray-500 prose-tr:even:bg-gray-700',
'lg:prose-xs prose prose-h1:text-[3.25em] prose-a:text-primary prose-a:no-underline prose-blockquote:rounded prose-blockquote:bg-gray-600 prose-code:rounded-md prose-code:bg-gray-650 prose-code:p-1 prose-code:font-normal prose-code:text-gray-400 prose-code:before:hidden prose-code:after:hidden prose-table:border-b prose-table:border-gray-500 prose-tr:even:bg-gray-700 prose-th:p-2 prose-td:border-l prose-td:border-gray-500 prose-td:p-2 prose-td:last:border-r prose-img:rounded dark:prose-invert text-[15px] sm:text-[16px]',
props.articleClassNames
)}
>

View file

@ -13,7 +13,7 @@ function NavLink(props: PropsWithChildren<{ link?: string }>) {
<a
href={props.link ?? '#'}
target={props.link?.startsWith('http') ? '_blank' : undefined}
className="p-4 text-gray-300 no-underline transition cursor-pointer hover:text-gray-50"
className="cursor-pointer p-4 text-gray-300 no-underline transition hover:text-gray-50"
rel="noreferrer"
>
{props.children}
@ -52,19 +52,19 @@ export default function NavBar() {
return (
<div
className={clsx(
'fixed transition px-2 z-[55] w-full h-16 border-b ',
'fixed z-[55] h-16 w-full border-b px-2 transition ',
isAtTop
? 'bg-transparent border-transparent'
: 'border-gray-550 bg-gray-700 bg-opacity-80 backdrop-blur'
? 'border-transparent bg-transparent'
: 'bg-opacity/80 border-gray-550 bg-gray-700 backdrop-blur'
)}
>
<div className="relative flex max-w-[100rem] mx-auto items-center h-full m-auto p-5">
<div className="relative m-auto flex h-full max-w-[100rem] items-center p-5">
<a href="/" className="absolute flex flex-row items-center">
<img src={AppLogo} className="z-30 w-8 h-8 mr-3" />
<img src={AppLogo} className="z-30 mr-3 h-8 w-8" />
<h3 className="text-xl font-bold text-white">Spacedrive</h3>
</a>
<div className="hidden m-auto space-x-4 text-white lg:block ">
<div className="m-auto hidden space-x-4 text-white lg:block ">
<NavLink link="/roadmap">Roadmap</NavLink>
<NavLink link="/team">Team</NavLink>
<NavLink link="/blog">Blog</NavLink>
@ -72,7 +72,7 @@ export default function NavBar() {
<div className="relative inline">
<NavLink link="/careers">Careers</NavLink>
{positions.length > 0 ? (
<span className="absolute bg-opacity-80 px-[5px] text-xs rounded-md bg-primary -top-1 -right-2">
<span className="bg-opacity/80 bg-primary absolute -top-1 -right-2 rounded-md px-[5px] text-xs">
{` ${positions.length} `}
</span>
) : null}
@ -82,10 +82,10 @@ export default function NavBar() {
<Dropdown.Root
button={
<Button className="ml-[140px] hover:!bg-transparent" size="icon">
<DotsThreeVertical weight="bold" className="w-6 h-6 " />
<DotsThreeVertical weight="bold" className="h-6 w-6 " />
</Button>
}
className="block h-6 text-white w-44 top-2 right-4 lg:hidden"
className="top-2 right-4 block h-6 w-44 text-white lg:hidden"
itemsClassName="!rounded-2xl shadow-2xl shadow-black p-2 !bg-gray-850 mt-2 !border-gray-500 text-[15px]"
>
<Dropdown.Section>
@ -118,7 +118,7 @@ export default function NavBar() {
</Dropdown.Section>
</Dropdown.Root>
<div className="absolute flex-row hidden space-x-5 right-3 lg:flex">
<div className="absolute right-3 hidden flex-row space-x-5 lg:flex">
<a href="https://discord.gg/gTaF2Z44f5" target="_blank" rel="noreferrer">
<Discord className="text-white" />
</a>

View file

@ -10,13 +10,13 @@ const NewBanner: React.FC<NewBannerProps> = (props) => {
return (
<aside
onClick={() => (window.location.href = href)}
className="z-10 text-xs w-10/12 cursor-pointer sm:w-auto sm:text-base fade-in-whats-new px-5 py-1.5 bg-opacity-50 mb-5 flex flex-row bg-gray-800 hover:bg-gray-750 border border-gray-600 hover:border-gray-550 rounded-full transition"
className="fade-in-whats-new bg-opacity/50 hover:border-gray-550 hover:bg-gray-750 z-10 mb-5 flex w-10/12 cursor-pointer flex-row rounded-full border border-gray-600 bg-gray-800 px-5 py-1.5 text-xs transition sm:w-auto sm:text-base"
>
<strong className="font-semibold truncate text-gray-350">{headline}</strong>
<div role="separator" className="w-[1px] mx-4 h-22 bg-gray-500" />
<strong className="text-gray-350 truncate font-semibold">{headline}</strong>
<div role="separator" className="h-22 mx-4 w-[1px] bg-gray-500" />
<a
href={href}
className="flex-shrink-0 text-transparent font-regular bg-clip-text bg-gradient-to-r from-primary-400 to-blue-600 decoration-primary-600"
className="font-regular from-primary-400 decoration-primary-600 shrink-0 bg-gradient-to-r to-blue-600 bg-clip-text text-transparent"
>
{link} <span aria-hidden="true">&rarr;</span>
</a>

View file

@ -52,9 +52,9 @@ export function TeamMember(props: TeamMemberProps) {
alt={`Portrait of ${props.name}`}
width={size}
height={size}
className={clsx('inline-flex m-0 rounded-md', {
'w-32 h-32 !xs:w-36 !xs:h-36 !sm:w-40 !sm:h-40': !props.investmentRound,
'lg:w-28 lg:h-28': props.investmentRound
className={clsx('m-0 inline-flex rounded-md', {
'!xs:w-36 !xs:h-36 !sm:w-40 !sm:h-40 h-32 w-32': !props.investmentRound,
'lg:h-28 lg:w-28': props.investmentRound
})}
/>
<h3 className="mt-4 mb-0 text-base">{props.name}</h3>
@ -66,27 +66,27 @@ export function TeamMember(props: TeamMemberProps) {
{props.role}
</p>
{props.investmentRound && (
<p className="mt-0 mb-0 text-sm font-semibold text-gray-450">{props.investmentRound}</p>
<p className="text-gray-450 my-0 text-sm font-semibold">{props.investmentRound}</p>
)}
<div className="flex flex-row mt-auto space-x-2">
<div className="mt-auto flex flex-row space-x-2">
{props.socials?.twitter && (
<Link href={props.socials.twitter}>
<Twitter className="w-[20px] h-[20px]" />
<Twitter className="h-[20px] w-[20px]" />
</Link>
)}
{props.socials?.github && (
<Link href={props.socials.github}>
<Github className="w-[20px] h-[20px]" />
<Github className="h-[20px] w-[20px]" />
</Link>
)}
{props.socials?.twitch && (
<Link href={props.socials.twitch}>
<Twitch className="w-[20px] h-[20px]" />
<Twitch className="h-[20px] w-[20px]" />
</Link>
)}
{props.socials?.dribbble && (
<Link href={props.socials.dribbble}>
<Dribbble className="w-[20px] h-[20px]" />
<Dribbble className="h-[20px] w-[20px]" />
</Link>
)}
</div>

View file

@ -13,16 +13,16 @@ function Page({ posts }: { posts: PostOrPage[] }) {
}
return (
<div className="container flex flex-col max-w-4xl gap-20 p-4 pt-32 m-auto mb-20 prose lg:prose-xs dark:prose-invert">
<div className="lg:prose-xs prose dark:prose-invert container m-auto mb-20 flex max-w-4xl flex-col gap-20 p-4 pt-32">
<Helmet>
<title>Spacedrive Blog</title>
<meta name="description" content="Get the latest from Spacedrive." />
</Helmet>
<section>
<h1 className="m-0 fade-in-heading">Blog</h1>
<h1 className="fade-in-heading m-0">Blog</h1>
<p className="fade-in-heading animation-delay-1">Get the latest from Spacedrive.</p>
</section>
<section className="grid grid-cols-1 gap-4 sm:grid-cols-1 lg:grid-cols-1 fade-in will-change-transform animation-delay-2">
<section className="fade-in animation-delay-2 grid grid-cols-1 gap-4 will-change-transform sm:grid-cols-1 lg:grid-cols-1">
{posts.map((post) => {
return (
<div
@ -30,24 +30,24 @@ function Page({ posts }: { posts: PostOrPage[] }) {
onClick={() => {
window.location.href = `/blog/${post.slug}`;
}}
className="relative z-0 flex flex-col gap-2 mb-8 overflow-hidden transition-colors border border-gray-500 cursor-pointer rounded-xl"
className="relative z-0 mb-8 flex cursor-pointer flex-col gap-2 overflow-hidden rounded-xl border border-gray-500 transition-colors"
>
{post.feature_image && (
<img
src={post.feature_image}
alt=""
className="inset-0 object-cover w-full m-0 md:h-96 -z-10 rounded-t-xl"
className="inset-0 -z-10 m-0 w-full rounded-t-xl object-cover md:h-96"
/>
)}
<div className="p-8">
<h2 className="m-0 text2xl md:text-4xl">{post.title}</h2>
<h2 className="text2xl m-0 md:text-4xl">{post.title}</h2>
<small className="m-0">{post.reading_time} minute read.</small>
<p className="my-2 line-clamp-3">{post.excerpt}</p>
<p className="line-clamp-3 my-2">{post.excerpt}</p>
<p className="m-0 text-white">
by {post.primary_author?.name} &middot;{' '}
{new Date(post.published_at ?? '').toLocaleDateString()}
</p>
<div className="flex flex-wrap gap-2 mt-4">
<div className="mt-4 flex flex-wrap gap-2">
{post.tags?.map((tag: Tag) => (
<BlogTag key={tag.id} tag={tag} />
))}

View file

@ -29,7 +29,7 @@ function Page({ post }: { post: PostOrPage }) {
<meta content="summary_large_image" name="twitter:card" />
<meta name="author" content={post?.primary_author?.name || 'Spacedrive Technology Inc.'} />
</Helmet>
<div className="container max-w-4xl p-4 m-auto mb-20 prose pt-14 lg:prose-xs dark:prose-invert">
<div className="lg:prose-xs prose dark:prose-invert container m-auto mb-20 max-w-4xl p-4 pt-14">
{post && (
<>
<figure>
@ -38,9 +38,9 @@ function Page({ post }: { post: PostOrPage }) {
></figcaption>
<img src={featured_image} alt="" className="mt-8 rounded-xl" />
</figure>
<section className="flex flex-wrap gap-4 px-8 -mx-8 rounded-xl">
<div className="flex-grow">
<h1 className="m-0 text-2xl leading-snug sm:leading-normal sm:text-4xl">
<section className="-mx-8 flex flex-wrap gap-4 rounded-xl px-8">
<div className="grow">
<h1 className="m-0 text-2xl leading-snug sm:text-4xl sm:leading-normal">
{post?.title}
</h1>
<p className="m-0 mt-2">

View file

@ -93,96 +93,96 @@ function Page() {
<title>Careers - Spacedrive</title>
<meta name="description" content="Work with us to build the future of file management." />
</Helmet>
<div className="container relative max-w-4xl min-h-screen p-4 pt-32 m-auto mb-20 prose text-white prose-invert">
<div className="prose prose-invert container relative m-auto mb-20 min-h-screen max-w-4xl p-4 pt-32 text-white">
<div
className="bloom subtle egg-bloom-two -top-60 -right-[400px]"
className="bloom subtle egg-bloom-two -top-60 right-[-400px]"
style={{ transform: 'scale(2)' }}
/>
<h1 className="px-2 mb-3 text-4xl font-black leading-tight text-center text-white fade-in-heading md:text-5xl">
<h1 className="fade-in-heading mb-3 px-2 text-center text-4xl font-black leading-tight text-white md:text-5xl">
Build the future of files.
</h1>
<div className="z-30 flex flex-col items-center fade-in animation-delay-1">
<p className="z-40 text-lg text-center text-gray-350">
<div className="fade-in animation-delay-1 z-30 flex flex-col items-center">
<p className="text-gray-350 z-40 text-center text-lg">
Spacedrive is redefining the way we think about our personal data, building a open
ecosystem to help preserve your digital legacy and make cross-platform file management a
breeze.
</p>
<Button
onClick={scrollToPositions}
className="z-30 border-0 cursor-pointer"
className="z-30 cursor-pointer border-0"
variant="accent"
>
See Open Positions
</Button>
<hr className="w-full my-24 border-gray-200 opacity-10 border-1" />
<h2 className="px-2 mb-0 text-4xl font-black leading-tight text-center">Our Values</h2>
<hr className="border-1 my-24 w-full border-gray-200 opacity-10" />
<h2 className="mb-0 px-2 text-center text-4xl font-black leading-tight">Our Values</h2>
<p className="mt-2 mb-4">What drives us daily.</p>
<div className="grid w-full grid-cols-1 gap-4 mt-5 sm:grid-cols-2">
<div className="mt-5 grid w-full grid-cols-1 gap-4 sm:grid-cols-2">
{values.map((value, index) => (
<div
key={value.title + index}
className="flex flex-col p-10 bg-opacity-50 border border-gray-500 rounded-md bg-gray-550"
className="bg-opacity/50 bg-gray-550 flex flex-col rounded-md border border-gray-500 p-10"
>
<value.icon className="w-8 m-0" />
<value.icon className="m-0 w-8" />
<h3 className="mt-4 mb-1 text-2xl font-bold leading-snug">{value.title}</h3>
<p className="mt-1 mb-0 text-gray-350">{value.desc}</p>
<p className="text-gray-350 mt-1 mb-0">{value.desc}</p>
</div>
))}
</div>
<hr className="w-full my-24 border-gray-200 opacity-10 border-1" />
<h2 className="px-2 mb-0 text-4xl font-black leading-tight text-center text-white">
<hr className="border-1 my-24 w-full border-gray-200 opacity-10" />
<h2 className="mb-0 px-2 text-center text-4xl font-black leading-tight text-white">
Perks and Benefits
</h2>
<p className="mt-2 mb-4">We're behind you 100%.</p>
<div className="grid w-full grid-cols-1 gap-4 mt-5 sm:grid-cols-3">
<div className="mt-5 grid w-full grid-cols-1 gap-4 sm:grid-cols-3">
{perks.map((value, index) => (
<div
key={value.title + index}
style={{ backgroundColor: value.color + '10', borderColor: value.color + '30' }}
className="flex flex-col p-8 border rounded-md bg-gray-550 bg-opacity-30"
className="bg-opacity30 bg-gray-550 flex flex-col rounded-md border p-8"
>
<value.icon className="w-8 m-0" color={value.color} />
<value.icon className="m-0 w-8" color={value.color} />
<h3 className="mt-4 mb-1">{value.title}</h3>
<p className="mt-1 mb-0 text-sm text-white opacity-60">{value.desc}</p>
</div>
))}
</div>
<hr className="w-full my-24 border-gray-200 opacity-10 border-1" ref={openPositionsRef} />
<h2 className="px-2 mb-0 text-4xl font-black leading-tight text-center text-white">
<hr className="border-1 my-24 w-full border-gray-200 opacity-10" ref={openPositionsRef} />
<h2 className="mb-0 px-2 text-center text-4xl font-black leading-tight text-white">
Open Positions
</h2>
<p className="mt-2 mb-4">If any open positions suit you, apply now!</p>
<div className="grid w-full grid-cols-1 gap-4 mt-5">
<div className="mt-5 grid w-full grid-cols-1 gap-4">
{positions.length === 0 ? (
<p className="m-0 text-center text-gray-350">
<p className="text-gray-350 m-0 text-center">
There are no positions open at this time. Please check back later!
</p>
) : (
positions.map((value, index) => (
<div
key={value.name + index}
className="flex flex-col p-10 bg-opacity-50 border border-gray-500 rounded-md bg-gray-550"
className="bg-opacity/50 bg-gray-550 flex flex-col rounded-md border border-gray-500 p-10"
>
<div className="flex flex-col sm:flex-row">
<h3 className="m-0 text-2xl leading-tight">{value.name}</h3>
<div className="mt-3 sm:mt-0.5">
<span className="text-sm font-semibold text-gray-300 sm:ml-4">
<CurrencyDollar className="inline w-4 mr-1 -mt-1" />
<CurrencyDollar className="mr-1 -mt-1 inline w-4" />
{value.salary}
</span>
<span className="ml-4 text-sm font-semibold text-gray-300">
<Clock className="inline w-4 mr-1 -mt-1" />
<Clock className="mr-1 -mt-1 inline w-4" />
{value.type}
</span>
</div>
</div>
<p className="mt-3 mb-0 text-gray-350">{value.description}</p>
<p className="text-gray-350 mt-3 mb-0">{value.description}</p>
</div>
))
)}
</div>
<hr className="w-full my-24 border-gray-200 opacity-10 border-1" />
<h2 className="px-2 mb-0 text-3xl font-black text-center text-white">How to apply?</h2>
<hr className="border-1 my-24 w-full border-gray-200 opacity-10" />
<h2 className="mb-0 px-2 text-center text-3xl font-black text-white">How to apply?</h2>
<p className="mt-2">
Send your cover letter and resume to <strong>careers at spacedrive dot com</strong> and
we'll get back to you shortly!

View file

@ -5,11 +5,11 @@ import { Helmet } from 'react-helmet';
import '../../atom-one.css';
import DocsLayout from '../../components/DocsLayout';
import Markdown from '../../components/Markdown';
import { SingleDocResponse, toTitleCase } from './api';
import { SingleDocResponse } from './api';
function BottomCard(props: PropsWithChildren) {
return (
<div className="flex flex-row items-center p-4 text-sm border border-gray-700 rounded-lg group !text-gray-200 hover:!text-primary hover:shadow-xl hover:border-primary hover:shadow-primary/10 transition-all duration-200 hover:-translate-y-[2px]">
<div className="hover:border-primary hover:!text-primary hover:shadow-primary/10 group flex flex-row items-center rounded-lg border border-gray-700 p-4 text-sm !text-gray-200 transition-all duration-200 hover:translate-y-[-2px] hover:shadow-xl">
{props.children}
</div>
);
@ -31,11 +31,11 @@ function Page({ doc, navigation, nextDoc }: SingleDocResponse) {
<DocsLayout doc={doc} navigation={navigation}>
<Markdown classNames="sm:mt-[105px] mt-6 min-h-screen ">
<h5 className="mb-2 text-sm font-semibold text-primary lg:min-w-[700px]">
<h5 className="text-primary mb-2 text-sm font-semibold lg:min-w-[700px]">
{doc.categoryName}
</h5>
<div dangerouslySetInnerHTML={{ __html: doc?.html as string }} />
<div className="flex flex-col gap-3 mt-10 sm:flex-row">
<div className="mt-10 flex flex-col gap-3 sm:flex-row">
<a
target="_blank"
rel="noreferrer"
@ -43,14 +43,14 @@ function Page({ doc, navigation, nextDoc }: SingleDocResponse) {
className="w-full"
>
<BottomCard>
<Github className="w-5 mr-3" />
<Github className="mr-3 w-5" />
Edit this page on GitHub
</BottomCard>
</a>
{nextDoc && (
<a href={`/docs/${nextDoc.url}`} className="w-full">
<BottomCard>
<CaretRight className="w-5 mr-3" />
<CaretRight className="mr-3 w-5" />
Next article: {nextDoc?.title}
</BottomCard>
</a>

View file

@ -20,7 +20,7 @@ function Page({ navigation }: { navigation: DocsNavigation }) {
need to get started with Spacedrive.
</p>
<a
className="transition text-primary-600 hover:text-primary-500"
className="text-primary-600 hover:text-primary-500 transition"
href="/docs/product/getting-started/introduction"
>
Get Started

View file

@ -2,7 +2,7 @@ import { ReactComponent as Info } from '@sd/assets/svgs/info.svg';
import clsx from 'clsx';
import { useEffect, useState } from 'react';
import { Helmet } from 'react-helmet';
import AppEmbed, { AppEmbedPlaceholder } from '../components/AppEmbed';
import AppEmbed from '../components/AppEmbed';
import { Bubbles } from '../components/Bubbles';
// import { Bubbles } from '../components/Bubbles';
import HomeCTA from '../components/HomeCTA';
@ -23,12 +23,12 @@ function Section(props: SectionProps = { orientation: 'left' }) {
<div className="px-4 py-10 sm:px-10">
{props.heading && <h1 className="text-2xl font-black sm:text-4xl">{props.heading}</h1>}
{props.description && (
<p className="mt-5 text-md sm:text-xl text-gray-450">{props.description}</p>
<p className="text-md text-gray-450 mt-5 sm:text-xl">{props.description}</p>
)}
</div>
);
return (
<div className={clsx('grid grid-cols-1 my-10 lg:grid-cols-2 lg:my-44', props.className)}>
<div className={clsx('my-10 grid grid-cols-1 lg:my-44 lg:grid-cols-2', props.className)}>
{props.orientation === 'right' ? (
<>
{info}
@ -77,10 +77,11 @@ function Page() {
alert('An error occurred while unsubscribing from waitlist');
}
})();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<div className="flex flex-col items-center w-full px-4">
<div className="flex w-full flex-col items-center px-4">
<Helmet>
<title>Spacedrive A file manager from the future.</title>
<meta
@ -107,18 +108,18 @@ function Page() {
{unsubscribedFromWaitlist && (
<div
className={
'-mt-8 flex flex-row items-center bg-opacity-20 border-2 my-2 px-2 rounded-md bg-green-800 border-green-900'
'bg-opacity/20 my-2 -mt-8 flex flex-row items-center rounded-md border-2 border-green-900 bg-green-800 px-2'
}
>
<Info className="w-5 mr-1 fill-green-500" />
<Info className="mr-1 w-5 fill-green-500" />
<p className={'text-sm text-green-500'}>You have been unsubscribed from the waitlist</p>
</div>
)}
<h1 className="z-30 px-2 mb-3 text-4xl font-black leading-tight text-center text-white fade-in-heading md:text-6xl">
<h1 className="fade-in-heading z-30 mb-3 px-2 text-center text-4xl font-black leading-tight text-white md:text-6xl">
A file explorer from the future.
</h1>
<p className="z-30 max-w-4xl mt-1 mb-8 text-center animation-delay-1 fade-in-heading text-md lg:text-lg leading-2 lg:leading-8 text-gray-450">
<p className="animation-delay-1 fade-in-heading text-md leading-2 text-gray-450 z-30 mt-1 mb-8 max-w-4xl text-center lg:text-lg lg:leading-8">
Combine your drives and clouds into one database that you can organize and explore from any
device.
<br />
@ -140,7 +141,7 @@ function Page() {
<br />
<br />
<a
className="transition text-primary-600 hover:text-primary-500"
className="text-primary-600 hover:text-primary-500 transition"
href="/docs/product/getting-started/introduction"
>
Find out more

View file

@ -123,25 +123,25 @@ function Page() {
<title>Roadmap - Spacedrive</title>
<meta name="description" content="What can Spacedrive do?" />
</Helmet>
<div className="container flex flex-col max-w-4xl gap-20 p-4 pt-32 m-auto mb-20 prose lg:prose-xs dark:prose-invert">
<div className="lg:prose-xs prose dark:prose-invert container m-auto mb-20 flex max-w-4xl flex-col gap-20 p-4 pt-32">
<section className="flex flex-col items-center">
<img className="w-24 pointer-events-none" />
<h1 className="mb-0 text-5xl leading-snug text-center fade-in-heading">
<img className="pointer-events-none w-24" />
<h1 className="fade-in-heading mb-0 text-center text-5xl leading-snug">
What's next for Spacedrive?
</h1>
<p className="text-center text-gray-400 animation-delay-2 fade-in-heading">
<p className="animation-delay-2 fade-in-heading text-center text-gray-400">
Here is a list of the features we are working on, and the progress we have made so far.
</p>
</section>
<section className="grid grid-cols-[auto_1fr] grid-flow-row auto-cols-auto gap-x-4">
<section className="grid auto-cols-auto grid-flow-row grid-cols-[auto_1fr] gap-x-4">
{items.map((item, i) => (
<>
{/* Using span so i can use the group-last-of-type selector */}
<span className="max-w-[10rem] flex items-start first:items-start justify-end gap-4 group">
<span className="group flex max-w-[10rem] items-start justify-end gap-4 first:items-start">
<div className="flex flex-col items-end">
<h3
className={
`m-0 hidden lg:block text-right ` +
`m-0 hidden text-right lg:block ` +
(i === 0 ? '-translate-y-1/4' : '-translate-y-1/2')
}
>
@ -149,17 +149,17 @@ function Page() {
</h3>
{item?.subtext && <span className="text-sm text-gray-300">{item?.subtext}</span>}
</div>
<div className="flex w-2 h-full group-first:rounded-t-full group-last-of-type:rounded-b-full lg:items-center group-first:mt-2">
<div className="flex h-full w-2 group-first:mt-2 group-first:rounded-t-full group-last-of-type:rounded-b-full lg:items-center">
<div
className={
'w-full h-full flex ' +
'flex h-full w-full ' +
(item.completed ? 'bg-primary-500 z-10' : 'bg-gray-550')
}
>
{item?.when !== undefined ? (
<div
className={clsx(
'absolute z-20 w-4 h-4 mt-5 -translate-y-1/2 border-2 border-gray-200 rounded-full group-first:mt-0 lg:mt-0 group-first:self-start -translate-x-1/4',
'absolute z-20 mt-5 h-4 w-4 -translate-y-1/2 -translate-x-1/4 rounded-full border-2 border-gray-200 group-first:mt-0 group-first:self-start lg:mt-0',
items[i - 1]?.completed || i === 0 ? 'bg-primary-500 z-10' : 'bg-gray-550'
)}
>
@ -171,11 +171,11 @@ function Page() {
</div>
</div>
</span>
<div className="flex flex-col items-start justify-center gap-4 group">
<div className="group flex flex-col items-start justify-center gap-4">
{item?.when && (
<h3 className="mb-0 group-first-of-type:m-0 lg:hidden">{item.when}</h3>
)}
<div className="flex flex-col w-full p-4 my-2 space-y-2 border border-gray-500 rounded-xl group-first-of-type:mt-0 group-last:mb-0">
<div className="my-2 flex w-full flex-col space-y-2 rounded-xl border border-gray-500 p-4 group-last:mb-0 group-first-of-type:mt-0">
<h3 className="m-0">{item.title}</h3>
<p>{item.description}</p>
</div>
@ -183,7 +183,7 @@ function Page() {
</>
))}
</section>
<section className="p-8 space-y-2 bg-gray-850 rounded-xl">
<section className="bg-gray-850 space-y-2 rounded-xl p-8">
<h2 className="my-1">That's not all.</h2>
<p>
We're always open to ideas and feedback over{' '}

View file

@ -202,34 +202,34 @@ function Page() {
<title>Our Team - Spacedrive</title>
<meta name="description" content="Who's behind Spacedrive?" />
</Helmet>
<div className="relative mx-auto team-page">
<div className="team-page relative mx-auto">
<div
className="bloom subtle egg-bloom-one -top-60 -right-[400px]"
className="bloom subtle egg-bloom-one -top-60 right-[-400px]"
style={{ transform: 'scale(2)' }}
/>
<div className="relative z-10">
<h1 className="text-5xl leading-tight sm:leading-snug fade-in-heading ">
<h1 className="fade-in-heading text-5xl leading-tight sm:leading-snug ">
We believe file management should be <span className="title-gradient">universal</span>.
</h1>
<p className="text-white/50 animation-delay-2 fade-in-heading ">
<p className="animation-delay-2 fade-in-heading text-white/50 ">
Your priceless personal data shouldn't be stuck in a device ecosystem. It should be OS
agnostic, permanent and owned by you.
</p>
<p className="text-white/50 animation-delay-2 fade-in-heading ">
<p className="animation-delay-2 fade-in-heading text-white/50 ">
The data we create daily is our legacythat will long outlive us. Open source technology
is the only way to ensure we retain absolute control over the files that define our
lives, at unlimited scale.
</p>
<a
href="/docs/product/resources/faq"
className="flex flex-row items-center text-gray-400 duration-150 animation-delay-3 fade-in-heading hover:text-white text-underline underline-offset-4"
className="animation-delay-3 fade-in-heading text-underline flex flex-row items-center text-gray-400 underline-offset-4 duration-150 hover:text-white"
>
<ArrowRight className="mr-2" />
Read more
</a>
<div className="fade-in-heading animation-delay-5">
<h2 className="mt-10 text-2xl leading-relaxed sm:mt-20 ">Meet the team</h2>
<div className="grid grid-cols-2 my-10 xs:grid-cols-3 sm:grid-cols-4 gap-x-5 gap-y-10">
<div className="xs:grid-cols-3 my-10 grid grid-cols-2 gap-x-5 gap-y-10 sm:grid-cols-4">
{teamMembers.map((member) => (
<TeamMember key={member.name} {...member} />
))}
@ -240,7 +240,7 @@ function Page() {
href="https://github.com/spacedriveapp/spacedrive/graphs/contributors"
target="_blank"
rel="noreferrer"
className="duration-200 oss-credit-gradient hover:opacity-75"
className="oss-credit-gradient duration-200 hover:opacity-75"
>
open source contributors
</a>{' '}
@ -252,7 +252,7 @@ function Page() {
<p className="text-sm text-gray-400 ">
We're backed by some of the greatest leaders in the technology industry.
</p>
<div className="grid grid-cols-3 my-10 sm:grid-cols-5 gap-x-5 gap-y-10">
<div className="my-10 grid grid-cols-3 gap-x-5 gap-y-10 sm:grid-cols-5">
{investors.map((investor) => (
<TeamMember key={investor.name + investor.investmentRound} {...investor} />
))}

View file

@ -13,9 +13,9 @@ function Page({ is404 }: { is404: boolean }) {
<Helmet>
<title>Not Found - Spacedrive</title>
</Helmet>
<div className="flex flex-col items-center m-auto ">
<div className="m-auto flex flex-col items-center ">
<div className="h-32" />
<SmileyXEyes className="mb-3 w-44 h-44" />
<SmileyXEyes className="mb-3 h-44 w-44" />
<h1 className="mb-2 text-center">In the quantum realm this page potentially exists.</h1>
<p>In other words, thats a 404.</p>
<div className="flex flex-wrap justify-center">

View file

@ -97,7 +97,7 @@ html {
}
.bloom {
@apply absolute w-[1200px] h-[1200px] -mt-[320px];
@apply absolute -mt-[320px] h-[1200px] w-[1200px];
will-change: opacity;
opacity: 0;
will-change: filter opacity;
@ -126,7 +126,7 @@ html {
animation-delay: 0ms;
}
&.bloom-three {
@apply left-auto right-auto invisible md:visible -mt-[250px] ml-24;
@apply invisible left-auto right-auto -mt-[250px] ml-24 md:visible;
background: url('/bloom-three.png') no-repeat center center;
background-size: contain;
animation-delay: 800ms;
@ -169,7 +169,7 @@ html {
}
.slot-block {
@apply bg-app-box py-3 px-4 border-l-4 border-app-line rounded mb-2;
@apply bg-app-box border-app-line mb-2 rounded border-l-4 py-3 px-4;
}
.slot-block.note {
@apply border-yellow-400 bg-yellow-300/20;
@ -181,7 +181,7 @@ html {
@apply border-red-400 bg-red-400/20;
}
.slot-block-title {
@apply text-white font-bold text-sm m-0 uppercase;
@apply m-0 text-sm font-bold uppercase text-white;
}
.slot-block-content {
@apply my-1 mx-0 mb-0 text-white;
@ -234,9 +234,9 @@ html {
width: 7px;
}
&::-webkit-scrollbar-track {
@apply bg-[#00000006] dark:bg-[#00000030] my-[10px] rounded-[6px];
@apply my-[10px] rounded-[6px] bg-[#00000006] dark:bg-[#00000030];
}
&::-webkit-scrollbar-thumb {
@apply rounded-[6px] bg-app-selected;
@apply bg-app-selected rounded-[6px];
}
}

View file

@ -39,7 +39,7 @@ function AppContainer() {
const { library } = useCurrentLibrary();
return (
<SafeAreaProvider style={tw`flex-1 bg-app`}>
<SafeAreaProvider style={tw`bg-app flex-1`}>
<GestureHandlerRootView style={tw`flex-1`}>
<MenuProvider>
<BottomSheetModalProvider>

View file

@ -114,19 +114,19 @@ const DeviceIcon = {
const Device = ({ name, size, type }: DeviceProps) => {
return (
<View style={tw`my-2 border rounded-md bg-app-overlay border-app-line`}>
<View style={tw`bg-app-overlay border-app-line my-2 rounded-md border`}>
<View style={tw`flex flex-row items-center px-3.5 pt-3 pb-2`}>
<View style={tw`flex flex-row items-center`}>
{DeviceIcon[type]}
<Text style={tw`text-base font-semibold text-ink`}>{name || 'Unnamed Device'}</Text>
<Text style={tw`text-ink text-base font-semibold`}>{name || 'Unnamed Device'}</Text>
{/* P2P Lock */}
<View style={tw`flex flex-row rounded items-center ml-2 bg-app-box py-[1px] px-[4px]`}>
<View style={tw`bg-app-box ml-2 flex flex-row items-center rounded py-[1px] px-[4px]`}>
<Lock weight="bold" size={12} color={tw.color('ink-dull')} />
<Text style={tw`text-ink-dull font-semibold ml-0.5 text-xs`}>P2P</Text>
<Text style={tw`text-ink-dull ml-0.5 text-xs font-semibold`}>P2P</Text>
</View>
</View>
{/* Size */}
<Text style={tw`ml-2 text-sm font-semibold text-ink-dull`}>{size}</Text>
<Text style={tw`text-ink-dull ml-2 text-sm font-semibold`}>{size}</Text>
</View>
<FlatList
data={placeholderFileItems}

View file

@ -1,9 +1,9 @@
import { Text, View } from 'react-native';
import { ExplorerItem, ObjectKind } from '@sd/client';
import Layout from '~/constants/Layout';
import tw, { twStyle } from '~/lib/tailwind';
import { getExplorerStore } from '~/stores/explorerStore';
import { isObject } from '~/types/helper';
import tw from '../../lib/tailwind';
import FileThumb from './FileThumb';
type FileItemProps = {
@ -21,7 +21,7 @@ const FileItem = ({ data }: FileItemProps) => {
return (
<View
style={tw.style('items-center', {
style={twStyle('items-center', {
width: gridItemSize,
height: gridItemSize
})}
@ -31,12 +31,12 @@ const FileItem = ({ data }: FileItemProps) => {
kind={data.item.extension === 'zip' ? 'zip' : isVid ? 'video' : 'other'}
/>
{item.extension && isVid && (
<View style={tw`absolute bottom-8 opacity-70 right-5 py-0.5 px-1 bg-black/70 rounded`}>
<Text style={tw`text-[9px] text-white uppercase font-semibold`}>{item.extension}</Text>
<View style={tw`absolute bottom-8 right-5 rounded bg-black/70 py-0.5 px-1 opacity-70`}>
<Text style={tw`text-[9px] font-semibold uppercase text-white`}>{item.extension}</Text>
</View>
)}
<View style={tw`px-1.5 py-[1px] mt-1`}>
<Text numberOfLines={1} style={tw`text-xs font-medium text-center text-white`}>
<View style={tw`mt-1 px-1.5 py-[1px]`}>
<Text numberOfLines={1} style={tw`text-center text-xs font-medium text-white`}>
{item?.name}
{item?.extension && `.${item.extension}`}
</Text>

View file

@ -1,7 +1,7 @@
import React from 'react';
import { Text, View } from 'react-native';
import { ExplorerItem, ObjectKind } from '@sd/client';
import tw from '~/lib/tailwind';
import tw, { twStyle } from '~/lib/tailwind';
import { getExplorerStore } from '~/stores/explorerStore';
import { isObject } from '~/types/helper';
import FileThumb from './FileThumb';
@ -19,7 +19,7 @@ const FileRow = ({ data }: FileRowProps) => {
return (
<View
style={tw.style('flex flex-row items-center px-3', {
style={twStyle('flex flex-row items-center px-3', {
height: getExplorerStore().listItemSize
})}
>
@ -29,7 +29,7 @@ const FileRow = ({ data }: FileRowProps) => {
size={0.6}
/>
<View style={tw`ml-3`}>
<Text numberOfLines={1} style={tw`text-xs font-medium text-center text-ink-dull`}>
<Text numberOfLines={1} style={tw`text-ink-dull text-center text-xs font-medium`}>
{item?.name}
{item?.extension && `.${item.extension}`}
</Text>

View file

@ -20,7 +20,7 @@ export const getThumbnailUrlById = (casId: string) =>
`${DocumentDirectoryPath}/thumbnails/${encodeURIComponent(casId)}.webp`;
const FileThumbWrapper = ({ children, size = 1 }) => (
<View style={[tw`justify-center items-center`, { width: 80 * size, height: 80 * size }]}>
<View style={[tw`items-center justify-center`, { width: 80 * size, height: 80 * size }]}>
{children}
</View>
);
@ -63,7 +63,7 @@ export default function FileThumb({ data, size = 1, kind }: FileThumbProps) {
if (data.has_thumbnail && url) {
return (
<FileThumbWrapper size={size}>
<Image source={{ uri: url }} resizeMode="contain" style={tw`w-full h-full`} />
<Image source={{ uri: url }} resizeMode="contain" style={tw`h-full w-full`} />
</FileThumbWrapper>
);
}

View file

@ -5,7 +5,7 @@ import { MotiView } from 'moti';
import { List } from 'phosphor-react-native';
import { Pressable, Text, View } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import tw from '~/lib/tailwind';
import tw, { twStyle } from '~/lib/tailwind';
// Default header with search bar and button to open drawer
export default function Header() {
@ -17,12 +17,12 @@ export default function Header() {
return (
<View
style={tw.style('mx-4 bg-app-overlay border border-app-line rounded', {
style={twStyle('border-app-line bg-app-overlay mx-4 rounded border', {
marginTop: top + 10
})}
>
<View style={tw`flex flex-row items-center h-10`}>
<Pressable style={tw`px-3 h-full justify-center`} onPress={() => navigation.openDrawer()}>
<View style={tw`flex h-10 flex-row items-center`}>
<Pressable style={tw`h-full justify-center px-3`} onPress={() => navigation.openDrawer()}>
<MotiView
animate={{ rotate: isDrawerOpen ? '90deg' : '0deg' }}
transition={{ type: 'timing' }}
@ -31,10 +31,10 @@ export default function Header() {
</MotiView>
</Pressable>
<Pressable
style={tw`flex-1 h-full justify-center`}
style={tw`h-full flex-1 justify-center`}
onPress={() => navigation.navigate('Search')}
>
<Text style={tw`text-ink-dull font-medium text-sm`}>Search</Text>
<Text style={tw`text-ink-dull text-sm font-medium`}>Search</Text>
</Pressable>
</View>
</View>

View file

@ -1,6 +1,6 @@
import React from 'react';
import { View, ViewProps } from 'react-native';
import tw from '~/lib/tailwind';
import { twStyle } from '~/lib/tailwind';
type CardProps = {
children: React.ReactNode;
@ -11,10 +11,7 @@ const Card = ({ children, ...props }: CardProps) => {
return (
<View
style={tw.style(
'px-4 py-3 border border-app-line rounded-lg bg-app-overlay',
style as string
)}
style={twStyle('border-app-line bg-app-overlay rounded-lg border px-4 py-3', style as string)}
{...otherProps}
>
{children}

View file

@ -16,7 +16,7 @@ const CollapsibleView = ({ title, titleStyle, containerStyle, children }: Collap
return (
<View style={containerStyle}>
<Pressable onPress={toggle} style={tw`flex flex-row justify-between items-center`}>
<Pressable onPress={toggle} style={tw`flex flex-row items-center justify-between`}>
<Text style={titleStyle} selectable={false}>
{title}
</Text>

View file

@ -74,14 +74,14 @@ const Dialog = (props: DialogProps) => {
>
{/* TODO: Blur may look cool here */}
<View
style={tw`min-w-[360px] max-w-[380px] rounded-md bg-app border border-app-line shadow shadow-app-shade overflow-hidden`}
style={tw`border-app-line bg-app shadow-app-shade min-w-[360px] max-w-[380px] overflow-hidden rounded-md border shadow`}
>
<View style={tw`p-5`}>
{/* Title */}
<Text style={tw`font-bold text-ink text-base`}>{props.title}</Text>
<Text style={tw`text-ink text-base font-bold`}>{props.title}</Text>
{/* Description */}
{props.description && (
<Text style={tw`text-sm text-ink-dull mt-2 leading-normal`}>
<Text style={tw`text-ink-dull mt-2 text-sm leading-normal`}>
{props.description}
</Text>
)}
@ -90,10 +90,10 @@ const Dialog = (props: DialogProps) => {
</View>
{/* Actions */}
<View
style={tw`flex flex-row items-center px-3 py-3 bg-app-highlight border-t border-app-line`}
style={tw`border-app-line bg-app-highlight flex flex-row items-center border-t p-3`}
>
{props.loading && <PulseAnimation style={tw`h-7`} />}
<View style={tw`flex-grow`} />
<View style={tw`grow`} />
<Button
variant="dark_gray"
size="md"

View file

@ -2,15 +2,15 @@ import { VariantProps, cva } from 'class-variance-authority';
import { MotiPressable, MotiPressableProps } from 'moti/interactions';
import { FC, useMemo } from 'react';
import { Pressable, PressableProps } from 'react-native';
import tw from '~/lib/tailwind';
import tw, { twStyle } from '~/lib/tailwind';
const button = cva(['border rounded-md items-center justify-center shadow-sm'], {
const button = cva(['items-center justify-center rounded-md border shadow-sm'], {
variants: {
variant: {
danger: ['bg-red-600 border-red-800'],
gray: ['bg-app-button border-app-line'],
dark_gray: ['bg-app border-app-box'],
accent: ['bg-accent border-accent-deep shadow-md shadow-app-shade/10']
danger: ['border-red-800 bg-red-600'],
gray: ['border-app-line bg-app-button'],
dark_gray: ['border-app-box bg-app'],
accent: ['border-accent-deep bg-accent shadow-app-shade/10 shadow-md']
},
size: {
default: ['py-1', 'px-3'],
@ -35,7 +35,7 @@ export const Button: FC<ButtonProps> = ({ variant, size, disabled, ...props }) =
return (
<Pressable
disabled={disabled}
style={tw.style(button({ variant, size, disabled }), style as string)}
style={twStyle(button({ variant, size, disabled }), style as string)}
{...otherProps}
>
{props.children}
@ -61,7 +61,7 @@ export const AnimatedButton: FC<AnimatedButtonProps> = ({ variant, size, disable
},
[]
)}
style={tw.style(button({ variant, size, disabled }), style as string)}
style={twStyle(button({ variant, size, disabled }), style as string)}
// MotiPressable acts differently than Pressable so containerStyle might need to used to achieve the same effect
containerStyle={containerStyle}
{...otherProps}

View file

@ -6,7 +6,7 @@ type DividerProps = {
};
const Divider = ({ style }: DividerProps) => {
return <View style={[tw`w-full my-1 h-[1px] bg-app-line`, style]} />;
return <View style={[tw`bg-app-line my-1 h-[1px] w-full`, style]} />;
};
export default Divider;

View file

@ -1,12 +1,12 @@
import { VariantProps, cva } from 'class-variance-authority';
import { FC } from 'react';
import { TextInputProps as RNTextInputProps, TextInput } from 'react-native';
import tw from '~/lib/tailwind';
import tw, { twStyle } from '~/lib/tailwind';
const input = cva(['text-sm rounded-md border shadow-sm'], {
const input = cva(['rounded-md border text-sm shadow-sm'], {
variants: {
variant: {
default: 'bg-app border-app-line text-ink'
default: 'border-app-line bg-app text-ink'
},
size: {
default: ['py-2', 'px-3']
@ -25,7 +25,7 @@ export const Input: FC<InputProps> = ({ variant, ...props }) => {
return (
<TextInput
placeholderTextColor={tw.color('ink-dull')}
style={tw.style(input({ variant }), style as string)}
style={twStyle(input({ variant }), style as string)}
{...otherProps}
/>
);

View file

@ -19,7 +19,7 @@ export const Menu = (props: MenuProps) => (
<View>
<PMenu>
<MenuTrigger>{props.trigger}</MenuTrigger>
<MenuOptions optionsContainerStyle={tw`bg-app-menu p-1 rounded`}>
<MenuOptions optionsContainerStyle={tw`bg-app-menu rounded p-1`}>
{props.children}
</MenuOptions>
</PMenu>
@ -43,7 +43,7 @@ export const MenuItem = ({ icon, ...props }: MenuItemProps) => {
<MenuOption
{...props}
customStyles={{
optionText: tw`text-ink text-sm font-medium py-0.5`
optionText: tw`text-ink py-0.5 text-sm font-medium`
}}
style={tw`flex flex-row items-center`}
/>

View file

@ -14,8 +14,8 @@ export const SwitchContainer: FC<SwitchContainerProps> = ({ title, description,
return (
<View style={tw`flex flex-row items-center justify-between pb-6`}>
<View style={tw`w-[80%]`}>
<Text style={tw`font-medium text-ink text-sm`}>{title}</Text>
{description && <Text style={tw`text-ink-dull text-sm mt-2`}>{description}</Text>}
<Text style={tw`text-ink text-sm font-medium`}>{title}</Text>
{description && <Text style={tw`text-ink-dull mt-2 text-sm`}>{description}</Text>}
</View>
<Switch trackColor={{ false: tw.color('app-line'), true: tw.color('accent') }} {...props} />
</View>

View file

@ -10,9 +10,9 @@ type SettingsContainerProps = PropsWithChildren<{
export function SettingsContainer({ children, title, description }: SettingsContainerProps) {
return (
<View style={tw``}>
{title && <Text style={tw`pb-2 pl-3 text-sm font-semibold text-ink-dull`}>{title}</Text>}
{title && <Text style={tw`text-ink-dull pb-2 pl-3 text-sm font-semibold`}>{title}</Text>}
{children}
{description && <Text style={tw`text-ink-dull text-sm px-3 pt-2`}>{description}</Text>}
{description && <Text style={tw`text-ink-dull px-3 pt-2 text-sm`}>{description}</Text>}
</View>
);
}

View file

@ -12,10 +12,10 @@ type SettingsItemProps = {
export function SettingsItem(props: SettingsItemProps) {
return (
<Pressable onPress={props.onPress}>
<View style={tw`flex flex-row items-center justify-between px-3 bg-app-overlay`}>
<View style={tw`bg-app-overlay flex flex-row items-center justify-between px-3`}>
<View style={tw`flex flex-row items-center py-4`}>
{props.leftIcon && props.leftIcon({ size: 18, color: tw.color('ink'), style: tw`mr-2` })}
<Text style={tw`text-sm text-ink`}>{props.title}</Text>
<Text style={tw`text-ink text-sm`}>{props.title}</Text>
</View>
{props.rightArea ? props.rightArea : <CaretRight size={20} color={tw.color('ink-faint')} />}
</View>
@ -26,7 +26,7 @@ export function SettingsItem(props: SettingsItemProps) {
export function SettingsItemDivider() {
return (
<View style={tw`bg-app-overlay`}>
<View style={tw`mx-3 border-b border-b-app-line`} />
<View style={tw`border-b-app-line mx-3 border-b`} />
</View>
);
}

View file

@ -4,7 +4,7 @@ import { ScrollView, Text, View } from 'react-native';
import RNFS from 'react-native-fs';
import { Statistics, useLibraryQuery } from '@sd/client';
import useCounter from '../hooks/useCounter';
import tw from '../lib/tailwind';
import tw, { twStyle } from '../lib/tailwind';
const StatItemNames: Partial<Record<keyof Statistics, string>> = {
total_bytes_capacity: 'Total capacity',
@ -21,8 +21,8 @@ const StatItem: FC<{ title: string; bytes: bigint }> = ({ title, bytes }) => {
return (
<View style={tw`flex flex-col p-4`}>
<Text style={tw`text-sm text-gray-400`}>{title}</Text>
<View style={tw`flex-row items-baseline mt-1`}>
<Text style={tw.style('text-2xl font-bold text-white tabular-nums')}>{count}</Text>
<View style={tw`mt-1 flex-row items-baseline`}>
<Text style={twStyle('text-2xl font-bold tabular-nums text-white')}>{count}</Text>
<Text style={tw`ml-1 text-sm text-gray-400`}>{unit}</Text>
</View>
</View>
@ -64,7 +64,7 @@ const OverviewStats = () => {
</ScrollView>
) : (
<View>
<Text style={tw`text-red-600 text-center font-bold`}>No library found...</Text>
<Text style={tw`text-center font-bold text-red-600`}>No library found...</Text>
</View>
);
};

View file

@ -4,7 +4,7 @@ import ColorPicker from 'react-native-wheel-color-picker';
import { queryClient, useLibraryMutation } from '@sd/client';
import Dialog from '~/components/layout/Dialog';
import { Input } from '~/components/primitive/Input';
import tw from '~/lib/tailwind';
import tw, { twStyle } from '~/lib/tailwind';
type Props = {
onSubmit?: () => void;
@ -57,17 +57,17 @@ const CreateTagDialog = ({ children, onSubmit, disableBackdropClose }: Props) =>
<View style={tw`flex flex-row items-center`}>
<Pressable
onPress={() => setShowPicker((v) => !v)}
style={tw.style({ backgroundColor: tagColor }, 'w-5 h-5 rounded-full')}
style={twStyle({ backgroundColor: tagColor }, 'h-5 w-5 rounded-full')}
/>
<Input
style={tw`flex-1 ml-2`}
style={tw`ml-2 flex-1`}
value={tagName}
onChangeText={(text) => setTagName(text)}
placeholder="Name"
/>
</View>
{showPicker && (
<View style={tw`h-64 mt-4`}>
<View style={tw`my-4 h-64`}>
<ColorPicker
autoResetSlider
gapSize={0}

View file

@ -4,7 +4,7 @@ import ColorPicker from 'react-native-wheel-color-picker';
import { Tag, queryClient, useLibraryMutation } from '@sd/client';
import Dialog from '~/components/layout/Dialog';
import { Input } from '~/components/primitive/Input';
import tw from '~/lib/tailwind';
import tw, { twStyle } from '~/lib/tailwind';
type Props = {
tag: Tag;
@ -48,20 +48,20 @@ const UpdateTagDialog = ({ children, onSubmit, tag }: Props) => {
setShowPicker(false); // Reset form
}}
>
<Text style={tw`mb-1 text-xs font-medium text-ink-dull ml-1 mt-3`}>Name</Text>
<Text style={tw`text-ink-dull mb-1 ml-1 mt-3 text-xs font-medium`}>Name</Text>
<Input value={tagName} onChangeText={(t) => setTagName(t)} />
<Text style={tw`mb-1 text-xs font-medium text-ink-dull ml-1 mt-3`}>Color</Text>
<View style={tw`flex flex-row items-center ml-2`}>
<Text style={tw`text-ink-dull mb-1 ml-1 mt-3 text-xs font-medium`}>Color</Text>
<View style={tw`ml-2 flex flex-row items-center`}>
<Pressable
onPress={() => setShowPicker((v) => !v)}
style={tw.style({ backgroundColor: tagColor }, 'w-5 h-5 rounded-full')}
style={twStyle({ backgroundColor: tagColor }, 'h-5 w-5 rounded-full')}
/>
{/* TODO: Make this editable. Need to make sure color is a valid hexcode and update the color on picker etc. etc. */}
<Input editable={false} value={tagColor} style={tw`flex-1 ml-2`} />
<Input editable={false} value={tagColor} style={tw`ml-2 flex-1`} />
</View>
{showPicker && (
<View style={tw`h-64 mt-4`}>
<View style={tw`mt-4 h-64`}>
<ColorPicker
autoResetSlider
gapSize={0}

View file

@ -3,7 +3,7 @@ import { DrawerContentComponentProps } from '@react-navigation/drawer/lib/typesc
import { Gear } from 'phosphor-react-native';
import { Image, Platform, Pressable, Text, View } from 'react-native';
import Layout from '~/constants/Layout';
import tw from '~/lib/tailwind';
import tw, { twStyle } from '~/lib/tailwind';
import { getStackNameFromState } from '~/utils/nav';
import Divider from '../../components/primitive/Divider';
import DrawerLibraryManager from './DrawerLibraryManager';
@ -20,11 +20,11 @@ const DrawerContent = ({ navigation, state }: DrawerContentComponentProps) => {
return (
<DrawerContentScrollView style={tw`flex-1 px-4 py-2`} scrollEnabled={false}>
<View style={tw.style('justify-between', { height: drawerHeight })}>
<View style={twStyle('justify-between', { height: drawerHeight })}>
<View>
<View style={tw`flex flex-row items-center`}>
<Image source={require('@sd/assets/images/logo.png')} style={tw`w-[35px] h-[35px]`} />
<Text style={tw`text-base font-bold text-ink ml-2`}>Spacedrive</Text>
<Image source={require('@sd/assets/images/logo.png')} style={tw`h-[35px] w-[35px]`} />
<Text style={tw`text-ink ml-2 text-base font-bold`}>Spacedrive</Text>
</View>
<Divider style={tw`my-4`} />
{/* Library Manager */}

View file

@ -5,7 +5,7 @@ import { CaretRight, Gear, Lock, Plus } from 'phosphor-react-native';
import { useEffect, useState } from 'react';
import { Pressable, Text, View } from 'react-native';
import { useCurrentLibrary } from '~/../../../packages/client/src';
import tw from '~/lib/tailwind';
import tw, { twStyle } from '~/lib/tailwind';
import { AnimatedHeight } from '../../components/animation/layout';
import Divider from '../../components/primitive/Divider';
import CreateLibraryDialog from '../dialog/CreateLibraryDialog';
@ -27,9 +27,9 @@ const DrawerLibraryManager = () => {
<View>
<Pressable onPress={() => setDropdownClosed((v) => !v)}>
<View
style={tw.style(
'flex flex-row justify-between items-center px-3 h-10 w-full bg-app-box border border-app-darkLine shadow-sm',
dropdownClosed ? 'rounded' : 'rounded-t border-b-app-box'
style={twStyle(
'border-app-darkLine bg-app-box flex h-10 w-full flex-row items-center justify-between border px-3 shadow-sm',
dropdownClosed ? 'rounded' : 'border-b-app-box rounded-t'
)}
>
<Text style={tw`text-ink text-sm font-semibold`}>{currentLibrary?.config.name}</Text>
@ -44,21 +44,19 @@ const DrawerLibraryManager = () => {
</View>
</Pressable>
<AnimatedHeight hide={dropdownClosed}>
<View
style={tw`py-2 px-2 bg-app-box border-l border-b border-r border-app-darkLine rounded-b`}
>
<View style={tw`border-app-darkLine bg-app-box rounded-b border-x border-b p-2`}>
{/* Libraries */}
{libraries?.map((library) => (
<Pressable key={library.uuid} onPress={() => switchLibrary(library.uuid)}>
<View
style={tw.style(
'p-2 mt-1',
style={twStyle(
'mt-1 p-2',
currentLibrary.uuid === library.uuid && 'bg-accent rounded'
)}
>
<Text
style={tw.style(
'text-sm text-ink font-semibold',
style={twStyle(
'text-ink text-sm font-semibold',
currentLibrary.uuid === library.uuid && 'text-white'
)}
>
@ -67,27 +65,27 @@ const DrawerLibraryManager = () => {
</View>
</Pressable>
))}
<Divider style={tw`mt-2 mb-2`} />
<Divider style={tw`my-2`} />
{/* Menu */}
<Pressable
onPress={() => navigation.navigate('Settings', { screen: 'LibraryGeneralSettings' })}
>
<View style={tw`flex flex-row items-center px-1.5 py-[8px]`}>
<Gear size={16} color={tw.color('ink-dull')} style={tw`mr-2`} />
<Text style={tw`text-sm text-ink font-semibold`}>Library Settings</Text>
<Text style={tw`text-ink text-sm font-semibold`}>Library Settings</Text>
</View>
</Pressable>
{/* Create Library */}
<CreateLibraryDialog>
<View style={tw`flex flex-row items-center px-1.5 py-[8px]`}>
<Plus size={16} weight="bold" color={tw.color('ink-dull')} style={tw`mr-2`} />
<Text style={tw`text-sm text-ink font-semibold`}>Add Library</Text>
<Text style={tw`text-ink text-sm font-semibold`}>Add Library</Text>
</View>
</CreateLibraryDialog>
<Pressable onPress={() => console.log('TODO: lock')}>
<View style={tw`flex flex-row items-center px-1.5 py-[8px]`}>
<Lock size={16} weight="bold" color={tw.color('ink-dull')} style={tw`mr-2`} />
<Text style={tw`text-sm text-ink font-semibold`}>Lock</Text>
<Text style={tw`text-ink text-sm font-semibold`}>Lock</Text>
</View>
</Pressable>
</View>

View file

@ -4,7 +4,7 @@ import { useNavigation } from '@react-navigation/native';
import { useRef } from 'react';
import { Pressable, Text, View } from 'react-native';
import { useLibraryQuery } from '@sd/client';
import tw from '~/lib/tailwind';
import tw, { twStyle } from '~/lib/tailwind';
import FolderIcon from '../../components/icons/FolderIcon';
import CollapsibleView from '../../components/layout/CollapsibleView';
import ImportModal from '../modal/ImportModal';
@ -19,9 +19,9 @@ const DrawerLocationItem: React.FC<DrawerLocationItemProps> = (props) => {
return (
<Pressable onPress={onPress}>
<View style={tw.style('flex mb-[4px] flex-row items-center py-2 px-1 rounded')}>
<View style={twStyle('mb-[4px] flex flex-row items-center rounded py-2 px-1')}>
<FolderIcon size={18} />
<Text style={tw.style('text-gray-300 text-sm font-medium ml-2')} numberOfLines={1}>
<Text style={twStyle('ml-2 text-sm font-medium text-gray-300')} numberOfLines={1}>
{folderName}
</Text>
</View>
@ -63,10 +63,8 @@ const DrawerLocations = ({ stackName }: DrawerLocationsProp) => {
</View>
{/* Add Location */}
<Pressable onPress={() => importModalRef.current.present()}>
<View style={tw`border border-dashed rounded border-app-line border-opacity-80 mt-1`}>
<Text style={tw`text-xs font-bold text-center text-gray-400 px-2 py-2`}>
Add Location
</Text>
<View style={tw`border-opacity/80 border-app-line mt-1 rounded border border-dashed`}>
<Text style={tw`p-2 text-center text-xs font-bold text-gray-400`}>Add Location</Text>
</View>
</Pressable>
</CollapsibleView>

View file

@ -2,7 +2,7 @@ import { DrawerNavigationHelpers } from '@react-navigation/drawer/lib/typescript
import { useNavigation } from '@react-navigation/native';
import { ColorValue, Pressable, Text, View } from 'react-native';
import { useLibraryQuery } from '@sd/client';
import tw from '~/lib/tailwind';
import tw, { twStyle } from '~/lib/tailwind';
import CollapsibleView from '../../components/layout/CollapsibleView';
import CreateTagDialog from '../dialog/tag/CreateTagDialog';
@ -16,9 +16,9 @@ const DrawerTagItem: React.FC<DrawerTagItemProps> = (props) => {
const { tagName, tagColor, onPress } = props;
return (
<Pressable onPress={onPress}>
<View style={tw.style('flex mb-[4px] flex-row items-center py-2 px-1 rounded')}>
<View style={tw.style('w-3 h-3 rounded-full', { backgroundColor: tagColor })} />
<Text style={tw.style('text-gray-300 text-sm font-medium ml-2')} numberOfLines={1}>
<View style={twStyle('mb-[4px] flex flex-row items-center rounded py-2 px-1')}>
<View style={twStyle('h-3 w-3 rounded-full', { backgroundColor: tagColor })} />
<Text style={twStyle('ml-2 text-sm font-medium text-gray-300')} numberOfLines={1}>
{tagName}
</Text>
</View>
@ -58,8 +58,8 @@ const DrawerTags = ({ stackName }: DrawerTagsProp) => {
</View>
{/* Add Tag */}
<CreateTagDialog>
<View style={tw`border border-dashed rounded border-app-line border-opacity-80 mt-1`}>
<Text style={tw`text-xs font-bold text-center text-gray-400 px-2 py-2`}>Add Tag</Text>
<View style={tw`border-opacity/80 border-app-line mt-1 rounded border border-dashed`}>
<Text style={tw`p-2 text-center text-xs font-bold text-gray-400`}>Add Tag</Text>
</View>
</CreateTagDialog>
</CollapsibleView>

View file

@ -24,7 +24,7 @@ const SortByMenu = () => {
<Menu
trigger={
<View style={tw`flex flex-row items-center`}>
<Text style={tw`text-ink font-medium mr-0.5`}>{sortOptions[sortBy]}</Text>
<Text style={tw`text-ink mr-0.5 font-medium`}>{sortOptions[sortBy]}</Text>
{sortDirection === 'asc' ? <ArrowUpIcon /> : <ArrowDownIcon />}
</View>
}

View file

@ -18,7 +18,7 @@ function MetaItem({ title, value }: MetaItemProps) {
return (
<View>
<Text style={tw`text-sm font-bold text-white`}>{title}</Text>
<Text style={tw`text-sm text-gray-400 mt-1`}>{value}</Text>
<Text style={tw`mt-1 text-sm text-gray-400`}>{value}</Text>
</View>
);
}
@ -34,14 +34,14 @@ export const FileModal = () => {
<>
<Modal ref={fileRef} snapPoints={['60%', '90%']}>
{data && (
<View style={tw`flex-1 p-4 bg-app`}>
<View style={tw`bg-app flex-1 p-4`}>
{/* File Icon / Name */}
<View style={tw`flex flex-row items-center`}>
<FileIcon data={data} size={1.6} />
{/* File Name, Details etc. */}
<View style={tw`ml-2`}>
<Text style={tw`text-base font-bold text-gray-200`}>{item.name}</Text>
<View style={tw`flex flex-row mt-2`}>
<View style={tw`mt-2 flex flex-row`}>
<Text style={tw`text-xs text-gray-400`}>5 MB,</Text>
<Text style={tw`ml-1 text-xs text-gray-400`}>
{item.extension.toUpperCase()},
@ -49,7 +49,7 @@ export const FileModal = () => {
<Text style={tw`ml-1 text-xs text-gray-400`}>15 Aug</Text>
</View>
<Pressable style={tw`mt-2`} onPress={() => fileDetailsRef.current.present()}>
<Text style={tw`text-sm text-accent`}>More</Text>
<Text style={tw`text-accent text-sm`}>More</Text>
</Pressable>
</View>
</View>
@ -71,15 +71,15 @@ export const FileModal = () => {
snapPoints={['70%']}
>
{data && (
<BottomSheetScrollView style={tw`flex-1 p-4 bg-app`}>
<BottomSheetScrollView style={tw`bg-app flex-1 p-4`}>
{/* Back Button */}
<Pressable style={tw`w-full ml-4`} onPress={() => fileDetailsRef.current.close()}>
<Pressable style={tw`ml-4 w-full`} onPress={() => fileDetailsRef.current.close()}>
<CaretLeft color={tw.color('accent')} size={20} />
</Pressable>
{/* File Icon / Name */}
<View style={tw`items-center`}>
<FileThumb data={data} size={1.8} />
<Text style={tw`text-base font-bold text-gray-200 mt-3`}>{item.name}</Text>
<Text style={tw`mt-3 text-base font-bold text-gray-200`}>{item.name}</Text>
</View>
{/* Details */}
<Divider style={tw`mt-6 mb-4`} />

View file

@ -126,7 +126,7 @@ const ImportModal = forwardRef<BottomSheetModal, unknown>((_, ref) => {
return (
<Modal ref={modalRef} snapPoints={['20%']}>
<View style={tw`flex-1 px-6 pt-1 pb-2 bg-app-box`}>
<View style={tw`bg-app-box flex-1 px-6 pt-1 pb-2`}>
{/* <Button size="md" variant="accent" style={tw`my-2`} onPress={testFN}>
<Text>TEST</Text>
</Button> */}

View file

@ -3,3 +3,4 @@ import { create } from 'twrnc';
const tw = create(require(`../../tailwind.config.js`));
export default tw;
export const twStyle = tw.style;

View file

@ -36,7 +36,7 @@ export default function TabNavigator() {
/>
),
tabBarLabel: 'Overview',
tabBarLabelStyle: tw`font-semibold text-tiny`
tabBarLabelStyle: tw`text-tiny font-semibold`
}}
/>
<Tab.Screen
@ -51,7 +51,7 @@ export default function TabNavigator() {
/>
),
tabBarLabel: 'Nodes',
tabBarLabelStyle: tw`font-semibold text-tiny`
tabBarLabelStyle: tw`text-tiny font-semibold`
}}
/>
<Tab.Screen
@ -66,7 +66,7 @@ export default function TabNavigator() {
/>
),
tabBarLabel: 'Spaces',
tabBarLabelStyle: tw`font-semibold text-tiny`
tabBarLabelStyle: tw`text-tiny font-semibold`
}}
/>
</Tab.Navigator>

View file

@ -5,7 +5,7 @@ import { NodesStackScreenProps } from '~/navigation/tabs/NodesStack';
export default function NodesScreen({ navigation }: NodesStackScreenProps<'Nodes'>) {
return (
<View style={tw`flex-1 items-center justify-center`}>
<Text style={tw`font-bold text-xl text-ink`}>Nodes</Text>
<Text style={tw`text-ink text-xl font-bold`}>Nodes</Text>
</View>
);
}

View file

@ -5,9 +5,9 @@ import { RootStackScreenProps } from '~/navigation';
export default function NotFoundScreen({ navigation }: RootStackScreenProps<'NotFound'>) {
return (
<View style={tw`flex-1 items-center justify-center p-5`}>
<Text style={tw`font-bold text-xl`}>This screen doesn&apos;t exist.</Text>
<Text style={tw`text-xl font-bold`}>This screen doesn&apos;t exist.</Text>
<TouchableOpacity onPress={() => navigation.replace('Root')} style={tw`mt-4 py-4`}>
<Text style={tw`text-sm text-ink-dull`}>Go to home screen!</Text>
<Text style={tw`text-ink-dull text-sm`}>Go to home screen!</Text>
</TouchableOpacity>
</View>
);

View file

@ -34,7 +34,7 @@ import { OverviewStackScreenProps } from '~/navigation/tabs/OverviewStack';
export default function OverviewScreen({ navigation }: OverviewStackScreenProps<'Overview'>) {
return (
<VirtualizedListWrapper>
<View style={tw`px-4 mt-4`}>
<View style={tw`mt-4 px-4`}>
{/* Stats */}
<OverviewStats />
{/* Devices */}

View file

@ -3,7 +3,7 @@ import { useState } from 'react';
import { ActivityIndicator, Pressable, Text, TextInput, View } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { Button } from '~/components/primitive/Button';
import tw from '~/lib/tailwind';
import tw, { twStyle } from '~/lib/tailwind';
import { RootStackScreenProps } from '~/navigation';
const SearchScreen = ({ navigation }: RootStackScreenProps<'Search'>) => {
@ -14,12 +14,12 @@ const SearchScreen = ({ navigation }: RootStackScreenProps<'Search'>) => {
// TODO: Animations!
return (
<View style={tw.style('flex-1', { marginTop: top + 10 })}>
<View style={twStyle('flex-1', { marginTop: top + 10 })}>
{/* Header */}
<View style={tw`flex flex-row items-center mx-4`}>
<View style={tw`mx-4 flex flex-row items-center`}>
{/* Search Input */}
<View style={tw`flex-1 bg-app-overlay border border-app-line rounded h-10 mr-3`}>
<View style={tw`flex flex-row h-full items-center px-3`}>
<View style={tw`border-app-line bg-app-overlay mr-3 h-10 flex-1 rounded border`}>
<View style={tw`flex h-full flex-row items-center px-3`}>
<View style={tw`mr-3`}>
{loading ? (
<ActivityIndicator size={'small'} color={'white'} />
@ -32,7 +32,7 @@ const SearchScreen = ({ navigation }: RootStackScreenProps<'Search'>) => {
clearButtonMode="never" // can't change the color??
underlineColorAndroid="transparent"
placeholderTextColor={tw.color('ink-dull')}
style={tw`flex-1 text-ink font-medium text-sm`}
style={tw`text-ink flex-1 text-sm font-medium`}
textContentType={'none'}
autoFocus
autoCapitalize="none"
@ -46,7 +46,7 @@ const SearchScreen = ({ navigation }: RootStackScreenProps<'Search'>) => {
</Pressable>
</View>
{/* Content */}
<View style={tw`flex-1 items-center mt-8`}>
<View style={tw`mt-8 flex-1 items-center`}>
<Button variant="accent" onPress={() => setLoading((v) => !v)}>
<Text>Toggle loading</Text>
</Button>

View file

@ -4,8 +4,8 @@ import { SpacesStackScreenProps } from '~/navigation/tabs/SpacesStack';
export default function SpacesScreen({ navigation }: SpacesStackScreenProps<'Spaces'>) {
return (
<View style={tw`items-center justify-center flex-1`}>
<Text style={tw`text-xl font-bold text-ink`}>Spaces</Text>
<View style={tw`flex-1 items-center justify-center`}>
<Text style={tw`text-ink text-xl font-bold`}>Spaces</Text>
</View>
);
}

View file

@ -11,7 +11,7 @@ export default function TagScreen({ navigation, route }: SharedScreenProps<'Tag'
return (
<View style={tw`flex-1 items-center justify-center`}>
<Text style={tw`font-bold text-xl text-ink`}>Tag {id}</Text>
<Text style={tw`text-ink text-xl font-bold`}>Tag {id}</Text>
<Explorer data={data} />
</View>
);

View file

@ -6,13 +6,13 @@ import { OnboardingStackScreenProps } from '~/navigation/OnboardingNavigator';
const CreateLibraryScreen = ({ navigation }: OnboardingStackScreenProps<'CreateLibrary'>) => {
return (
<View style={tw`flex-1 items-center justify-center bg-app p-4`}>
<Text style={tw`text-ink-dull text-center px-6 my-8 text-base leading-relaxed`}>
<View style={tw`bg-app flex-1 items-center justify-center p-4`}>
<Text style={tw`text-ink-dull my-8 px-6 text-center text-base leading-relaxed`}>
Onboarding screen for users to create their first library
</Text>
<CreateLibraryDialog disableBackdropClose>
<AnimatedButton variant="accent">
<Text style={tw`text-ink text-center px-6 py-2 text-base font-medium`}>
<Text style={tw`text-ink px-6 py-2 text-center text-base font-medium`}>
Create Library
</Text>
</AnimatedButton>

View file

@ -6,11 +6,11 @@ import { OnboardingStackScreenProps } from '~/navigation/OnboardingNavigator';
const OnboardingScreen = ({ navigation }: OnboardingStackScreenProps<'Onboarding'>) => {
return (
<View style={tw`flex-1 items-center justify-around bg-app p-4 z-10`}>
<View style={tw`bg-app z-10 flex-1 items-center justify-around p-4`}>
{/* Logo */}
<LogoAnimation>
<View style={tw`items-center mt-2`}>
<Image source={require('@sd/assets/images/logo.png')} style={tw`w-24 h-24`} />
<View style={tw`mt-2 items-center`}>
<Image source={require('@sd/assets/images/logo.png')} style={tw`h-24 w-24`} />
</View>
</LogoAnimation>
{/* Text */}
@ -21,7 +21,7 @@ const OnboardingScreen = ({ navigation }: OnboardingStackScreenProps<'Onboarding
</Text>
</FadeInUpAnimation>
<FadeInUpAnimation delay={800}>
<Text style={tw`text-ink-dull text-center px-6 mt-8 text-base leading-relaxed`}>
<Text style={tw`text-ink-dull mt-8 px-6 text-center text-base leading-relaxed`}>
Combine your drives and clouds into one database that you can organize and explore from
any device.
</Text>
@ -30,7 +30,7 @@ const OnboardingScreen = ({ navigation }: OnboardingStackScreenProps<'Onboarding
{/* Get Started Button */}
<FadeInUpAnimation delay={1200}>
<AnimatedButton variant="accent" onPress={() => navigation.navigate('CreateLibrary')}>
<Text style={tw`text-ink text-center px-6 py-2 text-base font-medium`}>Get Started</Text>
<Text style={tw`text-ink px-6 py-2 text-center text-base font-medium`}>Get Started</Text>
</AnimatedButton>
</FadeInUpAnimation>
</View>

View file

@ -15,7 +15,7 @@ import {
import React from 'react';
import { SectionList, Text, View } from 'react-native';
import { SettingsItem, SettingsItemDivider } from '~/components/settings/SettingsItem';
import tw from '~/lib/tailwind';
import tw, { twStyle } from '~/lib/tailwind';
import { SettingsStackParamList, SettingsStackScreenProps } from '~/navigation/SettingsNavigator';
type SectionType = {
@ -108,8 +108,8 @@ const sections: SectionType[] = [
function renderSectionHeader({ section }: { section: { title: string } }) {
return (
<Text
style={tw.style(
'mb-2 ml-2 text-sm font-semibold text-ink-dull',
style={twStyle(
'text-ink-dull mb-2 ml-2 text-sm font-semibold',
section.title === 'Client' ? 'mt-2' : 'mt-5'
)}
>
@ -134,9 +134,9 @@ export default function SettingsScreen({ navigation }: SettingsStackScreenProps<
)}
renderSectionHeader={renderSectionHeader}
ListFooterComponent={
<View style={tw`items-center mt-6 mb-4`}>
<Text style={tw`text-sm font-bold text-ink`}>Spacedrive</Text>
<Text style={tw`text-ink-dull text-xs mt-0.5`}>v0.1.0</Text>
<View style={tw`mt-6 mb-4 items-center`}>
<Text style={tw`text-ink text-sm font-bold`}>Spacedrive</Text>
<Text style={tw`text-ink-dull mt-0.5 text-xs`}>v0.1.0</Text>
</View>
}
showsVerticalScrollIndicator={false}

View file

@ -17,24 +17,24 @@ const GeneralSettingsScreen = ({ navigation }: SettingsStackScreenProps<'General
<Card>
{/* Card Header */}
<View style={tw`flex flex-row justify-between`}>
<Text style={tw`font-semibold text-ink`}>Connected Node</Text>
<Text style={tw`text-ink font-semibold`}>Connected Node</Text>
<View style={tw`flex flex-row`}>
{/* Peers */}
<View style={tw`rounded bg-app-highlight self-start px-1.5 py-[2px] mr-2`}>
<Text style={tw`text-xs font-semibold text-ink`}>0 Peers</Text>
<View style={tw`bg-app-highlight mr-2 self-start rounded px-1.5 py-[2px]`}>
<Text style={tw`text-ink text-xs font-semibold`}>0 Peers</Text>
</View>
{/* Status */}
<View style={tw`px-1.5 py-[2px] rounded bg-accent`}>
<Text style={tw`text-xs font-semibold text-ink`}>Running</Text>
<View style={tw`bg-accent rounded px-1.5 py-[2px]`}>
<Text style={tw`text-ink text-xs font-semibold`}>Running</Text>
</View>
</View>
</View>
{/* Divider */}
<Divider style={tw`mt-2 mb-4`} />
{/* Node Name and Port */}
<Text style={tw`mb-1 text-xs font-medium text-ink-dull ml-1`}>Node Name</Text>
<Text style={tw`text-ink-dull mb-1 ml-1 text-xs font-medium`}>Node Name</Text>
<Input value={node.name} />
<Text style={tw`mt-2 mb-1 text-xs font-medium text-ink-dull ml-1`}>Node Port</Text>
<Text style={tw`text-ink-dull mt-2 mb-1 ml-1 text-xs font-medium`}>Node Port</Text>
<Input value={node.p2p_port?.toString() ?? '5795'} keyboardType="numeric" />
</Card>
</View>

View file

@ -5,7 +5,7 @@ import { Swipeable } from 'react-native-gesture-handler';
import { LibraryConfigWrapped, useBridgeQuery } from '@sd/client';
import { AnimatedButton } from '~/components/primitive/Button';
import DeleteLibraryDialog from '~/containers/dialog/DeleteLibraryDialog';
import tw from '~/lib/tailwind';
import tw, { twStyle } from '~/lib/tailwind';
import { SettingsStackScreenProps } from '~/navigation/SettingsNavigator';
function LibraryItem({
@ -45,17 +45,17 @@ function LibraryItem({
return (
<Swipeable
containerStyle={tw.style(
containerStyle={twStyle(
index !== 0 && 'mt-2',
'bg-app-overlay border border-app-line rounded-lg px-4 py-3'
'border-app-line bg-app-overlay rounded-lg border px-4 py-3'
)}
enableTrackpadTwoFingerGesture
renderRightActions={renderRightActions}
>
<View style={tw`flex flex-row items-center justify-between`}>
<View>
<Text style={tw`font-semibold text-ink`}>{library.config.name}</Text>
<Text style={tw`mt-0.5 text-xs text-ink-dull`}>{library.uuid}</Text>
<Text style={tw`text-ink font-semibold`}>{library.config.name}</Text>
<Text style={tw`text-ink-dull mt-0.5 text-xs`}>{library.uuid}</Text>
</View>
<CaretRight color={tw.color('ink-dull')} size={18} />
</View>
@ -67,7 +67,7 @@ const LibrarySettingsScreen = ({ navigation }: SettingsStackScreenProps<'Library
const { data: libraries } = useBridgeQuery(['library.list']);
return (
<View style={tw`py-4 px-3 flex-1`}>
<View style={tw`flex-1 py-4 px-3`}>
<FlatList
data={libraries}
keyExtractor={(item) => item.uuid}

View file

@ -32,8 +32,8 @@ const LibraryGeneralSettingsScreen = ({
return (
<View>
{/* This looks bad... */}
<View style={tw`mt-4 px-2 py-4 bg-app-overlay`}>
<Text style={tw`mb-1 text-xs font-medium text-ink-dull ml-1`}>Name</Text>
<View style={tw`bg-app-overlay mt-4 px-2 py-4`}>
<Text style={tw`text-ink-dull mb-1 ml-1 text-xs font-medium`}>Name</Text>
<Controller
name="name"
control={form.control}
@ -42,7 +42,7 @@ const LibraryGeneralSettingsScreen = ({
)}
/>
{/* Description */}
<Text style={tw`mb-1 text-xs font-medium text-ink-dull ml-1 mt-3`}>Description</Text>
<Text style={tw`text-ink-dull mb-1 ml-1 mt-3 text-xs font-medium`}>Description</Text>
<Controller
name="description"
control={form.control}

View file

@ -11,7 +11,7 @@ import {
} from '@sd/client';
import FolderIcon from '~/components/icons/FolderIcon';
import DeleteLocationDialog from '~/containers/dialog/DeleteLocationDialog';
import tw from '~/lib/tailwind';
import tw, { twStyle } from '~/lib/tailwind';
import { SettingsStackScreenProps } from '~/navigation/SettingsNavigator';
function LocationItem({ location, index }: { location: Location & { node: Node }; index: number }) {
@ -36,14 +36,14 @@ function LocationItem({ location, index }: { location: Location & { node: Node }
>
<DeleteLocationDialog locationId={location.id}>
<View
style={tw`py-1.5 px-3 bg-app-button border-app-line border rounded-md items-center justify-center shadow-sm`}
style={tw`border-app-line bg-app-button items-center justify-center rounded-md border py-1.5 px-3 shadow-sm`}
>
<Trash size={18} color="white" />
</View>
</DeleteLocationDialog>
{/* Full Re-scan IS too much here */}
<Pressable
style={tw`py-1.5 px-3 bg-app-button border-app-line border rounded-md items-center justify-center shadow-sm mx-2`}
style={tw`border-app-line bg-app-button mx-2 items-center justify-center rounded-md border py-1.5 px-3 shadow-sm`}
onPress={() => fullRescan.mutate(location.id)}
>
<Repeat size={18} color="white" />
@ -54,8 +54,8 @@ function LocationItem({ location, index }: { location: Location & { node: Node }
return (
<Swipeable
containerStyle={tw.style(
'bg-app-overlay border border-app-line rounded-lg px-4 py-3',
containerStyle={twStyle(
'border-app-line bg-app-overlay rounded-lg border px-4 py-3',
index !== 0 && 'mt-2'
)}
enableTrackpadTwoFingerGesture
@ -66,24 +66,24 @@ function LocationItem({ location, index }: { location: Location & { node: Node }
<FolderIcon size={32} />
{/* Online/Offline Indicator */}
<View
style={tw.style(
'absolute w-2 h-2 right-0 bottom-0.5 rounded-full',
style={twStyle(
'absolute right-0 bottom-0.5 h-2 w-2 rounded-full',
onlineLocations.some((l) => arraysEqual(location.pub_id, l))
? 'bg-green-500'
: 'bg-red-500'
)}
/>
</View>
<View style={tw`flex-1 mx-4`}>
<Text numberOfLines={1} style={tw`text-sm font-semibold text-ink`}>
<View style={tw`mx-4 flex-1`}>
<Text numberOfLines={1} style={tw`text-ink text-sm font-semibold`}>
{location.name}
</Text>
<View style={tw`self-start bg-app-highlight py-[1px] px-1 rounded mt-0.5`}>
<Text numberOfLines={1} style={tw`text-xs font-semibold text-ink-dull`}>
<View style={tw`bg-app-highlight mt-0.5 self-start rounded py-[1px] px-1`}>
<Text numberOfLines={1} style={tw`text-ink-dull text-xs font-semibold`}>
{location.node.name}
</Text>
</View>
<Text numberOfLines={1} style={tw`mt-0.5 text-[10px] font-semibold text-ink-dull`}>
<Text numberOfLines={1} style={tw`text-ink-dull mt-0.5 text-[10px] font-semibold`}>
{location.local_path}
</Text>
</View>

View file

@ -5,7 +5,7 @@ import { Tag, useLibraryQuery } from '@sd/client';
import { AnimatedButton } from '~/components/primitive/Button';
import DeleteTagDialog from '~/containers/dialog/tag/DeleteTagDialog';
import UpdateTagDialog from '~/containers/dialog/tag/UpdateTagDialog';
import tw from '~/lib/tailwind';
import tw, { twStyle } from '~/lib/tailwind';
import { SettingsStackScreenProps } from '~/navigation/SettingsNavigator';
function TagItem({ tag, index }: { tag: Tag; index: number }) {
@ -40,8 +40,8 @@ function TagItem({ tag, index }: { tag: Tag; index: number }) {
return (
<Swipeable
containerStyle={tw.style(
'bg-app-overlay border border-app-line rounded-lg px-4 py-3',
containerStyle={twStyle(
'border-app-line bg-app-overlay rounded-lg border px-4 py-3',
index !== 0 && 'mt-2'
)}
enableTrackpadTwoFingerGesture
@ -49,8 +49,8 @@ function TagItem({ tag, index }: { tag: Tag; index: number }) {
>
<View style={tw`flex flex-row items-center justify-between`}>
<View style={tw`flex flex-row`}>
<View style={tw.style({ backgroundColor: tag.color }, 'w-4 h-4 rounded-full')} />
<Text style={tw`ml-3 text-ink`}>{tag.name}</Text>
<View style={twStyle({ backgroundColor: tag.color }, 'h-4 w-4 rounded-full')} />
<Text style={tw`text-ink ml-3`}>{tag.name}</Text>
</View>
<CaretRight color={tw.color('ink-dull')} size={18} />
</View>

View file

@ -13,8 +13,8 @@ export function App() {
const testCreate = rspc.useMutation('testCreate');
return (
<div className="w-screen h-screen flex flex-row divide-x divide-gray-300">
<div className="p-2 space-y-2 flex flex-col">
<div className="flex h-screen w-screen flex-row divide-x divide-gray-300">
<div className="flex flex-col space-y-2 p-2">
<div className="space-x-2">
<button className={ButtonStyles} onClick={() => createDb.mutate('pullOperations')}>
Add Database
@ -29,7 +29,7 @@ export function App() {
<ul className="w-full">
{Object.entries(tests).map(([key, test]) => (
<li key={key}>
<button className="p-2 bg-green-300" onClick={() => test.run()}>
<button className="bg-green-300 p-2" onClick={() => test.run()}>
{test.name}
</button>
</li>
@ -37,7 +37,7 @@ export function App() {
</ul>
</div>
<div className="flex-1">
<ul className="p-2 gap-2 flex flex-row flex-wrap">
<ul className="flex flex-row flex-wrap gap-2 p-2">
{dbs.data?.map((id) => (
<Suspense fallback={null} key={id}>
<DatabaseView id={id} />
@ -45,11 +45,11 @@ export function App() {
))}
</ul>
</div>
<div className="w-96 p-2 flex flex-col items-stretch">
<h1 className="text-center font-bold text-2xl">All Operations</h1>
<div className="flex w-96 flex-col items-stretch p-2">
<h1 className="text-center text-2xl font-bold">All Operations</h1>
<ul className="space-y-2">
{operations.data?.map((op) => (
<li key={op.id} className="bg-indigo-200 rounded-md p-2">
<li key={op.id} className="rounded-md bg-indigo-200 p-2">
<p className="truncate">ID: {op.id}</p>
<p className="truncate">Timestamp: {op.timestamp.toString()}</p>
<p className="truncate">Node: {op.node}</p>
@ -72,8 +72,8 @@ function DatabaseView(props: DatabaseViewProps) {
const pullOperations = rspc.useMutation('pullOperations');
return (
<div className="bg-indigo-300 rounded-md min-w-[32rem] flex-1 overflow-hidden">
<div className="flex flex-row justify-between items-center mx-2">
<div className="min-w-[32rem] flex-1 overflow-hidden rounded-md bg-indigo-300">
<div className="mx-2 flex flex-row items-center justify-between">
<h1 className="p-2 text-xl font-medium">{props.id}</h1>
<button className={ButtonStyles} onClick={() => pullOperations.mutate(props.id)}>
Pull Operations
@ -136,7 +136,7 @@ function OperationList(props: { db: string }) {
return (
<div>
{messages.data && (
<table className="font-mono border-spacing-x-4 border-separate">
<table className="border-separate border-spacing-x-4 font-mono">
{messages.data
.sort((a, b) => Number(a.timestamp - b.timestamp))
.map((message) => (

View file

@ -23,6 +23,7 @@
"codegen": "cargo test -p sd-core api::tests::test_and_export_rspc_bindings -- --exact",
"typecheck": "turbo run typecheck",
"lint": "turbo run lint",
"lint:fix": "turbo run lint -- --fix",
"clean": "rimraf node_modules/ **/node_modules/ target/ **/.build/ **/.next/ **/dist/**"
},
"pnpm": {
@ -40,6 +41,7 @@
"lint-staged": "^13.1.0",
"markdown-link-check": "^3.10.3",
"prettier": "^2.8.3",
"prettier-plugin-tailwindcss": "^0.2.2",
"rimraf": "^4.1.1",
"turbo": "^1.5.5",
"turbo-ignore": "^0.3.0",

View file

@ -12,6 +12,7 @@ module.exports = {
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'plugin:@typescript-eslint/recommended',
'plugin:tailwindcss/recommended',
'prettier',
'turbo'
],
@ -32,12 +33,19 @@ module.exports = {
'@typescript-eslint/no-empty-interface': 'off',
'@typescript-eslint/no-empty-function': 'off',
'no-control-regex': 'off',
'no-mixed-spaces-and-tabs': ['warn', 'smart-tabs']
'no-mixed-spaces-and-tabs': ['warn', 'smart-tabs'],
'tailwindcss/no-custom-classname': 'off',
'tailwindcss/no-contradicting-classname': 'warn'
},
ignorePatterns: ['dist', '**/*.js', '**/*.json', 'node_modules'],
settings: {
react: {
version: 'detect'
},
tailwindcss: {
config: 'packages/ui/style/tailwind.js',
callees: ['classnames', 'clsx', 'ctl', 'cva', 'tw', `twStyle`],
tags: ['tw', 'twStyle']
}
}
};

View file

@ -23,5 +23,10 @@ module.exports = {
]
}
]
},
settings: {
tailwindcss: {
config: 'apps/mobile/tailwind.config.js'
}
}
};

View file

@ -10,12 +10,13 @@
"eslint-react.js"
],
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.48.2",
"@typescript-eslint/parser": "^5.48.2",
"eslint": "^8.24.0",
"@typescript-eslint/eslint-plugin": "^5.51.0",
"@typescript-eslint/parser": "^5.51.0",
"eslint": "^8.33.0",
"eslint-config-prettier": "^8.5.0",
"eslint-config-turbo": "^0.0.7",
"eslint-plugin-react": "^7.31.8",
"eslint-plugin-react-hooks": "^4.6.0"
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-tailwindcss": "^3.8.3"
}
}

View file

@ -19,10 +19,10 @@ export function AppLayout() {
<div
className={clsx(
// App level styles
'flex h-screen overflow-hidden text-ink select-none cursor-default',
os === 'browser' && 'bg-app border-t border-app-line/50',
os === 'macOS' && 'rounded-[10px] has-blur-effects',
os !== 'browser' && os !== 'windows' && 'border border-app-frame'
'text-ink flex h-screen cursor-default select-none overflow-hidden',
os === 'browser' && 'bg-app border-app-line/50 border-t',
os === 'macOS' && 'has-blur-effects rounded-[10px]',
os !== 'browser' && os !== 'windows' && 'border-app-frame border'
)}
onContextMenu={(e) => {
// TODO: allow this on some UI text at least / disable default browser context menu
@ -32,7 +32,7 @@ export function AppLayout() {
>
<Sidebar />
<div className="relative flex w-full">
<Suspense fallback={<div className="w-screen h-screen bg-app" />}>
<Suspense fallback={<div className="bg-app h-screen w-screen" />}>
<Outlet />
</Suspense>
</div>

View file

@ -12,12 +12,12 @@ export function ErrorFallback({ error, resetErrorBoundary }: FallbackProps) {
<div
data-tauri-drag-region
role="alert"
className="flex flex-col items-center justify-center w-screen h-screen p-4 border rounded-lg border-app-divider bg-app"
className="border-app-divider bg-app flex h-screen w-screen flex-col items-center justify-center rounded-lg border p-4"
>
<p className="m-3 text-sm font-bold text-ink-faint">APP CRASHED</p>
<h1 className="text-2xl font-bold text-ink">We're past the event horizon...</h1>
<pre className="m-2 text-ink">Error: {error.message}</pre>
<div className="flex flex-row space-x-2 text-ink">
<p className="text-ink-faint m-3 text-sm font-bold">APP CRASHED</p>
<h1 className="text-ink text-2xl font-bold">We're past the event horizon...</h1>
<pre className="text-ink m-2">Error: {error.message}</pre>
<div className="text-ink flex flex-row space-x-2">
<Button variant="accent" className="mt-2" onClick={resetErrorBoundary}>
Reload
</Button>

View file

@ -7,9 +7,9 @@ export default function NotFound() {
<div
data-tauri-drag-region
role="alert"
className="flex flex-col items-center justify-center w-full h-full p-4 rounded-lg"
className="flex h-full w-full flex-col items-center justify-center rounded-lg p-4"
>
<p className="m-3 text-sm font-semibold uppercase text-ink-faint">Error: 404</p>
<p className="text-ink-faint m-3 text-sm font-semibold uppercase">Error: 404</p>
<h1 className="text-4xl font-bold">You chose nothingness.</h1>
<div className="flex flex-row space-x-2">
<Button variant="accent" className="mt-4" onClick={() => navigate(-1)}>

View file

@ -32,7 +32,7 @@ export default function AddLocationDialog(props: Props) {
ctaLabel="Add"
>
<Input
className="flex-grow w-full mt-3"
className="mt-3 w-full grow"
placeholder="/Users/jamie/Movies"
required
{...form.register('path')}

View file

@ -23,17 +23,17 @@ export const AlertDialog = (props: AlertDialogProps) => {
ctaLabel={props.label !== undefined ? props.label : 'Done'}
>
{props.inputBox && (
<div className="relative flex flex-grow mt-3">
<Input value={props.value} disabled className="flex-grow !py-0.5" />
<div className="relative mt-3 flex grow">
<Input value={props.value} disabled className="grow !py-0.5" />
<Button
type="button"
onClick={() => {
navigator.clipboard.writeText(props.value);
}}
size="icon"
className="border-none absolute right-[5px] top-[5px]"
className="absolute right-[5px] top-[5px] border-none"
>
<Clipboard className="w-4 h-4" />
<Clipboard className="h-4 w-4" />
</Button>
</div>
)}

View file

@ -69,9 +69,9 @@ export const BackupRestoreDialog = (props: BackupRestorationDialogProps) => {
loading={restoreKeystoreMutation.isLoading}
ctaLabel="Restore"
>
<div className="relative flex flex-grow mt-3 mb-2">
<div className="relative mt-3 mb-2 flex grow">
<Input
className="flex-grow !py-0.5"
className="grow !py-0.5"
placeholder="Master Password"
type={show.masterPassword ? 'text' : 'password'}
{...form.register('masterPassword', { required: true })}
@ -79,15 +79,15 @@ export const BackupRestoreDialog = (props: BackupRestorationDialogProps) => {
<Button
onClick={() => setShow((old) => ({ ...old, masterPassword: !old.masterPassword }))}
size="icon"
className="border-none absolute right-[5px] top-[5px]"
className="absolute right-[5px] top-[5px] border-none"
type="button"
>
<MPCurrentEyeIcon className="w-4 h-4" />
<MPCurrentEyeIcon className="h-4 w-4" />
</Button>
</div>
<div className="relative flex flex-grow mb-3">
<div className="relative mb-3 flex grow">
<Input
className="flex-grow !py-0.5"
className="grow !py-0.5"
placeholder="Secret Key"
type={show.secretKey ? 'text' : 'password'}
{...form.register('secretKey')}
@ -95,12 +95,12 @@ export const BackupRestoreDialog = (props: BackupRestorationDialogProps) => {
<Button
onClick={() => setShow((old) => ({ ...old, secretKey: !old.secretKey }))}
size="icon"
className="border-none absolute right-[5px] top-[5px]"
className="absolute right-[5px] top-[5px] border-none"
>
<SKCurrentEyeIcon className="w-4 h-4" />
<SKCurrentEyeIcon className="h-4 w-4" />
</Button>
</div>
<div className="relative flex flex-grow mb-2">
<div className="relative mb-2 flex grow">
<Button
size="sm"
variant={form.watch('filePath') !== '' ? 'accent' : 'gray'}

View file

@ -77,9 +77,9 @@ export default function CreateLibraryDialog(props: Props) {
ctaLabel="Create"
>
<div className="relative flex flex-col">
<p className="text-sm mt-2 mb-2 font-bold">Library name</p>
<p className="my-2 text-sm font-bold">Library name</p>
<Input
className="flex-grow w-full"
className="w-full grow"
placeholder="My Cool Library"
{...form.register('name', { required: true })}
/>
@ -89,13 +89,13 @@ export default function CreateLibraryDialog(props: Props) {
{/* <span className="text-sm">Make the secret key field empty to skip key setup.</span> */}
<div className="relative flex flex-col">
<p className="text-center mt-2 mb-1 text-[0.95rem] font-bold">Key Manager</p>
<div className="w-full my-1 h-[2px] bg-gray-500" />
<p className="mt-2 mb-1 text-center text-[0.95rem] font-bold">Key Manager</p>
<div className="my-1 h-[2px] w-full bg-gray-500" />
<p className="text-sm mt-2 mb-2 font-bold">Master password</p>
<div className="relative flex flex-grow mb-2">
<p className="my-2 text-sm font-bold">Master password</p>
<div className="relative mb-2 flex grow">
<Input
className="flex-grow !py-0.5"
className="grow !py-0.5"
placeholder="Password"
type={showMasterPassword1 ? 'text' : 'password'}
{...form.register('password')}
@ -111,33 +111,33 @@ export default function CreateLibraryDialog(props: Props) {
setShowMasterPassword2(true);
}}
size="icon"
className="border-none absolute right-[65px] top-[5px]"
className="absolute right-[65px] top-[5px] border-none"
>
<ArrowsClockwise className="w-4 h-4" />
<ArrowsClockwise className="h-4 w-4" />
</Button>
<Button
onClick={() => {
navigator.clipboard.writeText(form.watch('password') as string);
}}
size="icon"
className="border-none absolute right-[35px] top-[5px]"
className="absolute right-[35px] top-[5px] border-none"
>
<Clipboard className="w-4 h-4" />
<Clipboard className="h-4 w-4" />
</Button>
<Button
onClick={() => setShowMasterPassword1(!showMasterPassword1)}
size="icon"
className="border-none absolute right-[5px] top-[5px]"
className="absolute right-[5px] top-[5px] border-none"
>
<MP1CurrentEyeIcon className="w-4 h-4" />
<MP1CurrentEyeIcon className="h-4 w-4" />
</Button>
</div>
</div>
<div className="relative flex flex-col">
<p className="text-sm mt-2 mb-2 font-bold">Master password (again)</p>
<div className="relative flex flex-grow mb-2">
<p className="my-2 text-sm font-bold">Master password (again)</p>
<div className="relative mb-2 flex grow">
<Input
className="flex-grow !py-0.5"
className="grow !py-0.5"
placeholder="Password"
type={showMasterPassword2 ? 'text' : 'password'}
{...form.register('password_validate')}
@ -145,14 +145,14 @@ export default function CreateLibraryDialog(props: Props) {
<Button
onClick={() => setShowMasterPassword2(!showMasterPassword2)}
size="icon"
className="border-none absolute right-[5px] top-[5px]"
className="absolute right-[5px] top-[5px] border-none"
>
<MP2CurrentEyeIcon className="w-4 h-4" />
<MP2CurrentEyeIcon className="h-4 w-4" />
</Button>
</div>
</div>
<div className="grid w-full grid-cols-2 gap-4 mt-4 mb-3">
<div className="mt-4 mb-3 grid w-full grid-cols-2 gap-4">
<div className="flex flex-col">
<span className="text-sm font-bold">Encryption</span>
<Select

View file

@ -97,7 +97,7 @@ export const DecryptFileDialog = (props: DecryptDialogProps) => {
className="mt-2"
>
<span className="text-xs font-bold">Key Type</span>
<div className="flex flex-row gap-2 mt-2">
<div className="mt-2 flex flex-row gap-2">
<RadioGroup.Option disabled={!hasMountedKeys} value="key">
{({ checked }) => (
<Button
@ -121,7 +121,7 @@ export const DecryptFileDialog = (props: DecryptDialogProps) => {
</RadioGroup>
{form.watch('type') === 'key' && (
<div className="relative flex flex-grow mt-3 mb-2">
<div className="relative mt-3 mb-2 flex grow">
<div className="space-x-2">
<Switch
className="bg-app-selected"
@ -131,18 +131,18 @@ export const DecryptFileDialog = (props: DecryptDialogProps) => {
onCheckedChange={(e) => form.setValue('mountAssociatedKey', e)}
/>
</div>
<span className="ml-3 text-xs font-medium mt-0.5">Automatically mount key</span>
<span className="ml-3 mt-0.5 text-xs font-medium">Automatically mount key</span>
<Tooltip label="The key linked with the file will be automatically mounted">
<Info className="w-4 h-4 ml-1.5 text-ink-faint mt-0.5" />
<Info className="text-ink-faint ml-1.5 mt-0.5 h-4 w-4" />
</Tooltip>
</div>
)}
{form.watch('type') === 'password' && (
<>
<div className="relative flex flex-grow mt-3 mb-2">
<div className="relative mt-3 mb-2 flex grow">
<Input
className={`flex-grow w-max !py-0.5`}
className={`w-max grow !py-0.5`}
placeholder="Password"
type={show.password ? 'text' : 'password'}
{...form.register('password', { required: true })}
@ -150,14 +150,14 @@ export const DecryptFileDialog = (props: DecryptDialogProps) => {
<Button
onClick={() => setShow((old) => ({ ...old, password: !old.password }))}
size="icon"
className="border-none absolute right-[5px] top-[5px]"
className="absolute right-[5px] top-[5px] border-none"
type="button"
>
<PasswordCurrentEyeIcon className="w-4 h-4" />
<PasswordCurrentEyeIcon className="h-4 w-4" />
</Button>
</div>
<div className="relative flex flex-grow mt-3 mb-2">
<div className="relative mt-3 mb-2 flex grow">
<div className="space-x-2">
<Switch
className="bg-app-selected"
@ -165,22 +165,22 @@ export const DecryptFileDialog = (props: DecryptDialogProps) => {
{...form.register('saveToKeyManager')}
/>
</div>
<span className="ml-3 text-xs font-medium mt-0.5">Save to Key Manager</span>
<span className="ml-3 mt-0.5 text-xs font-medium">Save to Key Manager</span>
<Tooltip label="This key will be saved to the key manager">
<Info className="w-4 h-4 ml-1.5 text-ink-faint mt-0.5" />
<Info className="text-ink-faint ml-1.5 mt-0.5 h-4 w-4" />
</Tooltip>
</div>
</>
)}
<div className="grid w-full grid-cols-2 gap-4 mt-4 mb-3">
<div className="mt-4 mb-3 grid w-full grid-cols-2 gap-4">
<div className="flex flex-col">
<span className="text-xs font-bold">Output file</span>
<Button
size="sm"
variant={form.watch('outputPath') !== '' ? 'accent' : 'gray'}
className="h-[23px] text-xs leading-3 mt-2"
className="mt-2 h-[23px] text-xs leading-3"
type="button"
onClick={() => {
// if we allow the user to encrypt multiple files simultaneously, this should become a directory instead

View file

@ -86,7 +86,7 @@ export const EncryptFileDialog = ({ ...props }: EncryptDialogProps) => {
loading={encryptFile.isLoading}
ctaLabel="Encrypt"
>
<div className="grid w-full grid-cols-2 gap-4 mt-4 mb-3">
<div className="mt-4 mb-3 grid w-full grid-cols-2 gap-4">
<div className="flex flex-col">
<span className="text-xs font-bold">Key</span>
<Select
@ -105,7 +105,7 @@ export const EncryptFileDialog = ({ ...props }: EncryptDialogProps) => {
<Button
size="sm"
variant={form.watch('outputPath') !== '' ? 'accent' : 'gray'}
className="h-[23px] text-xs leading-3 mt-2"
className="mt-2 h-[23px] text-xs leading-3"
type="button"
onClick={() => {
// if we allow the user to encrypt multiple files simultaneously, this should become a directory instead
@ -130,7 +130,7 @@ export const EncryptFileDialog = ({ ...props }: EncryptDialogProps) => {
</div>
</div>
<div className="grid w-full grid-cols-2 gap-4 mt-4 mb-3">
<div className="mt-4 mb-3 grid w-full grid-cols-2 gap-4">
<div className="flex flex-col">
<span className="text-xs font-bold">Encryption</span>
<Select
@ -160,13 +160,13 @@ export const EncryptFileDialog = ({ ...props }: EncryptDialogProps) => {
</div>
</div>
<div className="grid w-full grid-cols-2 gap-4 mt-4 mb-3">
<div className="mt-4 mb-3 grid w-full grid-cols-2 gap-4">
<div className="flex">
<span className="text-sm font-bold mr-3 ml-0.5 mt-0.5">Metadata</span>
<span className="mr-3 ml-0.5 mt-0.5 text-sm font-bold">Metadata</span>
<CheckBox {...form.register('metadata')} />
</div>
<div className="flex">
<span className="text-sm font-bold mr-3 ml-0.5 mt-0.5">Preview Media</span>
<span className="mr-3 ml-0.5 mt-0.5 text-sm font-bold">Preview Media</span>
<CheckBox {...form.register('previewMedia')} />
</div>
</div>

View file

@ -45,11 +45,11 @@ export const EraseFileDialog = (props: EraseDialogProps) => {
loading={eraseFile.isLoading}
ctaLabel="Erase"
>
<div className="flex flex-col mt-2">
<div className="mt-2 flex flex-col">
<span className="text-xs font-bold"># of passes</span>
<div className="flex flex-row space-x-2">
<div className="relative flex flex-grow mt-2">
<div className="relative mt-2 flex grow">
<Slider
value={passes}
max={16}
@ -62,7 +62,7 @@ export const EraseFileDialog = (props: EraseDialogProps) => {
}}
/>
</div>
<span className="text-sm mt-2.5 font-medium">{passes}</span>
<span className="mt-2.5 text-sm font-medium">{passes}</span>
</div>
</div>

View file

@ -69,11 +69,11 @@ export const KeyViewerDialog = (props: KeyViewerDialogProps) => {
setContentSalt={setContentSalt}
/>
<div className="grid w-full gap-4 mt-4 mb-3">
<div className="mt-4 mb-3 grid w-full gap-4">
<div className="flex flex-col">
<span className="text-xs font-bold">Key</span>
<Select
className="mt-2 flex-grow"
className="mt-2 grow"
value={key}
onChange={(e) => {
setKey(e);
@ -83,7 +83,7 @@ export const KeyViewerDialog = (props: KeyViewerDialogProps) => {
</Select>
</div>
</div>
<div className="grid w-full grid-cols-2 gap-4 mt-4 mb-3">
<div className="mt-4 mb-3 grid w-full grid-cols-2 gap-4">
<div className="flex flex-col">
<span className="text-xs font-bold">Encryption</span>
<Select
@ -108,38 +108,38 @@ export const KeyViewerDialog = (props: KeyViewerDialogProps) => {
</Select>
</div>
</div>
<div className="grid w-full gap-4 mt-4 mb-3">
<div className="mt-4 mb-3 grid w-full gap-4">
<div className="flex flex-col">
<span className="text-xs font-bold mb-2">Content Salt (hex)</span>
<div className="relative flex flex-grow">
<Input value={contentSalt} disabled className="flex-grow !py-0.5" />
<span className="mb-2 text-xs font-bold">Content Salt (hex)</span>
<div className="relative flex grow">
<Input value={contentSalt} disabled className="grow !py-0.5" />
<Button
type="button"
onClick={() => {
navigator.clipboard.writeText(contentSalt);
}}
size="icon"
className="border-none absolute right-[5px] top-[5px]"
className="absolute right-[5px] top-[5px] border-none"
>
<Clipboard className="w-4 h-4" />
<Clipboard className="h-4 w-4" />
</Button>
</div>
</div>
</div>
<div className="grid w-full gap-4 mt-4 mb-3">
<div className="mt-4 mb-3 grid w-full gap-4">
<div className="flex flex-col">
<span className="text-xs font-bold mb-2">Key Value</span>
<div className="relative flex flex-grow">
<Input value={keyValue} disabled className="flex-grow !py-0.5" />
<span className="mb-2 text-xs font-bold">Key Value</span>
<div className="relative flex grow">
<Input value={keyValue} disabled className="grow !py-0.5" />
<Button
type="button"
onClick={() => {
navigator.clipboard.writeText(keyValue);
}}
size="icon"
className="border-none absolute right-[5px] top-[5px]"
className="absolute right-[5px] top-[5px] border-none"
>
<Clipboard className="w-4 h-4" />
<Clipboard className="h-4 w-4" />
</Button>
</div>
</div>

View file

@ -80,9 +80,9 @@ export const MasterPasswordChangeDialog = (props: MasterPasswordChangeDialogProp
ctaDanger={true}
ctaLabel="Change"
>
<div className="relative flex flex-grow mt-3 mb-2">
<div className="relative mt-3 mb-2 flex grow">
<Input
className={`flex-grow w-max !py-0.5`}
className={`w-max grow !py-0.5`}
placeholder="New password"
type={show.masterPassword ? 'text' : 'password'}
{...form.register('masterPassword', { required: true })}
@ -99,10 +99,10 @@ export const MasterPasswordChangeDialog = (props: MasterPasswordChangeDialogProp
}));
}}
size="icon"
className="border-none absolute right-[65px] top-[5px]"
className="absolute right-[65px] top-[5px] border-none"
type="button"
>
<ArrowsClockwise className="w-4 h-4" />
<ArrowsClockwise className="h-4 w-4" />
</Button>
<Button
type="button"
@ -110,22 +110,22 @@ export const MasterPasswordChangeDialog = (props: MasterPasswordChangeDialogProp
navigator.clipboard.writeText(form.watch('masterPassword') as string);
}}
size="icon"
className="border-none absolute right-[35px] top-[5px]"
className="absolute right-[35px] top-[5px] border-none"
>
<Clipboard className="w-4 h-4" />
<Clipboard className="h-4 w-4" />
</Button>
<Button
onClick={() => setShow((old) => ({ ...old, masterPassword: !old.masterPassword }))}
size="icon"
className="border-none absolute right-[5px] top-[5px]"
className="absolute right-[5px] top-[5px] border-none"
type="button"
>
<MP1CurrentEyeIcon className="w-4 h-4" />
<MP1CurrentEyeIcon className="h-4 w-4" />
</Button>
</div>
<div className="relative flex flex-grow mb-2">
<div className="relative mb-2 flex grow">
<Input
className={`flex-grow !py-0.5}`}
className={`!py-0.5} grow`}
placeholder="New password (again)"
type={show.masterPassword2 ? 'text' : 'password'}
{...form.register('masterPassword2', { required: true })}
@ -133,16 +133,16 @@ export const MasterPasswordChangeDialog = (props: MasterPasswordChangeDialogProp
<Button
onClick={() => setShow((old) => ({ ...old, masterPassword2: !old.masterPassword2 }))}
size="icon"
className="border-none absolute right-[5px] top-[5px]"
className="absolute right-[5px] top-[5px] border-none"
type="button"
>
<MP2CurrentEyeIcon className="w-4 h-4" />
<MP2CurrentEyeIcon className="h-4 w-4" />
</Button>
</div>
<PasswordMeter password={form.watch('masterPassword')} />
<div className="grid w-full grid-cols-2 gap-4 mt-4 mb-3">
<div className="mt-4 mb-3 grid w-full grid-cols-2 gap-4">
<div className="flex flex-col">
<span className="text-xs font-bold">Encryption</span>
<Select

View file

@ -44,10 +44,10 @@ export default function Explorer(props: Props) {
return (
<div className="relative">
<ExplorerContextMenu>
<div className="relative flex flex-col w-full">
<div className="relative flex w-full flex-col">
<TopBar showSeparator={separateTopBar} />
<div className="relative flex flex-row w-full max-h-full app-background">
<div className="app-background relative flex max-h-full w-full flex-row">
{props.data && (
<VirtualizedList
data={props.data.items}

View file

@ -17,15 +17,8 @@ import {
TrashSimple
} from 'phosphor-react';
import { PropsWithChildren, useMemo } from 'react';
import {
ExplorerItem,
getLibraryIdRaw,
useDebugState,
useLibraryMutation,
useLibraryQuery
} from '@sd/client';
import { ContextMenu as CM } from '@sd/ui';
import { dialogManager } from '@sd/ui';
import { ExplorerItem, getLibraryIdRaw, useLibraryMutation, useLibraryQuery } from '@sd/client';
import { ContextMenu as CM, dialogManager } from '@sd/ui';
import { getExplorerStore, useExplorerStore } from '~/hooks/useExplorerStore';
import { useOperatingSystem } from '~/hooks/useOperatingSystem';
import { useExplorerParams } from '~/screens/LocationExplorer';
@ -63,7 +56,7 @@ const AssignTagMenuItems = (props: { objectId: number }) => {
}}
>
<div
className="block w-[15px] h-[15px] mr-0.5 border rounded-full"
className="mr-0.5 block h-[15px] w-[15px] rounded-full border"
style={{
backgroundColor: active ? tag.color || '#efefef' : 'transparent' || '#efefef',
borderColor: tag.color || '#efefef'

View file

@ -3,11 +3,11 @@ import { Select, SelectOption } from '@sd/ui';
import Slider from '../primitive/Slider';
function Heading({ children }: PropsWithChildren) {
return <div className="text-xs font-semibold text-ink-dull">{children}</div>;
return <div className="text-ink-dull text-xs font-semibold">{children}</div>;
}
function SubHeading({ children }: PropsWithChildren) {
return <div className="mb-1 text-xs font-medium text-ink-dull">{children}</div>;
return <div className="text-ink-dull mb-1 text-xs font-medium">{children}</div>;
}
const sortOptions = {
@ -29,7 +29,7 @@ export function ExplorerOptionsPanel() {
{/* <Heading>Explorer Appearance</Heading> */}
<SubHeading>Item size</SubHeading>
<Slider defaultValue={size} step={10} />
<div className="grid grid-cols-2 gap-2 my-2 mt-4">
<div className="my-2 mt-4 grid grid-cols-2 gap-2">
<div className="flex flex-col">
<SubHeading>Sort by</SubHeading>
<Select value={sortBy} size="sm" onChange={setSortBy}>

View file

@ -36,7 +36,7 @@ export interface TopBarButtonProps {
// export const TopBarIcon = (icon: any) => tw(icon)`m-0.5 w-5 h-5 text-ink-dull`;
const topBarButtonStyle = cva(
'border-none text-ink hover:text-ink mr-[1px] flex py-0.5 px-0.5 text-md font-medium transition-colors duration-100 outline-none hover:bg-app-selected radix-state-open:bg-app-selected',
'text-ink hover:text-ink text-md hover:bg-app-selected radix-state-open:bg-app-selected mr-[1px] flex border-none p-0.5 font-medium outline-none transition-colors duration-100',
{
variants: {
active: {
@ -101,7 +101,7 @@ const SearchBar = forwardRef<HTMLInputElement, DefaultProps>((props, forwardedRe
{...searchField}
/>
<div className={clsx('space-x-1 absolute right-1 peer-focus:invisible pointer-events-none')}>
<div className={clsx('pointer-events-none absolute right-1 space-x-1 peer-focus:invisible')}>
{platform === 'browser' ? (
<Shortcut chars="⌘F" aria-label={'Press Command-F to focus search bar'} />
) : os === 'macOS' ? (
@ -187,8 +187,9 @@ export const TopBar: React.FC<TopBarProps> = (props) => {
<>
<div
data-tauri-drag-region
// eslint-disable-next-line tailwindcss/no-contradicting-classname
className={clsx(
'flex h-[46px] max-w z-20 pl-3 flex-shrink-0 items-center border-transparent border-b bg-app overflow-hidden transition-[background-color] transition-[border-color] duration-250 ease-out',
'max-w bg-app duration-250 z-20 flex h-[46px] shrink-0 items-center overflow-hidden border-b border-transparent pl-3 transition-[background-color] transition-[border-color] ease-out',
props.showSeparator && 'top-bar-blur !bg-app/90'
)}
>
@ -211,8 +212,8 @@ export const TopBar: React.FC<TopBarProps> = (props) => {
<TopBarButton group right icon={SquaresFour} />
</div> */}
<div data-tauri-drag-region className="flex flex-row justify-center flex-grow">
<div className="flex mx-8">
<div data-tauri-drag-region className="flex grow flex-row justify-center">
<div className="mx-8 flex">
<Tooltip label="Grid view">
<TopBarButton
rounding="left"
@ -263,7 +264,7 @@ export const TopBar: React.FC<TopBarProps> = (props) => {
<SearchBar ref={searchRef} />
<div className="flex mx-8 space-x-2">
<div className="mx-8 flex space-x-2">
<Tooltip label="Key Manager">
<Popover
className="focus:outline-none"
@ -303,7 +304,7 @@ export const TopBar: React.FC<TopBarProps> = (props) => {
</Tooltip>
</div>
</div>
<div className="flex mr-3 space-x-2">
<div className="mr-3 flex space-x-2">
<Tooltip label="File display options" position="left">
<Popover
className="focus:outline-none"

View file

@ -10,7 +10,7 @@ import { isObject } from './utils';
const NameArea = tw.div`flex justify-center`;
const nameContainerStyles = cva(
'px-1.5 py-[1px] truncate text-center rounded-md text-xs font-medium cursor-default',
'cursor-default truncate rounded-md px-1.5 py-[1px] text-center text-xs font-medium',
{
variants: {
selected: {
@ -41,7 +41,7 @@ function FileItem({ data, selected, index, ...rest }: Props) {
}}
{...rest}
draggable
className={clsx('inline-block w-[100px] mb-3', rest.className)}
className={clsx('mb-3 inline-block w-[100px]', rest.className)}
>
<div
style={{
@ -49,7 +49,7 @@ function FileItem({ data, selected, index, ...rest }: Props) {
height: getExplorerStore().gridItemSize
}}
className={clsx(
'border-2 border-transparent rounded-lg text-center mb-1 active:translate-y-[1px]',
'mb-1 rounded-lg border-2 border-transparent text-center active:translate-y-[1px]',
{
'bg-app-selected/30': selected
}
@ -57,20 +57,20 @@ function FileItem({ data, selected, index, ...rest }: Props) {
>
<div
className={clsx(
'flex relative items-center justify-center h-full p-1 rounded border-transparent border-2 shrink-0'
'relative flex h-full shrink-0 items-center justify-center rounded border-2 border-transparent p-1'
)}
>
<FileThumb
className={clsx(
'border-2 border-app-line rounded-sm 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-[7px]'
'border-app-line max-h-full w-auto max-w-full overflow-hidden rounded-sm border-2 object-cover shadow shadow-black/40',
isVid && 'rounded border-x-0 border-y-[7px] !border-black'
)}
data={data}
kind={ObjectKind[objectData?.kind || 0]}
size={getExplorerStore().gridItemSize}
/>
{item.extension && isVid && (
<div className="absolute bottom-4 font-semibold opacity-70 right-2 py-0.5 px-1 text-[9px] uppercase bg-black/60 rounded">
<div className="absolute bottom-4 right-2 rounded bg-black/60 py-0.5 px-1 text-[9px] font-semibold uppercase opacity-70">
{item.extension}
</div>
)}

View file

@ -22,7 +22,7 @@ function FileRow({ data, index, selected, ...props }: Props) {
{columns.map((col) => (
<div
key={col.key}
className="flex items-center px-4 py-2 pr-2 table-body-cell"
className="table-body-cell flex items-center px-4 py-2 pr-2"
style={{ width: col.width }}
>
<RenderCell data={data} colKey={col.key} />
@ -40,7 +40,7 @@ const RenderCell: React.FC<{
case 'name':
return (
<div className="flex flex-row items-center overflow-hidden">
<div className="flex items-center justify-center w-6 h-6 mr-3 shrink-0">
<div className="mr-3 flex h-6 w-6 shrink-0 items-center justify-center">
<FileThumb data={data} size={0} />
</div>
{/* {colKey == 'name' &&
@ -55,13 +55,13 @@ const RenderCell: React.FC<{
return <DocumentIcon className="flex-shrink-0 w-5 h-5 mr-3 text-gray-300" />;
}
})()} */}
<span className="text-xs truncate">{data.item[colKey]}</span>
<span className="truncate text-xs">{data.item[colKey]}</span>
</div>
);
// case 'size_in_bytes':
// return <span className="text-xs text-left">{byteSize(Number(value || 0))}</span>;
case 'extension':
return <span className="text-xs text-left">{data.item[colKey]}</span>;
return <span className="text-left text-xs">{data.item[colKey]}</span>;
// case 'meta_integrity_hash':
// return <span className="truncate">{value}</span>;
// case 'tags':

View file

@ -51,7 +51,7 @@ export default function FileThumb({ data, ...props }: Props) {
style={props.style}
decoding="async"
// width={props.size}
className={clsx('pointer-events-none z-90', props.className)}
className={clsx('z-90 pointer-events-none', props.className)}
src={url}
/>
);
@ -64,5 +64,5 @@ export default function FileThumb({ data, ...props }: Props) {
else if (props.kind === 'Executable') icon = executable;
else if (props.kind === 'Encrypted') icon = archive;
return <img src={icon} className={clsx('overflow-hidden h-full', props.iconClassNames)} />;
return <img src={icon} className={clsx('h-full overflow-hidden', props.iconClassNames)} />;
}

View file

@ -26,7 +26,7 @@ export const MetaValue = tw.p`text-xs break-all text-ink truncate`;
const MetaTextLine = tw.div`flex items-center my-0.5 text-xs text-ink-dull`;
const InspectorIcon = ({ component: Icon, ...props }: any) => (
<Icon weight="bold" {...props} className={clsx('mr-2 flex-shrink-0', props.className)} />
<Icon weight="bold" {...props} className={clsx('mr-2 shrink-0', props.className)} />
);
interface Props extends DefaultProps<HTMLDivElement> {
@ -63,13 +63,13 @@ export const Inspector = ({ data, context, ...elementProps }: Props) => {
return (
<div
{...elementProps}
className="-mt-[50px] pt-[55px] z-10 pl-1.5 pr-1 w-full h-screen overflow-x-hidden custom-scroll inspector-scroll pb-4"
className="custom-scroll inspector-scroll z-10 mt-[-50px] h-screen w-full overflow-x-hidden pt-[55px] pl-1.5 pr-1 pb-4"
>
{data && (
<>
<div
className={clsx(
'flex h-52 items-center justify-center w-full mb-[10px] overflow-hidden rounded-lg',
'mb-[10px] flex h-52 w-full items-center justify-center overflow-hidden rounded-lg',
objectData?.kind === 7 && objectData?.has_thumbnail && 'bg-black'
)}
>
@ -77,29 +77,29 @@ export const Inspector = ({ data, context, ...elementProps }: Props) => {
iconClassNames="my-3 max-h-[150px]"
size={230}
kind={ObjectKind[objectData?.kind || 0]}
className="flex flex-grow-0 flex-shrink bg-green-500"
className="flex shrink grow-0 bg-green-500"
data={data}
/>
</div>
<div className="flex flex-col w-full pt-0.5 pb-0.5 overflow-hidden bg-app-box rounded-lg select-text shadow-app-shade/10 border border-app-line">
<h3 className="px-3 pt-2 pb-1 text-base font-bold truncate">
<div className="bg-app-box shadow-app-shade/10 border-app-line flex w-full select-text flex-col overflow-hidden rounded-lg border py-0.5">
<h3 className="truncate px-3 pt-2 pb-1 text-base font-bold">
{item?.name}
{item?.extension && `.${item.extension}`}
</h3>
{objectData && (
<div className="flex flex-row mt-1 mb-0.5 mx-3 space-x-0.5">
<div className="mx-3 mt-1 mb-0.5 flex flex-row space-x-0.5">
<Tooltip label="Favorite">
<FavoriteButton data={objectData} />
</Tooltip>
<Tooltip label="Encrypt">
<Button size="icon">
<Lock className="w-[18px] h-[18px]" />
<Lock className="h-[18px] w-[18px]" />
</Button>
</Tooltip>
<Tooltip label="Share">
<Button size="icon">
<Link className="w-[18px] h-[18px]" />
<Link className="h-[18px] w-[18px]" />
</Button>
</Tooltip>
</div>

View file

@ -116,10 +116,10 @@ export const VirtualizedList = memo(({ data, context, onScroll }: Props) => {
// );
return (
<div style={{ marginTop: -TOP_BAR_HEIGHT }} className="w-full pl-2 cursor-default">
<div style={{ marginTop: -TOP_BAR_HEIGHT }} className="w-full cursor-default pl-2">
<div
ref={scrollRef}
className="h-screen custom-scroll explorer-scroll"
className="custom-scroll explorer-scroll h-screen"
onClick={(e) => {
getExplorerStore().selectedRowIndex = -1;
}}

View file

@ -1 +1 @@
export const Divider = () => <div className="w-full my-1 h-[1px] bg-app-line/60" />;
export const Divider = () => <div className="bg-app-line/60 my-1 h-[1px] w-full" />;

View file

@ -31,7 +31,7 @@ export default function FavoriteButton(props: Props) {
return (
<Button onClick={toggleFavorite} size="icon">
<Heart weight={favorite ? 'fill' : 'regular'} className="w-[18px] h-[18px]" />
<Heart weight={favorite ? 'fill' : 'regular'} className="h-[18px] w-[18px]" />
</Button>
);
}

View file

@ -27,6 +27,7 @@ export default function Note(props: Props) {
2000
);
// eslint-disable-next-line react-hooks/exhaustive-deps
const debouncedNote = useCallback((note: string) => debounce(note), [props.data.id, fileSetNote]);
// when input is updated, cache note
@ -43,7 +44,7 @@ export default function Note(props: Props) {
<MetaContainer>
<MetaTitle>Note</MetaTitle>
<TextArea
className="mt-2 mb-1 text-xs leading-snug !py-2"
className="mt-2 mb-1 !py-2 text-xs leading-snug"
value={note || ''}
onChange={handleNoteUpdate}
/>{' '}

View file

@ -9,7 +9,7 @@ export const DriveListItem: React.FC<DriveListItemProps> = (props) => {
return (
<div
className={clsx(
'rounded px-1.5 py-1 text-xs font-medium inline-block cursor-default',
'inline-block cursor-default rounded px-1.5 py-1 text-xs font-medium',
props.className
)}
></div>

View file

@ -105,25 +105,25 @@ export function JobsManager() {
const clearAllJobs = useLibraryMutation(['jobs.clearAll']);
return (
<div className="h-full pb-10 overflow-hidden">
<div className="h-full overflow-hidden pb-10">
<HeaderContainer>
<CategoryHeading className="ml-2">Recent Jobs</CategoryHeading>
<div className="flex-grow" />
<div className="grow" />
<Button onClick={() => clearAllJobs.mutate(null)} size="icon">
<Tooltip label="Clear out finished jobs">
<Trash className="w-5 h-5" />
<Trash className="h-5 w-5" />
</Tooltip>
</Button>
<PopoverClose asChild>
<Button size="icon">
<Tooltip label="Close">
<X className="w-5 h-5" />
<X className="h-5 w-5" />
</Tooltip>
</Button>
</PopoverClose>
</HeaderContainer>
<div className="h-full mr-1 overflow-x-hidden custom-scroll inspector-scroll">
<div className="custom-scroll inspector-scroll mr-1 h-full overflow-x-hidden">
<div className="">
<div className="py-1">
{runningJobs.data?.map((job) => (
@ -133,7 +133,7 @@ export function JobsManager() {
<Job key={job.id} job={job} />
))}
{jobs.data?.length === 0 && runningJobs.data?.length === 0 && (
<div className="flex items-center justify-center h-32 text-ink-dull">No jobs.</div>
<div className="text-ink-dull flex h-32 items-center justify-center">No jobs.</div>
)}
</div>
</div>
@ -149,20 +149,20 @@ function Job({ job }: { job: JobReport }) {
};
const isRunning = job.status === 'Running';
return (
<div className="flex items-center px-2 py-2 pl-4 border-b border-app-line/50 bg-opacity-60">
<div className="border-app-line/50 bg-opacity/60 flex items-center border-b p-2 pl-4">
<Tooltip label={job.status}>
<niceData.icon className={clsx('w-5 h-5 mr-3')} />
<niceData.icon className={clsx('mr-3 h-5 w-5')} />
</Tooltip>
<div className="flex flex-col truncate">
<span className="mt-0.5 font-semibold truncate">
<span className="mt-0.5 truncate font-semibold">
{isRunning ? job.message : niceData.name}
</span>
{isRunning && (
<div className="w-full my-1">
<div className="my-1 w-full">
<ProgressBar value={job.completed_task_count} total={job.task_count} />
</div>
)}
<div className="flex items-center truncate text-ink-faint">
<div className="text-ink-faint flex items-center truncate">
<span className="text-xs">
{isRunning ? 'Elapsed' : job.status === 'Failed' ? 'Failed after' : 'Took'}{' '}
{job.seconds_elapsed
@ -178,12 +178,12 @@ function Job({ job }: { job: JobReport }) {
</div>
{/* <span className="mt-0.5 opacity-50 text-tiny text-ink-faint">{job.id}</span> */}
</div>
<div className="flex-grow" />
<div className="flex flex-row space-x-2 ml-7">
<div className="grow" />
<div className="ml-7 flex flex-row space-x-2">
{job.status === 'Running' && (
<Button size="icon">
<Tooltip label="Pause">
<Pause className="w-4 h-4" />
<Pause className="h-4 w-4" />
</Tooltip>
</Button>
)}
@ -196,7 +196,7 @@ function Job({ job }: { job: JobReport }) {
)}
<Button size="icon">
<Tooltip label="Remove">
<X className="w-4 h-4" />
<X className="h-4 w-4" />
</Tooltip>
</Button>
</div>

View file

@ -67,9 +67,9 @@ export const KeyDropdown = ({
// most of this is copied over from the `OverlayPanel`
className={clsx(
'flex flex-col',
'pl-4 pr-4 pt-2 pb-2 z-50 m-2 space-y-1',
'select-none cursor-default rounded-lg',
'text-left text-sm text-ink',
'z-50 m-2 space-y-1 px-4 py-2',
'cursor-default select-none rounded-lg',
'text-ink text-left text-sm',
'bg-app-overlay/80 backdrop-blur',
// 'border border-app-overlay',
'shadow-2xl shadow-black/60 ',
@ -102,13 +102,13 @@ export const Key: React.FC<{ data: Key; index: number }> = ({ data, index }) =>
return (
<div
className={clsx(
'flex items-center justify-between px-2 py-1.5 shadow-app-shade/10 text-sm bg-app-box shadow-lg rounded-lg'
'shadow-app-shade/10 bg-app-box flex items-center justify-between rounded-lg px-2 py-1.5 text-sm shadow-lg'
)}
>
<div className="flex items-center">
<KeyIcon
className={clsx(
'w-5 h-5 ml-1 mr-3',
'ml-1 mr-3 h-5 w-5',
data.mounted ? (data.locked ? 'text-accent' : 'text-accent') : 'text-gray-400/80'
)}
/>
@ -116,33 +116,33 @@ export const Key: React.FC<{ data: Key; index: number }> = ({ data, index }) =>
<div className="flex flex-row items-center">
<div className="font-semibold">{data.name}</div>
{data.mounted && (
<div className="inline ml-2 px-1 text-[8pt] font-medium text-gray-300 bg-gray-500 rounded">
<div className="ml-2 inline rounded bg-gray-500 px-1 text-[8pt] font-medium text-gray-300">
{data.nodes?.length || 0 > 0 ? `${data.nodes?.length || 0} nodes` : 'This node'}
</div>
)}
{data.default && (
<div className="inline ml-2 px-1 text-[8pt] font-medium text-gray-300 bg-gray-500 rounded">
<div className="ml-2 inline rounded bg-gray-500 px-1 text-[8pt] font-medium text-gray-300">
Default
</div>
)}
</div>
{/* <div className="text-xs text-gray-300 opacity-30">#{data.id}</div> */}
{data.stats ? (
<div className="flex flex-row mt-[1px] space-x-3">
<div className="mt-[1px] flex flex-row space-x-3">
{data.stats.objectCount && (
<div className="text-[8pt] font-medium text-ink-dull opacity-30">
<div className="text-ink-dull text-[8pt] font-medium opacity-30">
{data.stats.objectCount} Objects
</div>
)}
{data.stats.containerCount && (
<div className="text-[8pt] font-medium text-ink-dull opacity-30">
<div className="text-ink-dull text-[8pt] font-medium opacity-30">
{data.stats.containerCount} Containers
</div>
)}
</div>
) : (
!data.mounted && (
<div className="text-[8pt] font-medium text-ink-dull opacity-30">
<div className="text-ink-dull text-[8pt] font-medium opacity-30">
{data.queue.has(data.id) ? 'Key mounting...' : 'Key not mounted'}
</div>
)
@ -153,14 +153,14 @@ export const Key: React.FC<{ data: Key; index: number }> = ({ data, index }) =>
{data.mounted && (
<Tooltip label="Browse files">
<Button size="icon">
<Eye className="w-4 h-4 text-ink-faint" />
<Eye className="text-ink-faint h-4 w-4" />
</Button>
</Tooltip>
)}
<KeyDropdown
trigger={
<Button size="icon">
<DotsThree className="w-4 h-4 text-ink-faint" />
<DotsThree className="text-ink-faint h-4 w-4" />
</Button>
}
>
@ -226,7 +226,7 @@ export const KeyDropdownItem = (props: {
}) => {
return (
<DropdownMenu.DropdownMenuItem
className="!cursor-default select-none text-menu-ink focus:outline-none py-0.5 active:opacity-80"
className="text-menu-ink !cursor-default select-none py-0.5 focus:outline-none active:opacity-80"
onClick={props.onClick}
hidden={props.hidden}
>
@ -237,9 +237,9 @@ export const KeyDropdownItem = (props: {
export const DummyKey = (props: { text: string }) => {
return (
<div className="flex items-center justify-between px-2 py-1.5 pt-2 pb-2 shadow-app-shade/10 text-sm bg-app-box shadow-lg rounded-lg">
<div className="shadow-app-shade/10 bg-app-box flex items-center justify-between rounded-lg p-2 py-1.5 text-sm shadow-lg">
<div className="flex items-center">
<KeyIcon className="w-5 h-5 ml-1 mr-3 text-gray-400/80" />
<KeyIcon className="ml-1 mr-3 h-5 w-5 text-gray-400/80" />
<div className="flex flex-col ">
<div className="flex flex-row items-center">
<div className="font-medium">{props.text}</div>

View file

@ -65,8 +65,8 @@ export const KeyList = (props: KeyListProps) => {
const unmountAll = useLibraryMutation(['keys.unmountAll']);
return (
<div className="flex flex-col h-full max-h-[360px]">
<div className="p-3 custom-scroll overlay-scroll">
<div className="flex h-full max-h-[360px] flex-col">
<div className="custom-scroll overlay-scroll p-3">
<div className="">
{/* <CategoryHeading>Mounted keys</CategoryHeading> */}
<div className="space-y-1.5">
@ -74,7 +74,7 @@ export const KeyList = (props: KeyListProps) => {
</div>
</div>
</div>
<div className="flex w-full p-2 border-t border-app-line rounded-b-md">
<div className="border-app-line flex w-full rounded-b-md border-t p-2">
<Button
size="sm"
variant="gray"
@ -84,7 +84,7 @@ export const KeyList = (props: KeyListProps) => {
>
Unmount All
</Button>
<div className="flex-grow" />
<div className="grow" />
<Button size="sm" variant="gray">
Close
</Button>

View file

@ -38,39 +38,39 @@ export function KeyManager(props: KeyManagerProps) {
return (
<div className="p-2">
<div className="relative flex flex-grow mb-2">
<div className="relative mb-2 flex grow">
<Input
value={masterPassword}
onChange={(e) => setMasterPassword(e.target.value)}
autoFocus
type={showMasterPassword ? 'text' : 'password'}
className="flex-grow !py-0.5"
className="grow !py-0.5"
placeholder="Master Password"
/>
<Button
onClick={() => setShowMasterPassword(!showMasterPassword)}
size="icon"
className="border-none absolute right-[5px] top-[5px]"
className="absolute right-[5px] top-[5px] border-none"
>
<MPCurrentEyeIcon className="w-4 h-4" />
<MPCurrentEyeIcon className="h-4 w-4" />
</Button>
</div>
{enterSkManually && (
<div className="relative flex flex-grow mb-2">
<div className="relative mb-2 flex grow">
<Input
value={secretKey}
onChange={(e) => setSecretKey(e.target.value)}
type={showSecretKey ? 'text' : 'password'}
className="flex-grow !py-0.5"
className="grow !py-0.5"
placeholder="Secret Key"
/>
<Button
onClick={() => setShowSecretKey(!showSecretKey)}
size="icon"
className="border-none absolute right-[5px] top-[5px]"
className="absolute right-[5px] top-[5px] border-none"
>
<SKCurrentEyeIcon className="w-4 h-4" />
<SKCurrentEyeIcon className="h-4 w-4" />
</Button>
</div>
)}
@ -93,7 +93,7 @@ export function KeyManager(props: KeyManagerProps) {
Unlock
</Button>
{!enterSkManually && (
<div className="relative flex flex-grow">
<div className="relative flex grow">
<p
className="text-accent mt-2"
onClick={(e) => {
@ -118,7 +118,7 @@ export function KeyManager(props: KeyManagerProps) {
<Tabs.Trigger className="text-sm font-medium" value="keys">
Keys
</Tabs.Trigger>
<div className="flex-grow" />
<div className="grow" />
<Button
size="icon"
onClick={() => {
@ -128,7 +128,7 @@ export function KeyManager(props: KeyManagerProps) {
variant="subtle"
className="text-ink-faint"
>
<Lock className="w-4 h-4 text-ink-faint" />
<Lock className="text-ink-faint h-4 w-4" />
</Button>
<ButtonLink
to="/settings/keys"
@ -136,7 +136,7 @@ export function KeyManager(props: KeyManagerProps) {
variant="subtle"
className="text-ink-faint"
>
<Gear className="w-4 h-4 text-ink-faint" />
<Gear className="text-ink-faint h-4 w-4" />
</ButtonLink>
</Tabs.List>
</div>

Some files were not shown because too many files have changed in this diff Show more