Skip to content

Commit

Permalink
temp
Browse files Browse the repository at this point in the history
  • Loading branch information
Oksamies committed Nov 29, 2023
1 parent 76a07b9 commit 730f4c3
Show file tree
Hide file tree
Showing 23 changed files with 3,329 additions and 5,300 deletions.
64 changes: 64 additions & 0 deletions packages/cyberstorm-forms/src/components/FormSelect.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
.SelectTrigger {
display: inline-flex;
flex-shrink: 0;
gap: 1rem;
align-items: center;
justify-content: center;
height: 2.75rem;
padding: 0.75rem 1rem;
border-radius: 0.5rem;
color: #f5f5f6;
font-weight: var(--font-weight-boldest);
font-size: 0.875rem;
line-height: normal;
background: rgb(63 63 136 / 0.55);
}

.SelectIcon {
color: #f5f5f6;
}

.SelectContent {
display: flex;
flex-direction: column;
align-items: flex-start;
padding: 0.5rem 0;
border: 1px solid #29295b;

border-radius: 0.5rem;
overflow: auto;
background: #15152d;
box-shadow: 0 12px 24px 5px rgb(0 0 0 / 0.75);
}

.SelectViewport > div {
display: flex;
gap: 1rem;
align-items: center;
align-self: stretch;
justify-content: space-between;
padding: 0.75rem 1rem;
color: var(--text-primary, #f5f5f6);
font-weight: var(--font-weight-medium);
font-size: 0.875rem;
font-style: normal;
line-height: normal;
user-select: none;
}

.SelectLabel {
padding: 0 25px;
color: yellow;
font-size: 12px;
line-height: 25px;
}

.SelectScrollButton {
display: flex;
align-items: center;
justify-content: center;
height: 25px;
color: violet;
background-color: white;
cursor: default;
}
126 changes: 126 additions & 0 deletions packages/cyberstorm-forms/src/components/FormSelect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
"use client";

import { z, ZodObject } from "zod";
import { ZodRawShape } from "zod/lib/types";
import { Path, useController } from "react-hook-form";
import styles from "./FormSelect.module.css";
import * as Select from "@radix-ui/react-select";
import React, { PropsWithChildren } from "react";
import { Icon } from "@thunderstore/cyberstorm";
import { faCaretDown, faCheckCircle } from "@fortawesome/pro-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";

export type FormSelectProps<
Schema extends ZodObject<Z>,
Z extends ZodRawShape
> = {
// The schema is required to allow TS to infer valid values for the name field
schema: Schema;
name: Path<z.infer<Schema>>;
options: { value: string; label: string }[];
placeholder?: string;
defaultValue?: string;
ariaLabel?: string;
};
export function FormSelect<Schema extends ZodObject<Z>, Z extends ZodRawShape>({
name,
defaultValue,
options,
ariaLabel,
}: FormSelectProps<Schema, Z>) {
const {
field,
fieldState: { error },
formState: { isSubmitting, disabled },
} = useController({ name });

if (defaultValue) {
React.useEffect(() => {
field.onChange(defaultValue);
}, [defaultValue]);
}

return (
<>
<TempSelect
{...field}
options={options}
ariaLabel={ariaLabel}
disabled={isSubmitting || disabled}
defaultValue={defaultValue}
/>
{error && <span className={styles.errorMessage}>{error.message}</span>}
</>
);
}

FormSelect.displayName = "FormSelect";

interface TempSelectProps {
options: { value: string; label: string }[];
onChange: (val: string) => void;
placeholder?: string;
value?: string;
disabled?: boolean;
ariaLabel?: string;
defaultValue?: string;
}

const TempSelect = React.forwardRef<HTMLButtonElement, TempSelectProps>(
function SelectDemo(props, ref) {
return (
<Select.Root
disabled={props.disabled}
onValueChange={props.onChange}
defaultValue={props.defaultValue}
>
<Select.Trigger
className={styles.SelectTrigger}
aria-label={props.ariaLabel}
>
<Select.Value placeholder={props.placeholder} ref={ref} />
<Select.Icon className={styles.SelectIcon}>
<Icon inline>
<FontAwesomeIcon icon={faCaretDown} />
</Icon>
</Select.Icon>
</Select.Trigger>
<Select.Portal>
<Select.Content position="popper" className={styles.SelectContent}>
<Select.Viewport className={styles.SelectViewport}>
{props.options.map((option) => (
<SelectItem key={option.value} value={option.value}>
{option.label}
</SelectItem>
))}
</Select.Viewport>
</Select.Content>
</Select.Portal>
</Select.Root>
);
}
);

interface SelectItemProps {
value: string;
disabled?: boolean;
}

const SelectItem = React.forwardRef<
HTMLDivElement,
PropsWithChildren<SelectItemProps>
>((props: PropsWithChildren<SelectItemProps>, forwardedRef) => {
const { value, disabled = false, children } = props;
return (
<Select.Item value={value} disabled={disabled} ref={forwardedRef}>
<Select.ItemText>{children}</Select.ItemText>
<Select.ItemIndicator className={styles.SelectItemIndicator}>
<Icon inline>
<FontAwesomeIcon icon={faCheckCircle} />
</Icon>
</Select.ItemIndicator>
</Select.Item>
);
});

SelectItem.displayName = "SelectItem";
29 changes: 27 additions & 2 deletions packages/cyberstorm-forms/src/components/FormSubmitButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,39 @@ const SubmitButtonContent = React.memo(

SubmitButtonContent.displayName = "SubmitButtonContent";

export function FormSubmitButton({ text }: { text: string }) {
export function FormSubmitButton({
text,
colorScheme = "accent",
}: {
text: string;
colorScheme?:
| "danger"
| "default"
| "primary"
| "accent"
| "tertiary"
| "fancyAccent"
| "success"
| "warning"
| "discord"
| "github"
| "overwolf"
| "specialGreen"
| "specialPurple"
| "transparentDanger"
| "transparentDefault"
| "transparentTertiary"
| "transparentAccent"
| "transparentPrimary"
| "wideDarker";
}) {
const { isSubmitting, disabled } = useFormState();

return (
<Button.Root
type="submit"
paddingSize="large"
colorScheme="accent"
colorScheme={colorScheme}
disabled={isSubmitting || disabled}
>
<SubmitButtonContent isSubmitting={isSubmitting} text={text} />
Expand Down
31 changes: 31 additions & 0 deletions packages/cyberstorm-forms/src/components/GhostInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"use client";

import { z, ZodObject, ZodRawShape } from "zod";
import { Path, useController } from "react-hook-form";
import React from "react";

export type GhostInputProps<
Schema extends ZodObject<Z>,
Z extends ZodRawShape
> = {
// The schema is required to allow TS to infer valid values for the name field
schema: Schema;
name: Path<z.infer<Schema>>;
value?: string;
};
export function GhostInput<Schema extends ZodObject<Z>, Z extends ZodRawShape>({
name,
value,
}: GhostInputProps<Schema, Z>) {
const { field } = useController({ name });

if (value) {
React.useEffect(() => {
field.onChange(value);
}, [value]);
}

return <input {...field} ref={field.ref} />;
}

GhostInput.displayName = "GhostInput";
42 changes: 42 additions & 0 deletions packages/cyberstorm-forms/src/forms/AddTeamMemberForm.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
.root {
display: flex;
flex-direction: column;
}

.dialog {
display: flex;
flex-direction: column;
gap: 1.5rem;
padding: var(--space--32);
border-top: var(--border-width--px) solid var(--color-surface--5);
}

.dialogText {
color: var(--color-text--secondary);
font-weight: var(--font-weight-medium);
font-size: var(--font-size--l);
line-height: var(--line-height--l);
}

.fields {
display: flex;
flex-direction: row;
gap: 1rem;
}

.fields > :first-child {
flex-grow: 1;
}

.teamNameText {
color: #39e9aa;
}

.footer {
display: flex;
flex-direction: row-reverse;
gap: 1rem;
justify-content: space-between;
padding: var(--space--16) var(--space--24);
border-top: var(--border-width--px) solid var(--color-surface--5);
}
62 changes: 62 additions & 0 deletions packages/cyberstorm-forms/src/forms/AddTeamMemberForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"use client";

import styles from "./AddTeamMemberForm.module.css";
import { teamAddMember } from "@thunderstore/thunderstore-api";
import {
ApiForm,
teamAddMemberFormSchema,
} from "@thunderstore/ts-api-react-forms";
import {
FormSubmitButton,
FormTextInput,
useFormToaster,
} from "@thunderstore/cyberstorm-forms";
import { FormSelect } from "../components/FormSelect";

export function AddTeamMemberForm(props: { teamName: string }) {
const toaster = useFormToaster({
successMessage: `Member TODO added to ${props.teamName}`,
});

const roleOptions = [
{ value: "member", label: "Member" },
{ value: "owner", label: "Owner" },
];

return (
<ApiForm
{...toaster}
schema={teamAddMemberFormSchema}
metaData={{ identifier: props.teamName }}
endpoint={teamAddMember}
formProps={{ className: styles.root }}
>
<div className={styles.dialog}>
<div className={styles.dialogText}>
Enter the username of the user you wish to add to the team{" "}
<span className={styles.teamNameText}>{props.teamName}</span>
</div>
<div className={styles.fields}>
<FormTextInput
schema={teamAddMemberFormSchema}
name={"user"}
placeholder={"Enter username..."}
/>
<FormSelect
schema={teamAddMemberFormSchema}
name={"role"}
options={roleOptions}
defaultValue="member"
placeholder="Select role..."
ariaLabel={"role"}
/>
</div>
</div>
<div className={styles.footer}>
<FormSubmitButton text="Add member" />
</div>
</ApiForm>
);
}

AddTeamMemberForm.displayName = "AddTeamMemberForm";
1 change: 1 addition & 0 deletions packages/cyberstorm-forms/src/forms/CreateTeamForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export function CreateTeamForm() {
<ApiForm
{...toaster}
schema={createTeamFormSchema}
metaData={{}}
endpoint={createTeam}
formProps={{ className: styles.root }}
>
Expand Down
Loading

0 comments on commit 730f4c3

Please sign in to comment.