From cecfb52afe59e4e9599fe7a82a56dd8326983409 Mon Sep 17 00:00:00 2001
From: Jake Howell
Date: Mon, 3 Aug 2026 13:13:57 +0000
Subject: [PATCH 1/4] refactor(site): demui template editor dialogs and
create-template inputs
Migrate remaining MUI usage in template create/editor flows to shared shadcn components (`FormField`, `Input`, `Textarea`, `Checkbox`, `RadioGroup`, `Link`).
Also drops `disablePortal` on the publish-version help popover so it is no longer clipped by the dialog overflow.
---
.../TemplateExampleCard.tsx | 13 +--
.../CreateTemplatePage/TemplateUpload.tsx | 9 +-
.../CreateTemplatePage/VariableInput.tsx | 44 +++++-----
.../TemplateScheduleAutostart.tsx | 5 +-
.../TemplateVersionEditorPage/FileDialog.tsx | 40 +++++----
.../ProvisionerTagsPopover.tsx | 15 +---
.../PublishTemplateVersionDialog.tsx | 84 +++++++++++--------
.../pages/TemplatesPage/EmptyTemplates.tsx | 4 +-
8 files changed, 115 insertions(+), 99 deletions(-)
diff --git a/site/src/modules/templates/TemplateExampleCard/TemplateExampleCard.tsx b/site/src/modules/templates/TemplateExampleCard/TemplateExampleCard.tsx
index b401f71ff9514..2ad2d00a54bcb 100644
--- a/site/src/modules/templates/TemplateExampleCard/TemplateExampleCard.tsx
+++ b/site/src/modules/templates/TemplateExampleCard/TemplateExampleCard.tsx
@@ -1,9 +1,9 @@
-import Link from "@mui/material/Link";
import type { FC, HTMLAttributes } from "react";
import { Link as RouterLink } from "react-router";
import type { TemplateExample } from "#/api/typesGenerated";
import { Button } from "#/components/Button/Button";
import { ExternalImage } from "#/components/ExternalImage/ExternalImage";
+import { Link } from "#/components/Link/Link";
import { Pill } from "#/components/Pill/Pill";
import { cn } from "#/utils/cn";
@@ -53,11 +53,14 @@ export const TemplateExampleCard: FC = ({
{example.description}{" "}
- Read more
+
+ Read more
+
diff --git a/site/src/pages/CreateTemplatePage/TemplateUpload.tsx b/site/src/pages/CreateTemplatePage/TemplateUpload.tsx
index e5a9e67f2df57..1a0882c4c401a 100644
--- a/site/src/pages/CreateTemplatePage/TemplateUpload.tsx
+++ b/site/src/pages/CreateTemplatePage/TemplateUpload.tsx
@@ -1,7 +1,7 @@
-import Link from "@mui/material/Link";
import type { FC } from "react";
import { Link as RouterLink } from "react-router";
import { FileUpload } from "#/components/FileUpload/FileUpload";
+import { Link } from "#/components/Link/Link";
export interface TemplateUploadProps {
isUploading: boolean;
@@ -20,14 +20,15 @@ export const TemplateUpload: FC = ({
<>
The template has to be a .tar or .zip file. You can also use our{" "}
{
e.stopPropagation();
}}
+ asChild
+ showExternalIcon={false}
+ className="p-0"
>
- starter templates
+ starter templates
{" "}
to get started with Coder.
>
diff --git a/site/src/pages/CreateTemplatePage/VariableInput.tsx b/site/src/pages/CreateTemplatePage/VariableInput.tsx
index 3d2e4c1070cbb..b5ed2ae05ca83 100644
--- a/site/src/pages/CreateTemplatePage/VariableInput.tsx
+++ b/site/src/pages/CreateTemplatePage/VariableInput.tsx
@@ -1,9 +1,8 @@
-import FormControlLabel from "@mui/material/FormControlLabel";
-import Radio from "@mui/material/Radio";
-import RadioGroup from "@mui/material/RadioGroup";
-import TextField from "@mui/material/TextField";
import type { FC } from "react";
import type { TemplateVersionVariable } from "#/api/typesGenerated";
+import { Input } from "#/components/Input/Input";
+import { Label } from "#/components/Label/Label";
+import { RadioGroup, RadioGroupItem } from "#/components/RadioGroup/RadioGroup";
const isBoolean = (variable: TemplateVersionVariable) => {
return variable.type === "bool";
@@ -62,35 +61,36 @@ const VariableField: FC = ({
defaultValue,
}) => {
if (isBoolean(variable)) {
+ const trueId = `${variable.name}-true`;
+ const falseId = `${variable.name}-false`;
+
return (
{
- onChange(event.target.value);
- }}
+ disabled={disabled}
+ onValueChange={onChange}
>
- }
- label="True"
- />
- }
- label="False"
- />
+
+
+
+
+
+
+
+
);
}
return (
- = ({
? "number"
: variable.sensitive
? "password"
- : "string"
+ : "text"
}
/>
);
diff --git a/site/src/pages/TemplateSettingsPage/TemplateSchedulePage/TemplateScheduleAutostart.tsx b/site/src/pages/TemplateSettingsPage/TemplateSchedulePage/TemplateScheduleAutostart.tsx
index fdff2130f9346..e6558478e0dcf 100644
--- a/site/src/pages/TemplateSettingsPage/TemplateSchedulePage/TemplateScheduleAutostart.tsx
+++ b/site/src/pages/TemplateSettingsPage/TemplateSchedulePage/TemplateScheduleAutostart.tsx
@@ -1,4 +1,3 @@
-import FormHelperText from "@mui/material/FormHelperText";
import type { FC } from "react";
import { Button } from "#/components/Button/Button";
import {
@@ -54,9 +53,9 @@ export const TemplateScheduleAutostart: FC = ({
))}
-
+
-
+
);
};
diff --git a/site/src/pages/TemplateVersionEditorPage/FileDialog.tsx b/site/src/pages/TemplateVersionEditorPage/FileDialog.tsx
index ef0d5ec17c944..a00fd1750e722 100644
--- a/site/src/pages/TemplateVersionEditorPage/FileDialog.tsx
+++ b/site/src/pages/TemplateVersionEditorPage/FileDialog.tsx
@@ -1,6 +1,6 @@
-import TextField from "@mui/material/TextField";
import { type ChangeEvent, type FC, useState } from "react";
import { ConfirmDialog } from "#/components/Dialog/ConfirmDialog/ConfirmDialog";
+import { FormField } from "#/components/FormField/FormField";
import { type FileTree, isFolder, validatePath } from "#/utils/filetree";
interface CreateFileDialogProps {
@@ -63,22 +63,25 @@ export const CreateFileDialog: FC = ({
Specify the path to a file to be created. This path can contain
slashes too.