material 0.5.3 → 0.6.2

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 CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "material",
3
- "version": "0.5.3",
3
+ "version": "0.6.2",
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:alkaloid/material.git"
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 es2015 vanilla javascript"
17
+ "lightweight material design ui component es6 vanilla javascript"
18
18
  ],
19
19
  "devDependencies": {
20
20
  "babel-core": "^6.26.0",
@@ -0,0 +1,23 @@
1
+ class EventEmitter {
2
+ constructor () {
3
+ this.events = {}
4
+ }
5
+
6
+ on (event, listener) {
7
+ if (!this.events[event]) {
8
+ this.events[event] = []
9
+ }
10
+ this.events[event].push(listener)
11
+
12
+ return this
13
+ }
14
+
15
+ emit (event, ...args) {
16
+ if (this.events[event]) {
17
+ this.events[event].forEach(listener => listener.apply(this, args))
18
+ }
19
+ return this
20
+ }
21
+ }
22
+
23
+ export default EventEmitter
@@ -56,6 +56,10 @@ class Button {
56
56
  build () {
57
57
  this.root = document.createElement(this.options.tag)
58
58
 
59
+ this.element = this.root
60
+
61
+ // console.log('class', this.options.class)
62
+
59
63
  if (this.options.class !== 'button') {
60
64
  this.root.setAttribute('class', 'button ' + this.options.class)
61
65
  } else {
@@ -1,5 +1,3 @@
1
- 'use strict'
2
-
3
1
  // dialog related modules
4
2
  import emitter from '../module/emitter'
5
3
  import attach from '../module/attach'
@@ -27,7 +25,7 @@ let defaults = {
27
25
  ]
28
26
  ],
29
27
  events: [
30
- ['root.click', 'onClickRoot'],
28
+ ['element.click', 'onClickRoot'],
31
29
  ['surface.click', 'onClick'],
32
30
  ['ui.ok.click', 'ok'],
33
31
  ['ui.cancel.click', 'cancel'],
@@ -62,6 +60,8 @@ class Dialog {
62
60
  this.root = document.createElement('div')
63
61
  this.root.classList.add('dialog')
64
62
 
63
+ this.element = this.root
64
+
65
65
  if (this.options.class !== 'dialog') {
66
66
  this.root.classList.add(this.options.class)
67
67
  }
@@ -149,6 +149,7 @@ class Dialog {
149
149
  }
150
150
 
151
151
  onClickRoot (e) {
152
+ console.log('onClickRoot')
152
153
  e.stopPropagation()
153
154
  if (!this.options.modal) {
154
155
  this.destroy()
@@ -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.root.href = link
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
 
@@ -1,9 +1,22 @@
1
- import addClass from './module/addclass'
1
+ // menu related modules
2
+ import emitter from '../module/emitter'
3
+ import attach from '../module/attach'
4
+ import build from '../module/build'
5
+ import display from '../module/display'
6
+
7
+ import Layout from '../layout'
8
+ import Element from '../element'
9
+ import Button from './text'
2
10
 
3
11
  const defaults = {
4
- class: 'text',
5
- tag: 'span',
6
- seprator: ' | '
12
+ class: 'list',
13
+ layout: [
14
+ [Element, 'main', { tag: 'ul' }]
15
+ ],
16
+ item: [Text, { tag: 'li' }],
17
+ events: [
18
+ ['ui.main.click', 'select']
19
+ ]
7
20
  }
8
21
 
9
22
  class List {
@@ -14,40 +27,15 @@ class List {
14
27
  */
15
28
  constructor (options) {
16
29
  this.options = Object.assign({}, defaults, options || {})
17
-
18
- // console.log('options', this.options)
30
+ // implement modules
31
+ Object.assign(this, emitter, build, attach, display)
19
32
 
20
33
  this.build()
21
34
 
22
35
  return this
23
36
  }
24
37
 
25
- /**
26
- * Build Method
27
- * @return {Object} This class instance
28
- */
29
- build () {
30
- this.root = document.createElement(this.options.tag)
31
- addClass(this.root, this.options.class)
32
-
33
- if (this.options.class !== 'text') {
34
- this.root.classList.add('text')
35
- }
36
-
37
- if (this.options.list) {
38
- this.set(this.options.list)
39
- }
40
-
41
- if (this.options.container) {
42
- this.options.container.appendChild(this.root)
43
- }
44
-
45
- return this
46
- }
47
-
48
- set (list) {
49
- var text = ''
50
-
38
+ add (items) {
51
39
  for (var i = 0; i < list.length; i++) {
52
40
  if (i < list.length - 1) {
53
41
  text = text + list[i] + this.options.seprator
@@ -68,6 +56,8 @@ class List {
68
56
  }
69
57
  }
70
58
 
59
+ select()
60
+
71
61
  setText (text) {
72
62
  // console.log('setText', text)
73
63
  this.root.innerHTML = text
@@ -0,0 +1,85 @@
1
+ import EventEmitter from '../component/emitter'
2
+ // menu related modules
3
+ import build from '../module/build'
4
+ import bindEvents from '../module/events'
5
+ import display from '../module/display'
6
+
7
+ import Element from '../element'
8
+ import Button from './button'
9
+
10
+ class Menu extends EventEmitter {
11
+ static defaults = {
12
+ class: 'menu',
13
+ transition: 200,
14
+ modal: false,
15
+ layout: [
16
+ [Element, 'surface', { class: 'surface' },
17
+ [Element, 'list', { tag: 'ul', class: 'items' }]
18
+ ]
19
+ ],
20
+ events: [
21
+ ['element.click', 'close']
22
+ ]
23
+ };
24
+
25
+ constructor (options) {
26
+ super()
27
+
28
+ this.init(options)
29
+ this.build(this.constructor)
30
+ this.bindEvents()
31
+
32
+ this.render(this.options.items)
33
+ }
34
+
35
+ init(options) {
36
+ this.options = Object.assign({}, Menu.defaults, options || {})
37
+ Object.assign(this, build, bindEvents, display)
38
+ }
39
+
40
+ render (items) {
41
+ if (items && Array.isArray(items)) {
42
+ for (var i = 0; i < items.length; i++) {
43
+ this.add(items[i])
44
+ }
45
+ }
46
+
47
+ return this
48
+ }
49
+
50
+ add (obj) {
51
+ if (typeof obj !== 'object') return this;
52
+ let item;
53
+ if (obj.type === 'divider') {
54
+ item = new Element({ tag: 'li', class: 'divider' })
55
+ } else {
56
+ obj.container = this.ui.list
57
+ obj.class = 'item'
58
+ item = new Button(obj).on('click', (ev) => {
59
+ // console.log('select', ev.target.name)
60
+ this.emit('select', ev.target.name)
61
+ })
62
+ }
63
+
64
+ return this
65
+ }
66
+
67
+ position(target) {
68
+ if (!target) return
69
+ var offs = target.getBoundingClientRect()
70
+
71
+ var offsw = this.offset = this.ui.surface.getBoundingClientRect()
72
+
73
+ this.ui.surface.style.top = (offs.top - 4) + 'px'
74
+ this.ui.surface.style.left = offs.left - offsw.width + offs.width + 'px'
75
+
76
+ return this
77
+ }
78
+
79
+ close() {
80
+ // console.log('close')
81
+ this.destroy()
82
+ }
83
+ }
84
+
85
+ export default Menu
@@ -0,0 +1,89 @@
1
+ // base class
2
+ import EventEmitter from '../component/emitter'
3
+ // related modules
4
+ import build from '../module/build'
5
+ import bindEvents from '../module/events'
6
+ import display from '../module/display'
7
+ // ui element
8
+ import Text from './text'
9
+ import Button from './button'
10
+
11
+ class Snackbar extends EventEmitter {
12
+ static defaults = {
13
+ class: 'snackbar',
14
+ transition: 225,
15
+ duration: 4000,
16
+ close: false,
17
+ layout: [
18
+ [Text, 'text', { tag: 'span', class: 'text' }],
19
+ [Button, 'action', { class: 'action', type: 'link' }],
20
+ [Button, 'close', { class: 'close', type: 'action' }]
21
+ ],
22
+ events: [
23
+ ['ui.action.click', 'action'],
24
+ ['ui.close.click', 'destroy']
25
+ ]
26
+ };
27
+
28
+ constructor (options) {
29
+ super()
30
+
31
+ this.init(options)
32
+ this.build(this.constructor)
33
+ this.render()
34
+ this.bindEvents()
35
+ this.show()
36
+
37
+ if (this.options.duration)
38
+ setTimeout(()=>{
39
+ this.destroy()
40
+ }, this.options.duration)
41
+ }
42
+
43
+ init(options) {
44
+ this.options = Object.assign({}, Snackbar.defaults, options || {})
45
+ Object.assign(this, build, bindEvents, display)
46
+
47
+ this.buildSnackbarContainer(this.options.container)
48
+ }
49
+
50
+ buildSnackbarContainer (container = document.body) {
51
+ console.log('buildSnackbarContainer', container)
52
+
53
+ let snackbarContainer = container.querySelector('.snackbars')
54
+
55
+ console.log('snackbarContainer', snackbarContainer)
56
+
57
+ if (!snackbarContainer) {
58
+ this.options.container = document.createElement('div')
59
+ this.options.container.classList.add('snackbars')
60
+ container.appendChild(this.options.container)
61
+ } else {
62
+ this.options.container = snackbarContainer
63
+ }
64
+ }
65
+
66
+ render () {
67
+ this.ui.text.set(this.options.text)
68
+ if (this.options.action) {
69
+ this.ui.action.set(this.options.action)
70
+ this.ui.action.element.classList.add('show')
71
+ }
72
+
73
+ if (this.options.close) this.ui.close.element.classList.add('show')
74
+
75
+ return this
76
+ }
77
+
78
+ action () {
79
+ this.emit('action')
80
+ this.destroy()
81
+ }
82
+
83
+ close() {
84
+ // console.log('close')
85
+ this.destroy()
86
+ }
87
+ }
88
+
89
+ export default Snackbar
@@ -50,7 +50,11 @@ class Text {
50
50
 
51
51
  var label = this.options.label || ''
52
52
 
53
- this.root.innerHTML = label + text
53
+ if (this.options.textFirst) {
54
+ this.root.innerHTML = text + label
55
+ } else {
56
+ this.root.innerHTML = label + text
57
+ }
54
58
 
55
59
  if (this.options.spaceAfter) {
56
60
  this.root.innerHTML = this.root.innerHTML + ' '
@@ -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/element.js CHANGED
@@ -1,46 +1,21 @@
1
-
2
- /**
3
- * Class Element
4
- * @class
5
- * @since 0.0.1
6
- * @example
7
- * var div = new Element({
8
- * tag: 'div',
9
- * class: 'mydiv',
10
- * })
11
- */
12
-
13
1
  class Element {
14
2
  static isElement () {
15
3
  return true
16
4
  }
17
5
 
18
- /**
19
- * The init method of the Button class
20
- * @param {Object} The element attributes
21
- * @private
22
- * @return {DOMElement} The dom element
23
- */
24
6
  constructor (options) {
25
7
  this.options = Object.assign({}, options || {})
26
8
  // console.log('element options', options)
27
9
  var element = document.createElement(this.options.tag || 'div')
10
+ delete this.options.tag
28
11
 
29
- if (options.html) {
30
- element.innerHTML = this.options.html
31
- }
32
-
33
- if (options.text) {
34
- element.textContent = this.options.text
35
- }
36
-
37
- if (options.id) {
38
- element.setAttribute('id', options.id)
39
- }
12
+ if (options.html) element.innerHTML = this.options.html
13
+ delete this.options.html
40
14
 
41
- delete this.options.tag
15
+ if (options.text) element.textContent = this.options.text
42
16
  delete this.options.text
43
- delete this.options.html
17
+
18
+ if (options.id) element.setAttribute('id', options.id)
44
19
 
45
20
  for (var property in this.options) {
46
21
  if (this.options.hasOwnProperty(property)) {
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) {
@@ -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
@@ -41,7 +41,6 @@ export default {
41
41
  } else if (e && e.element && e.element.on && f && bound) {
42
42
  e.element.on(e.name, f.bind(bound))
43
43
  } else {
44
- // console.trace('can\'t attach', def[0])
45
44
  // console.log('can\'t attach', def[0])
46
45
  }
47
46
  })
@@ -0,0 +1,43 @@
1
+ import dataset from './dataset'
2
+ import Layout from '../layout'
3
+
4
+ export default {
5
+ build () {
6
+ this.element = document.createElement(this.options.tag || 'div')
7
+ // for backward compatibility
8
+ this.root = this.element
9
+
10
+ const defaults = this.constructor.defaults || {}
11
+
12
+ this.element.classList.add(defaults.class)
13
+
14
+ if (this.options.class !== defaults.class) {
15
+ this.addClass(this.options.class)
16
+ }
17
+
18
+ if (this.options.data) {
19
+ dataset(this.root, this.options.data)
20
+ }
21
+
22
+ this.container = this.options.container
23
+
24
+ if (this.container) this.appendTo(this.container)
25
+
26
+ if (this.options.layout) {
27
+ this.layout = new Layout(this.options.layout, this.element)
28
+ this.ui = this.layout.component
29
+ }
30
+
31
+ if (this.options.show === true && this.show) this.show()
32
+ },
33
+
34
+ appendTo (container) {
35
+ container.appendChild(this.element)
36
+ },
37
+
38
+ addClass (c) {
39
+ const list = c.split(' ')
40
+ list.forEach(item => this.element.classList.add(item))
41
+ }
42
+
43
+ }
@@ -0,0 +1,12 @@
1
+
2
+ function dataset (element, data) {
3
+ if (data) {
4
+ for (var property in data) {
5
+ if (data.hasOwnProperty(property)) {
6
+ element.dataset[property] = data[property]
7
+ }
8
+ }
9
+ }
10
+ }
11
+
12
+ export default dataset
@@ -0,0 +1,88 @@
1
+
2
+ export default {
3
+ toggle () {
4
+ this.visible ? this.hide() : this.show()
5
+
6
+ this.emit?.('toggle')
7
+ return this
8
+ },
9
+
10
+ show () {
11
+ console.log('show', this.visible)
12
+
13
+ // if (this.options.transition) {
14
+ // this.element.style.display = 'initial'
15
+ // }
16
+
17
+ this.element.getBoundingClientRect()
18
+
19
+ this.element.classList.add('show')
20
+ this.visible = true
21
+
22
+ if (this.underlay) {
23
+ this.underlay.classList.add('show')
24
+ }
25
+
26
+ this.emit?.('show')
27
+ return this
28
+ },
29
+
30
+ hide () {
31
+ console.log('hide')
32
+ // if (this.element.style.display === 'none') return
33
+ // clearTimeout(this.displayTimeout)
34
+ // this._display = getComputedStyle(this.root).display
35
+
36
+ if (!this.root) return
37
+
38
+ this.element.classList.remove('show')
39
+ this.visible = false
40
+
41
+ if (this.underlay) {
42
+ this.underlay.classList.remove('show')
43
+ }
44
+
45
+ // if (this.options.transition) {
46
+ // this.displayTimeout = setTimeout(() => {
47
+ // console.log('display: none', this._display)
48
+ // this.element.style.display = 'none'
49
+ // }, this.options.transition)
50
+ // }
51
+
52
+ this.emit?.('hide')
53
+ return this
54
+ },
55
+
56
+ destroy () {
57
+ // console.log('destroy', this.options.transition, this.root)
58
+ if (this.options.transition && this.root) {
59
+ this.element.classList.remove('show')
60
+
61
+ if (this.underlay) {
62
+ this.underlay.classList.remove('show')
63
+ }
64
+
65
+ setTimeout(() => {
66
+ this.removeChild()
67
+ }, this.options.transition)
68
+ } else {
69
+ this.removeChild()
70
+ }
71
+
72
+ this.emit?.('destroy')
73
+ },
74
+
75
+ removeChild () {
76
+ if (this.root && this.element.parentNode) {
77
+ this.element.parentNode.removeChild(this.root)
78
+ this.root = null
79
+ }
80
+
81
+ if (this.underlay && this.underlay.parentNode) {
82
+ this.underlay.parentNode.removeChild(this.underlay)
83
+ }
84
+
85
+ this.emit?.('remove')
86
+ return this
87
+ }
88
+ }
@@ -0,0 +1,55 @@
1
+ import extract from './extract'
2
+
3
+ export default {
4
+ bindEvents: function (events) {
5
+ console.log('bindEvents', events)
6
+ events = events || this.options.events
7
+ if (!events) return
8
+
9
+ console.log('attach', events, this)
10
+ var instance = this
11
+ events.map((def) => {
12
+ var e = extract.e(instance, def[0])
13
+ var f = extract.f(instance, def[1])
14
+ var option = def[2]
15
+
16
+ var keys = def[1].split('.')
17
+
18
+ keys.pop()
19
+ var bound = this.last(keys.join('.'))
20
+
21
+ if (f && bound && e && e.element && e.element.addEventListener) {
22
+ if (!f) { console.log('error') }
23
+
24
+ if (option) {
25
+ e.element.addEventListener(e.name, f.bind(bound), option)
26
+ } else {
27
+ e.element.addEventListener(e.name, f.bind(bound))
28
+ }
29
+ } else if (e && e.element && e.element.on && f && bound) {
30
+ e.element.on(e.name, f.bind(bound))
31
+ } else {
32
+ // console.log('can\'t attach', def[0])
33
+ }
34
+ })
35
+
36
+ return this
37
+ },
38
+
39
+ last: function (str) {
40
+ // console.log('_path', str)
41
+ if (!str) return this
42
+ else if (!str.match(/\./)) return this[str]
43
+ var last
44
+
45
+ var keys = str.split('.')
46
+ for (var i = 0, l = keys.length; i < l; i++) {
47
+ var key = keys[i]
48
+
49
+ last = last || this
50
+ last = last[key]
51
+ }
52
+
53
+ return last
54
+ }
55
+ }
@@ -0,0 +1,20 @@
1
+ export default function jsonToHTML (obj) {
2
+ // Start an HTML string
3
+ let html = '<div>'
4
+
5
+ // Loop through each property of the object
6
+ for (const [key, value] of Object.entries(obj)) {
7
+ // If the value is an object, call the function recursively
8
+ if (typeof value === 'object' && value !== null) {
9
+ html += `<div class="${key}">${key}${jsonToHTML(value)}</div>`
10
+ } else if (Array.isArray(value)) {
11
+ html += `<div class="${key}">${key}<ul>${value.map(item => `<li>${item}</li>`).join('')}</ul></div>`
12
+ } else {
13
+ html += `<p>${key}: ${value || 'N/A'}</p>`
14
+ }
15
+ }
16
+
17
+ // Close the HTML string
18
+ html += '</div>'
19
+ return html
20
+ }
@@ -1,17 +1,22 @@
1
+ function passiveEvents () {
2
+ let supportsPassive = false
1
3
 
2
- function passive () {
3
- var supportsPassive = false
4
4
  try {
5
- var opts = Object.defineProperty({}, 'passive', {
6
- get: function () {
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 passive
22
+ export default passiveEvents
@@ -0,0 +1,29 @@
1
+ .menu
2
+ //display: none
3
+ &.show
4
+ //display: block
5
+ .surface
6
+ background: rgba(0,0,0,.05)
7
+ .list
8
+ background: white
9
+ .item
10
+ color: rgba(0,0,0,.87)
11
+
12
+ &.floating
13
+ position: fixed
14
+ top: 0
15
+ left: 0
16
+ bottom: 0
17
+ right: 0
18
+ background-color: rgba(0, 0, 0, 0.5)
19
+ display: flex
20
+ align-items: center
21
+ justify-content: center
22
+ overflow: hidden
23
+ opacity: 0
24
+ transition: 0.2s
25
+ .surface
26
+ position: absolute
27
+ background-color: white
28
+
29
+
@@ -0,0 +1,65 @@
1
+ $width: 500px
2
+
3
+ .snackbars
4
+ position: absolute
5
+ z-index: 300
6
+ display: flex
7
+ width: $width
8
+ flex-direction: column
9
+ background-color: rgba(0,0,0,.1)
10
+ bottom: 160px
11
+ width: 100%
12
+ .snackbar
13
+ overflow: hidden
14
+ display: flex
15
+ opacity: 0
16
+ height: 2px
17
+ flex-direction: row
18
+ padding: 0
19
+ margin: 2px
20
+ background-color: #322F35
21
+ border-radius: 4px
22
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2)
23
+ transition: 225ms opacity cubic-bezier(.4,0,.2,1), 225ms height cubic-bezier(.4,0,.2,1), 225ms padding cubic-bezier(.4,0,.2,1)
24
+ &.show
25
+ opacity: 1
26
+ padding: 8px
27
+ height: initial
28
+ transition: 225ms opacity cubic-bezier(.4,0,.2,1), 225ms height cubic-bezier(.4,0,.2,1), 225ms padding cubic-bezier(.4,0,.2,1)
29
+ .text
30
+ line-height: 2em
31
+ padding-left: 8px
32
+ flex: 1
33
+ color: rgba(255,255,255,.87)
34
+ button.action
35
+ flex:none
36
+ display: none
37
+ color: green
38
+ .show
39
+ display: inline-block
40
+ .close
41
+ flex: none
42
+ display: none
43
+ width: 24px
44
+ height: 24px
45
+ min-width: 24px
46
+ background-image: url('../../theme/common/icon/dark/close.svg')
47
+ background-color: transparent
48
+ &:hover, &:active
49
+ background-color: transparent
50
+ &.show
51
+ display: inline-block
52
+
53
+
54
+ @media only screen and (min-width: $desktop_switch)
55
+ .snackbars
56
+ left: 50%
57
+ bottom: 200px
58
+ margin-left: -$width / 2
59
+ width: $width
60
+ transition: 195ms bottom cubic-bezier(0.4, 0, 0.2, 1)
61
+ &.up
62
+ bottom: 500px
63
+ transition: 225ms bottom cubic-bezier(0.4, 0, 0.2, 1)
64
+
65
+
package/src/view/build.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import scrollbar from '../module/scrollbar'
2
- import dataset from './dataset'
2
+ import dataset from '../module/dataset'
3
3
  import Layout from '../layout'
4
4
 
5
5
  export default {
@@ -31,7 +31,7 @@ export default {
31
31
  },
32
32
 
33
33
  hide () {
34
- // console.log('hide', this.root.style.display)
34
+ // console.log('hide')
35
35
  // if (this.root.style.display === 'none') return
36
36
  // clearTimeout(this.displayTimeout)
37
37
  // this._display = getComputedStyle(this.root).display