Emdash source with visual editor image upload fix

Fixes:
1. media.ts: wrap placeholder generation in try-catch
2. toolbar.ts: check r.ok, display error message in popover
This commit is contained in:
2026-05-03 10:44:54 +07:00
parent 78f81bebb6
commit 2d1be52177
2352 changed files with 662964 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
# @emdash-cms/plugin-color
## 0.2.0
### Minor Changes
- [#814](https://github.com/emdash-cms/emdash/pull/814) [`a838000`](https://github.com/emdash-cms/emdash/commit/a83800068678daf6391e02bba8acf27ff4db0e19) Thanks [@arashackdev](https://github.com/arashackdev)! - rtl srtyle improvements and LTR/RTL compatible arrow/caret icons
### Patch Changes
- Updated dependencies [[`e2b3c6c`](https://github.com/emdash-cms/emdash/commit/e2b3c6cd930d5fa6fc607a0b26fd796f5b0f98b2), [`9dfc65c`](https://github.com/emdash-cms/emdash/commit/9dfc65c42c04c41088e0c8f5a8ca4347643e2fea), [`e0dc6fb`](https://github.com/emdash-cms/emdash/commit/e0dc6fb8adadc0e048f3f314d62bfa98d9bb48d4), [`c22fb3a`](https://github.com/emdash-cms/emdash/commit/c22fb3a10d445f12cca91620c9258d50695afa44), [`6a4e9b8`](https://github.com/emdash-cms/emdash/commit/6a4e9b8b0fa6064989224a42b14de435f487a76f), [`0ee372a`](https://github.com/emdash-cms/emdash/commit/0ee372a7f33eecce7d90e12624923d2d9c132adf), [`22a16ee`](https://github.com/emdash-cms/emdash/commit/22a16eed607a4e81391ecb6c45fe2e59aaca92fe), [`1e2b024`](https://github.com/emdash-cms/emdash/commit/1e2b02486ee0407e4f50b8342ba1a9e7d060e405), [`81662e9`](https://github.com/emdash-cms/emdash/commit/81662e98fcf1ad0ee880d4f1af96271c527d7423), [`2f22f57`](https://github.com/emdash-cms/emdash/commit/2f22f57abadf305cf6d3ce07ee78290178e032d1), [`ef3f076`](https://github.com/emdash-cms/emdash/commit/ef3f076c8112e9dffc2a87c019e5521e823f5e86), [`a9c29ea`](https://github.com/emdash-cms/emdash/commit/a9c29ea584300f6cf67206bedcb1d39f05ea1c26), [`e7df21f`](https://github.com/emdash-cms/emdash/commit/e7df21f0adca795cdb233d6e64cd543ead7e2347), [`d5f7c48`](https://github.com/emdash-cms/emdash/commit/d5f7c481a507868f470361cfd715a5828640d45a), [`8ae227c`](https://github.com/emdash-cms/emdash/commit/8ae227cceade5c9852897c7b56f89e7422ee82a1), [`e2d5d16`](https://github.com/emdash-cms/emdash/commit/e2d5d160acea4444945b1ea79c80ca9ce138965b), [`0d98c62`](https://github.com/emdash-cms/emdash/commit/0d98c620a5f407648f3b7f3cbd30b642c74be607), [`64bf5b9`](https://github.com/emdash-cms/emdash/commit/64bf5b98125ca18ec26f7e0e65a71fcbe71fd44f), [`e81aa0f`](https://github.com/emdash-cms/emdash/commit/e81aa0f717be11bacdff30ed9bbc454824268555), [`0041d76`](https://github.com/emdash-cms/emdash/commit/0041d7699b32b77b4cd2ecd77b97340f0dd3abce), [`cee403d`](https://github.com/emdash-cms/emdash/commit/cee403d5c008feb9ca60bb7201e151b828737743), [`a8bac5d`](https://github.com/emdash-cms/emdash/commit/a8bac5d7216e185b1bd9a2aaaeaa9a0306ab066e), [`5b6f059`](https://github.com/emdash-cms/emdash/commit/5b6f059d06175ae0cb740d1ba32867d1ec6b2249), [`a86ff80`](https://github.com/emdash-cms/emdash/commit/a86ff80836fed175508ff06f744c7ad6b805627c), [`d4be24f`](https://github.com/emdash-cms/emdash/commit/d4be24f478a0c8d0a7bba3c299e11105bba3ed94), [`eb6dbd0`](https://github.com/emdash-cms/emdash/commit/eb6dbd056717fd076a8b5fa807d91516a00f5f2f)]:
- emdash@0.9.0
## 0.1.1
### Patch Changes
- Updated dependencies [[`422018a`](https://github.com/emdash-cms/emdash/commit/422018aeb227dffe3da7bfc772d86f9ce9c2bcd1), [`4221ba4`](https://github.com/emdash-cms/emdash/commit/4221ba48bc87ab9fa0b1bae144f6f2920beb4f5a), [`9269759`](https://github.com/emdash-cms/emdash/commit/9269759674bf254863f37d4cf1687fae56082063), [`d6cfc43`](https://github.com/emdash-cms/emdash/commit/d6cfc437f23e3e435a8862cab17d2c19363847d7), [`1bcfc50`](https://github.com/emdash-cms/emdash/commit/1bcfc502112d8756e34a720b8a170eb5486b425a), [`8c693b5`](https://github.com/emdash-cms/emdash/commit/8c693b582d7c5e29bd138161e81d9c8affb53689), [`5b3e33c`](https://github.com/emdash-cms/emdash/commit/5b3e33c26bc2eb30ab2a032960a5d57eb06f148a), [`9d10d27`](https://github.com/emdash-cms/emdash/commit/9d10d2791fe16be901d9d138e434bd79cf9335c4), [`91e31fb`](https://github.com/emdash-cms/emdash/commit/91e31fb2cab4c0470088c5d61bab6e2028821569), [`f112ac4`](https://github.com/emdash-cms/emdash/commit/f112ac48194d1c2302e93756d54b116d3d207c22), [`e9a6f7a`](https://github.com/emdash-cms/emdash/commit/e9a6f7ac3ceeaf5c2d0a557e4cf6cab5f3d7d764), [`b297fdd`](https://github.com/emdash-cms/emdash/commit/b297fdd88dadcabeb93f47abea9f24f70b7d4b71), [`d211452`](https://github.com/emdash-cms/emdash/commit/d2114523a55021f65ee46e44e11157b06334819e), [`8e28cfc`](https://github.com/emdash-cms/emdash/commit/8e28cfc5d66f58f0fb91aa35c02afdd426bb6555), [`38af118`](https://github.com/emdash-cms/emdash/commit/38af118ad517fd9aa83064368543bf64bc32c08a)]:
- emdash@0.1.1
## 0.1.0
### Minor Changes
- [#14](https://github.com/emdash-cms/emdash/pull/14) [`755b501`](https://github.com/emdash-cms/emdash/commit/755b5017906811f97f78f4c0b5a0b62e67b52ec4) Thanks [@ascorbic](https://github.com/ascorbic)! - First beta release
### Patch Changes
- Updated dependencies [[`755b501`](https://github.com/emdash-cms/emdash/commit/755b5017906811f97f78f4c0b5a0b62e67b52ec4)]:
- emdash@0.1.0
## 0.0.3
### Patch Changes
- Updated dependencies [[`3c319ed`](https://github.com/emdash-cms/emdash/commit/3c319ed6411a595e6974a86bc58c2a308b91c214)]:
- emdash@0.0.3
## 0.0.2
### Patch Changes
- Updated dependencies [[`b09bfd5`](https://github.com/emdash-cms/emdash/commit/b09bfd51cece5e88fe8314668a591ab11de36b4d)]:
- emdash@0.0.2

View File

@@ -0,0 +1,39 @@
{
"name": "@emdash-cms/plugin-color",
"version": "0.2.0",
"description": "Color picker field widget for EmDash CMS",
"type": "module",
"main": "src/index.ts",
"exports": {
".": "./src/index.ts",
"./admin": "./src/admin.tsx"
},
"files": [
"src"
],
"keywords": [
"emdash",
"cms",
"plugin",
"color",
"picker",
"field-widget"
],
"author": "Matt Kane",
"license": "MIT",
"peerDependencies": {
"emdash": "workspace:>=0.9.0",
"react": "^18.0.0 || ^19.0.0"
},
"devDependencies": {
"@types/react": "catalog:"
},
"scripts": {
"typecheck": "tsgo --noEmit"
},
"repository": {
"type": "git",
"url": "git+https://github.com/emdash-cms/emdash.git",
"directory": "packages/plugins/color"
}
}

View File

@@ -0,0 +1,98 @@
/**
* 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 ms-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,
};

View File

@@ -0,0 +1,54 @@
/**
* 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",
};
}

View File

@@ -0,0 +1,10 @@
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"jsx": "react-jsx"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}