Merge pull request 'ui/navigation-section' (#4880) from ui/navigation-section into main

Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/4880
This commit is contained in:
brianmcgee
2025-08-22 11:20:14 +00:00
6 changed files with 108 additions and 108 deletions

View File

@@ -12,13 +12,4 @@
.clans {
@apply flex flex-col gap-2;
}
.clan {
@apply flex items-center justify-between;
@apply px-4 py-5 bg-def-2;
.meta {
@apply flex flex-col gap-1;
}
}
}

View File

@@ -9,6 +9,7 @@ import { For, Show } from "solid-js";
import { activeClanURI, clanURIs, setActiveClanURI } from "@/src/stores/clan";
import { useClanListQuery } from "@/src/hooks/queries";
import { Alert } from "@/src/components/Alert/Alert";
import { NavSection } from "../NavSection/NavSection";
export interface ListClansModalProps {
onClose?: () => void;
@@ -78,20 +79,10 @@ export const ListClansModal = (props: ListClansModalProps) => {
<ul class={cx(styles.clans)}>
<For each={clanList()}>
{(clan) => (
<li class={cx(styles.clan)}>
<div class={cx(styles.meta)}>
<Typography hierarchy="label" weight="bold" size="default">
{clan.data.name}
</Typography>
<Typography hierarchy="body" size="s">
{clan.data.description}
</Typography>
</div>
<Button
hierarchy="secondary"
ghost
icon="CaretRight"
<li>
<NavSection
label={clan.data.name}
description={clan.data.description ?? undefined}
onClick={selectClan(clan.data.uri)}
/>
</li>

View File

@@ -0,0 +1,16 @@
.navSection {
@apply w-full flex gap-2 items-center justify-between;
@apply rounded-md px-4 py-5 bg-def-2;
.meta {
@apply flex flex-col gap-2;
}
&:hover {
@apply bg-def-3 cursor-pointer;
}
&:active {
@apply bg-def-4;
}
}

View File

@@ -0,0 +1,35 @@
import type { Meta, StoryObj } from "@kachurun/storybook-solid";
import {
NavSection,
NavSectionProps,
} from "@/src/components/NavSection/NavSection";
const meta: Meta<NavSectionProps> = {
title: "Components/NavSection",
component: NavSection,
decorators: [
(Story: StoryObj) => (
<div class="w-96">
<Story />
</div>
),
],
};
export default meta;
type Story = StoryObj<NavSectionProps>;
export const Default: Story = {
args: {
label: "My Clan",
},
};
export const WithDescription: Story = {
args: {
...Default.args,
description:
"This is my Clan. There are many Clans like it, but this one is mine",
},
};

View File

@@ -0,0 +1,35 @@
import cx from "classnames";
import styles from "./NavSection.module.css";
import { Button } from "@kobalte/core/button";
import Icon from "../Icon/Icon";
import { Typography } from "../Typography/Typography";
import { Show } from "solid-js";
export interface NavSectionProps {
label: string;
description?: string;
onClick: () => void;
}
export const NavSection = (props: NavSectionProps) => {
return (
<Button class={cx(styles.navSection)} onClick={props.onClick}>
<div class={cx(styles.meta)}>
<Typography hierarchy="label" size="default" weight="bold">
{props.label}
</Typography>
<Show when={props.description}>
<Typography
hierarchy="body"
size="s"
weight="normal"
color="secondary"
>
{props.description}
</Typography>
</Show>
</div>
<Icon icon="CaretRight" />
</Button>
);
};

View File

@@ -1,56 +1,22 @@
import { defineSteps, useStepper } from "@/src/hooks/stepper";
import { InstallSteps } from "../install";
import { Typography } from "@/src/components/Typography/Typography";
import { Button } from "@/src/components/Button/Button";
import { StepLayout } from "../../Steps";
import { NavSection } from "@/src/components/NavSection/NavSection";
const ChoiceLocalOrRemote = () => {
const stepSignal = useStepper<InstallSteps>();
return (
<div class="flex size-full flex-col gap-3">
<div class="flex flex-col gap-6 rounded-md px-4 py-6 text-fg-def-1 bg-def-2">
<div class="flex justify-between gap-2">
<div class="flex flex-col justify-center gap-1 px-1">
<Typography
hierarchy="body"
size="default"
weight="bold"
color="primary"
>
I have physical access to the machine.
</Typography>
</div>
<Button
type="button"
ghost
hierarchy="secondary"
icon="CaretRight"
<NavSection
label="I have physical access to the machine"
onClick={() => stepSignal.setActiveStep("local:choice")}
/>
</div>
</div>
<div class="flex flex-col gap-6 rounded-md px-4 py-6 text-fg-def-1 bg-def-2">
<div class="flex justify-between gap-2">
<div class="flex flex-col justify-center gap-1 px-1">
<Typography
hierarchy="body"
size="default"
weight="bold"
color="primary"
>
The Machine is remote and i have ssh access to it.
</Typography>
</div>
<Button
type="button"
ghost
hierarchy="secondary"
icon="CaretRight"
<NavSection
label="The Machine is remote and i have ssh access to it"
onClick={() => stepSignal.setActiveStep("install:address")}
/>
</div>
</div>
</div>
);
};
@@ -60,49 +26,15 @@ const ChoiceLocalInstaller = () => {
<StepLayout
body={
<div class="flex flex-col gap-3">
<div class="flex flex-col gap-6 rounded-md px-4 py-6 text-fg-def-1 bg-def-2">
<div class="flex justify-between gap-2">
<div class="flex flex-col justify-center gap-1 px-1">
<Typography
hierarchy="body"
size="default"
weight="bold"
color="primary"
>
I have an installer
</Typography>
</div>
<Button
type="button"
ghost
hierarchy="secondary"
icon="CaretRight"
<NavSection
label="I have an installer"
onClick={() => stepSignal.setActiveStep("install:address")}
/>
</div>
</div>
<div class="flex flex-col gap-6 rounded-md px-4 py-6 text-fg-def-1 bg-def-2">
<div class="flex justify-between gap-2">
<div class="flex flex-col justify-center gap-1 px-1">
<Typography
hierarchy="body"
size="default"
weight="bold"
color="primary"
>
I don't have an installer, yet
</Typography>
</div>
<Button
type="button"
ghost
hierarchy="secondary"
icon="CaretRight"
<NavSection
label="I don't have an installer, yet"
onClick={() => stepSignal.setActiveStep("create:prose")}
/>
</div>
</div>
</div>
}
footer={
<div class="flex justify-start">