material 0.5.2 → 0.6.1
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/package.json +3 -3
- package/src/control/link.js +10 -2
- package/src/control/textfield.js +2 -2
- package/src/form/controller.js +1 -1
- package/src/layout.js +4 -36
- package/src/list/build.js +2 -4
- package/src/list/filter.js +3 -3
- package/src/list/select.js +18 -0
- package/src/list/virtual.new.js +202 -0
- package/src/module/attach.js +0 -1
- package/src/module/passive.js +11 -6
- package/src/skin/material/container/dialog.sass +1 -13
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "material",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "A lightweight implementation of Material Design Components - ES6",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
|
-
"url": "git@gitlab.com
|
|
8
|
+
"url": "git+ssh://git@gitlab.com/alkaloid/material.git"
|
|
9
9
|
},
|
|
10
10
|
"author": "Jérôme Vial <jerome.vial@gmail.com>",
|
|
11
11
|
"license": "MIT",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
},
|
|
15
15
|
"homepage": "https://gitlab.com/alkaloid/material",
|
|
16
16
|
"keywords": [
|
|
17
|
-
"lightweight material design component es6
|
|
17
|
+
"lightweight material design ui component es6 vanilla javascript"
|
|
18
18
|
],
|
|
19
19
|
"devDependencies": {
|
|
20
20
|
"babel-core": "^6.26.0",
|
package/src/control/link.js
CHANGED
|
@@ -35,7 +35,7 @@ class Link {
|
|
|
35
35
|
this.set(this.options.link)
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
if (this.options.target) {
|
|
38
|
+
if (this.options.target !== 'blank') {
|
|
39
39
|
this.root.target = this.options.target
|
|
40
40
|
}
|
|
41
41
|
|
|
@@ -54,7 +54,15 @@ class Link {
|
|
|
54
54
|
// console.log('set', text)
|
|
55
55
|
if (link === undefined) return
|
|
56
56
|
|
|
57
|
-
this.
|
|
57
|
+
if (this.options.target === 'blank') {
|
|
58
|
+
this.root.href = '#'
|
|
59
|
+
this.root.addEventListener('click', () => {
|
|
60
|
+
window.open(link)
|
|
61
|
+
return false
|
|
62
|
+
})
|
|
63
|
+
} else {
|
|
64
|
+
this.root.href = link
|
|
65
|
+
}
|
|
58
66
|
}
|
|
59
67
|
}
|
|
60
68
|
|
package/src/control/textfield.js
CHANGED
|
@@ -93,7 +93,7 @@ class Text {
|
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
onInput (ev) {
|
|
96
|
-
console.log('onInput', this.value, this.input.value)
|
|
96
|
+
// console.log('onInput', this.value, this.input.value)
|
|
97
97
|
|
|
98
98
|
this.emit('change', ev)
|
|
99
99
|
}
|
|
@@ -109,7 +109,7 @@ class Text {
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
onClick (ev) {
|
|
112
|
-
console.log('click')
|
|
112
|
+
// console.log('click')
|
|
113
113
|
this.emit('click', ev)
|
|
114
114
|
}
|
|
115
115
|
|
package/src/form/controller.js
CHANGED
package/src/layout.js
CHANGED
|
@@ -1,33 +1,14 @@
|
|
|
1
|
-
|
|
2
1
|
import { is as isObject } from './module/object'
|
|
3
2
|
import css from './module/css'
|
|
4
3
|
|
|
5
|
-
/**
|
|
6
|
-
*
|
|
7
|
-
*/
|
|
8
4
|
class Layout {
|
|
9
|
-
/**
|
|
10
|
-
* [constructor description]
|
|
11
|
-
* @param {?} schema [description]
|
|
12
|
-
* @param {?} container [description]
|
|
13
|
-
* @return {?} [description]
|
|
14
|
-
*/
|
|
15
5
|
constructor (schema, container) {
|
|
16
6
|
this.components = []
|
|
17
7
|
this.component = this.create(schema, container)
|
|
18
8
|
|
|
19
|
-
// console.log('this', this)
|
|
20
|
-
|
|
21
9
|
return this
|
|
22
10
|
}
|
|
23
11
|
|
|
24
|
-
/**
|
|
25
|
-
* [create description]
|
|
26
|
-
* @param {?} schema [description]
|
|
27
|
-
* @param {?} container [description]
|
|
28
|
-
* @param {?} structure [description]
|
|
29
|
-
* @return {?} [description]
|
|
30
|
-
*/
|
|
31
12
|
create (schema, container, structure, level) {
|
|
32
13
|
level = level || 0
|
|
33
14
|
level++
|
|
@@ -79,6 +60,10 @@ class Layout {
|
|
|
79
60
|
var wrapper = container.root || container
|
|
80
61
|
|
|
81
62
|
wrapper.appendChild(element)
|
|
63
|
+
|
|
64
|
+
if (component.onInserted) {
|
|
65
|
+
component.onInserted(wrapper)
|
|
66
|
+
}
|
|
82
67
|
}
|
|
83
68
|
component._container = container
|
|
84
69
|
}
|
|
@@ -94,11 +79,6 @@ class Layout {
|
|
|
94
79
|
return structure
|
|
95
80
|
}
|
|
96
81
|
|
|
97
|
-
/**
|
|
98
|
-
* [_initFlexDirection description]
|
|
99
|
-
* @param {Element} container Init direction for the given container
|
|
100
|
-
* @param {string} direction (horizontal,vertical)
|
|
101
|
-
*/
|
|
102
82
|
display (element, options) {
|
|
103
83
|
var display = options.display
|
|
104
84
|
var direction = options.direction || 'horizontal'
|
|
@@ -112,11 +92,6 @@ class Layout {
|
|
|
112
92
|
}
|
|
113
93
|
}
|
|
114
94
|
|
|
115
|
-
/**
|
|
116
|
-
* [style description]
|
|
117
|
-
* @param {?} component [description]
|
|
118
|
-
* @return {?} [description]
|
|
119
|
-
*/
|
|
120
95
|
style (component) {
|
|
121
96
|
var options = component.options || {}
|
|
122
97
|
|
|
@@ -166,16 +141,9 @@ class Layout {
|
|
|
166
141
|
}
|
|
167
142
|
}
|
|
168
143
|
|
|
169
|
-
// console.log('--- field', field)
|
|
170
|
-
|
|
171
144
|
return field
|
|
172
145
|
}
|
|
173
146
|
|
|
174
|
-
/**
|
|
175
|
-
* [get description]
|
|
176
|
-
* @param {?} name [description]
|
|
177
|
-
* @return {?} [description]
|
|
178
|
-
*/
|
|
179
147
|
get (name) {
|
|
180
148
|
if (name) return this.component[name]
|
|
181
149
|
else return this.component
|
package/src/list/build.js
CHANGED
|
@@ -79,10 +79,7 @@ export default {
|
|
|
79
79
|
// console.log('render', this.data[i])
|
|
80
80
|
return this.renderItem(this.data[i])
|
|
81
81
|
}
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
// console.log('dynamic')
|
|
85
|
-
this.virtual.on('next', (total) => {
|
|
82
|
+
}).on('next', (total) => {
|
|
86
83
|
// console.log('next', total)
|
|
87
84
|
if (this.stop) return
|
|
88
85
|
|
|
@@ -113,6 +110,7 @@ export default {
|
|
|
113
110
|
// console.log('!!!!size', size)
|
|
114
111
|
// this.size = size
|
|
115
112
|
// })
|
|
113
|
+
//
|
|
116
114
|
},
|
|
117
115
|
|
|
118
116
|
onProgress (value) {
|
package/src/list/filter.js
CHANGED
|
@@ -21,12 +21,12 @@ export default {
|
|
|
21
21
|
},
|
|
22
22
|
|
|
23
23
|
getFilter () {
|
|
24
|
-
|
|
24
|
+
console.log('getFilter')
|
|
25
25
|
var filter = null
|
|
26
26
|
for (var name in this.filter) {
|
|
27
27
|
if (this.filter.hasOwnProperty(name)) {
|
|
28
|
-
|
|
29
|
-
if (this.filter[name].get() !== '' && this.filter[name].get() !== []) {
|
|
28
|
+
console.log('--', typeof this.filter[name].get(), this.filter[name].get())
|
|
29
|
+
if (this.filter[name].get() !== ''/* && this.filter[name].get() !== [] */) {
|
|
30
30
|
if (filter) {
|
|
31
31
|
filter = filter + '&' + name + '=' + this.filter[name].get()
|
|
32
32
|
} else {
|
package/src/list/select.js
CHANGED
|
@@ -41,6 +41,14 @@ export default {
|
|
|
41
41
|
this.item = null
|
|
42
42
|
},
|
|
43
43
|
|
|
44
|
+
getInfoById (id) {
|
|
45
|
+
return this.dataStore[id]
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
getSelectedInfo () {
|
|
49
|
+
return this.dataStore[this.id]
|
|
50
|
+
},
|
|
51
|
+
|
|
44
52
|
getItemById (id, silent) {
|
|
45
53
|
// console.log('selectItemById', id)
|
|
46
54
|
var item = this.ui.body.querySelector('[data-id="' + id + '"]')
|
|
@@ -102,6 +110,7 @@ export default {
|
|
|
102
110
|
item.classList.add('selected')
|
|
103
111
|
|
|
104
112
|
if (this.options.updatePosition === true) {
|
|
113
|
+
// console.log('selectPosition', item)
|
|
105
114
|
this.selectPosition(item, direction)
|
|
106
115
|
}
|
|
107
116
|
|
|
@@ -181,6 +190,15 @@ export default {
|
|
|
181
190
|
}
|
|
182
191
|
},
|
|
183
192
|
|
|
193
|
+
scrollIntoView (item) {
|
|
194
|
+
// console.log('selectPrevious', this.id)
|
|
195
|
+
item = item || this.item
|
|
196
|
+
|
|
197
|
+
if (item) {
|
|
198
|
+
item.scrollIntoView({ behavior: 'instant', block: 'end', inline: 'nearest' })
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
|
|
184
202
|
highlight (item) {
|
|
185
203
|
if (this.item) {
|
|
186
204
|
this.item.classList.remove('selected')
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
// based on https://sergimansilla.com/blog/virtual-scrolling/
|
|
2
|
+
|
|
3
|
+
// Import necessary modules
|
|
4
|
+
import passiveEvents from '../module/passive' // Import the passiveEvents utility.
|
|
5
|
+
import emitter from '../module/emitter' // Import the emitter module.
|
|
6
|
+
|
|
7
|
+
// Define the VirtualList class
|
|
8
|
+
class VirtualList {
|
|
9
|
+
constructor (options) {
|
|
10
|
+
// Initialize the class with options passed to the constructor.
|
|
11
|
+
this.options = { ...(options || {}) } // Spread operator to merge options with default values.
|
|
12
|
+
Object.assign(this, emitter) // Assign emitter methods to the instance.
|
|
13
|
+
|
|
14
|
+
// Destructure options for easier access to properties.
|
|
15
|
+
const { itemHeight = 0, size = 0, items = [], render, container } = options
|
|
16
|
+
|
|
17
|
+
// Initialize instance variables with default or provided values.
|
|
18
|
+
this.itemHeight = itemHeight
|
|
19
|
+
this.next = false
|
|
20
|
+
this.size = size
|
|
21
|
+
this.chunkSize = size
|
|
22
|
+
this.items = items
|
|
23
|
+
this.render = render
|
|
24
|
+
this.scroller = VirtualList.createScroller()
|
|
25
|
+
this.container = container
|
|
26
|
+
|
|
27
|
+
// Get the offset height of the container.
|
|
28
|
+
this.setOffset()
|
|
29
|
+
|
|
30
|
+
// Add a window resize event listener to update the offset height.
|
|
31
|
+
window.addEventListener('resize', () => {
|
|
32
|
+
clearTimeout(this.resizeTimeout)
|
|
33
|
+
|
|
34
|
+
this.resizeTimeout = setTimeout(() => {
|
|
35
|
+
this.setOffset()
|
|
36
|
+
}, 50)
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
// Add 'virtual' class to the container element.
|
|
40
|
+
this.container.classList.add('virtual')
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Method to render a chunk of items within the visible range.
|
|
44
|
+
renderChunk (node, from, number) {
|
|
45
|
+
const fragment = document.createDocumentFragment()
|
|
46
|
+
fragment.appendChild(this.scroller)
|
|
47
|
+
|
|
48
|
+
let last = from + number
|
|
49
|
+
if (last > this.count) last = this.count
|
|
50
|
+
|
|
51
|
+
for (let i = from; i < last; i++) {
|
|
52
|
+
const item = this.render(i)
|
|
53
|
+
|
|
54
|
+
// Position the item absolutely based on its index and item height.
|
|
55
|
+
item.style.position = 'absolute'
|
|
56
|
+
item.style.top = i * this.itemHeight + 'px'
|
|
57
|
+
fragment.appendChild(item)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
node.innerHTML = ''
|
|
61
|
+
node.appendChild(fragment)
|
|
62
|
+
|
|
63
|
+
// Emit 'next' event if applicable.
|
|
64
|
+
console.log('last', last)
|
|
65
|
+
console.log('count', this.count)
|
|
66
|
+
console.log('next', this.next)
|
|
67
|
+
console.log('size', this.size)
|
|
68
|
+
|
|
69
|
+
if (this.next && last && last > (this.count - this.size / 2)) {
|
|
70
|
+
this.emit('next', this.count)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
this.next = true
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Method to set the items and render the initial chunk.
|
|
77
|
+
set (items) {
|
|
78
|
+
this.next = false
|
|
79
|
+
this.items = items
|
|
80
|
+
this.count = items.length
|
|
81
|
+
|
|
82
|
+
if (this.count < 1 || this.count === undefined) return
|
|
83
|
+
|
|
84
|
+
this.container.innerHTML = ''
|
|
85
|
+
this.container.scrollTop = 0
|
|
86
|
+
|
|
87
|
+
const height = this.itemHeight * this.count
|
|
88
|
+
|
|
89
|
+
this.scroller.style.height = height + 'px'
|
|
90
|
+
|
|
91
|
+
this.itemsByScreen = Math.ceil(this.offsetHeight / this.itemHeight)
|
|
92
|
+
|
|
93
|
+
let size = this.itemsByScreen * 4
|
|
94
|
+
this.renderChunk(this.container, 0, size)
|
|
95
|
+
|
|
96
|
+
this.size = size
|
|
97
|
+
|
|
98
|
+
this.emit('size', size)
|
|
99
|
+
|
|
100
|
+
let lastRepaintY
|
|
101
|
+
const maxBuffer = this.itemsByScreen * this.itemHeight
|
|
102
|
+
|
|
103
|
+
// Add a scroll event listener to render items dynamically.
|
|
104
|
+
const onScroll = (e) => {
|
|
105
|
+
const scrollTop = e.target.scrollTop
|
|
106
|
+
let first = parseInt(scrollTop / this.itemHeight) - this.itemsByScreen
|
|
107
|
+
|
|
108
|
+
size = this.itemsByScreen * 4
|
|
109
|
+
|
|
110
|
+
if (!lastRepaintY || Math.abs(scrollTop - lastRepaintY) > maxBuffer) {
|
|
111
|
+
this.renderChunk(this.container, first, size)
|
|
112
|
+
lastRepaintY = scrollTop
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const progress = Math.ceil((scrollTop / this.itemHeight) + this.itemsByScreen) - 1
|
|
116
|
+
this.emit('progress', progress)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (!this.scrollEvents) {
|
|
120
|
+
// Add scroll event listener with passive option if supported.
|
|
121
|
+
this.container.addEventListener(
|
|
122
|
+
'scroll',
|
|
123
|
+
onScroll,
|
|
124
|
+
passiveEvents() ? { passive: true } : false
|
|
125
|
+
)
|
|
126
|
+
this.scrollEvents = true
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Method to update the items and re-render the visible chunk.
|
|
131
|
+
update (items) {
|
|
132
|
+
this.items = items || this.items
|
|
133
|
+
|
|
134
|
+
if (!this.items) return
|
|
135
|
+
|
|
136
|
+
this.count = this.items.length
|
|
137
|
+
const cachedItemsLen = this.itemsByScreen * 4
|
|
138
|
+
const scrollTop = this.container.scrollTop
|
|
139
|
+
const height = this.itemHeight * this.count
|
|
140
|
+
|
|
141
|
+
this.scroller.style.height = height + 'px'
|
|
142
|
+
|
|
143
|
+
let first = parseInt(scrollTop / this.itemHeight) - this.itemsByScreen
|
|
144
|
+
first = first < 0 ? 0 : first
|
|
145
|
+
|
|
146
|
+
this.renderChunk(this.container, first, cachedItemsLen)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Method to add items and update the container height.
|
|
150
|
+
add (items) {
|
|
151
|
+
this.items = items || this.items
|
|
152
|
+
|
|
153
|
+
if (!this.items) return
|
|
154
|
+
|
|
155
|
+
this.count = this.items.length
|
|
156
|
+
const height = this.itemHeight * this.count
|
|
157
|
+
|
|
158
|
+
this.scroller.style.height = height + 'px'
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Method to reset the items and container to an initial state.
|
|
162
|
+
reset () {
|
|
163
|
+
this.items = []
|
|
164
|
+
this.count = 0
|
|
165
|
+
|
|
166
|
+
this.container.scrollTop = 0
|
|
167
|
+
|
|
168
|
+
this.scroller.style.height = '0'
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Method to set the offset height of the container.
|
|
172
|
+
setOffset (info) {
|
|
173
|
+
this.offsetHeight = this.container.offsetHeight
|
|
174
|
+
if (this.offsetHeight < 1) {
|
|
175
|
+
this.offsetHeight = window.innerHeight ||
|
|
176
|
+
document.documentElement.clientHeight ||
|
|
177
|
+
document.body.clientHeight
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
this.itemsByScreen = Math.ceil(this.offsetHeight / this.itemHeight)
|
|
181
|
+
|
|
182
|
+
const itemsByScreen = Math.ceil(this.offsetHeight / this.itemHeight)
|
|
183
|
+
const size = itemsByScreen * 4
|
|
184
|
+
|
|
185
|
+
return size
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Method to get the total count of items.
|
|
189
|
+
getCount () {
|
|
190
|
+
return this.count
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Static method to create a scroller element.
|
|
194
|
+
static createScroller () {
|
|
195
|
+
const scroller = document.createElement('div')
|
|
196
|
+
scroller.classList.add('scroller')
|
|
197
|
+
return scroller
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Export the VirtualList class as the default export.
|
|
202
|
+
export default VirtualList
|
package/src/module/attach.js
CHANGED
package/src/module/passive.js
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
|
+
function passiveEvents () {
|
|
2
|
+
let supportsPassive = false
|
|
1
3
|
|
|
2
|
-
function passive () {
|
|
3
|
-
var supportsPassive = false
|
|
4
4
|
try {
|
|
5
|
-
|
|
6
|
-
get
|
|
5
|
+
const opts = Object.defineProperty({}, 'passive', {
|
|
6
|
+
get () {
|
|
7
7
|
supportsPassive = true
|
|
8
8
|
}
|
|
9
9
|
})
|
|
10
|
+
|
|
11
|
+
// Test if the browser supports passive event listeners
|
|
10
12
|
window.addEventListener('testPassive', null, opts)
|
|
11
13
|
window.removeEventListener('testPassive', null, opts)
|
|
12
|
-
} catch (e) {
|
|
14
|
+
} catch (e) {
|
|
15
|
+
// If there was an error, it's safe to assume that passive event listeners are not supported
|
|
16
|
+
supportsPassive = false
|
|
17
|
+
}
|
|
13
18
|
|
|
14
19
|
return supportsPassive
|
|
15
20
|
}
|
|
16
21
|
|
|
17
|
-
export default
|
|
22
|
+
export default passiveEvents
|
|
@@ -43,18 +43,6 @@
|
|
|
43
43
|
box-shadow: 0px 11px 15px -7px rgba(0, 0, 0, 0.2), 0px 24px 38px 3px rgba(0, 0, 0, 0.14), 0px 9px 46px 8px rgba(0, 0, 0, 0.12)
|
|
44
44
|
transform: translateY(150px) scale(0.8)
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
46
|
.material-dialog
|
|
59
47
|
position: fixed
|
|
60
48
|
top: 0
|
|
@@ -143,7 +131,7 @@
|
|
|
143
131
|
// justify-content: flex-end;
|
|
144
132
|
padding: 8px
|
|
145
133
|
|
|
146
|
-
.material-
|
|
134
|
+
.material-button
|
|
147
135
|
margin: 0 0 0 8px
|
|
148
136
|
|
|
149
137
|
&.dialog-show
|