From ef2f0cc33384ab33f711d5f17328b2984465deb9 Mon Sep 17 00:00:00 2001
From: Matt Kane
Date: Fri, 8 May 2026 15:04:07 +0100
Subject: [PATCH 1/2] fix(admin): replace raw checkboxes with Kumo Switch and
Checkbox
Migrates 20 raw elements to Kumo:
Switches (single-boolean toggles with description):
- ContentTypeEditor: SEO, Enable comments, Auto-approve authenticated users
- RepeaterField: boolean sub-field
- PortableTextEditor: plugin 'toggle' field type renderer
- FieldEditor: Required / Unique / Searchable + sub-field Required
- WordPressImport: Import navigation menus, Categories (locked-on),
Tags (locked-on), Site title and tagline, Logo and favicon, SEO
settings, per-post-type toggles
Checkboxes (multi-select / list items):
- ContentTypeEditor: supports[] options
- PluginManager: 'Also delete plugin storage data' uninstall option
- TaxonomyManager: collection multi-select
- TaxonomySidebar: term tree nodes
Drops manual
-
- setDeleteData(e.target.checked)}
- className="rounded border"
- />
- {t`Also delete plugin storage data`}
-
+ setDeleteData(checked)}
+ label={t`Also delete plugin storage data`}
+ />
diff --git a/packages/admin/src/components/PortableTextEditor.tsx b/packages/admin/src/components/PortableTextEditor.tsx
index 9c3bb6335..15224c906 100644
--- a/packages/admin/src/components/PortableTextEditor.tsx
+++ b/packages/admin/src/components/PortableTextEditor.tsx
@@ -11,7 +11,7 @@
* - Floating menu on empty lines
*/
-import { Button, Dialog, Input, Select } from "@cloudflare/kumo";
+import { Button, Dialog, Input, Select, Switch } from "@cloudflare/kumo";
import {
DndContext,
KeyboardSensor,
@@ -1361,15 +1361,11 @@ function BlockKitField({
}
case "toggle": {
return (
-
- onChange(field.action_id, e.target.checked)}
- className="h-4 w-4"
- />
- {field.label}
-
+
onChange(field.action_id, checked)}
+ label={{field.label}}
+ />
);
}
case "repeater": {
diff --git a/packages/admin/src/components/RepeaterField.tsx b/packages/admin/src/components/RepeaterField.tsx
index 0fbd061a2..4859dac6b 100644
--- a/packages/admin/src/components/RepeaterField.tsx
+++ b/packages/admin/src/components/RepeaterField.tsx
@@ -5,7 +5,7 @@
* Items can be added, removed, and reordered via drag-and-drop.
*/
-import { Button, Input, InputArea, Select } from "@cloudflare/kumo";
+import { Button, Input, InputArea, Select, Switch } from "@cloudflare/kumo";
import { DndContext, closestCenter } from "@dnd-kit/core";
import type { DragEndEvent } from "@dnd-kit/core";
import {
@@ -335,14 +335,11 @@ function SubFieldInput({ subField, value, onChange }: SubFieldInputProps) {
);
case "boolean":
return (
-
- onChange(e.target.checked)}
- />
- {subField.label}
-
+ onChange(checked)}
+ label={{subField.label}}
+ />
);
case "datetime":
return (
diff --git a/packages/admin/src/components/TaxonomyManager.tsx b/packages/admin/src/components/TaxonomyManager.tsx
index 56460f907..34ca21678 100644
--- a/packages/admin/src/components/TaxonomyManager.tsx
+++ b/packages/admin/src/components/TaxonomyManager.tsx
@@ -657,18 +657,13 @@ function CreateTaxonomyDialog({
{collectionEntries.map(({ slug, label: collLabel }) => (
-
-
+ toggleCollection(slug)}
- className="rounded"
+ onCheckedChange={() => toggleCollection(slug)}
+ label={{collLabel}}
/>
- {collLabel}
-
+
))}
diff --git a/packages/admin/src/components/TaxonomySidebar.tsx b/packages/admin/src/components/TaxonomySidebar.tsx
index 6186417fe..cc0335e5e 100644
--- a/packages/admin/src/components/TaxonomySidebar.tsx
+++ b/packages/admin/src/components/TaxonomySidebar.tsx
@@ -6,7 +6,7 @@
* - Tag input for flat taxonomies (tags)
*/
-import { Button, Input, Label, Toast } from "@cloudflare/kumo";
+import { Button, Checkbox, Input, Label, Toast } from "@cloudflare/kumo";
import { i18n } from "@lingui/core";
import { msg } from "@lingui/core/macro";
import { useLingui } from "@lingui/react/macro";
@@ -118,18 +118,16 @@ function CategoryCheckboxTree({
return (
-
- onToggle(term.id)}
- className="me-2"
+ onCheckedChange={() => onToggle(term.id)}
+ label={{term.label}}
/>
- {term.label}
-
+
{term.children.map((child) => (
{/* Menus */}
-
-
-
onImportMenusChange(e.target.checked)}
- className="h-4 w-4 rounded border-gray-300"
- aria-label={t`Import navigation menus`}
- />
+
onImportMenusChange(checked)}
+ label={
@@ -1603,43 +1607,31 @@ function ReviewStep({
-
-
+ }
+ />
{/* Categories count */}
{analysis.categories > 0 && (
-
-
-
-
{t`Categories (${analysis.categories})`}
-
-
+
{}}
+ disabled
+ label={{t`Categories (${analysis.categories})`}
}
+ />
)}
{/* Tags count */}
{analysis.tags > 0 && (
-
-
-
-
{t`Tags (${analysis.tags})`}
-
-
+
{}}
+ disabled
+ label={{t`Tags (${analysis.tags})`}
}
+ />
)}
@@ -1661,53 +1653,36 @@ function ReviewStep({
{/* Site title & tagline */}
-
-
onImportSiteTitleChange(e.target.checked)}
- className="h-4 w-4 rounded border-gray-300"
- aria-label={t`Import site title and tagline`}
- />
-
-
{t`Site title & tagline`}
-
-
+
onImportSiteTitleChange(checked)}
+ label={{t`Site title & tagline`}
}
+ />
{/* Logo & favicon */}
-
-
onImportLogoChange(e.target.checked)}
- className="h-4 w-4 rounded border-gray-300"
- aria-label={t`Import logo and favicon`}
- />
-
-
+
onImportLogoChange(checked)}
+ label={{t`Logo & favicon`}
}
+ />
{/* SEO settings */}
-
-
onImportSeoChange(e.target.checked)}
- className="h-4 w-4 rounded border-gray-300"
- aria-label={t`Import SEO settings`}
- />
-
-
{t`SEO settings (Yoast)`}
-
- {t`Meta titles, descriptions, and social images`}
-
-
-
+
onImportSeoChange(checked)}
+ label={
+
+
{t`SEO settings (Yoast)`}
+
+ {t`Meta titles, descriptions, and social images`}
+
+
+ }
+ />
@@ -1812,13 +1787,10 @@ function PostTypeRow({