UNPKG

3.44 kBJavaScriptView Raw
1import BaseComponent from 'bootstrap/js/src/base-component.js'
2
3import SelectorEngine from 'bootstrap/js/src/dom/selector-engine'
4import Manipulator from 'bootstrap/js/src/dom/manipulator'
5
6import MasonryPlugin from 'masonry-layout'
7
8const NAME = 'masonry'
9//const DATA_KEY = 'bs.masonry'
10//const EVENT_KEY = `.${DATA_KEY}`
11//const DATA_API_KEY = '.data-api'
12
13const CLASS_NAME_SHOW = 'show'
14const CLASS_NAME_LOADER = 'masonry-loader'
15
16const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="masonry"]'
17const SELECTOR_LOADER = `.${CLASS_NAME_LOADER}`
18
19const Default = {
20 percentPosition: true,
21}
22
23//const MASONRY_EXISTS = !!window.Masonry
24
25class Masonry extends BaseComponent {
26 constructor(element, config) {
27 /*if (!MASONRY_EXISTS) {
28 throw new Error("[Masonry] you can't instantiate Mesonry component without Masonry Library")
29 }*/
30
31 super(element)
32
33 this._config = this._getConfig(config)
34 this._masonry = null
35
36 this._images = SelectorEngine.find('img', this._element)
37 this._loadCounter = 0
38
39 this._init()
40 }
41
42 // Getters
43
44 static get NAME() {
45 return NAME
46 }
47
48 // Public
49 dispose() {
50 if (this._masonry) {
51 this._masonry.destroy()
52 this._masonry = null
53 }
54
55 super.dispose()
56 }
57
58 // Private
59 _getConfig(config) {
60 config = {
61 ...Default,
62 ...Manipulator.getDataAttributes(this._element),
63 ...(typeof config === 'object' ? config : {}),
64 }
65 return config
66 }
67
68 _init() {
69 if (this._images.length > 0) {
70 //this._showLoader()
71
72 this._images.forEach((img) => {
73 const imgDummy = new Image()
74 imgDummy.onload = () => this._onLoadEnd()
75 imgDummy.src = img.src
76 })
77 } else {
78 this._initMasonry()
79 }
80 }
81
82 _onLoadEnd() {
83 this._loadCounter++
84 if (this._loadCounter >= this._images.length) {
85 //this._hideLoader()
86 this._initMasonry()
87 }
88 }
89
90 _initMasonry() {
91 this._masonry = new MasonryPlugin(this._element, this._config)
92 }
93
94 _createLoader() {
95 const loader = document.createElement('div')
96 loader.classList.add(CLASS_NAME_LOADER, 'fade', 'd-flex', 'justify-content-center', 'align-items-center')
97 loader.innerHTML = '<div class="progress-spinner progress-spinner-active"><span class="visually-hidden">Caricamento...</span></div>'
98 this._element.appendChild(loader)
99 return loader
100 }
101 _getOrCreateLoader() {
102 const loader = SelectorEngine.findOne(SELECTOR_LOADER, this._element)
103 if (!loader) {
104 return this._createLoader()
105 }
106 return loader
107 }
108 _destroyLoader() {
109 const loader = SelectorEngine.findOne(SELECTOR_LOADER, this._element)
110 if (loader) {
111 loader.remove()
112 }
113 }
114 _showLoader() {
115 const loader = this._getOrCreateLoader()
116 loader.classList.add(CLASS_NAME_SHOW)
117 }
118 _hideLoader() {
119 this._destroyLoader()
120 }
121}
122
123/**
124 * ------------------------------------------------------------------------
125 * Data Api implementation
126 * ------------------------------------------------------------------------
127 */
128
129const masonries = SelectorEngine.find(SELECTOR_DATA_TOGGLE)
130if (masonries.length > 0) {
131 /*if (!MASONRY_EXISTS) {
132 console.warn('[Masonry] Masonry component needs Masonry library to work properly')
133 } else {
134 masonries.forEach((masonry) => {
135 Masonry.getOrCreateInstance(masonry)
136 })
137 }*/
138 masonries.forEach((masonry) => {
139 Masonry.getOrCreateInstance(masonry)
140 })
141}
142
143export default Masonry