replies timeline only, appview-less bluesky client

feat: refactor and improve post composer styling

ptr.pet 5eb5dcce 46b29c37

verified
Changed files
+52 -25
src
components
routes
+26 -4
src/components/PostComposer.svelte
···
};
$effect(() => {
if (isFocused && textareaEl) textareaEl.focus();
if (quoting || replying) isFocused = true;
});
···
}}
placeholder="what's on your mind?"
rows="4"
-
class="field-sizing-content single-line-input resize-none bg-(--nucleus-bg)/40 focus:scale-100"
-
style="border-color: color-mix(in srgb, {color} 27%, transparent);"
></textarea>
{#if quoting}
{@render renderPost(quoting)}
···
onfocus={() => (isFocused = true)}
type="text"
placeholder="what's on your mind?"
-
class="single-line-input flex-1 bg-(--nucleus-bg)/40 p-1 px-2"
-
style="border-color: color-mix(in srgb, {color} 27%, transparent);"
/>
{/if}
</div>
···
</div>
</div>
</div>
···
};
$effect(() => {
+
document.documentElement.style.setProperty('--acc-color', color);
if (isFocused && textareaEl) textareaEl.focus();
if (quoting || replying) isFocused = true;
});
···
}}
placeholder="what's on your mind?"
rows="4"
+
class="field-sizing-content resize-none"
></textarea>
{#if quoting}
{@render renderPost(quoting)}
···
onfocus={() => (isFocused = true)}
type="text"
placeholder="what's on your mind?"
+
class="flex-1"
/>
{/if}
</div>
···
</div>
</div>
</div>
+
+
<style>
+
@reference "../app.css";
+
+
input,
+
textarea {
+
@apply single-line-input bg-(--nucleus-bg)/35;
+
border-color: color-mix(in srgb, var(--acc-color) 30%, transparent);
+
}
+
+
input {
+
@apply p-1 px-2;
+
}
+
+
textarea {
+
@apply focus:scale-100;
+
}
+
+
input::placeholder,
+
textarea::placeholder {
+
color: color-mix(in srgb, var(--acc-color) 45%, var(--nucleus-bg));
+
}
+
</style>
+26 -21
src/routes/+page.svelte
···
});
</script>
<div class="mx-auto max-w-2xl">
<!-- thread list (page scrolls as a whole) -->
<div
···
{/if}
{#if showScrollToTop}
-
<button
-
onclick={scrollToTop}
-
class="group shrink-0 rounded-sm bg-(--nucleus-accent)/15 p-2 text-(--nucleus-accent) transition-all hover:scale-110 hover:shadow-lg"
-
aria-label="scroll to top"
-
title="scroll to top"
-
>
-
<Icon
-
class="transition-transform group-hover:-translate-y-0.5"
-
icon="heroicons:arrow-up-16-solid"
-
width={28}
-
/>
-
</button>
{/if}
</div>
···
style="background: linear-gradient(to right, var(--nucleus-accent), var(--nucleus-accent2));"
></div>
-
<div class="flex items-center justify-between px-2 py-1">
<div class="mb-2">
<h1 class="text-3xl font-bold tracking-tight">nucleus</h1>
<div class="mt-1 flex gap-2">
···
<div class="h-1 w-8 rounded-full bg-(--nucleus-accent2)"></div>
</div>
</div>
-
<button
-
onclick={() => (isSettingsOpen = true)}
-
class="group rounded-sm bg-(--nucleus-accent)/15 p-2 text-(--nucleus-accent) transition-all hover:scale-110 hover:shadow-lg"
-
aria-label="settings"
-
>
-
<Icon class="group-hover:hidden" icon="heroicons:cog-6-tooth" width={28} />
-
<Icon class="hidden group-hover:block" icon="heroicons:cog-6-tooth-solid" width={28} />
-
</button>
</div>
<!-- <hr
···
});
</script>
+
{#snippet appButton(onClick: () => void, icon: string, ariaLabel: string, iconHover?: string)}
+
<button
+
onclick={onClick}
+
class="group rounded-sm bg-(--nucleus-accent)/15 p-2 text-(--nucleus-accent) transition-all hover:scale-110 hover:shadow-lg"
+
aria-label={ariaLabel}
+
>
+
<Icon class="group-hover:hidden" {icon} width={28} />
+
<Icon class="hidden group-hover:block" icon={iconHover ?? icon} width={28} />
+
</button>
+
{/snippet}
+
<div class="mx-auto max-w-2xl">
<!-- thread list (page scrolls as a whole) -->
<div
···
{/if}
{#if showScrollToTop}
+
{@render appButton(scrollToTop, 'heroicons:arrow-up-16-solid', 'scroll to top')}
{/if}
</div>
···
style="background: linear-gradient(to right, var(--nucleus-accent), var(--nucleus-accent2));"
></div>
+
<div class="flex items-center gap-1.5 px-2 py-1">
<div class="mb-2">
<h1 class="text-3xl font-bold tracking-tight">nucleus</h1>
<div class="mt-1 flex gap-2">
···
<div class="h-1 w-8 rounded-full bg-(--nucleus-accent2)"></div>
</div>
</div>
+
<div class="grow"></div>
+
{@render appButton(
+
() => (isSettingsOpen = true),
+
'heroicons:bell',
+
'notifications',
+
'heroicons:bell-solid'
+
)}
+
{@render appButton(
+
() => (isSettingsOpen = true),
+
'heroicons:cog-6-tooth',
+
'settings',
+
'heroicons:cog-6-tooth-solid'
+
)}
</div>
<!-- <hr