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); // Joined surfaces share the outer component's corners. Rounding each // child creates seams, scalloped panels and rounded splitter rails. const joined = ( { StatsBar: ["item", "content"], AuthSplitLayout: ["content"], Collapse: ["trigger", "panel", "content"], InputNumber: ["button", "content", "input"], LayoutSplitter: ["handle"], } as Record )[name]?.includes(part); if ( descriptor.properties.includes("borderRadius") && !roundedFalse && !circle && !semanticGeometry && !joined ) { 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") && !joined && !(name === "PreferenceSwitcher" && part === "menu") ) 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; }