vuetify-masonry 0.2.4 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,47 +1,85 @@
1
1
  # vuetify-masonry
2
2
 
3
- A small Vue 3 component providing a simple masonry grid compatible with Vuetify 3's layout primitives.
3
+ Lightweight Vue 3 component that provides a responsive masonry-style grid built on Vuetify 3 layout primitives (`VRow`, `VCol`). Use it to render lists of variable-height items in evenly balanced columns.
4
4
 
5
- ## Install
5
+ ## Installation
6
6
 
7
- As a published package:
7
+ Install the package and ensure peer dependencies are present:
8
8
 
9
+ ```bash
9
10
  npm install vuetify-masonry
11
+ # or
12
+ # yarn add vuetify-masonry
13
+ ```
10
14
 
11
- Peer dependencies: `vue` and `vuetify` (install those in your app).
15
+ Peer dependencies: Vue 3 and Vuetify 3 (see `package.json`).
12
16
 
13
17
  ## Usage
14
18
 
15
- Global install:
16
-
17
- import { createApp } from 'vue'
18
- import App from './App.vue'
19
- import { createVuetify } from 'vuetify'
20
- import VuetifyMasonry from 'vuetify-masonry'
21
-
22
- const app = createApp(App)
23
- app.use(createVuetify())
24
- app.use(VuetifyMasonry)
25
- app.mount('#app')
19
+ Import the component locally when you need it:
26
20
 
27
- Or local import:
28
-
29
- import { MasonryGrid } from 'vuetify-masonry'
21
+ ```js
22
+ import { VMasonry } from 'vuetify-masonry'
23
+ ```
30
24
 
31
- export default { components: { MasonryGrid } }
25
+ ## Props
26
+
27
+ - `items` (Array<T>, default `[]`): the list of items to render into the masonry columns.
28
+ - `col` (1 | 2 | 3 | 4 | 6 | 12 or string): default number of columns fallback.
29
+ - `xs`, `sm`, `md`, `lg`, `xl`, `xxl` (same as `col`): responsive column count overrides for each breakpoint.
30
+
31
+ The component uses Vuetify's `useDisplay` breakpoints to pick the appropriate column count.
32
+
33
+ ## Slot API
34
+
35
+ Provide a named slot `item` to render each item. The slot receives these props:
36
+
37
+ - `item`: the item value from the `items` array
38
+ - `index`: the index of the item within its column
39
+ - `columnIndex`: the index of the column the item was placed into
40
+
41
+ Example:
42
+
43
+ ```vue
44
+ <template>
45
+ <v-masonry :items="cards" col="3">
46
+ <template #item="{ item }">
47
+ <v-card>
48
+ <v-card-title>{{ item.title }}</v-card-title>
49
+ <v-card-text>{{ item.description }}</v-card-text>
50
+ </v-card>
51
+ </template>
52
+ </v-masonry>
53
+ </template>
54
+
55
+ <script setup>
56
+ const cards = [
57
+ { title: 'One', description: 'Short' },
58
+ {
59
+ title: 'Two',
60
+ description: 'Longer content to demonstrate varying heights',
61
+ },
62
+ // ...
63
+ ]
64
+ </script>
65
+ ```
32
66
 
33
- ### Slot API
67
+ ## Notes
34
68
 
35
- Use the `item` named slot and read `item`, `index`, `columnIndex` from slot props.
69
+ - The component implementation lives in `src/components/VMasonry.vue` and relies on Vuetify's `VRow` and `VCol` for layout.
70
+ - Column distribution places items round-robin into columns: `columns[index % nbColumns]`.
71
+ - This package targets Vue 3 + Vuetify 3 (see `peerDependencies` in `package.json`).
36
72
 
37
- ## Build
73
+ ## Development
38
74
 
39
- Install dev dependencies and build:
75
+ Run the dev server or build for publishing:
40
76
 
41
77
  ```bash
42
- cd vuetify-masonry
43
78
  npm install
44
- npm run build
79
+ npm run dev # start example / dev server
80
+ npm run build # produce files in dist/
45
81
  ```
46
82
 
