left sidebar

This commit is contained in:
grngxd 2024-08-10 08:18:34 +01:00
parent add5093fa3
commit 334445ece3
6 changed files with 79 additions and 28 deletions

View file

@ -1,8 +1,12 @@
import { component$, IntrinsicHTMLElements, Slot } from "@builder.io/qwik"; import { component$, IntrinsicHTMLElements, Slot } from "@builder.io/qwik";
export default component$((props: IntrinsicHTMLElements["div"]) => { interface ButtonProps {
light?: boolean;
}
export default component$((props: IntrinsicHTMLElements["div"] & ButtonProps) => {
return ( return (
<div class={`text-lg flex w-full justify-center items-center bg-clatter-gray-400 hover:bg-clatter-gray-300 active:bg-clatter-gray-500 duration-150 transition-all ease-in-out rounded-full py-2 h-min active:scale-95 select-none`} {...props}> <div class={`text-lg flex w-full justify-center items-center ${props.light ? "bg-clatter-gray-500" : "bg-clatter-gray-400"} ${props.light ? "hover:bg-clatter-gray-400" : "hover:bg-clatter-gray-300"} ${props.light ? "active:bg-clatter-gray-600" : "active:bg-clatter-gray-500"} duration-150 transition-all ease-in-out rounded-full py-2 h-min active:scale-95 select-none`} {...props}>
<Slot /> <Slot />
</div> </div>
); );

View file

@ -1,7 +1,7 @@
import { component$ } from "@builder.io/qwik"; import { component$ } from "@builder.io/qwik";
import { UserType } from "~/lib/types"; import { UserType } from "~/lib/types";
import ButtonLight from "../button/ButtonLight"; import Button from "../button/Button";
import User from "../user/User"; import { User } from "../user/User";
export const SidebarLeft = component$(() => { export const SidebarLeft = component$(() => {
return ( return (
@ -11,11 +11,31 @@ export const SidebarLeft = component$(() => {
<div class="flex flex-col gap-4 rounded-5xl p-3 bg-clatter-gray-100 h-full justify-between"> <div class="flex flex-col gap-4 rounded-5xl p-3 bg-clatter-gray-100 h-full justify-between">
<div class="mx-2"> <div class="mx-2">
<ButtonLight> <Button light={true}>
Post <span class="font-semibold">Post</span>
</ButtonLight> </Button>
</div> </div>
<User background={true} accountSwitcher={true} action="" user={{
<div class="bg-clatter-gray-200 rounded-5xl p-3 gap-1.5 flex flex-col">
<Button light={true}>
<span class="font-semibold">Home</span>
</Button>
<Button>
<span>
<span class="relative">
Notifications
<span class="bg-clatter-gray-500 text-white rounded-full text-xs font-semibold absolute -top-1 -right-8 px-1">99+</span>
</span>
</span>
</Button>
<Button>
Search
</Button>
</div>
<User background={true} accountSwitcher={true} user={{
id: "1", id: "1",
userName: "username", userName: "username",
displayName: "Display Name", displayName: "Display Name",

View file

@ -1,36 +1,57 @@
import { component$, useSignal } from "@builder.io/qwik"; import { component$, useContext, useContextProvider, useSignal } from "@builder.io/qwik";
import * as contexts from "~/lib/contexts";
import { UserType } from "~/lib/types"; import { UserType } from "~/lib/types";
import { LucideUsers } from "../icons/lucide/LucideUsers"; import { LucideUsers } from "../icons/lucide/LucideUsers";
interface UserProps { interface UserProps {
background: boolean; background?: boolean;
accountSwitcher: boolean; accountSwitcher?: boolean;
action: string | undefined; action? : string;
user: UserType; user: UserType;
accountSwitcherUser?: boolean;
} }
export default component$((props: UserProps) => { export const AccountSwitcher = component$(() => {
const visible = useSignal(false); const visible = useContext(contexts.AccountSwitcher);
return ( return (
<div> <div class="relative w-full">
<div class="relative w-full"> <div
<div id="account-switcher"
id="account-switcher" class={`flex flex-col gap-2 overflow-auto absolute w-full max-h-48 min-h-16 p-2 bg-clatter-gray-300 rounded-4xl shadow-xl transition-all duration-300 ease-in-out transform ${visible.value ? 'opacity-100 bottom-2' : 'opacity-0 -bottom-2'}`}
class={`absolute bottom-2 w-full h-48 bg-clatter-gray-300 rounded-4xl shadow-lg overflow-hidden transition-opacity duration-300 ease-in-out transform ${visible.value ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-2'}`} >
> <User accountSwitcherUser={true} user={{
Account Switcher id: "1",
</div> userName: "username",
</div> displayName: "Display Name",
avatar: "https://via.placeholder.com/150"
} as UserType} />
<div class="w-full h-16 rounded-full p-2 bg-clatter-gray-300 flex justify-between gap-2"> <User accountSwitcherUser={true} user={{
id: "1",
userName: "username",
displayName: "Display Name",
avatar: "https://via.placeholder.com/150"
} as UserType} />
</div>
</div>
)
});
export const User = component$((props: UserProps) => {
const visible = useSignal(false);
useContextProvider(contexts.AccountSwitcher, visible);
return (
<div>
{props.accountSwitcher && <AccountSwitcher />}
<div class={`w-full h-16 rounded-full p-2 ${props.accountSwitcherUser ? "bg-clatter-gray-400" : "bg-clatter-gray-300"} flex justify-between gap-2`}>
<div class="flex gap-2"> <div class="flex gap-2">
<img src={props.user.avatar} alt="avatar" class="w-12 h-12 rounded-full" /> <img src={props.user.avatar} alt="avatar" class="w-12 h-12 rounded-full" />
<div class="flex flex-col gap-1 justify-center"> <div class="flex flex-col gap-1 justify-center">
<p class="text-md font-semibold">{props.user.displayName}</p> <p class="text-md font-semibold">{props.user.displayName}</p>
<p class="text-sm font-semibold -mt-2.5"> <p class="text-sm font-semibold -mt-2.5">
<span class="text-clatter-gray-400">@</span> <span class={props.accountSwitcherUser ? "text-clatter-gray-500" : "text-clatter-gray-400"}>@</span>
<span class="text-clatter-gray-500"> <span class={props.accountSwitcherUser ? "text-clatter-gray-600" : "text-clatter-gray-500"}>
{props.user.userName} {props.action} {props.user.userName} {props.action}
</span> </span>
</p> </p>

3
web/src/lib/contexts.ts Normal file
View file

@ -0,0 +1,3 @@
import { createContextId, Signal } from "@builder.io/qwik";
export const AccountSwitcher = createContextId<Signal<boolean>>("clatter.user.switcher");

View file

@ -15,7 +15,7 @@ export const onGet: RequestHandler = async ({ cacheControl }) => {
export default component$(() => { export default component$(() => {
return ( return (
<div class="bg-clatter-black text-white p-8 flex flex-grow h-screen gap-12 !font-lexend !font-semibold !tracking-[-4%]"> <div class="bg-clatter-black text-white p-8 flex flex-grow h-screen gap-12 !font-lexend !font-medium !tracking-[-4%]">
<SidebarLeft /> <SidebarLeft />
<div class="flex-[0.55]"> <div class="flex-[0.55]">
<Slot /> <Slot />

View file

@ -1,6 +1,7 @@
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
export default { export default {
content: ['./src/**/*.{js,ts,jsx,tsx,mdx}'], content: ['./src/**/*.{js,ts,jsx,tsx,mdx}'],
mode: "jit",
theme: { theme: {
extend: { extend: {
colors: { colors: {
@ -11,7 +12,9 @@ export default {
300: "#4e4947", 300: "#4e4947",
350: "#5a5553", 350: "#5a5553",
400: "#6b6563", 400: "#6b6563",
450: "#7c7674",
500: "#9c9591", 500: "#9c9591",
550: "#a9a4a1",
600: "#b3adaa", 600: "#b3adaa",
} }
}, },