{"_id":"@bnomei/emdash-bento","_rev":"5-4868698e4f044787ab2bd1e3dc7ab9e1","name":"@bnomei/emdash-bento","dist-tags":{"latest":"0.2.2"},"versions":{"0.1.0":{"name":"@bnomei/emdash-bento","version":"0.1.0","keywords":["astro","bento-grid","cms","emdash","emdash-plugin","field-widget","json","layout-builder","react","typescript"],"author":{"url":"https://bnomei.com","name":"Bruno Meilick","email":"b@bnomei.com"},"license":"MIT","_id":"@bnomei/emdash-bento@0.1.0","maintainers":[{"name":"bnomei","email":"b@bnomei.com"}],"homepage":"https://github.com/bnomei/emdash-bento#readme","bugs":{"url":"https://github.com/bnomei/emdash-bento/issues"},"dist":{"shasum":"dcd82ef273dd6b41ada52fc96115b85f586ddb9f","tarball":"https://registry.npmjs.org/@bnomei/emdash-bento/-/emdash-bento-0.1.0.tgz","fileCount":8,"integrity":"sha512-Caf+GrIGWuYU4Y/msz5zK0CuNKwx/43rISQrhTJ3Egu77oa2zqBV5aCvW6/GlrVjbfqsGWU9VLnMOfck4vaRNw==","signatures":[{"sig":"MEUCIQCpg1rGje7eJm4lLu0kgJ1Kk/ALuD+rPBaj/S/7H+/XwQIgTYTROk1F9YbbYZBz4rF4xFeg8+dYhT2BKWBzGfO/p2o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":112050},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","engines":{"node":">=22.12.0"},"exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./admin":{"types":"./dist/admin.d.mts","import":"./dist/admin.mjs"}},"gitHead":"8627457492fac578cd3fc324d7174d787f9df1ca","scripts":{"build":"vp pack src/index.ts src/admin.tsx --format esm --dts --clean --tsconfig tsconfig.json","check":"vp check .","prepack":"npm run build","typecheck":"tsc --noEmit","pack:check":"vp pack src/index.ts src/admin.tsx --format esm --dts --clean --tsconfig tsconfig.json --publint","types:check":"attw --pack . --profile esm-only --no-summary","prepublishOnly":"npm run check && npm run typecheck && npm run pack:check && npm run types:check"},"_npmUser":{"name":"bnomei","email":"b@bnomei.com"},"repository":{"url":"git+https://github.com/bnomei/emdash-bento.git","type":"git"},"_npmVersion":"11.16.0","description":"Bento grid field widget for EmDash JSON fields, using Block Builder for nested blocks.","directories":{},"sideEffects":false,"_nodeVersion":"26.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.7","emdash":"^0.19.0","publint":"^0.3.21","react-dom":"^19.2.7","vite-plus":"^0.1.24","typescript":"^6.0.3","@types/react":"^19.2.17","@cloudflare/kumo":"^2.5.2","@types/react-dom":"^19.2.3","@arethetypeswrong/cli":"^0.18.3","@bnomei/emdash-blocks":"^0.1.0","@phosphor-icons/react":"^2.1.10"},"peerDependencies":{"react":"^18.0.0 || ^19.0.0","emdash":">=0.17.0","react-dom":"^18.0.0 || ^19.0.0","@cloudflare/kumo":"^2.5.0","@bnomei/emdash-blocks":"^0.1.0","@phosphor-icons/react":"^2.1.10"},"_npmOperationalInternal":{"tmp":"tmp/emdash-bento_0.1.0_1781301401386_0.7048299398138158","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@bnomei/emdash-bento","version":"0.1.1","keywords":["astro","bento-grid","cms","emdash","emdash-plugin","field-widget","json","layout-builder","react","typescript"],"author":{"url":"https://bnomei.com","name":"Bruno Meilick","email":"b@bnomei.com"},"license":"MIT","_id":"@bnomei/emdash-bento@0.1.1","maintainers":[{"name":"bnomei","email":"b@bnomei.com"}],"homepage":"https://github.com/bnomei/emdash-bento#readme","bugs":{"url":"https://github.com/bnomei/emdash-bento/issues"},"dist":{"shasum":"d3a070669304ce52e1aeb29c3c9db2501d2adb7b","tarball":"https://registry.npmjs.org/@bnomei/emdash-bento/-/emdash-bento-0.1.1.tgz","fileCount":9,"integrity":"sha512-91k9I9PWLN/fh0Ab7IqC3Z10iM2tSAPdZMswzBplltw4Ql6ars9D7M2+K+y6kSygxEnapUsJmUTUFnRZx1dNSQ==","signatures":[{"sig":"MEQCIBIrzN3fZcNkGW34vy56kdJmmMHAITwS2xj48qftYUBNAiANcVz3HElQ34Cy9SW/MzZ6+LfIKnryX7ejEbbRlhxZeA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":113730},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","engines":{"node":">=22.12.0"},"exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./admin":{"types":"./dist/admin.d.mts","import":"./dist/admin.mjs"}},"gitHead":"05797a2ddb45a37edb2d8a94314837dfd6233a3c","scripts":{"test":"rm -rf .test-dist && tsc --ignoreConfig --module NodeNext --moduleResolution NodeNext --target ES2022 --types node --skipLibCheck --outDir .test-dist src/layout.test.ts && node --test .test-dist/layout.test.js test/admin-empty-layout.test.mjs","build":"vp pack src/index.ts src/admin.tsx --format esm --dts --clean --tsconfig tsconfig.json","check":"vp check .","prepack":"npm run build","typecheck":"tsc --noEmit","pack:check":"vp pack src/index.ts src/admin.tsx --format esm --dts --clean --tsconfig tsconfig.json --publint","types:check":"attw --pack . --profile esm-only --no-summary","prepublishOnly":"npm run check && npm run typecheck && npm run pack:check && npm run types:check"},"_npmUser":{"name":"bnomei","email":"b@bnomei.com"},"repository":{"url":"git+https://github.com/bnomei/emdash-bento.git","type":"git"},"_npmVersion":"11.16.0","description":"Bento grid field widget for EmDash JSON fields, using Block Builder for nested blocks.","directories":{},"sideEffects":false,"_nodeVersion":"26.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.7","emdash":"^0.19.0","publint":"^0.3.21","react-dom":"^19.2.7","vite-plus":"^0.1.24","typescript":"^6.0.3","@types/react":"^19.2.17","@cloudflare/kumo":"^2.5.2","@types/react-dom":"^19.2.3","@arethetypeswrong/cli":"^0.18.3","@bnomei/emdash-blocks":"^0.1.0","@phosphor-icons/react":"^2.1.10"},"peerDependencies":{"react":"^18.0.0 || ^19.0.0","emdash":">=0.17.0","react-dom":"^18.0.0 || ^19.0.0","@cloudflare/kumo":"^2.5.0","@bnomei/emdash-blocks":"^0.1.0","@phosphor-icons/react":"^2.1.10"},"_npmOperationalInternal":{"tmp":"tmp/emdash-bento_0.1.1_1781798734803_0.5308246622682204","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@bnomei/emdash-bento","version":"0.2.0","keywords":["astro","bento-grid","cms","emdash","emdash-plugin","field-widget","json","layout-builder","react","typescript"],"author":{"url":"https://bnomei.com","name":"Bruno Meilick","email":"b@bnomei.com"},"license":"MIT","_id":"@bnomei/emdash-bento@0.2.0","maintainers":[{"name":"bnomei","email":"b@bnomei.com"}],"homepage":"https://github.com/bnomei/emdash-bento#readme","bugs":{"url":"https://github.com/bnomei/emdash-bento/issues"},"dist":{"shasum":"15c501c53f6d05f5e8cbfefba468dac98ed0e560","tarball":"https://registry.npmjs.org/@bnomei/emdash-bento/-/emdash-bento-0.2.0.tgz","fileCount":10,"integrity":"sha512-UDas4Y+71Q77c+U5pG0IeFKeodn2QZSjnePRJX4bHxAFmJk9HjiNBD4XYmEtmHKjthYcwdj+LCIjAnJcUPlcaQ==","signatures":[{"sig":"MEYCIQDhKtHy2UiYMJtKnDohBHgVG/V0zOCPWkNhHR6MysrzNwIhALIMcSkvdgn+KPJXwjAAeoWoa3mBVAgdF2ExETtcQixm","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":121126},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","engines":{"node":">=22.12.0"},"exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./admin":{"types":"./dist/admin.d.mts","import":"./dist/admin.mjs"}},"gitHead":"bca49a4dedc9d60ab5956f9d731a34719df372ea","scripts":{"test":"rm -rf .test-dist && tsc --ignoreConfig --module NodeNext --moduleResolution NodeNext --target ES2022 --types node --skipLibCheck --outDir .test-dist src/layout.test.ts && node --test .test-dist/layout.test.js test/admin-empty-layout.test.mjs","build":"vp pack src/index.ts src/admin.tsx --format esm --dts --clean --tsconfig tsconfig.json","check":"vp check .","prepack":"npm run build","typecheck":"tsc --noEmit","pack:check":"vp pack src/index.ts src/admin.tsx --format esm --dts --clean --tsconfig tsconfig.json --publint","types:check":"attw --pack . --profile esm-only --no-summary","prepublishOnly":"npm run check && npm run typecheck && npm run pack:check && npm run types:check"},"_npmUser":{"name":"bnomei","email":"b@bnomei.com"},"repository":{"url":"git+https://github.com/bnomei/emdash-bento.git","type":"git"},"_npmVersion":"11.16.0","description":"Bento grid field widget for EmDash JSON fields, using Block Builder for nested blocks.","directories":{},"sideEffects":false,"_nodeVersion":"26.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.7","emdash":"^0.19.0","publint":"^0.3.21","react-dom":"^19.2.7","vite-plus":"^0.1.24","typescript":"^6.0.3","@types/react":"^19.2.17","@cloudflare/kumo":"^2.5.2","@types/react-dom":"^19.2.3","@arethetypeswrong/cli":"^0.18.3","@bnomei/emdash-blocks":"^0.1.0","@phosphor-icons/react":"^2.1.10"},"peerDependencies":{"react":"^18.0.0 || ^19.0.0","emdash":">=0.17.0","react-dom":"^18.0.0 || ^19.0.0","@cloudflare/kumo":"^2.5.0","@bnomei/emdash-blocks":"^0.1.0","@phosphor-icons/react":"^2.1.10"},"_npmOperationalInternal":{"tmp":"tmp/emdash-bento_0.2.0_1781814986536_0.993924278435649","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@bnomei/emdash-bento","version":"0.2.1","keywords":["astro","bento-grid","cms","emdash","emdash-plugin","field-widget","json","layout-builder","react","typescript"],"author":{"url":"https://bnomei.com","name":"Bruno Meilick","email":"b@bnomei.com"},"license":"MIT","_id":"@bnomei/emdash-bento@0.2.1","maintainers":[{"name":"bnomei","email":"b@bnomei.com"}],"homepage":"https://github.com/bnomei/emdash-bento#readme","bugs":{"url":"https://github.com/bnomei/emdash-bento/issues"},"dist":{"shasum":"39eb0566928dfdf0f7d88397bc7e2951e9c3393f","tarball":"https://registry.npmjs.org/@bnomei/emdash-bento/-/emdash-bento-0.2.1.tgz","fileCount":10,"integrity":"sha512-bZOj3o5M2TxDSY9NUdduCka2/rM8/BgD/Pf7eX/8akAdwUKGF9Kqg3B5P7NQuPL3gqW6OzbeQFLOcDfp8KPesg==","signatures":[{"sig":"MEUCIFCkLf/eiJePYoeKETbLTlOs8GUmrP6xSYTRMbErlYHkAiEAgFyBek1fnMv1zkDC3RMvRJQ2paP2MDxAUEGy7hC4OdU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":121126},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","engines":{"node":">=22.12.0"},"exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./admin":{"types":"./dist/admin.d.mts","import":"./dist/admin.mjs"}},"gitHead":"3b6cde2ba522cd8dc3a761679eff06aa637340f3","scripts":{"test":"rm -rf .test-dist && tsc --ignoreConfig --module NodeNext --moduleResolution NodeNext --target ES2022 --types node --skipLibCheck --outDir .test-dist src/layout.test.ts && node --test .test-dist/layout.test.js test/admin-empty-layout.test.mjs","build":"vp pack src/index.ts src/admin.tsx --format esm --dts --clean --tsconfig tsconfig.json","check":"vp check .","prepack":"npm run build","typecheck":"tsc --noEmit","pack:check":"vp pack src/index.ts src/admin.tsx --format esm --dts --clean --tsconfig tsconfig.json --publint","types:check":"attw --pack . --profile esm-only --no-summary","prepublishOnly":"npm run check && npm run typecheck && npm run pack:check && npm run types:check"},"_npmUser":{"name":"bnomei","email":"b@bnomei.com"},"repository":{"url":"git+https://github.com/bnomei/emdash-bento.git","type":"git"},"_npmVersion":"11.16.0","description":"Bento grid field widget for EmDash JSON fields, using Block Builder for nested blocks.","directories":{},"sideEffects":false,"_nodeVersion":"26.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.7","emdash":"^0.19.0","publint":"^0.3.21","react-dom":"^19.2.7","vite-plus":"^0.1.24","typescript":"^6.0.3","@types/react":"^19.2.17","@cloudflare/kumo":"^2.5.2","@types/react-dom":"^19.2.3","@arethetypeswrong/cli":"^0.18.3","@bnomei/emdash-blocks":"^0.2.0","@phosphor-icons/react":"^2.1.10"},"peerDependencies":{"react":"^18.0.0 || ^19.0.0","emdash":">=0.17.0","react-dom":"^18.0.0 || ^19.0.0","@cloudflare/kumo":"^2.5.0","@bnomei/emdash-blocks":"^0.2.0","@phosphor-icons/react":"^2.1.10"},"_npmOperationalInternal":{"tmp":"tmp/emdash-bento_0.2.1_1781816981365_0.5954754767048587","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@bnomei/emdash-bento","version":"0.2.2","description":"Bento grid field widget for EmDash JSON fields, using Block Builder for nested blocks.","keywords":["astro","bento-grid","cms","emdash","emdash-plugin","field-widget","json","layout-builder","react","typescript"],"homepage":"https://github.com/bnomei/emdash-bento#readme","bugs":{"url":"https://github.com/bnomei/emdash-bento/issues"},"license":"MIT","author":{"name":"Bruno Meilick","email":"b@bnomei.com","url":"https://bnomei.com"},"repository":{"type":"git","url":"git+https://github.com/bnomei/emdash-bento.git"},"type":"module","sideEffects":false,"main":"./dist/index.mjs","types":"./dist/index.d.mts","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./admin":{"types":"./dist/admin.d.mts","import":"./dist/admin.mjs"}},"publishConfig":{"access":"public"},"scripts":{"test":"rm -rf .test-dist && tsc --ignoreConfig --module NodeNext --moduleResolution NodeNext --target ES2022 --types node --skipLibCheck --outDir .test-dist src/layout.test.ts && node --test .test-dist/layout.test.js test/admin-empty-layout.test.mjs","build":"vp pack src/index.ts src/admin.tsx --format esm --dts --clean --tsconfig tsconfig.json","check":"vp check .","pack:check":"vp pack src/index.ts src/admin.tsx --format esm --dts --clean --tsconfig tsconfig.json --publint","prepack":"npm run build","prepublishOnly":"npm run check && npm run typecheck && npm run pack:check && npm run types:check","types:check":"attw --pack . --profile esm-only --no-summary","typecheck":"tsc --noEmit"},"devDependencies":{"@arethetypeswrong/cli":"^0.18.3","@bnomei/emdash-blocks":"^0.2.1","@cloudflare/kumo":"^2.5.2","@phosphor-icons/react":"^2.1.10","@types/react":"^19.2.17","@types/react-dom":"^19.2.3","emdash":"^0.19.0","publint":"^0.3.21","react":"^19.2.7","react-dom":"^19.2.7","typescript":"^6.0.3","vite-plus":"^0.1.24"},"peerDependencies":{"@bnomei/emdash-blocks":"^0.2.1","@cloudflare/kumo":"^2.5.0","@phosphor-icons/react":"^2.1.10","emdash":">=0.17.0","react":"^18.0.0 || ^19.0.0","react-dom":"^18.0.0 || ^19.0.0"},"engines":{"node":">=22.12.0"},"gitHead":"45fef558669c6ca9909957738d1495e36b945c98","_id":"@bnomei/emdash-bento@0.2.2","_nodeVersion":"26.4.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-KDRS6yd17WyU8H0ph/dEBriHGDlIrsfcMjjqMQqKPff+RMUHcCppo7JFyE7G2iuLsDUessN3Sga0uXj75NjNRQ==","shasum":"e0ea40261d61815b58845664e957d6decda25b2c","tarball":"https://registry.npmjs.org/@bnomei/emdash-bento/-/emdash-bento-0.2.2.tgz","fileCount":10,"unpackedSize":130518,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDhczZE0ymGQi4opGeaM5yT/B1J47yjxrDHBBunkJ4qbgIgPpe8/k4kdoNM6uPCo3LyHT4tzJLrOWtAByvmj7+NsdQ="}]},"_npmUser":{"name":"bnomei","email":"b@bnomei.com"},"directories":{},"maintainers":[{"name":"bnomei","email":"b@bnomei.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/emdash-bento_0.2.2_1782747114573_0.5491316052466126"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-12T21:56:41.178Z","modified":"2026-06-29T15:31:54.835Z","0.1.0":"2026-06-12T21:56:41.562Z","0.1.1":"2026-06-18T16:05:34.987Z","0.2.0":"2026-06-18T20:36:26.715Z","0.2.1":"2026-06-18T21:09:41.581Z","0.2.2":"2026-06-29T15:31:54.730Z"},"bugs":{"url":"https://github.com/bnomei/emdash-bento/issues"},"author":{"name":"Bruno Meilick","email":"b@bnomei.com","url":"https://bnomei.com"},"license":"MIT","homepage":"https://github.com/bnomei/emdash-bento#readme","keywords":["astro","bento-grid","cms","emdash","emdash-plugin","field-widget","json","layout-builder","react","typescript"],"repository":{"type":"git","url":"git+https://github.com/bnomei/emdash-bento.git"},"description":"Bento grid field widget for EmDash JSON fields, using Block Builder for nested blocks.","maintainers":[{"name":"bnomei","email":"b@bnomei.com"}],"readme":"# @bnomei/emdash-bento\n\n[![npm version](https://img.shields.io/npm/v/@bnomei/emdash-bento.svg)](https://www.npmjs.com/package/@bnomei/emdash-bento)\n[![npm downloads](https://img.shields.io/npm/dm/@bnomei/emdash-bento.svg)](https://www.npmjs.com/package/@bnomei/emdash-bento)\n[![license](https://img.shields.io/npm/l/@bnomei/emdash-bento.svg)](https://www.npmjs.com/package/@bnomei/emdash-bento)\n[![types](https://img.shields.io/badge/types-included-blue.svg)](./package.json)\n[![source](https://img.shields.io/badge/source-GitHub-181717.svg?logo=github)](https://github.com/bnomei/emdash-bento)\n\nBento grid field widget for EmDash JSON fields.\n\n`@bnomei/emdash-bento` is a native EmDash plugin for row and\ncolumn layout data stored as plain JSON. It registers the `bento:layouts`\nadmin widget, reuses `@bnomei/emdash-blocks` for nested column content,\nand exports helpers for Astro renderers to prepare visible rows and translate\nfractional spans into a 12-column grid. Use it when editors need controlled\nlayout composition while templates still own the frontend markup.\n\n## What It Provides\n\n- Native EmDash plugin factory: `bentoPlugin()`.\n- JSON field widget: `bento:layouts`.\n- One editable layout pattern string per row.\n- Nested block controls through `options.blockDefinitions`.\n- Admin UI built with [Kumo UI](https://kumo-ui.com/) with full light and dark\n  mode support.\n- Frontend helpers: `visibleLayoutRows()` and `spanToGridColumns()`.\n\n## Install\n\n```sh\nnpm install @bnomei/emdash-bento @bnomei/emdash-blocks\n```\n\nRegister both plugins in `astro.config.mjs`:\n\n```js\nimport emdash from \"emdash/astro\";\nimport { bentoPlugin } from \"@bnomei/emdash-bento\";\nimport { blockBuilderPlugin } from \"@bnomei/emdash-blocks\";\n\nexport default {\n  integrations: [\n    emdash({\n      plugins: [blockBuilderPlugin(), bentoPlugin()],\n    }),\n  ],\n};\n```\n\n## Field Widget\n\nUse the widget on an EmDash `json` field:\n\n```json\n{\n  \"slug\": \"layouts\",\n  \"label\": \"Grid\",\n  \"type\": \"json\",\n  \"widget\": \"bento:layouts\",\n  \"options\": {\n    \"blockDefinitions\": [\n      {\n        \"type\": \"heading\",\n        \"label\": \"Heading\",\n        \"props\": [{ \"key\": \"text\", \"label\": \"Text\", \"type\": \"text\" }]\n      },\n      {\n        \"type\": \"text\",\n        \"label\": \"Text\",\n        \"props\": [{ \"key\": \"text\", \"label\": \"Text\", \"type\": \"markdown\" }]\n      },\n      {\n        \"type\": \"image\",\n        \"label\": \"Image\",\n        \"props\": [{ \"key\": \"image\", \"label\": \"Image\", \"type\": \"media\" }]\n      }\n    ]\n  }\n}\n```\n\n## Stored Value\n\n```ts\ntype LayoutBuilderValue = Array<{\n  id: string;\n  layout: string;\n  settings?: Record<string, unknown>;\n  columns: Array<{\n    id: string;\n    span: string;\n    blocks: BlockBuilderValue;\n  }>;\n}>;\n```\n\nEmpty layout fields stay empty when the admin widget mounts, so opening an\nuntouched entry does not write a default row or mark the field dirty. The widget\nshows an empty state with the Add Layout button, and clicking that button creates\nthe first editable row.\n\nEach row stores exactly one `layout` pattern. The pattern is a comma-separated\nlist of column spans, for example `1/1`, `1/2, 1/2`, or `1/1, 1/3, 2/3`.\nEditing the pattern updates the row's columns by position, preserving existing\ncolumn blocks where a matching column index still exists. If the edited pattern\nhas fewer spans than the row already has columns, columns beyond that pattern\nare removed. The per-column `span` values mirror the row pattern and are stored\nso frontend renderers can read the same data directly.\n\nEditors can also append a column with the row-level Add Column button. New\ncolumns start as `1/1`, and the row pattern updates to match the visible\ncolumns.\n\nThe Add Layout button creates a new row with `1/1, 1/2, 1/3`; editors can\nchange that row's layout pattern after it has been added.\n\nEach column header also exposes a sorted width select and a remove button. The\nselect choices are the unique spans in that row's current layout pattern.\nLayouts can be reordered with up/down controls. Columns can be reordered with\nleft/right controls.\n\nThe admin widget renders columns on a 12-column CSS grid where `1/2` spans 6 grid columns and `1/3` spans 4 columns. If a row's widths add up to more than `1/1`, the extra columns wrap to the next line. The widget accepts comma-separated fractions with denominators up to twelfths, so editors can type one row pattern such as `1/1`, `1/2, 1/2`, or `1/1, 2/3, 1/3` and override it whenever the layout needs to change.\n\nNested blocks use `@bnomei/emdash-blocks` directly. Pass\n`options.blockDefinitions` to control the available nested block types and their\ntyped prop controls. Standalone block fields and layout column blocks share the\nsame definition shape.\n\n## Frontend Rendering\n\nRender layout rows as a 12-column CSS grid. The package exports helpers for the\ncommon data preparation and span calculation:\n\n```ts\nimport { layoutGridSpans, visibleLayoutRows } from \"@bnomei/emdash-bento\";\nimport { visibleBlocks } from \"@bnomei/emdash-blocks\";\n\nconst rows = visibleLayoutRows(entry.layouts);\n```\n\n```astro\n{\n  rows.map((row) => {\n    const gridSpans = layoutGridSpans(row.columns.map((column) => column.span));\n\n    return (\n      <section class=\"layout\" data-layout-id={row.id}>\n        {row.columns.map((column, columnIndex) => (\n          <div\n            class=\"column\"\n            style={`--span: ${gridSpans[columnIndex] ?? 12}`}\n            data-column-id={column.id}\n          >\n            {visibleBlocks(column.blocks).map((block) => renderBlock(block))}\n          </div>\n        ))}\n      </section>\n    );\n  })\n}\n```\n\n```css\n.layout {\n  display: grid;\n  grid-template-columns: repeat(12, minmax(0, 1fr));\n}\n\n.column {\n  grid-column: span var(--span) / span var(--span);\n}\n```\n\nThe helpers accept native Bento values. Migration from other systems should\nhappen before values are saved into EmDash.\n\n## Package Surface\n\n- ESM entry: `@bnomei/emdash-bento`.\n- Admin entry: `@bnomei/emdash-bento/admin`.\n- Type declarations are included from `dist/`.\n- Peer dependencies: `@bnomei/emdash-blocks` `^0.2.1`, `emdash`\n  `>=0.17.0`, `react` `^18.0.0 || ^19.0.0`, `react-dom`\n  `^18.0.0 || ^19.0.0`, `@cloudflare/kumo` `^2.5.0`, and\n  `@phosphor-icons/react` `^2.1.10`.\n\n## Status\n\nThis package ships as a native EmDash plugin because the editor is a trusted React admin field widget. Package exports point at Viteplus `vp pack`-built `dist/` JavaScript and declarations; use `npm run build` for the production pack and `npm run pack:check` for the publint-verified pack check.\n\n## Related Packages\n\n- `@bnomei/emdash-blocks` provides the nested block editor used by Bento\n  columns.\n- `@bnomei/emdash-fields` provides smaller JSON-backed field widgets.\n\n## License\n\nMIT.\n\n## Screenshot\n\n![Bento screenshot](./screenshot.png)\n","readmeFilename":"README.md"}