chore: improve the design of the create workspace page for dynamic parameters (#17654)

contributes to coder/preview#59

1. Improves the design and layout of the presets dropdown and switch
2. Improves the design for the immutable badge

<img width="537" alt="Screenshot 2025-05-01 at 23 28 11"
src="https://github.com/user-attachments/assets/f0967758-5ea7-4436-b44a-e014c048202c"
/>
<img width="714" alt="Screenshot 2025-05-01 at 23 28 34"
src="https://github.com/user-attachments/assets/0bb091e1-611f-4a58-8f6f-b3bb027c6a10"
/>
This commit is contained in:
Jaayden Halko
2025-05-02 11:14:32 -04:00
committed by GitHub
parent 912b6aba82
commit e37ddd44d2
3 changed files with 44 additions and 25 deletions
+7 -2
View File
@@ -26,10 +26,15 @@ const badgeVariants = cva(
sm: "text-2xs font-regular h-5.5 [&_svg]:size-icon-xs",
md: "text-xs font-medium [&_svg]:size-icon-sm",
},
border: {
none: "border-transparent",
solid: "border border-solid",
},
},
defaultVariants: {
variant: "default",
size: "md",
border: "solid",
},
},
);
@@ -41,14 +46,14 @@ export interface BadgeProps
}
export const Badge = forwardRef<HTMLDivElement, BadgeProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
({ className, variant, size, border, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "div";
return (
<Comp
{...props}
ref={ref}
className={cn(badgeVariants({ variant, size }), className)}
className={cn(badgeVariants({ variant, size, border }), className)}
/>
);
},
@@ -106,7 +106,7 @@ const ParameterLabel: FC<ParameterLabelProps> = ({ parameter, isPreset }) => {
<Tooltip>
<TooltipTrigger asChild>
<span className="flex items-center">
<Badge size="sm" variant="warning">
<Badge size="sm" variant="warning" border="none">
<TriangleAlert />
Immutable
</Badge>
@@ -5,12 +5,17 @@ import { ErrorAlert } from "components/Alert/ErrorAlert";
import { Avatar } from "components/Avatar/Avatar";
import { Button } from "components/Button/Button";
import { FeatureStageBadge } from "components/FeatureStageBadge/FeatureStageBadge";
import { SelectFilter } from "components/Filter/SelectFilter";
import { Input } from "components/Input/Input";
import { Label } from "components/Label/Label";
import { Pill } from "components/Pill/Pill";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "components/Select/Select";
import { Spinner } from "components/Spinner/Spinner";
import { Stack } from "components/Stack/Stack";
import { Switch } from "components/Switch/Switch";
import { UserAutocomplete } from "components/UserAutocomplete/UserAutocomplete";
import { type FormikContextType, useFormik } from "formik";
@@ -153,11 +158,11 @@ export const CreateWorkspacePageViewExperimental: FC<
}, [form.submitCount, form.errors]);
const [presetOptions, setPresetOptions] = useState([
{ label: "None", value: "" },
{ label: "None", value: "None" },
]);
useEffect(() => {
setPresetOptions([
{ label: "None", value: "" },
{ label: "None", value: "None" },
...presets.map((preset) => ({
label: preset.Name,
value: preset.ID,
@@ -421,7 +426,7 @@ export const CreateWorkspacePageViewExperimental: FC<
)}
{parameters.length > 0 && (
<section className="flex flex-col gap-6">
<section className="flex flex-col gap-9">
<hgroup>
<h2 className="text-xl font-semibold m-0">Parameters</h2>
<p className="text-sm text-content-secondary m-0">
@@ -429,30 +434,39 @@ export const CreateWorkspacePageViewExperimental: FC<
parameters cannot be modified once the workspace is created.
</p>
</hgroup>
<Diagnostics diagnostics={diagnostics} />
{diagnostics.length > 0 && (
<Diagnostics diagnostics={diagnostics} />
)}
{presets.length > 0 && (
<Stack direction="column" spacing={2}>
<div className="flex flex-col gap-2">
<div className="flex gap-2 items-center">
<Label className="text-sm">Preset</Label>
<FeatureStageBadge contentType={"beta"} size="md" />
</div>
<div className="flex">
<SelectFilter
label="Preset"
options={presetOptions}
onSelect={(option) => {
<div className="flex flex-col gap-2">
<div className="flex gap-2 items-center">
<Label className="text-sm">Preset</Label>
<FeatureStageBadge contentType={"beta"} size="md" />
</div>
<div className="flex flex-col gap-4">
<div className="max-w-lg">
<Select
onValueChange={(option) => {
const index = presetOptions.findIndex(
(preset) => preset.value === option?.value,
(preset) => preset.value === option,
);
if (index === -1) {
return;
}
setSelectedPresetIndex(index);
}}
placeholder="Select a preset"
selectedOption={presetOptions[selectedPresetIndex]}
/>
>
<SelectTrigger>
<SelectValue placeholder={"Select a preset"} />
</SelectTrigger>
<SelectContent>
{presetOptions.map((option) => (
<SelectItem key={option.value} value={option.value}>
{option.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<span className="flex items-center gap-3">
<Switch
@@ -465,7 +479,7 @@ export const CreateWorkspacePageViewExperimental: FC<
</Label>
</span>
</div>
</Stack>
</div>
)}
<div className="flex flex-col gap-9">