Animate sidebar

This commit is contained in:
dnlklmn
2024-01-24 13:34:38 +00:00
committed by Rūdolfs Ošiņš
parent 060a7f1b54
commit e0154ef94d
3 changed files with 173 additions and 183 deletions
+169 -179
View File
@@ -88,15 +88,19 @@
display: flex;
flex-direction: column;
justify-content: space-between;
transition: 150ms ease-in-out;
width: 4.5rem;
}
.expanded {
.sidebar.expanded {
width: 22.5rem;
}
.project-navigation {
display: flex;
flex-direction: column;
gap: 0.25rem;
flex: 1;
}
.counter {
border-radius: var(--border-radius-tiny);
background-color: var(--color-fill-ghost);
@@ -116,100 +120,149 @@
gap: 0.5rem;
justify-content: space-between;
width: 100%;
opacity: 0;
transition: 150ms ease-in-out;
}
.title-counter.expanded {
opacity: 1;
}
.sidebar-footer {
display: flex;
justify-content: space-between;
width: 100%;
}
.help {
z-index: 10;
opacity: 0;
}
.help.expanded {
opacity: 1;
transition: 150ms;
transition-delay: 150ms;
}
.help-box {
width: 20.5rem;
padding: 1rem;
margin-bottom: 0.5rem;
background-color: var(--color-background-float);
border: 1px solid var(--color-border-hint);
font-size: var(--font-size-small);
border-radius: var(--border-radius-small);
}
.vertical-buttons {
opacity: 1;
height: fit-content;
display: flex;
flex-direction: column-reverse;
transition: 150ms ease-in-out;
transition-delay: 60ms;
margin-bottom: 0.5rem;
}
.vertical-buttons.expanded {
opacity: 0;
height: 0;
}
.horizontal-buttons {
display: flex;
gap: 0.5rem;
opacity: 0;
transition: 30ms ease-in-out;
}
.horizontal-buttons.expanded {
opacity: 1;
transition: 150ms ease-in-out;
}
.icon {
transform: rotate(180deg);
transition: 150ms ease-in-out;
}
.icon.expanded {
transform: rotate(0deg);
}
.bottom {
display: flex;
flex-direction: column;
justify-items: flex-end;
}
</style>
<div class="sidebar" class:expanded>
{#if expanded}
<div style="display: flex; flex-direction: column; gap: 1rem;">
<div class="project-navigation">
<Link
title="Source"
route={{
resource: "project.source",
project: project.id,
node: baseUrl,
path: "/",
}}>
<Button
stylePadding="0.5rem 0.75rem"
size="large"
styleWidth="100%"
styleJustifyContent={"flex-start"}
variant={activeTab === "source" ? "gray" : "background"}>
<IconSmall name="chevron-left-right" />
Source
</Button>
</Link>
<Link
title={`${project.issues.open} Issues`}
route={{
resource: "project.issues",
project: project.id,
node: baseUrl,
}}>
<Button
stylePadding="0.5rem 0.75rem"
let:hover
size="large"
styleJustifyContent={"flex-start"}
styleWidth="100%"
variant={activeTab === "issues" ? "gray" : "background"}>
<IconSmall name="issue" />
<div class="title-counter">
Issues
<span
class="counter"
class:selected={activeTab === "issues"}
class:hover={hover && activeTab !== "issues"}>
{project.issues.open}
</span>
</div>
</Button>
</Link>
<div class="project-navigation">
<Link
title="Source"
route={{
resource: "project.source",
project: project.id,
node: baseUrl,
path: "/",
}}>
<Button
stylePadding="0.5rem 0.75rem"
size="large"
styleWidth="100%"
styleJustifyContent={"flex-start"}
variant={activeTab === "source" ? "gray" : "background"}>
<IconSmall name="chevron-left-right" />
<span class="title-counter" class:expanded>Source</span>
</Button>
</Link>
<Link
title={`${project.issues.open} Issues`}
route={{
resource: "project.issues",
project: project.id,
node: baseUrl,
}}>
<Button
stylePadding="0.5rem 0.75rem"
let:hover
size="large"
styleJustifyContent={"flex-start"}
styleWidth="100%"
variant={activeTab === "issues" ? "gray" : "background"}>
<IconSmall name="issue" />
<div class="title-counter" class:expanded>
Issues
<span
class="counter"
class:selected={activeTab === "issues"}
class:hover={hover && activeTab !== "issues"}>
{project.issues.open}
</span>
</div>
</Button>
</Link>
<Link
title={`${project.patches.open} Patches`}
route={{
resource: "project.patches",
project: project.id,
node: baseUrl,
}}>
<Button
stylePadding="0.5rem 0.75rem"
let:hover
size="large"
styleWidth="100%"
styleJustifyContent={"flex-start"}
variant={activeTab === "patches" ? "gray" : "background"}>
<IconSmall name="patch" />
<div class="title-counter">
Patches
<span
class="counter"
class:hover={hover && activeTab !== "patches"}
class:selected={activeTab === "patches"}>
{project.patches.open}
</span>
</div>
</Button>
</Link>
</div>
</div>
<div style="display: flex; flex-direction:column; gap: 1rem;">
{#if !hideContextHelp}
<Link
title={`${project.patches.open} Patches`}
route={{
resource: "project.patches",
project: project.id,
node: baseUrl,
}}>
<Button
stylePadding="0.5rem 0.75rem"
let:hover
size="large"
styleWidth="100%"
styleJustifyContent={"flex-start"}
variant={activeTab === "patches" ? "gray" : "background"}>
<IconSmall name="patch" />
<div class="title-counter" class:expanded>
Patches
<span
class="counter"
class:hover={hover && activeTab !== "patches"}
class:selected={activeTab === "patches"}>
{project.patches.open}
</span>
</div>
</Button>
</Link>
</div>
<div class="bottom">
<div class="help" class:expanded>
{#if !hideContextHelp && expanded}
{#if loadingContextHelp}
<div
style="display: flex; justify-content: center; align-items: center; height: 2rem;">
@@ -227,106 +280,8 @@
</div>
{/if}
{/if}
<div class="sidebar-footer" style:flex-direction="row">
<Button
title={"Collapse"}
on:click={toggleSidebar}
variant="background">
<IconSmall name="chevron-left" />
</Button>
<div style:width="1.5rem" />
<Popover popoverPositionBottom="2.5rem" popoverPositionLeft="0">
<Button
variant="background"
title="Settings"
slot="toggle"
let:toggle
on:click={toggle}>
<IconSmall name="settings" />
Settings
</Button>
<Settings slot="popover" />
</Popover>
<Popover popoverPositionBottom="2.5rem" popoverPositionLeft="0">
<Button
variant="background"
title="Help"
slot="toggle"
let:toggle
on:click={toggle}>
<IconSmall name="help" />
Help
</Button>
<Help slot="popover" />
</Popover>
</div>
</div>
{:else}
<div style="display: flex; flex-direction: column; gap: 1rem;">
<div class="project-navigation">
<Link
title="Source"
route={{
resource: "project.source",
project: project.id,
node: baseUrl,
path: "/",
}}>
<Button
size="large"
stylePadding="0 0.75rem"
variant={activeTab === "source" ? "gray" : "background"}>
<IconSmall name="chevron-left-right" />
</Button>
</Link>
<Link
title={`${project.issues.open} Issues`}
route={{
resource: "project.issues",
project: project.id,
node: baseUrl,
}}>
<Button
size="large"
stylePadding="0 0.75rem"
variant={activeTab === "issues" ? "gray" : "background"}>
<IconSmall name="issue" />
</Button>
</Link>
<Link
title={`${project.patches.open} Patches`}
route={{
resource: "project.patches",
project: project.id,
node: baseUrl,
}}>
<Button
size="large"
stylePadding="0 0.75rem"
variant={activeTab === "patches" ? "gray" : "background"}>
<IconSmall name="patch" />
</Button>
</Link>
</div>
</div>
<div
class="sidebar-footer"
style:flex-direction="column-reverse"
style:gap="0.5rem">
<Button
stylePadding="0 0.75rem"
variant="background"
title={"Expand"}
on:click={toggleSidebar}>
<IconSmall name="chevron-right" />
</Button>
<div class="vertical-buttons" class:expanded style:gap="0.5rem">
<Popover popoverPositionBottom="0" popoverPositionLeft="3rem">
<Button
stylePadding="0 0.75rem"
@@ -370,7 +325,7 @@
slot="toggle"
let:toggle
on:click={toggle}>
<IconSmall name="globe" />
<IconSmall name="device" />
</Button>
<ContextHelp
@@ -386,5 +341,40 @@
{/if}
{/if}
</div>
{/if}
<div class="sidebar-footer" style:flex-direction="row">
<Button title={"Collapse"} on:click={toggleSidebar} variant="background">
<div class="icon" class:expanded>
<IconSmall name="chevron-left" />
</div>
</Button>
<div style:width="1.5rem" />
<div class="horizontal-buttons" class:expanded>
<Popover popoverPositionBottom="2.5rem" popoverPositionLeft="0">
<Button
variant="background"
title="Settings"
slot="toggle"
let:toggle
on:click={toggle}>
<IconSmall name="settings" />
Settings
</Button>
<Settings slot="popover" />
</Popover>
<Popover popoverPositionBottom="2.5rem" popoverPositionLeft="0">
<Button
variant="background"
title="Help"
slot="toggle"
let:toggle
on:click={toggle}>
<IconSmall name="help" />
Help
</Button>
<Help slot="popover" />
</Popover>
</div>
</div>
</div>
</div>
+1 -1
View File
@@ -383,7 +383,7 @@ test("only one modal can be open at a time", async ({ page }) => {
await expect(page.getByText("bob")).not.toBeVisible();
await expect(page.getByText("feature/branch")).not.toBeVisible();
await page.getByRole("button", { name: "Settings" }).first().click();
await page.getByText("Settings").click();
await expect(page.getByText("Code font")).toBeVisible();
await expect(page.getByText("Use the Radicle CLI")).not.toBeVisible();
await expect(page.getByText("bob")).not.toBeVisible();
+3 -3
View File
@@ -19,7 +19,7 @@ test("theme persistance", async ({ page }) => {
await expect(
page.getByRole("banner").getByRole("link", { name: "source-browsing" }),
).toBeVisible();
await page.getByRole("button", { name: "Settings" }).first().click();
await page.getByText("Settings").click();
await page.getByText("System").click();
await page.getByRole("button", { name: "Light Mode" }).click();
@@ -38,7 +38,7 @@ test("change theme", async ({ page }) => {
await expect(
page.getByRole("banner").getByRole("link", { name: "source-browsing" }),
).toBeVisible();
await page.getByRole("button", { name: "Settings" }).first().click();
await page.getByText("Settings").click();
await page.getByRole("button", { name: "Light Mode" }).click();
await expect(page.locator("html")).toHaveAttribute("data-theme", "light");
@@ -65,7 +65,7 @@ test("change code font", async ({ page }) => {
page.getByRole("banner").getByRole("link", { name: "source-browsing" }),
).toBeVisible();
await page.getByRole("button", { name: "Settings" }).first().click();
await page.getByText("Settings").click();
await page.getByText("System").click();
await expect(page.getByText("System")).toHaveClass(/selected/);