{"_id":"@brendlij/flux-grid","_rev":"7-fbe2d109454925e4eb91f11f4e066bd9","name":"@brendlij/flux-grid","dist-tags":{"latest":"0.1.6"},"versions":{"0.1.1":{"name":"@brendlij/flux-grid","version":"0.1.1","keywords":["vue","grid","layout","dashboard","css-grid"],"author":{"name":"brendlij"},"license":"MIT","_id":"@brendlij/flux-grid@0.1.1","maintainers":[{"name":"brendlij","email":"dev.brendlij@gmail.com"}],"homepage":"https://github.com/brendlij/flux-grid#readme","bugs":{"url":"https://github.com/brendlij/flux-grid/issues"},"dist":{"shasum":"a7f60ba5cfa43c9a881522f2a6958a2f388b6fa2","tarball":"https://registry.npmjs.org/@brendlij/flux-grid/-/flux-grid-0.1.1.tgz","fileCount":6,"integrity":"sha512-WAaGUVeM8+gBevTCkW+pb7+7Ia8I9C16zt2tYV9ev3RBXiFP/oWEaeD17sKWcT66rkp030HsRDY/m7x/3slmVA==","signatures":[{"sig":"MEUCIDwAOOQlIJlIvkP1ofdjFup3rG8K6Ev5qoWtzC8DxINZAiEAkL4He8KNBF6eyd9gUAClD6i+JrF/UtO0ct6Jss5lbn4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17097},"main":"./dist/flux-grid.cjs","type":"module","types":"./dist/types/index.d.ts","module":"./dist/flux-grid.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/flux-grid.js","require":"./dist/flux-grid.cjs"},"./style.css":"./dist/style.css"},"gitHead":"dc7ff8f204fc8e9808b09924b5c7753e16f1a088","private":false,"scripts":{"dev":"vite","build":"vue-tsc -p tsconfig.lib.json --declaration --emitDeclarationOnly && vite build","preview":"vite preview"},"_npmUser":{"name":"brendlij","email":"dev.brendlij@gmail.com"},"repository":{"url":"git+https://github.com/brendlij/flux-grid.git","type":"git"},"_npmVersion":"11.5.1","description":"Flexible Vue 3 grid layout components with explicit or responsive track control.","directories":{},"sideEffects":false,"_nodeVersion":"24.7.0","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"vue":"^3.5.24","vite":"^7.2.4","vue-tsc":"^3.1.4","typescript":"~5.9.3","@types/node":"^24.10.1","@vue/tsconfig":"^0.8.1","@vitejs/plugin-vue":"^6.0.1"},"peerDependencies":{"vue":"^3.4.0 || ^3.5.0"},"_npmOperationalInternal":{"tmp":"tmp/flux-grid_0.1.1_1763974821974_0.5256455046618793","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.1.2":{"name":"@brendlij/flux-grid","version":"0.1.2","keywords":["vue","grid","layout","dashboard","css-grid"],"author":{"name":"brendlij"},"license":"MIT","_id":"@brendlij/flux-grid@0.1.2","maintainers":[{"name":"brendlij","email":"dev.brendlij@gmail.com"}],"homepage":"https://github.com/brendlij/flux-grid#readme","bugs":{"url":"https://github.com/brendlij/flux-grid/issues"},"dist":{"shasum":"4ffb263e8454fa207e0e7a2f994e0c410648b808","tarball":"https://registry.npmjs.org/@brendlij/flux-grid/-/flux-grid-0.1.2.tgz","fileCount":6,"integrity":"sha512-JTuS7yh46F7+MF7nstIuTi8YpvdqFe4Ue+/qecf9xCNhSa3Yp7EEfgR4mggh2rq7YaKdC4y4Whk1tyJwPQ6uzA==","signatures":[{"sig":"MEUCIQDEX7vSIfJvRgS8w4mMPQFQHM8wpDPaougwiqKTe7OeWQIgWiLF7cuNEIhKEfEJ+/SjDuzsFKz8Y2lPGIwZwamGzKk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17097},"main":"./dist/flux-grid.cjs","type":"module","types":"./dist/types/index.d.ts","module":"./dist/flux-grid.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/flux-grid.js","require":"./dist/flux-grid.cjs"},"./style.css":"./dist/style.css"},"gitHead":"dc7ff8f204fc8e9808b09924b5c7753e16f1a088","private":false,"scripts":{"dev":"vite","build":"vite build && vue-tsc -p tsconfig.lib.json --declaration --emitDeclarationOnly","preview":"vite preview"},"_npmUser":{"name":"brendlij","email":"dev.brendlij@gmail.com"},"repository":{"url":"git+https://github.com/brendlij/flux-grid.git","type":"git"},"_npmVersion":"11.5.1","description":"Flexible Vue 3 grid layout components with explicit or responsive track control.","directories":{},"sideEffects":false,"_nodeVersion":"24.7.0","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"vue":"^3.5.24","vite":"^7.2.4","vue-tsc":"^3.1.4","typescript":"~5.9.3","@types/node":"^24.10.1","@vue/tsconfig":"^0.8.1","@vitejs/plugin-vue":"^6.0.1"},"peerDependencies":{"vue":"^3.4.0 || ^3.5.0"},"_npmOperationalInternal":{"tmp":"tmp/flux-grid_0.1.2_1763976200972_0.5492460528146426","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.1.3":{"name":"@brendlij/flux-grid","version":"0.1.3","keywords":["vue","grid","layout","dashboard","css-grid"],"author":{"name":"brendlij"},"license":"MIT","_id":"@brendlij/flux-grid@0.1.3","maintainers":[{"name":"brendlij","email":"dev.brendlij@gmail.com"}],"homepage":"https://github.com/brendlij/flux-grid#readme","bugs":{"url":"https://github.com/brendlij/flux-grid/issues"},"dist":{"shasum":"ccea34a26069066932df8cecfae7077469338dd8","tarball":"https://registry.npmjs.org/@brendlij/flux-grid/-/flux-grid-0.1.3.tgz","fileCount":9,"integrity":"sha512-ZSflwYFrhY1n6OE4pMxdBZcu88jtyHPa/zfE4cvoTsdtr5srbEIEAeWcnGUzAVPfIeqAXJjkFiTuvinu77vrhg==","signatures":[{"sig":"MEYCIQDrV9wEZIKce6Zpgg0kXh5H2eIRDgxm7Eq0qdWHoZ4TfgIhALiYXqkZhUBbCmpBt+AwvylG19UumumOwpFxW5GHHK7J","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":18434},"main":"./dist/flux-grid.cjs","type":"module","types":"./dist/types/index.d.ts","module":"./dist/flux-grid.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/flux-grid.js","require":"./dist/flux-grid.cjs"},"./style.css":"./dist/style.css"},"gitHead":"dc7ff8f204fc8e9808b09924b5c7753e16f1a088","private":false,"scripts":{"dev":"vite","build":"bunx vite build && bunx vue-tsc -p tsconfig.lib.json --declaration --emitDeclarationOnly --outDir dist/types","prepare":"npm run build","preview":"vite preview","prepublishOnly":"npm run build"},"_npmUser":{"name":"brendlij","email":"dev.brendlij@gmail.com"},"repository":{"url":"git+https://github.com/brendlij/flux-grid.git","type":"git"},"_npmVersion":"11.5.1","description":"Flexible Vue 3 grid layout components with explicit or responsive track control.","directories":{},"sideEffects":false,"_nodeVersion":"24.7.0","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"vue":"^3.5.24","vite":"^7.2.4","vue-tsc":"^3.1.4","typescript":"~5.9.3","@types/node":"^24.10.1","@vue/tsconfig":"^0.8.1","@vitejs/plugin-vue":"^6.0.1"},"peerDependencies":{"vue":"^3.4.0 || ^3.5.0"},"_npmOperationalInternal":{"tmp":"tmp/flux-grid_0.1.3_1763977465546_0.9076419295885878","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.1.4":{"name":"@brendlij/flux-grid","version":"0.1.4","keywords":["vue","grid","layout","dashboard","css-grid"],"author":{"name":"brendlij"},"license":"MIT","_id":"@brendlij/flux-grid@0.1.4","maintainers":[{"name":"brendlij","email":"dev.brendlij@gmail.com"}],"homepage":"https://github.com/brendlij/flux-grid#readme","bugs":{"url":"https://github.com/brendlij/flux-grid/issues"},"dist":{"shasum":"103845809b53e93519fbaa0e46d8db80e3a9076e","tarball":"https://registry.npmjs.org/@brendlij/flux-grid/-/flux-grid-0.1.4.tgz","fileCount":9,"integrity":"sha512-0LwM8tRgGxL8zZdHMTgKc4dGR/S4yYKou1bfY6UnsPKULw+k/Q4LQ0kvQVBoDX8qGCwYyAnV3GgYcqzTRb8iiA==","signatures":[{"sig":"MEYCIQC2R6Ww5EzLo5SSpwbUk3C907AWmOIIAkBxo+D+v/SDzAIhAMmT/sRRqouOO2DBmTrX206hSAJZ+vqDxaiYGL4mAOG9","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":18461},"main":"./dist/flux-grid.cjs","type":"module","types":"./dist/types/index.d.ts","module":"./dist/flux-grid.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/flux-grid.js","require":"./dist/flux-grid.cjs"},"./style.css":"./dist/style.css"},"gitHead":"dc7ff8f204fc8e9808b09924b5c7753e16f1a088","private":false,"scripts":{"dev":"vite","build":"bunx vite build && bunx vue-tsc -p tsconfig.lib.json --declaration --emitDeclarationOnly --outDir dist/types","prepare":"npm run build","preview":"vite preview","prepublishOnly":"npm run build"},"_npmUser":{"name":"brendlij","email":"dev.brendlij@gmail.com"},"repository":{"url":"git+https://github.com/brendlij/flux-grid.git","type":"git"},"_npmVersion":"11.5.1","description":"Flexible Vue 3 grid layout components with explicit or responsive track control.","directories":{},"sideEffects":["./dist/flux-grid.css"],"_nodeVersion":"24.7.0","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"vue":"^3.5.24","vite":"^7.2.4","vue-tsc":"^3.1.4","typescript":"~5.9.3","@types/node":"^24.10.1","@vue/tsconfig":"^0.8.1","@vitejs/plugin-vue":"^6.0.1"},"peerDependencies":{"vue":"^3.4.0 || ^3.5.0"},"_npmOperationalInternal":{"tmp":"tmp/flux-grid_0.1.4_1763978360634_0.8743057524748239","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.1.5":{"name":"@brendlij/flux-grid","version":"0.1.5","keywords":["vue","grid","layout","dashboard","css-grid"],"author":{"name":"brendlij"},"license":"MIT","_id":"@brendlij/flux-grid@0.1.5","maintainers":[{"name":"brendlij","email":"dev.brendlij@gmail.com"}],"homepage":"https://github.com/brendlij/flux-grid#readme","bugs":{"url":"https://github.com/brendlij/flux-grid/issues"},"dist":{"shasum":"a9adaedc434c52d51ed2a3a2292955aa5f98588b","tarball":"https://registry.npmjs.org/@brendlij/flux-grid/-/flux-grid-0.1.5.tgz","fileCount":10,"integrity":"sha512-6GZa3A4/PsbctBfGCbyHpgZc/cYC4P9YrSnT7U/X8TSAe6oIy1wCpWTE2+2plUqIzruGjh4qHYvOCH2OPqTFHQ==","signatures":[{"sig":"MEUCIBY8ae4Fum4xzs3Rqss9m1DoaBACg181RHKe84qQrxCXAiEA7zqXCIT2J2l3LqR+GWVs94CpUuG+DNwYGXHnSd8TJTM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":19841},"main":"./dist/flux-grid.cjs","type":"module","types":"./dist/types/index.d.ts","module":"./dist/flux-grid.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/flux-grid.js","require":"./dist/flux-grid.cjs"},"./style.css":"./dist/style.css"},"gitHead":"dc7ff8f204fc8e9808b09924b5c7753e16f1a088","private":false,"scripts":{"dev":"vite","build":"bunx vite build && bunx vue-tsc -p tsconfig.lib.json --declaration --emitDeclarationOnly --outDir dist/types","prepare":"npm run build","preview":"vite preview","prepublishOnly":"npm run build"},"_npmUser":{"name":"brendlij","email":"dev.brendlij@gmail.com"},"repository":{"url":"git+https://github.com/brendlij/flux-grid.git","type":"git"},"_npmVersion":"11.5.1","description":"Flexible Vue 3 grid layout components with explicit or responsive track control.","directories":{},"sideEffects":["./dist/flux-grid.css"],"_nodeVersion":"24.7.0","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"vue":"^3.5.24","vite":"^7.2.4","vue-tsc":"^3.1.4","typescript":"~5.9.3","@types/node":"^24.10.1","@vue/tsconfig":"^0.8.1","@vitejs/plugin-vue":"^6.0.1"},"peerDependencies":{"vue":"^3.4.0 || ^3.5.0"},"_npmOperationalInternal":{"tmp":"tmp/flux-grid_0.1.5_1763978651976_0.6407787476060254","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.1.6":{"name":"@brendlij/flux-grid","version":"0.1.6","keywords":["vue","grid","layout","dashboard","css-grid"],"author":{"name":"brendlij"},"license":"MIT","_id":"@brendlij/flux-grid@0.1.6","maintainers":[{"name":"brendlij","email":"dev.brendlij@gmail.com"}],"homepage":"https://github.com/brendlij/flux-grid#readme","bugs":{"url":"https://github.com/brendlij/flux-grid/issues"},"dist":{"shasum":"5da3f838868f342ea8aca31bf46458274009b4e7","tarball":"https://registry.npmjs.org/@brendlij/flux-grid/-/flux-grid-0.1.6.tgz","fileCount":17,"integrity":"sha512-QLXEeWFqEbjec/AWvnOMAuXwVmux1fD/4jUYGePPhBYIjWE7tV/JwsmJ+DhgX6CNb63LJNs4Azmn58F+W4Krng==","signatures":[{"sig":"MEQCIAYgP7W8TvBwogFtgJZKOAIRpcOo8SczkEAGE/MV1hycAiAlWlchS02paaq+emFxbQUHXNm2DwOYm8EsuZcbcBO/nA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":48904},"main":"./dist/flux-grid.cjs","type":"module","types":"./dist/types/index.d.ts","module":"./dist/flux-grid.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/flux-grid.js","require":"./dist/flux-grid.cjs"},"./style.css":"./dist/style.css"},"gitHead":"4d3ecef2be268993f90231252cd98f108c4f822b","private":false,"scripts":{"dev":"vite","build":"bunx vite build && bunx vue-tsc -p tsconfig.lib.json --declaration --emitDeclarationOnly --outDir dist/types","prepare":"npm run build","preview":"vite preview","prepublishOnly":"npm run build"},"_npmUser":{"name":"brendlij","email":"dev.brendlij@gmail.com"},"repository":{"url":"git+https://github.com/brendlij/flux-grid.git","type":"git"},"_npmVersion":"11.6.1","description":"Flexible Vue 3 grid layout components with explicit or responsive track control.","directories":{},"sideEffects":["./dist/flux-grid.css"],"_nodeVersion":"20.19.2","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"vue":"^3.5.24","vite":"^7.2.4","vue-tsc":"^3.1.4","typescript":"~5.9.3","@types/node":"^24.10.1","@vue/tsconfig":"^0.8.1","@vitejs/plugin-vue":"^6.0.1"},"peerDependencies":{"vue":"^3.4.0 || ^3.5.0"},"_npmOperationalInternal":{"tmp":"tmp/flux-grid_0.1.6_1764004550847_0.5453646802477519","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."}},"time":{"created":"2025-11-24T09:00:21.876Z","modified":"2025-12-01T19:19:32.579Z","0.1.1":"2025-11-24T09:00:22.153Z","0.1.2":"2025-11-24T09:23:21.199Z","0.1.3":"2025-11-24T09:44:25.745Z","0.1.4":"2025-11-24T09:59:20.830Z","0.1.5":"2025-11-24T10:04:12.141Z","0.1.6":"2025-11-24T17:15:51.040Z"},"bugs":{"url":"https://github.com/brendlij/flux-grid/issues"},"author":{"name":"brendlij"},"license":"MIT","homepage":"https://github.com/brendlij/flux-grid#readme","keywords":["vue","grid","layout","dashboard","css-grid"],"repository":{"url":"git+https://github.com/brendlij/flux-grid.git","type":"git"},"description":"Flexible Vue 3 grid layout components with explicit or responsive track control.","maintainers":[{"name":"brendlij","email":"dev.brendlij@gmail.com"}],"readme":"# Flux Grid\r\n\r\nFlux Grid is a lightweight Vue 3 layout utility that lets you drop arbitrary components, text, or media into a flexible CSS Grid surface. Define fixed tracks, responsive auto-fit columns with custom min/max constraints, or a fully locked canvas where every tile has coordinates—all with a pair of components.\r\n\r\n## Features\r\n\r\n- 💡 **Single component API** – `FluxGrid` defines the surface, `FluxGridItem` decides placement.\r\n- 📐 **Fixed or dynamic tracks** – Supply numeric counts, explicit templates, or auto-fit/auto-fill objects with custom min/max values.\r\n- 📱 **Responsive by default** – Auto-fit mode stretches or collapses columns at each breakpoint; flip on `locked` to freeze the layout width.\r\n- 🪄 **Breakpoint presets** – Declare container width ranges that retune columns, gaps, and row heights without writing media queries.\r\n- 🧱 **Explicit coordinates** – Pass `col`/`row` plus `colSpan`/`rowSpan` to build magazine-style grids.\r\n- 📦 **Self-contained cards** – `FluxCard` component with auto-sizing, slot system, and safe overflow handling.\r\n- 🧩 **Drop anything inside** – Slots accept plain text, cards, charts, or entire feature components.\r\n- 🎯 **Drag & drop ready** – Grid items expose `data-grid-*` attributes for future interaction layers.\r\n\r\n## Quick start\r\n\r\n```bash\r\nbun install\r\nbun dev\r\n```\r\n\r\n## Usage\r\n\r\n```vue\r\n<script setup lang=\"ts\">\r\nimport { FluxGrid, FluxGridItem } from \"flux-grid\";\r\n\r\nconst dashboardBreakpoints = [\r\n  { name: \"stacked\", columns: 1, gap: \"1rem\" },\r\n  { name: \"tablet\", minWidth: 640, columns: 2, gap: \"1.25rem\" },\r\n  { name: \"desktop\", minWidth: 1024, columns: 3, gap: \"1.5rem\" },\r\n  {\r\n    name: \"wide\",\r\n    minWidth: 1280,\r\n    columns: { type: \"auto-fit\", min: \"16rem\", max: \"1fr\" },\r\n  },\r\n];\r\n\r\nconst widgets = [\r\n  { id: \"hero\", colSpan: 2, rowSpan: 2, title: \"Hero\" },\r\n  { id: \"chart\", title: \"Chart\" },\r\n];\r\n</script>\r\n\r\n<template>\r\n  <FluxGrid :breakpoints=\"dashboardBreakpoints\" row-height=\"auto\">\r\n    <FluxGridItem\r\n      v-for=\"widget in widgets\"\r\n      :key=\"widget.id\"\r\n      :col-span=\"widget.colSpan\"\r\n      :row-span=\"widget.rowSpan\"\r\n    >\r\n      <WidgetCard :title=\"widget.title\" />\r\n    </FluxGridItem>\r\n  </FluxGrid>\r\n</template>\r\n```\r\n\r\n### Locked layout\r\n\r\n```vue\r\n<FluxGrid :columns=\"4\" :rows=\"4\" locked :gap=\"16\" :row-height=\"160\">\r\n  <FluxGridItem col=\"1\" row=\"1\" :col-span=\"2\" :row-span=\"2\">\r\n    <HeroModule />\r\n  </FluxGridItem>\r\n  <FluxGridItem col=\"3\" row=\"1\" :col-span=\"2\">\r\n    <ActivityFeed />\r\n  </FluxGridItem>\r\n</FluxGrid>\r\n```\r\n\r\n### Simple card grid (auto-fit)\r\n\r\n```vue\r\n<script setup lang=\"ts\">\r\nimport { FluxGrid, FluxGridItem } from \"flux-grid\";\r\n\r\nconst cards = [\r\n  { id: 1, title: \"Card A\" },\r\n  { id: 2, title: \"Card B\" },\r\n  { id: 3, title: \"Card C\" },\r\n];\r\n</script>\r\n\r\n<template>\r\n  <!-- Auto-fit columns that collapse on small screens -->\r\n  <FluxGrid :columns=\"{ type: 'auto-fit', min: '250px', max: '1fr' }\" :gap=\"16\">\r\n    <FluxGridItem v-for=\"card in cards\" :key=\"card.id\">\r\n      <div class=\"card\">{{ card.title }}</div>\r\n    </FluxGridItem>\r\n  </FluxGrid>\r\n</template>\r\n```\r\n\r\n### Fixed 12-column grid (like Bootstrap)\r\n\r\n```vue\r\n<!-- Define 12 equal columns with explicit placement -->\r\n<FluxGrid :columns=\"12\" :gap=\"20\" locked>\r\n  <FluxGridItem col=\"1\" :col-span=\"8\">\r\n    <MainContent />\r\n  </FluxGridItem>\r\n  <FluxGridItem col=\"9\" :col-span=\"4\">\r\n    <Sidebar />\r\n  </FluxGridItem>\r\n</FluxGrid>\r\n```\r\n\r\n### Aspect ratio preservation\r\n\r\n```vue\r\n<!-- Perfect for image galleries or video previews -->\r\n<FluxGrid :columns=\"{ type: 'auto-fit', min: '200px', max: '1fr' }\" :gap=\"12\">\r\n  <FluxGridItem\r\n    v-for=\"item in items\"\r\n    :key=\"item.id\"\r\n    aspect-ratio=\"16/9\"\r\n  >\r\n    <img :src=\"item.src\" alt=\"\" />\r\n  </FluxGridItem>\r\n</FluxGrid>\r\n```\r\n\r\n### Mixed sizes with breakpoints\r\n\r\n```vue\r\n<script setup lang=\"ts\">\r\nimport { FluxGrid, FluxGridItem } from \"flux-grid\";\r\n\r\nconst photoBreakpoints = [\r\n  { columns: 1, gap: \"1rem\" },\r\n  { minWidth: 640, columns: 2, gap: \"1.25rem\" },\r\n  { minWidth: 1024, columns: 3, gap: \"1.5rem\" },\r\n  { minWidth: 1440, columns: 4, gap: \"2rem\" },\r\n];\r\n\r\nconst photos = Array.from({ length: 12 }, (_, i) => ({ id: i }));\r\n</script>\r\n\r\n<template>\r\n  <FluxGrid :breakpoints=\"photoBreakpoints\" :gap=\"16\">\r\n    <FluxGridItem\r\n      v-for=\"(photo, idx) in photos\"\r\n      :key=\"photo.id\"\r\n      :col-span=\"idx === 0 ? 2 : 1\"\r\n      :row-span=\"idx === 0 ? 2 : 1\"\r\n    >\r\n      <img :src=\"`/photo-${idx}.jpg`\" alt=\"\" />\r\n    </FluxGridItem>\r\n  </FluxGrid>\r\n</template>\r\n```\r\n\r\n### Dashboard with hero and widgets\r\n\r\n```vue\r\n<script setup lang=\"ts\">\r\nimport { FluxGrid, FluxGridItem } from \"flux-grid\";\r\n\r\nconst dashboardBreakpoints = [\r\n  { columns: 1, gap: \"1rem\", rowHeight: \"200px\" },\r\n  { minWidth: 768, columns: 2, gap: \"1.25rem\", rowHeight: \"240px\" },\r\n  { minWidth: 1200, columns: 4, gap: \"1.5rem\", rowHeight: \"200px\" },\r\n];\r\n</script>\r\n\r\n<template>\r\n  <FluxGrid :breakpoints=\"dashboardBreakpoints\">\r\n    <!-- Hero spans full width on mobile, 2 cols on tablet, 2 cols on desktop -->\r\n    <FluxGridItem :col-span=\"1\" :row-span=\"1\">\r\n      <HeroCard />\r\n    </FluxGridItem>\r\n\r\n    <!-- Widgets fill remaining space -->\r\n    <FluxGridItem v-for=\"i in 5\" :key=\"i\">\r\n      <MetricWidget :index=\"i\" />\r\n    </FluxGridItem>\r\n  </FluxGrid>\r\n</template>\r\n```\r\n\r\n### Using custom CSS for styling\r\n\r\n```vue\r\n<script setup lang=\"ts\">\r\nimport { FluxGrid, FluxGridItem } from \"flux-grid\";\r\nimport \"flux-grid/style.css\";\r\n</script>\r\n\r\n<template>\r\n  <FluxGrid :columns=\"3\" :gap=\"20\" class=\"my-grid\">\r\n    <FluxGridItem v-for=\"i in 9\" :key=\"i\" class=\"grid-card\">\r\n      <div>Card {{ i }}</div>\r\n    </FluxGridItem>\r\n  </FluxGrid>\r\n</template>\r\n\r\n<style scoped>\r\n/* Override grid gap with CSS custom properties */\r\n:deep(.my-grid) {\r\n  --flux-grid-gap: 24px;\r\n}\r\n\r\n/* Style individual items */\r\n:deep(.grid-card) {\r\n  --flux-grid-item-bg: rgba(100, 150, 200, 0.1);\r\n  --flux-grid-item-radius: 12px;\r\n}\r\n</style>\r\n```\r\n\r\n## API reference\r\n\r\n### `<FluxGrid />`\r\n\r\n| Prop                      | Type                                                                                                                   | Default           | Description                                                                                                                                                     |\r\n| ------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |\r\n| `columns`                 | `number \\| string \\| string[] \\| { type?: 'auto-fit' \\| 'auto-fill'; min?: string \\| number; max?: string \\| number }` | auto-fit template | Track template for columns. Numbers create equal columns, strings are passed through, objects create minmax auto-fit ranges.                                    |\r\n| `rows`                    | same as `columns`                                                                                                      | `undefined`       | Optional row template. Leave unset to allow implicit rows with `rowHeight`.                                                                                     |\r\n| `gap`                     | `string \\| number`                                                                                                     | `1.25rem`         | Gap between items. Numbers resolve to `px`.                                                                                                                     |\r\n| `rowHeight`               | `string \\| number`                                                                                                     | `undefined`       | Sets `grid-auto-rows` so implicitly created rows share a height.                                                                                                |\r\n| `columnMin` / `columnMax` | `string \\| number`                                                                                                     | `12rem` / `1fr`   | Fallbacks when columns are auto-generated.                                                                                                                      |\r\n| `rowMin` / `rowMax`       | `string \\| number`                                                                                                     | `8rem` / `auto`   | Fallbacks when rows are auto-generated.                                                                                                                         |\r\n| `locked`                  | `boolean`                                                                                                              | `false`           | When `true`, the grid width is clamped to its content, producing a fixed canvas.                                                                                |\r\n| `autoFlow`                | `'row' \\| 'column' \\| 'dense' \\| 'row dense' \\| 'column dense'`                                                        | `'row dense'`     | Native `grid-auto-flow` passthrough.                                                                                                                            |\r\n| `breakpoints`             | `FluxGridBreakpoint[]`                                                                                                 | `[]`              | Ordered list of container-width presets that override any of the props above. Each entry accepts `minWidth`/`maxWidth` plus `columns`, `gap`, `rowHeight`, etc. |\r\n| `tag`                     | `string`                                                                                                               | `'div'`           | Root element tag.                                                                                                                                               |\r\n\r\n`FluxGridBreakpoint` mirrors the main layout props and adds optional `name`, `minWidth`, and `maxWidth` fields (numbers are treated as `px`, or pass CSS lengths with `px`, `rem`, or `em`). Breakpoints are evaluated against the grid's container width (powered by `ResizeObserver`), so you can preview responsive states inside design systems, docs, or Storybook without resizing the entire browser. The component exposes a `data-breakpoint` attribute reflecting the active breakpoint's `name` to help style or debug demos.\r\n\r\n### `<FluxGridItem />`\r\n\r\n| Prop                 | Type               | Default     | Description                                                            |\r\n| -------------------- | ------------------ | ----------- | ---------------------------------------------------------------------- |\r\n| `col`, `row`         | `number`           | `undefined` | 1-based starting coordinate. Optional—omit for natural auto-placement. |\r\n| `colSpan`, `rowSpan` | `number`           | `1`         | Number of tracks to span. Works with or without explicit coordinates.  |\r\n| `aspectRatio`        | `string \\| number` | `undefined` | Sets CSS `aspect-ratio` to reserve space for media.                    |\r\n| `zIndex`             | `number`           | `undefined` | Lift an item above overlapping neighbors.                              |\r\n| `tag`                | `string`           | `'div'`     | Wrapper element tag.                                                   |\r\n\r\nEach item also exposes `data-grid-col`, `data-grid-row`, and span attributes so you can layer drag-and-drop or analytics later on.\r\n\r\n### `<FluxCard />`\r\n\r\nSelf-contained card component with auto-sizing, overflow safety, and a three-slot structure (header, body, footer).\r\n\r\n| Prop          | Type                                        | Default     | Description                                                                            |\r\n| ------------- | ------------------------------------------- | ----------- | -------------------------------------------------------------------------------------- |\r\n| `aspectRatio` | `string \\| number`                          | `undefined` | CSS aspect-ratio value (e.g., `\"16/9\"`, `1.5`). Maintains ratio regardless of content. |\r\n| `overflow`    | `'hidden' \\| 'auto' \\| 'visible'`           | `'hidden'`  | How to handle content overflow. `'hidden'` prevents layout breaking.                   |\r\n| `padding`     | `string \\| number`                          | `'1rem'`    | Internal padding. Numbers resolve to `px`.                                             |\r\n| `align`       | `'start' \\| 'center' \\| 'end' \\| 'stretch'` | `'start'`   | Vertical alignment of content within the card.                                         |\r\n| `tag`         | `string`                                    | `'div'`     | Root HTML element tag.                                                                 |\r\n| `class`       | `string`                                    | `undefined` | Additional CSS classes for custom styling.                                             |\r\n\r\n**Slots:**\r\n\r\n- `default` (body) – Primary content. Flexes to fill available space with `flex: 1`.\r\n- `header` – Optional header area. Useful for titles or badges.\r\n- `footer` – Optional footer area. Useful for actions or metadata.\r\n\r\n**Example:**\r\n\r\n```vue\r\n<FluxCard aspect-ratio=\"16/9\" padding=\"1rem\">\r\n  <template #header>\r\n    <h3>Card Title</h3>\r\n  </template>\r\n  \r\n  <img src=\"image.jpg\" alt=\"\" class=\"flux-cover\" />\r\n  \r\n  <template #footer>\r\n    <p>Card footer text</p>\r\n  </template>\r\n</FluxCard>\r\n```\r\n\r\n## Utility Classes\r\n\r\nFlux Grid ships with CSS utility classes for safe content handling:\r\n\r\n| Class                   | Purpose                                                                     |\r\n| ----------------------- | --------------------------------------------------------------------------- |\r\n| `.flux-truncate`        | Single-line text overflow with ellipsis.                                    |\r\n| `.flux-truncate-lines`  | Multi-line text truncation (use `--flux-truncate-lines` to set line count). |\r\n| `.flux-overflow-hidden` | Hide overflow without ellipsis.                                             |\r\n| `.flux-cover`           | Image scaling (CSS `object-fit: cover`).                                    |\r\n| `.flux-contain`         | Image scaling (CSS `object-fit: contain`).                                  |\r\n\r\n**Example:**\r\n\r\n```vue\r\n<!-- Truncate long text -->\r\n<p class=\"flux-truncate\">Very long text that will be cut off...</p>\r\n\r\n<!-- Multi-line truncation -->\r\n<p class=\"flux-truncate-lines\" style=\"--flux-truncate-lines: 3;\">\r\n  Text limited to 3 lines...\r\n</p>\r\n\r\n<!-- Safe image display -->\r\n<img src=\"photo.jpg\" alt=\"\" class=\"flux-cover\" />\r\n```\r\n\r\n## CSS Customization\r\n\r\nFlux Grid exposes CSS custom properties for theming:\r\n\r\n```css\r\n/* Grid container */\r\n--flux-grid-gap: 1.25rem; /* Gap between items */\r\n\r\n/* Grid items */\r\n--flux-grid-item-bg: transparent; /* Background color */\r\n--flux-grid-item-radius: 0.75rem; /* Border radius */\r\n```\r\n\r\nOverride these in your component or globally:\r\n\r\n```css\r\n:root {\r\n  --flux-grid-gap: 2rem;\r\n  --flux-grid-item-bg: #f5f5f5;\r\n  --flux-grid-item-radius: 1rem;\r\n}\r\n```\r\n\r\n## Tips & Patterns\r\n\r\n### Responsive without breakpoints\r\n\r\nUse `auto-fit` or `auto-fill` to let CSS Grid handle responsiveness naturally:\r\n\r\n```vue\r\n<FluxGrid :columns=\"{ type: 'auto-fit', min: '16rem', max: '1fr' }\">\r\n  <!-- Automatically wraps at viewport size -->\r\n</FluxGrid>\r\n```\r\n\r\n### Combining locked items with flexible layout\r\n\r\nMix explicit placement with auto-flow:\r\n\r\n```vue\r\n<FluxGrid :columns=\"4\" :gap=\"16\">\r\n  <!-- Explicitly placed hero -->\r\n  <FluxGridItem col=\"1\" :col-span=\"2\" :row-span=\"2\">\r\n    <Hero />\r\n  </FluxGridItem>\r\n  \r\n  <!-- Remaining items flow naturally -->\r\n  <FluxGridItem v-for=\"item in rest\" :key=\"item.id\">\r\n    <Card :item=\"item\" />\r\n  </FluxGridItem>\r\n</FluxGrid>\r\n```\r\n\r\n### Reordering on mobile with breakpoints\r\n\r\nAdjust `colSpan` and `rowSpan` per breakpoint:\r\n\r\n```vue\r\n<script setup lang=\"ts\">\r\nconst breakpoints = [\r\n  {\r\n    name: \"mobile\",\r\n    columns: 1,\r\n    gap: \"1rem\",\r\n  },\r\n  {\r\n    name: \"desktop\",\r\n    minWidth: 1024,\r\n    columns: 2,\r\n    gap: \"2rem\",\r\n  },\r\n];\r\n</script>\r\n\r\n<template>\r\n  <FluxGrid :breakpoints=\"breakpoints\">\r\n    <!-- Each item can have different appearance per breakpoint -->\r\n    <FluxGridItem col-span=\"1\" row-span=\"1\">\r\n      <Header />\r\n    </FluxGridItem>\r\n  </FluxGrid>\r\n</template>\r\n```\r\n\r\n### Masonry-like layout\r\n\r\nUse `column-dense` auto-flow to pack items tightly:\r\n\r\n```vue\r\n<FluxGrid\r\n  :columns=\"{ type: 'auto-fit', min: '200px', max: '1fr' }\"\r\n  :gap=\"16\"\r\n  auto-flow=\"column dense\"\r\n>\r\n  <!-- Items fill rows left-to-right, then columns top-to-bottom -->\r\n</FluxGrid>\r\n```\r\n\r\n### Building custom card components with FluxCard\r\n\r\nThe ideal pattern: Create domain-specific components that wrap `FluxCard` internally. The card handles all layout concerns, your component provides content.\r\n\r\n**PingCard.vue (example custom component):**\r\n\r\n```vue\r\n<script setup lang=\"ts\">\r\nimport FluxCard from \"flux-grid\";\r\n\r\nexport interface PingCardProps {\r\n  name: string;\r\n  email: string;\r\n  status?: \"online\" | \"away\" | \"offline\";\r\n}\r\n\r\ndefineProps<PingCardProps>();\r\n</script>\r\n\r\n<template>\r\n  <FluxCard padding=\"1rem\">\r\n    <template #header>\r\n      <h4 style=\"margin: 0; font-size: 0.95rem;\">{{ name }}</h4>\r\n    </template>\r\n    <div>\r\n      <p style=\"margin: 0; font-size: 0.85rem; color: var(--flux-text-muted);\">\r\n        {{ email }}\r\n      </p>\r\n      <div\r\n        style=\"margin-top: 0.5rem; font-size: 0.8rem; color: var(--flux-text-muted);\"\r\n      >\r\n        {{ status }}\r\n      </div>\r\n    </div>\r\n  </FluxCard>\r\n</template>\r\n```\r\n\r\n**Usage in grid:**\r\n\r\n```vue\r\n<script setup lang=\"ts\">\r\nimport { FluxGrid, FluxGridItem } from \"flux-grid\";\r\nimport PingCard from \"@/components/PingCard.vue\";\r\n\r\nconst users = [\r\n  { name: \"Alice\", email: \"alice@company.com\", status: \"online\" },\r\n  { name: \"Bob\", email: \"bob@company.com\", status: \"away\" },\r\n];\r\n</script>\r\n\r\n<template>\r\n  <FluxGrid :columns=\"{ type: 'auto-fit', min: '280px', max: '1fr' }\" :gap=\"20\">\r\n    <FluxGridItem v-for=\"user in users\" :key=\"user.name\">\r\n      <PingCard :name=\"user.name\" :email=\"user.email\" :status=\"user.status\" />\r\n    </FluxGridItem>\r\n  </FluxGrid>\r\n</template>\r\n```\r\n\r\n**Benefits of this pattern:**\r\n\r\n- ✅ FluxCard handles height, overflow, padding, and slot structure\r\n- ✅ Your component (PingCard) only worries about content and styling\r\n- ✅ Grid automatically sizes everything—no layout logic in custom components\r\n- ✅ Easy to create many domain-specific cards (UserCard, StatsCard, ChartCard, etc.)\r\n- ✅ Reusable across projects\r\n\r\n## Development\r\n\r\n- `bun dev` – run the playground showcasing both responsive and locked grids.\r\n- `bun build` – type-check via `vue-tsc` and emit the production bundle.\r\n- `bun preview` – inspect the built assets locally.\r\n\r\n## Roadmap\r\n\r\n- **Drag-and-drop helpers** – Vue 3 composables to easily reorder items using the existing `data-grid-*` attributes.\r\n- **Serialization utilities** – Save and restore grid layouts as JSON (useful for dashboards and dashboards).\r\n- **Storybook docs site** – Interactive examples and design system integration.\r\n- **Layout presets** – Pre-configured templates (dashboard, masonry, card grid, etc.).\r\n- **Container queries** – Enhanced responsive behavior with `@container` queries.\r\n- **Error boundaries** – Better console warnings for invalid slot content or prop misuse.\r\n\r\n## License\r\n\r\nMIT © [brendlij](https://github.com/brendlij)\r\n","readmeFilename":"README.md"}