diff --git a/pkgs/clan-app/ui/tests/types.test.ts b/pkgs/clan-app/ui/error.ts/types.test.ts
similarity index 100%
rename from pkgs/clan-app/ui/tests/types.test.ts
rename to pkgs/clan-app/ui/error.ts/types.test.ts
diff --git a/pkgs/clan-app/ui/src/components/Form/Checkbox.tsx b/pkgs/clan-app/ui/src/components/Form/Checkbox.tsx
index 2f92f0eeb..8226a648c 100644
--- a/pkgs/clan-app/ui/src/components/Form/Checkbox.tsx
+++ b/pkgs/clan-app/ui/src/components/Form/Checkbox.tsx
@@ -1,8 +1,10 @@
import {
- Checkbox as KCheckbox,
CheckboxInputProps as KCheckboxInputProps,
CheckboxRootProps as KCheckboxRootProps,
} from "@kobalte/core/checkbox";
+
+import { Checkbox as KCheckbox } from "@kobalte/core";
+
import Icon from "@/src/components/Icon/Icon";
import cx from "classnames";
@@ -11,7 +13,7 @@ import { PolymorphicProps } from "@kobalte/core/polymorphic";
import "./Checkbox.css";
import { FieldProps } from "./Field";
import { Orienter } from "./Orienter";
-import { Show } from "solid-js";
+import { Match, splitProps, Switch } from "solid-js";
export type CheckboxProps = FieldProps &
KCheckboxRootProps & {
@@ -19,6 +21,9 @@ export type CheckboxProps = FieldProps &
};
export const Checkbox = (props: CheckboxProps) => {
+ // we need to separate output the input otherwise it interferes with prop binding
+ const [_, rootProps] = splitProps(props, ["input"]);
+
const alignment = () =>
(props.orientation || "vertical") == "vertical" ? "start" : "center";
@@ -41,34 +46,36 @@ export const Checkbox = (props: CheckboxProps) => {
);
return (
-
-
-
-
-
- {props.readOnly && (
-
- {iconChecked}
-
- )}
- {!props.readOnly && (
- {iconChecked}
- )}
-
-
-
+ {(state) => (
+
+
+
+
+
+
+ {iconChecked}
+
+
+ {iconChecked}
+
+
+ {iconUnchecked}
+
+
+
+
+ )}
+
);
};
diff --git a/pkgs/clan-app/ui/src/components/Form/TextInput.tsx b/pkgs/clan-app/ui/src/components/Form/TextInput.tsx
index 4692e9bda..011960b05 100644
--- a/pkgs/clan-app/ui/src/components/Form/TextInput.tsx
+++ b/pkgs/clan-app/ui/src/components/Form/TextInput.tsx
@@ -18,33 +18,35 @@ export type TextInputProps = FieldProps &
input?: PolymorphicProps<"input", TextFieldInputProps<"input">>;
};
-export const TextInput = (props: TextInputProps) => (
-
-
-
-
- {props.icon && !props.readOnly && (
-
- )}
- {
+ return (
+
+
+
-
-
-
-);
+
+ {props.icon && !props.readOnly && (
+
+ )}
+
+
+
+
+ );
+};
diff --git a/pkgs/clan-app/ui/src/components/Sidebar/SidebarBody.tsx b/pkgs/clan-app/ui/src/components/Sidebar/SidebarBody.tsx
index a5757bacb..1175e0bea 100644
--- a/pkgs/clan-app/ui/src/components/Sidebar/SidebarBody.tsx
+++ b/pkgs/clan-app/ui/src/components/Sidebar/SidebarBody.tsx
@@ -6,7 +6,7 @@ import { Typography } from "@/src/components/Typography/Typography";
import { For } from "solid-js";
import { MachineStatus } from "@/src/components/MachineStatus/MachineStatus";
import { buildMachinePath, useClanURI } from "@/src/hooks/clan";
-import { useMachinesQuery } from "@/src/queries/queries";
+import { useMachinesQuery } from "@/src/hooks/queries";
import { SidebarProps } from "./Sidebar";
interface MachineProps {
diff --git a/pkgs/clan-app/ui/src/components/Sidebar/SidebarHeader.tsx b/pkgs/clan-app/ui/src/components/Sidebar/SidebarHeader.tsx
index c0acc59db..968617a2c 100644
--- a/pkgs/clan-app/ui/src/components/Sidebar/SidebarHeader.tsx
+++ b/pkgs/clan-app/ui/src/components/Sidebar/SidebarHeader.tsx
@@ -4,7 +4,7 @@ import { DropdownMenu } from "@kobalte/core/dropdown-menu";
import { useNavigate } from "@solidjs/router";
import { Typography } from "../Typography/Typography";
import { createSignal, For, Suspense } from "solid-js";
-import { useClanListQuery } from "@/src/queries/queries";
+import { useClanListQuery } from "@/src/hooks/queries";
import { navigateToClan, useClanURI } from "@/src/hooks/clan";
import { clanURIs } from "@/src/stores/clan";
diff --git a/pkgs/clan-app/ui/src/components/Sidebar/SidebarPane.stories.tsx b/pkgs/clan-app/ui/src/components/Sidebar/SidebarPane.stories.tsx
index 135c7dc0a..7121c9685 100644
--- a/pkgs/clan-app/ui/src/components/Sidebar/SidebarPane.stories.tsx
+++ b/pkgs/clan-app/ui/src/components/Sidebar/SidebarPane.stories.tsx
@@ -8,7 +8,32 @@ import { Divider } from "@/src/components/Divider/Divider";
import { TextInput } from "@/src/components/Form/TextInput";
import { TextArea } from "@/src/components/Form/TextArea";
import { Checkbox } from "@/src/components/Form/Checkbox";
-import { Combobox } from "../Form/Combobox";
+import { SidebarSectionForm } from "@/src/components/Sidebar/SidebarSectionForm";
+import * as v from "valibot";
+import { splitProps } from "solid-js";
+import { Typography } from "@/src/components/Typography/Typography";
+
+type Story = StoryObj;
+
+const schema = v.object({
+ firstName: v.pipe(v.string(), v.nonEmpty("Please enter a first name.")),
+ lastName: v.pipe(v.string(), v.nonEmpty("Please enter a last name.")),
+ bio: v.string(),
+ shareProfile: v.optional(v.boolean()),
+ tags: v.pipe(v.optional(v.array(v.string()))),
+});
+
+const clanURI = "/home/brian/clans/my-clan";
+
+const profiles = {
+ ron: {
+ firstName: "Ron",
+ lastName: "Burgundy",
+ bio: "It's actually an optical illusion, it's the pattern on the pants.",
+ shareProfile: true,
+ tags: ["All", "Home Server", "Backup", "Random"],
+ },
+};
const meta: Meta = {
title: "Components/SidebarPane",
@@ -17,8 +42,6 @@ const meta: Meta = {
export default meta;
-type Story = StoryObj;
-
export const Default: Story = {
args: {
title: "Neptune",
@@ -27,87 +50,115 @@ export const Default: Story = {
},
children: (
<>
- {
+ schema={schema}
+ initialValues={profiles.ron}
+ onSubmit={async () => {
console.log("saving general");
}}
>
- {(editing) => (
-
- {
- console.log("saving general");
- }}
- >
- {(editing) => (
-
- )}
-
- {
- console.log("saving general");
- }}
- >
- {(editing) => <>>}
+
+ {/* todo fix tags component */}
+ {/* {*/}
+ {/* console.log("saving general");*/}
+ {/* }}*/}
+ {/*>*/}
+ {/* {({ editing, Field }) => (*/}
+ {/* */}
+ {/* {(field, input) => (*/}
+ {/* */}
+ {/* )}*/}
+ {/* */}
+ {/* )}*/}
+ {/**/}
+
+
+ Static Content
+
+
+ This is a non-form section with static content
+
>
),
diff --git a/pkgs/clan-app/ui/src/components/Sidebar/SidebarSection.css b/pkgs/clan-app/ui/src/components/Sidebar/SidebarSection.css
index 67f7fdfd0..9200dee88 100644
--- a/pkgs/clan-app/ui/src/components/Sidebar/SidebarSection.css
+++ b/pkgs/clan-app/ui/src/components/Sidebar/SidebarSection.css
@@ -1,5 +1,5 @@
div.sidebar-section {
- @apply flex flex-col gap-2 w-full h-full;
+ @apply flex flex-col gap-2 w-full h-fit;
& > div.header {
@apply flex items-center justify-between px-1.5;
diff --git a/pkgs/clan-app/ui/src/components/Sidebar/SidebarSection.tsx b/pkgs/clan-app/ui/src/components/Sidebar/SidebarSection.tsx
index 29d26a330..54bdd0b5b 100644
--- a/pkgs/clan-app/ui/src/components/Sidebar/SidebarSection.tsx
+++ b/pkgs/clan-app/ui/src/components/Sidebar/SidebarSection.tsx
@@ -1,26 +1,17 @@
-import { createSignal, JSX } from "solid-js";
+import { JSX } from "solid-js";
import "./SidebarSection.css";
import { Typography } from "@/src/components/Typography/Typography";
-import { Button as KButton } from "@kobalte/core/button";
-import Icon from "../Icon/Icon";
+import cx from "classnames";
export interface SidebarSectionProps {
title: string;
- onSave: () => Promise;
- children: (editing: boolean) => JSX.Element;
+ class?: string;
+ children: JSX.Element;
}
export const SidebarSection = (props: SidebarSectionProps) => {
- const [editing, setEditing] = createSignal(false);
-
- const save = async () => {
- // todo how do we surface errors?
- await props.onSave();
- setEditing(false);
- };
-
return (
-