Files
formulation/scripts/extract-meez-tokens.js
T
nicholas 21651e1ce8 feat(ui): meez visual alignment and unified responsive layouts across desktop and mobile
- Resolve ingredient table overflow and 2-column layout on laptop screens (1280px-1440px)
- Align recipe, ingredient, and directory pages with meez visual design specifications
- Implement segmented icon navigation tabs across recipe and ingredient detail views
- Standardize top utility bar and entity detail header alignment across all viewports
- Fix mobile home page filter popup z-index and viewport overflow clipping
- Clean up legacy prototype media queries and consolidate responsive CSS system
2026-08-17 00:48:35 -05:00

84 lines
3.3 KiB
JavaScript

/**
* Meez Design Token & Style Extractor
*
* Paste this snippet into the DevTools Console while viewing Meez
* (e.g. https://app.getmeez.com/home?type=recipe or a recipe detail page).
* It will collect computed styles, layout metrics, and SVG icons and copy
* a formatted JSON report to your clipboard.
*/
(() => {
const getStyle = (el, prop) => el ? window.getComputedStyle(el).getPropertyValue(prop) : null;
const extractComponent = (selector, name) => {
const el = document.querySelector(selector);
if (!el) return null;
const style = window.getComputedStyle(el);
const rect = el.getBoundingClientRect();
return {
name,
selector,
dimensions: { width: rect.width, height: rect.height },
typography: {
fontFamily: style.fontFamily,
fontSize: style.fontSize,
fontWeight: style.fontWeight,
lineHeight: style.lineHeight,
letterSpacing: style.letterSpacing,
color: style.color,
},
surface: {
backgroundColor: style.backgroundColor,
borderRadius: style.borderRadius,
border: `${style.borderWidth} ${style.borderStyle} ${style.borderColor}`,
boxShadow: style.boxShadow,
},
spacing: {
padding: style.padding,
margin: style.margin,
gap: style.gap,
}
};
};
// Collect key UI elements on current page
const report = {
url: window.location.href,
timestamp: new Date().toISOString(),
global: {
bodyBackground: getStyle(document.body, 'background-color'),
fontFamily: getStyle(document.body, 'font-family'),
fontSize: getStyle(document.body, 'font-size'),
color: getStyle(document.body, 'color'),
},
components: {
header: extractComponent('header, [role="banner"], .MuiAppBar-root', 'Header / Top Bar'),
searchBox: extractComponent('input[type="search"], input[placeholder*="Search"]', 'Search Input'),
newButton: extractComponent('button:has(svg), a:has(svg)', 'New Button'),
tableHeader: extractComponent('[role="rowgroup"] [role="row"]:first-child, thead tr', 'Table Header'),
tableRow: extractComponent('[role="rowgroup"] [role="row"]:not(:first-child), tbody tr:first-child', 'Table Data Row'),
tabPillActive: extractComponent('.MuiChip-root, [role="tab"][aria-selected="true"]', 'Active Tab / Pill'),
},
svgIcons: Array.from(document.querySelectorAll('svg')).slice(0, 30).map((svg, idx) => ({
index: idx,
viewBox: svg.getAttribute('viewBox'),
width: svg.getAttribute('width') || svg.clientWidth,
height: svg.getAttribute('height') || svg.clientHeight,
fill: getStyle(svg, 'fill') || getStyle(svg, 'color'),
paths: Array.from(svg.querySelectorAll('path')).map(p => p.getAttribute('d')),
ariaLabel: svg.getAttribute('aria-label') || svg.closest('button, a')?.getAttribute('aria-label') || ''
}))
};
console.log('=== MEEZ EXTRACTED TOKENS ===', report);
const jsonStr = JSON.stringify(report, null, 2);
if (navigator.clipboard) {
navigator.clipboard.writeText(jsonStr).then(() => {
console.log('✅ Tokens copied to clipboard!');
}).catch(() => {
console.log('Copy to clipboard failed. Access report via window.__meezReport');
});
}
window.__meezReport = report;
return report;
})();