///
/**
* Link Module - Pattern for web links/resources
*
* A composable pattern that can be used standalone or embedded in containers
* like Record. Stores URL, title, and description.
*/
import { computed, type Default, NAME, recipe, UI } from "commontools";
import type { ModuleMetadata } from "./container-protocol.ts";
// ===== Self-Describing Metadata =====
export const MODULE_METADATA: ModuleMetadata = {
type: "link",
label: "Link",
icon: "\u{1F310}", // globe emoji
schema: {
url: { type: "string", format: "uri", description: "URL" },
linkTitle: { type: "string", description: "Link title" },
description: { type: "string", description: "Description" },
},
fieldMapping: ["url", "linkTitle", "description"],
};
// ===== Types =====
export interface LinkModuleInput {
/** URL */
url: Default;
/** Link title */
linkTitle: Default;
/** Description */
description: Default;
}
// ===== The Pattern =====
export const LinkModule = recipe(
"LinkModule",
({ url, linkTitle, description }) => {
const displayText = computed(() => linkTitle || url || "Not set");
return {
[NAME]: computed(() => `${MODULE_METADATA.icon} Link: ${displayText}`),
[UI]: (
),
url,
linkTitle,
description,
};
},
);
export default LinkModule;