47
- The build outputs `dist` suitable for publishing to npm.
83
+ ## License
84
+
85
+ MIT
@@ -1,7 +1,7 @@
1
- import { defineComponent as b, computed as f, createBlock as p, openBlock as n, unref as c, withCtx as i, createVNode as h, createElementBlock as d, Fragment as x, renderList as v, normalizeClass as B, renderSlot as M, createTextVNode as N } from "vue";
1
+ import { defineComponent as B, computed as c, createBlock as d, openBlock as o, unref as f, withCtx as p, createElementBlock as i, Fragment as x, renderList as v, normalizeClass as E, renderSlot as M, createTextVNode as g, createElementVNode as N } from "vue";
2
2
  import { useDisplay as w } from "vuetify";
3
- import { VContainer as E, VRow as z, VCol as D } from "vuetify/components";
4
- const g = /* @__PURE__ */ b({
3
+ import { VRow as _, VCol as z } from "vuetify/components";
4
+ const y = /* @__PURE__ */ B({
5
5
  __name: "VMasonry",
6
6
  props: {
7
7
  col: {},
@@ -15,24 +15,24 @@ const g = /* @__PURE__ */ b({
15
15
  },
16
16
  setup(u) {
17
17
  const e = u, {
18
- xs: y,
19
- smAndUp: V,
20
- mdAndUp: A,
21
- lgAndUp: C,
18
+ xs: b,
19
+ smAndUp: A,
20
+ mdAndUp: V,
21
+ lgAndUp: k,
22
22
  xlAndUp: U,
23
- xxl: _
24
- } = w(), a = f(() => {
25
- const t = (l) => {
26
- if (l !== void 0)
27
- return typeof l == "string" ? Number(l) : l;
28
- }, r = (...l) => {
29
- for (const o of l) {
30
- const s = t(o);
23
+ xxl: h
24
+ } = w(), a = c(() => {
25
+ const l = (t) => {
26
+ if (t !== void 0)
27
+ return typeof t == "string" ? Number(t) : t;
28
+ }, r = (...t) => {
29
+ for (const n of t) {
30
+ const s = l(n);
31
31
  if (s !== void 0) return s;
32
32
  }
33
33
  return 1;
34
34
  };
35
- return _.value ? r(
35
+ return h.value ? r(
36
36
  e.xxl,
37
37
  e.xl,
38
38
  e.lg,
@@ -40,51 +40,52 @@ const g = /* @__PURE__ */ b({
40
40
  e.sm,
41
41
  e.xs,
42
42
  e.col
43
- ) : U.value ? r(e.xl, e.lg, e.md, e.sm, e.xs, e.col) : C.value ? r(e.lg, e.md, e.sm, e.xs, e.col) : A.value ? r(e.md, e.sm, e.xs, e.col) : V.value ? r(e.sm, e.xs, e.col) : y.value ? r(e.xs, e.col) : r(e.col);
44
- }), k = f(() => {
45
- const t = Array.from({ length: a.value }, () => []);
46
- return e.items.forEach((r, l) => {
47
- t[l % a.value].push(r);
48
- }), t;
43
+ ) : U.value ? r(e.xl, e.lg, e.md, e.sm, e.xs, e.col) : k.value ? r(e.lg, e.md, e.sm, e.xs, e.col) : V.value ? r(e.md, e.sm, e.xs, e.col) : A.value ? r(e.sm, e.xs, e.col) : b.value ? r(e.xs, e.col) : r(e.col);
44
+ }), C = c(() => {
45
+ const l = Array.from({ length: a.value }, () => []);
46
+ return e.items.forEach((r, t) => {
47
+ l[t % a.value].push(r);
48
+ }), l;
49
49
  });
50
- return (t, r) => (n(), p(c(E), { class: "pt-6" }, {
51
- default: i(() => [
52
- h(c(z), null, {
53
- default: i(() => [
54
- (n(!0), d(x, null, v(k.value, (l, o) => (n(), p(c(D), {
55
- key: o,
56
- cols: 12 / a.value
57
- }, {
58
- default: i(() => [
59
- (n(!0), d(x, null, v(l, (s, m) => (n(), d("div", {
60
- key: m,
61
- class: B({ "mb-6": m !== l.length - 1 })
62
- }, [
63
- M(t.$slots, "item", {
64
- item: s,
65
- index: m,
66
- columnIndex: o
67
- }, () => [
68
- r[0] || (r[0] = N(' Please define a slot named "item" to render items ', -1))
69
- ])
70
- ], 2))), 128))
71
- ]),
72
- _: 2
73
- }, 1032, ["cols"]))), 128))
50
+ return (l, r) => (o(), d(f(_), null, {
51
+ default: p(() => [
52
+ (o(!0), i(x, null, v(C.value, (t, n) => (o(), d(f(z), {
53
+ key: n,
54
+ cols: 12 / a.value
55
+ }, {
56
+ default: p(() => [
57
+ (o(!0), i(x, null, v(t, (s, m) => (o(), i("div", {
58
+ key: m,
59
+ class: E({ "mb-6": m !== t.length - 1 })
60
+ }, [
61
+ M(l.$slots, "item", {
62
+ item: s,
63
+ index: m,
64
+ columnIndex: n
65
+ }, () => [
66
+ r[0] || (r[0] = g(" Please provide an item slot – see the ", -1)),
67
+ r[1] || (r[1] = N("a", {
68
+ href: "https://github.com/senerh/vuetify-masonry?tab=readme-ov-file#slot-api",
69
+ target: "_blank",
70
+ rel: "noopener"
71
+ }, "documentation", -1)),
72
+ r[2] || (r[2] = g(". ", -1))
73
+ ])
74
+ ], 2))), 128))
74
75
  ]),
75
- _: 3
76
- })
76
+ _: 2
77
+ }, 1032, ["cols"]))), 128))
77
78
  ]),
78
79
  _: 3
79
80
  }));
80
81
  }
81
- }), R = {
82
- ...g,
82
+ }), P = {
83
+ ...y,
83
84
  install(u) {
84
- u.component("VMasonry", g);
85
+ u.component("VMasonry", y);
85
86
  }
86
87
  };
87
88
  export {
88
- g as VMasonry,
89
- R as default
89
+ y as VMasonry,
90
+ P as default
90
91
  };
@@ -1 +1 @@
1
- (function(o,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue"),require("vuetify"),require("vuetify/components")):typeof define=="function"&&define.amd?define(["exports","vue","vuetify","vuetify/components"],e):(o=typeof globalThis<"u"?globalThis:o||self,e(o.VuetifyMasonry={},o.Vue,o.Vuetify,o.Vuetify))})(this,(function(o,e,m,c){"use strict";const u=e.defineComponent({__name:"VMasonry",props:{col:{},items:{default:()=>[]},xs:{},sm:{},md:{},lg:{},xl:{},xxl:{}},setup(d){const t=d,{xs:x,smAndUp:y,mdAndUp:k,lgAndUp:V,xlAndUp:B,xxl:g}=m.useDisplay(),f=e.computed(()=>{const l=r=>{if(r!==void 0)return typeof r=="string"?Number(r):r},n=(...r)=>{for(const s of r){const i=l(s);if(i!==void 0)return i}return 1};return g.value?n(t.xxl,t.xl,t.lg,t.md,t.sm,t.xs,t.col):B.value?n(t.xl,t.lg,t.md,t.sm,t.xs,t.col):V.value?n(t.lg,t.md,t.sm,t.xs,t.col):k.value?n(t.md,t.sm,t.xs,t.col):y.value?n(t.sm,t.xs,t.col):x.value?n(t.xs,t.col):n(t.col)}),h=e.computed(()=>{const l=Array.from({length:f.value},()=>[]);return t.items.forEach((n,r)=>{l[r%f.value].push(n)}),l});return(l,n)=>(e.openBlock(),e.createBlock(e.unref(c.VContainer),{class:"pt-6"},{default:e.withCtx(()=>[e.createVNode(e.unref(c.VRow),null,{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(h.value,(r,s)=>(e.openBlock(),e.createBlock(e.unref(c.VCol),{key:s,cols:12/f.value},{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(r,(i,a)=>(e.openBlock(),e.createElementBlock("div",{key:a,class:e.normalizeClass({"mb-6":a!==r.length-1})},[e.renderSlot(l.$slots,"item",{item:i,index:a,columnIndex:s},()=>[n[0]||(n[0]=e.createTextVNode(' Please define a slot named "item" to render items ',-1))])],2))),128))]),_:2},1032,["cols"]))),128))]),_:3})]),_:3}))}}),p={...u,install(d){d.component("VMasonry",u)}};o.VMasonry=u,o.default=p,Object.defineProperties(o,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
1
+ (function(r,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue"),require("vuetify"),require("vuetify/components")):typeof define=="function"&&define.amd?define(["exports","vue","vuetify","vuetify/components"],e):(r=typeof globalThis<"u"?globalThis:r||self,e(r.VuetifyMasonry={},r.Vue,r.Vuetify,r.Vuetify))})(this,(function(r,e,m,f){"use strict";const u=e.defineComponent({__name:"VMasonry",props:{col:{},items:{default:()=>[]},xs:{},sm:{},md:{},lg:{},xl:{},xxl:{}},setup(c){const t=c,{xs:x,smAndUp:y,mdAndUp:k,lgAndUp:V,xlAndUp:g,xxl:B}=m.useDisplay(),a=e.computed(()=>{const l=o=>{if(o!==void 0)return typeof o=="string"?Number(o):o},n=(...o)=>{for(const s of o){const i=l(s);if(i!==void 0)return i}return 1};return B.value?n(t.xxl,t.xl,t.lg,t.md,t.sm,t.xs,t.col):g.value?n(t.xl,t.lg,t.md,t.sm,t.xs,t.col):V.value?n(t.lg,t.md,t.sm,t.xs,t.col):k.value?n(t.md,t.sm,t.xs,t.col):y.value?n(t.sm,t.xs,t.col):x.value?n(t.xs,t.col):n(t.col)}),h=e.computed(()=>{const l=Array.from({length:a.value},()=>[]);return t.items.forEach((n,o)=>{l[o%a.value].push(n)}),l});return(l,n)=>(e.openBlock(),e.createBlock(e.unref(f.VRow),null,{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(h.value,(o,s)=>(e.openBlock(),e.createBlock(e.unref(f.VCol),{key:s,cols:12/a.value},{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(o,(i,d)=>(e.openBlock(),e.createElementBlock("div",{key:d,class:e.normalizeClass({"mb-6":d!==o.length-1})},[e.renderSlot(l.$slots,"item",{item:i,index:d,columnIndex:s},()=>[n[0]||(n[0]=e.createTextVNode(" Please provide an item slot see the ",-1)),n[1]||(n[1]=e.createElementVNode("a",{href:"https://github.com/senerh/vuetify-masonry?tab=readme-ov-file#slot-api",target:"_blank",rel:"noopener"},"documentation",-1)),n[2]||(n[2]=e.createTextVNode(". ",-1))])],2))),128))]),_:2},1032,["cols"]))),128))]),_:3}))}}),p={...u,install(c){c.component("VMasonry",u)}};r.VMasonry=u,r.default=p,Object.defineProperties(r,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vuetify-masonry",
3
- "version": "0.2.4",
3
+ "version": "0.3.0",
4
4
  "description": "A simple Vuetify-compatible masonry grid Vue 3 component",
5
5
  "main": "dist/vuetify-masonry.umd.js",
6
6
  "module": "dist/vuetify-masonry.mjs",
@@ -24,7 +24,8 @@
24
24
  "dev": "vite",
25
25
  "prepublishOnly": "npm run build",
26
26
  "build": "vite build",
27
- "lint": "eslint . --ext .ts,.vue",
27
+ "lint": "eslint . --fix",
28
+ "format": "prettier --write src/",
28
29
  "release": "semantic-release"
29
30
  },
30
31
  "peerDependencies": {
@@ -34,9 +35,12 @@
34
35
  "devDependencies": {
35
36
  "@vitejs/plugin-vue": "^6.0.3",
36
37
  "typescript": "^5.0.0",
38
+ "eslint": "^9.13.0",
39
+ "eslint-plugin-vue": "^9.29.0",
37
40
  "vite": "^7.3.0",
38
41
  "vite-plugin-dts": "^4.5.4",
39
42
  "vue": "^3.2.0",
40
- "vuetify": "^3.0.0"
43
+ "vuetify": "^3.0.0",
44
+ "prettier": "^3.3.3"
41
45
  }
42
46
  }