{"id":48465910,"url":"https://github.com/troychaplin/component2block","last_synced_at":"2026-04-07T04:32:27.150Z","repository":{"id":341320150,"uuid":"1169501190","full_name":"troychaplin/component2block","owner":"troychaplin","description":null,"archived":false,"fork":false,"pushed_at":"2026-03-01T05:29:04.000Z","size":11995,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-01T07:17:58.822Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/troychaplin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-28T19:30:58.000Z","updated_at":"2026-02-28T21:07:48.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/troychaplin/component2block","commit_stats":null,"previous_names":["troychaplin/component2block"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/troychaplin/component2block","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troychaplin%2Fcomponent2block","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troychaplin%2Fcomponent2block/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troychaplin%2Fcomponent2block/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troychaplin%2Fcomponent2block/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/troychaplin","download_url":"https://codeload.github.com/troychaplin/component2block/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troychaplin%2Fcomponent2block/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31500397,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T03:10:19.677Z","status":"ssl_error","status_checked_at":"2026-04-07T03:10:13.982Z","response_time":105,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-07T04:32:26.440Z","updated_at":"2026-04-07T04:32:27.136Z","avatar_url":"https://github.com/troychaplin.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"docs/images/banner.png\" alt=\"Block Finder Plugin Banner\" style=\"width: 100%; height: auto;\"\u003e\n\n# component2block\n\nA design token generator for Storybook component libraries that target WordPress block themes. Define your tokens once in a single JSON config, and component2block generates everything both platforms need — CSS variables, `@font-face` declarations, base typography, WordPress `theme.json`, and PHP integration hooks.\n\n## The Problem\n\nBuilding a component library that works in both Storybook/React and WordPress means maintaining design tokens in multiple formats. Colors, spacing, fonts, and typography settings need to exist as CSS custom properties for your components, as `theme.json` presets for the WordPress Site Editor, and as PHP hooks to wire it all together. Keeping these in sync manually is tedious and error-prone.\n\n## How It Works\n\nYou write one config file. The generator produces everything.\n\n```\nc2b.config.json                                single source of truth\n    │\n    │   npx c2b generate\n    │\n    ├──► src/styles/tokens.css                 CSS custom properties\n    ├──► src/styles/fonts.css                  @font-face declarations\n    ├──► src/styles/_content-generated.scss    Base typography (zero-specificity)\n    │\n    ├──► dist/wp/theme.json                    WordPress settings + styles\n    ├──► dist/wp/tokens.wp.css                 CSS vars mapped to --wp--preset--*\n    ├──► dist/wp/tokens.css                    CSS vars with hardcoded values\n    └──► dist/wp/integrate.php                 PHP hooks for the theme.json cascade\n```\n\nYour components always reference `--prefix--*` CSS variables. In Storybook, those resolve to hardcoded values. In WordPress, they can optionally map to `--wp--preset--*` variables so themes can override them via the Site Editor.\n\n## Key Concepts\n\n- **Single source of truth** — One config drives all outputs. Change a color once, it updates everywhere.\n- **12 token categories** — Colors, gradients, spacing, font families, font sizes, shadows, layout, font weights, line heights, border radii, transitions, and z-index.\n- **Locked vs themeable** — By default, tokens are hardcoded (locked). Set `output.wpThemeable: true` to let WordPress themes override them.\n- **Zero-specificity base styles** — Generated SCSS uses `:where()` selectors so component BEM classes always win over base typography.\n- **Storybook preset** — Auto-injects all generated styles into Storybook. No manual imports.\n- **WordPress default layer** — The generated `theme.json` injects at the lowest priority layer, so any theme can override it.\n\n## Quick Example\n\n```json\n{\n  \"prefix\": \"mylib\",\n  \"tokens\": {\n    \"color\": {\n      \"primary\": \"#0073aa\",\n      \"primary-hover\": { \"value\": \"#005a87\", \"cssOnly\": true }\n    },\n    \"fontSize\": {\n      \"small\": { \"min\": \"0.875rem\", \"max\": \"1rem\" }\n    }\n  }\n}\n```\n\n```bash\nnpx c2b generate\n```\n\nThen in your components:\n\n```scss\n.mylib-card {\n  color: var(--mylib--color-primary);\n  font-size: var(--mylib--font-size-small);\n}\n```\n\n## CLI\n\n```\nnpx c2b generate [options]\n\nOptions:\n  --config \u003cpath\u003e   Path to config file (default: ./c2b.config.json)\n  --dry-run         Output to stdout instead of writing files\n```\n\n## Programmatic API\n\n```ts\nimport { generate } from 'component2block';\n\nconst result = generate('./c2b.config.json');\n// result.files: Array\u003c{ path: string; size: number }\u003e\n```\n\nIndividual generators are also exported:\n\n```ts\nimport {\n  loadConfig,\n  generateTokensCss,\n  generateTokensWpCss,\n  generateThemeJson,\n  generateFontsCss,\n  generateContentScss,\n  generateIntegratePhp,\n} from 'component2block';\n```\n\n## Documentation\n\n[Getting Started](./docs/README.md) — Install, configure, and generate\n\n### Configuration Reference\n\n| Guide | Description |\n|-------|-------------|\n| [Overview](./docs/config/README.md) | Global fields, token categories, generated files, and full example |\n| [Colors \u0026 Gradients](./docs/config/colors.md) | Color palette, gradients, cssOnly tokens, and locked vs themeable mode |\n| [Spacing](./docs/config/spacing.md) | Spacing scale, WordPress slug conventions, and responsive values |\n| [Shadows](./docs/config/shadow.md) | Box shadows, preset vs custom behavior, and Site Editor integration |\n| [Fonts](./docs/config/fonts.md) | Static fonts, variable fonts, Google Fonts, and file placement |\n| [Base Styles](./docs/config/base-styles.md) | Elements, typography, colors, spacing, and `:where()` selectors |\n\n### Guides\n\n| Guide | Description |\n|-------|-------------|\n| [Tokens](./docs/guides/tokens.md) | Token syntax, categories, fluid fonts, CSS output |\n| [Markup Patterns](./docs/guides/markup.md) | Layout classes for Storybook and WordPress |\n| [Storybook Preset](./docs/guides/storybook-preset.md) | Auto-injecting generated styles into Storybook |\n| [CLI \u0026 Build](./docs/guides/cli-and-build.md) | CLI commands, build scripts, and publishing setup |\n\n### WordPress\n\n| Guide | Description |\n|-------|-------------|\n| [Integration](./docs/wordpress/integration.md) | Adding compiled assets to a WordPress block theme |\n| [Theming](./docs/wordpress/theming.md) | Locked vs themeable mode, overrides, style variations |\n| [Blocks](./docs/wordpress/blocks.md) | Block plugin setup and component registration |\n| [Editor Styles](./docs/wordpress/editor-styles.md) | Loading styles inside the block editor iframe |\n| [theme.json Reference](./docs/wordpress/theme-json-reference.md) | Full settings and styles structure |\n\n### Advanced\n\n| Guide | Description |\n|-------|-------------|\n| [Architecture](./docs/advanced/architecture.md) | Design decisions, project structure, category registry |\n| [Token Flow](./docs/advanced/token-flow.md) | How tokens resolve differently per output |\n\n## Development\n\n```bash\nnpm install\nnpm run build    # Compile TypeScript\nnpm test         # Run 191 tests\n```\n\n## Screenshots\n\n| Before | After |\n|-------|-------------|\n| \u003cimg src=\"docs/images/before-01-styles.jpg\" alt=\"Block Finder Plugin Banner\" style=\"width: 100%; height: auto;\"\u003e | \u003cimg src=\"docs/images/after-01-styles.jpg\" alt=\"Block Finder Plugin Banner\" style=\"width: 100%; height: auto;\"\u003e |\n| \u003cimg src=\"docs/images/before-02-typography.jpg\" alt=\"Block Finder Plugin Banner\" style=\"width: 100%; height: auto;\"\u003e | \u003cimg src=\"docs/images/after-02-typography.jpg\" alt=\"Block Finder Plugin Banner\" style=\"width: 100%; height: auto;\"\u003e |\n| \u003cimg src=\"docs/images/before-03-colors.jpg\" alt=\"Block Finder Plugin Banner\" style=\"width: 100%; height: auto;\"\u003e | \u003cimg src=\"docs/images/after-03-colors.jpg\" alt=\"Block Finder Plugin Banner\" style=\"width: 100%; height: auto;\"\u003e |\n| \u003cimg src=\"docs/images/before-04-template.jpg\" alt=\"Block Finder Plugin Banner\" style=\"width: 100%; height: auto;\"\u003e | \u003cimg src=\"docs/images/after-04-template.jpg\" alt=\"Block Finder Plugin Banner\" style=\"width: 100%; height: auto;\"\u003e |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftroychaplin%2Fcomponent2block","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftroychaplin%2Fcomponent2block","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftroychaplin%2Fcomponent2block/lists"}