Custom field input components #383
Replies: 2 comments
-
|
I believe this is already available through plugins. You can create custom components and pass them to the 'fieldWidgets' array when creating the plugin. See example from their /**
* Color Picker Plugin for EmDash CMS
*
* Provides a color picker field widget that replaces the default
* string input with a visual color selector. Demonstrates the
* field widget plugin capability.
*
* Usage:
* 1. Add the plugin to your emdash config
* 2. Create a field with type "string" and widget "color:picker"
* 3. The admin editor will show a color picker instead of a text input
*
* The color value is stored as a hex string (e.g., "#ff6600").
*/
import type { PluginDescriptor } from "emdash";
import { definePlugin } from "emdash";
/**
* Create the color picker plugin instance.
* Called by the virtual module system at runtime.
*/
export function createPlugin() {
return definePlugin({
id: "color",
version: "0.0.1",
admin: {
entry: "@emdash-cms/plugin-color/admin",
fieldWidgets: [
{
name: "picker",
label: "Color Picker",
fieldTypes: ["string"],
},
],
},
});
}
export default createPlugin;
/**
* Create a plugin descriptor for use in emdash config.
*/
export function colorPlugin(): PluginDescriptor {
return {
id: "color",
version: "0.0.1",
entrypoint: "@emdash-cms/plugin-color",
options: {},
adminEntry: "@emdash-cms/plugin-color/admin",
};
}And the component: /**
* Color picker admin component.
*
* Exports a `fields` map with a "picker" widget that renders a color
* input with hex value display and preview swatch.
*/
import * as React from "react";
interface FieldWidgetProps {
value: unknown;
onChange: (value: unknown) => void;
label: string;
id: string;
required?: boolean;
options?: Record<string, unknown>;
minimal?: boolean;
}
/** Named CSS colors for the preset palette */
const PRESETS = [
"#ef4444",
"#f97316",
"#eab308",
"#22c55e",
"#06b6d4",
"#3b82f6",
"#8b5cf6",
"#ec4899",
"#000000",
"#ffffff",
];
const VALID_HEX_PATTERN = /^#[\da-f]{6}$/i;
function ColorPicker({ value, onChange, label, id, required, minimal }: FieldWidgetProps) {
const rawColor = typeof value === "string" && value ? value : "#000000";
// Only pass valid 6-digit hex to the native color input and preview;
// partial input while typing would produce invalid color values.
const color = VALID_HEX_PATTERN.test(rawColor) ? rawColor : "#000000";
const handleHexChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const v = e.target.value;
// Allow partial input while typing
onChange(v);
};
return (
<div data-testid="color-picker-widget">
{!minimal && (
<label htmlFor={id} className="text-sm font-medium leading-none mb-1.5 block">
{label}
{required && <span className="text-destructive ml-0.5">*</span>}
</label>
)}
<div className="flex items-center gap-3">
<input
type="color"
id={id}
value={color}
onChange={(e) => onChange(e.target.value)}
className="h-10 w-10 cursor-pointer rounded border border-input p-0.5"
data-testid="color-input"
/>
<input
type="text"
value={typeof value === "string" ? value : ""}
onChange={handleHexChange}
placeholder="#000000"
className="flex h-10 w-28 rounded-md border border-input bg-transparent px-3 py-2 text-sm font-mono ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
data-testid="color-hex-input"
/>
<div
className="h-10 flex-1 rounded-md border border-input"
style={{ backgroundColor: color }}
data-testid="color-preview"
/>
</div>
<div className="mt-2 flex gap-1" data-testid="color-presets">
{PRESETS.map((preset) => (
<button
key={preset}
type="button"
onClick={() => onChange(preset)}
className="h-6 w-6 rounded-sm border border-input transition-transform hover:scale-110"
style={{ backgroundColor: preset }}
title={preset}
data-testid={`color-preset-${preset.slice(1)}`}
/>
))}
</div>
</div>
);
}
export const fields = {
picker: ColorPicker,
};That being said, I have added the plugin and have not been able to choose the the widget as a field type when adding fields to a collection through the admin UI. Maybe it has to go in the seed file. Plugin code here: https://github.com/emdash-cms/emdash/tree/main/packages/plugins/color |
Beta Was this translation helpful? Give feedback.
-
|
As @coderreco says, this is already available. There is also now the field-kit plugin which provides lots more types. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Similar to Sanity's components: { input: MyComponent }, allow plugin authors (or site developers) to register a React component as the input UI for a specific field type or field slug in the content editing form. This would enable visual pickers (spacing, color, icon) without leaving the entry editor.
Beta Was this translation helpful? Give feedback.
All reactions