import { CATALOG_COMPONENT_CONTRACTS } from "./catalog-contracts.ts"; import type { ComponentRecipe, RecipeStyles } from "./types.ts"; /** Family defaults change styling only: no display, dimensions, positioning, clipping or graph geometry. */ export function catalogRecipes(): Record { const recipes: Record = {}; const ref = (name: string) => ({ ref: name }); for (const [name, contract] of Object.entries(CATALOG_COMPONENT_CONTRACTS)) { const base: Record = {}; const axes: Record = contract.axes; for (const [part, descriptor] of Object.entries(contract.parts)) { if (descriptor.ownership !== "framework" || descriptor.profile === "managed") continue; const styles: RecipeStyles = {}; if ( descriptor.properties.includes("fontFamily") && descriptor.role !== "code" && name !== "Kbd" ) styles.fontFamily = ref( /^title|heading|headline/i.test(part) ? "type.heading" : "type.body", ); const roundedFalse = axes.rounded?.default === "false"; const circle = ["circle", "round"].includes(axes.shape?.default ?? ""); const semanticGeometry = /thumb|track|spinner|progress|marker|port$|status|dot|star|srOnly/i.test(part); if ( descriptor.properties.includes("borderRadius") && !roundedFalse && !circle && !semanticGeometry ) { styles.borderRadius = ref( descriptor.profile === "control" ? "shape.control" : "shape.panel", ); } // Only existing surfaces receive elevation. Layout wrappers and provider hosts are untouched. if (descriptor.profile === "surface" && descriptor.properties.includes("boxShadow")) styles.boxShadow = ref("elevation.panel"); if (Object.keys(styles).length) base[part] = styles; } // Every catalog component has a deliberate recipe, even if only its text wrapper is styled. recipes[name] = { contractVersion: 1, base }; } return recipes; }