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:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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",
|
||||
},
|
||||
};
|
||||
35
pkgs/clan-app/ui/src/components/NavSection/NavSection.tsx
Normal file
35
pkgs/clan-app/ui/src/components/NavSection/NavSection.tsx
Normal 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>
|
||||
);
|
||||
};
|
||||
@@ -1,55 +1,21 @@
|
||||
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"
|
||||
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"
|
||||
onClick={() => stepSignal.setActiveStep("install:address")}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<NavSection
|
||||
label="I have physical access to the machine"
|
||||
onClick={() => stepSignal.setActiveStep("local:choice")}
|
||||
/>
|
||||
<NavSection
|
||||
label="The Machine is remote and i have ssh access to it"
|
||||
onClick={() => stepSignal.setActiveStep("install:address")}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -60,48 +26,14 @@ 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"
|
||||
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"
|
||||
onClick={() => stepSignal.setActiveStep("create:prose")}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<NavSection
|
||||
label="I have an installer"
|
||||
onClick={() => stepSignal.setActiveStep("install:address")}
|
||||
/>
|
||||
<NavSection
|
||||
label="I don't have an installer, yet"
|
||||
onClick={() => stepSignal.setActiveStep("create:prose")}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
footer={
|
||||
|
||||
Reference in New Issue
Block a user