material 0.9.11 → 0.9.13

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.
@@ -0,0 +1,15 @@
1
+ // Recursively freeze an object to prevent mutation
2
+
3
+ const isObject = item => {
4
+ return item && typeof item === 'object' && !Array.isArray(item)
5
+ }
6
+
7
+ const freeze = obj => {
8
+ if (isObject(obj)) {
9
+ Object.freeze(obj)
10
+ Object.keys(obj).forEach(key => freeze(obj[key]))
11
+ }
12
+ return obj
13
+ }
14
+
15
+ export default freeze
@@ -0,0 +1,16 @@
1
+ const insertion = (element, callback) => {
2
+ const observer = new MutationObserver((mutations) => {
3
+ mutations.forEach((mutation) => {
4
+ mutation.addedNodes.forEach((node) => {
5
+ if (node === element || node.contains(element)) {
6
+ callback()
7
+ observer.disconnect()
8
+ }
9
+ })
10
+ })
11
+ })
12
+
13
+ observer.observe(document.body, { childList: true, subtree: true })
14
+ }
15
+
16
+ export { insertion }
@@ -1,4 +1,3 @@
1
-
2
1
  const is = (object) => {
3
2
  return object &&
4
3
  typeof object === 'object' &&
@@ -34,7 +34,6 @@
34
34
  // overscroll-behavior: none
35
35
  // height: 100%
36
36
  .item
37
- user-select: none
38
37
  width: 100%
39
38
  display: flex
40
39
  flex-direction: row
package/src/snackbar.js CHANGED
@@ -1,17 +1,13 @@
1
- // base class
2
- import EventEmitter from './mixin/emitter'
3
- // related modules
4
- import build from './mixin/build'
5
- import events from './module/events'
1
+ import Control from './class/control'
6
2
  import display from './mixin/display'
7
- // ui element
8
3
  import Element from './element'
9
4
  import Text from './text'
10
5
  import Button from './button'
11
6
 
12
- class Snackbar extends EventEmitter {
7
+ class Snackbar extends Control {
13
8
  static defaults = {
14
9
  class: 'snackbar',
10
+ mixins: [display],
15
11
  transition: 225,
16
12
  duration: 4000,
17
13
  stack: false,
@@ -30,12 +26,9 @@ class Snackbar extends EventEmitter {
30
26
  }
31
27
 
32
28
  constructor (options) {
33
- super()
34
-
29
+ super(options)
35
30
  this.init(options)
36
- this.build(this.constructor)
37
31
  this.render()
38
- events.attach(this.options.events, this)
39
32
  this.show()
40
33
 
41
34
  if (this.options.duration) {
@@ -46,19 +39,12 @@ class Snackbar extends EventEmitter {
46
39
  }
47
40
 
48
41
  init (options) {
49
- this.options = Object.assign({}, Snackbar.defaults, options || {})
50
- Object.assign(this, build, display)
51
-
52
42
  this.buildSnackbarContainer(this.options.container)
53
43
  }
54
44
 
55
45
  buildSnackbarContainer (container = document.body) {
56
- // console.log('buildSnackbarContainer', container)
57
-
58
46
  const snackbarContainer = container.querySelector('.snackbars')
59
47
 
60
- // console.log('snackbarContainer', snackbarContainer)
61
-
62
48
  if (!snackbarContainer) {
63
49
  this.options.container = document.createElement('div')
64
50
  this.options.container.classList.add('snackbars')
@@ -67,31 +53,46 @@ class Snackbar extends EventEmitter {
67
53
  if (this.options.stack === false) snackbarContainer.innerHTML = ''
68
54
  this.options.container = snackbarContainer
69
55
  }
56
+
57
+ this.options.container.appendChild(this.element)
70
58
  }
71
59
 
72
60
  render () {
73
- this.ui.message.set(this.options.message)
61
+ if (!this.ui) {
62
+ console.error('UI elements not initialized properly.')
63
+ return
64
+ }
65
+
66
+ const { message, callback, close, action } = this.ui
67
+
68
+ if (message) {
69
+ message.set(this.options.message)
70
+ } else {
71
+ console.error('Message UI element not initialized.')
72
+ }
74
73
 
75
- if (this.options.action) {
76
- this.ui.callback.set(this.options.action)
77
- this.ui.callback.element.classList.add('show')
78
- this.ui.action.classList.add('show')
74
+ if (this.options.action && callback && callback.element) {
75
+ callback.set(this.options.action)
76
+ callback.element.classList.add('show')
77
+ if (action) {
78
+ action.classList.add('show')
79
+ }
79
80
  }
80
81
 
81
- if (this.options.close) {
82
- this.ui.close.element.classList.add('show')
83
- this.ui.action.classList.add('show')
82
+ if (this.options.close && close && close.element) {
83
+ close.element.classList.add('show')
84
+ if (action) {
85
+ action.classList.add('show')
86
+ }
84
87
  }
85
88
  }
86
89
 
87
90
  action () {
88
- // console.log('action')
89
91
  this.emit('action')
90
92
  this.destroy()
91
93
  }
92
94
 
93
95
  close () {
94
- // console.log('close')
95
96
  this.destroy()
96
97
  }
97
98
  }
package/src/switch.js CHANGED
@@ -110,7 +110,7 @@ class Switch extends EventEmitter {
110
110
  }
111
111
  break
112
112
  default:
113
- this.setValue(prop, value)
113
+ this.setValue(prop, silent)
114
114
  }
115
115
 
116
116
  return this
package/src/tabs.js CHANGED
@@ -1,99 +1,88 @@
1
- import create from './mixin/create'
2
- import insert from './mixin/insert'
3
- import emitter from './module/emitter'
4
-
1
+ // modules
2
+ import { insertion } from './module/mutation.js'
3
+ import display from './mixin/display'
5
4
  import offset from './element/offset'
6
5
 
7
- import List from './list'
6
+ // ui
7
+ import Control from './class/control'
8
8
  import Button from './button'
9
- import Element from './element'
10
9
 
11
- class Tabs {
10
+ class Tabs extends Control {
12
11
  static defaults = {
13
- prefix: 'material',
14
12
  class: 'tabs',
15
- tag: 'div',
13
+ mixins: [display],
14
+ show: true,
15
+ style: 'primary',
16
16
  indicator: {
17
- prefix: 'material',
18
- class: 'indicator',
19
- tag: 'div'
17
+ size: 30
20
18
  }
21
19
  }
22
20
 
23
21
  constructor (options) {
24
- this.init(options)
25
- this.build()
22
+ super(options)
26
23
 
27
- return this
24
+ insertion(this.element, () => this.setup())
28
25
  }
29
26
 
30
- init (options) {
31
- this.options = { ...Tabs.defaults, ...options }
32
- Object.assign(this, insert, emitter)
33
- }
27
+ setup () {
28
+ this.items = Array.from(this.element.childNodes).filter(node => node.nodeType === Node.ELEMENT_NODE)
29
+ this.item = {}
34
30
 
35
- /**
36
- * Build Method
37
- * @return {Object} This class instance
38
- */
39
- build () {
40
- this.element = create(this.options)
41
- this.tab = { }
42
- if (this.options.list) {
43
- this.list = new List({
44
- tag: 'div',
45
- container: this.element,
46
- list: this.options.list,
47
- target: '.material-button',
48
- height: 600,
49
- label: 'Flat',
50
-
51
- render: (info) => {
52
- let item
53
- if (info.type === 'divider') {
54
- item = new Element({ class: 'divider' })
55
- } else {
56
- item = new Button({
57
- name: info.name,
58
- text: info.text || info.name,
59
- tooltip: info.tootip
60
- })
61
- }
62
-
63
- this.tab[info.name] = item
64
-
65
- return item
66
- },
67
- select: (item) => {
68
- this.selected = item
69
- this.click(item)
70
- }
71
- })
72
- }
31
+ this.items.forEach(item => {
32
+ this.item[item.name] = item
33
+ this.addListener(item)
34
+ })
35
+
36
+ this.indicator = document.createElement('div')
37
+ this.indicator.classList.add('indicator')
38
+ this.element.appendChild(this.indicator)
73
39
 
74
- this.indicator = create(this.options.indicator)
75
- this.insertElement(this.indicator, this.element)
40
+ if (this.options.show) this.show()
76
41
 
77
- if (this.options.container) {
78
- this.insert(this.options.container)
42
+ if (this.options.selected && this.item[this.options.selected]) {
43
+ this.select(this.options.selected, true)
79
44
  }
80
45
 
81
- return this
46
+ this.emit('ready')
82
47
  }
83
48
 
84
- select (tab) {
85
- // console.log('select', tab, this.tab)
86
- this.selected = this.tab[tab]
87
- this.click(this.selected.element, true)
49
+ select (name, silent = false) {
50
+ this.items.forEach(item => {
51
+ item.classList.toggle('selected', name === item.name)
52
+ })
53
+
54
+ this.selectedName = name
55
+
56
+ if (!silent) this.emit('select', name)
57
+ this.updateIndicator(name)
88
58
  }
89
59
 
90
- click (item, silent) {
91
- // console.log('clickitem', item, this.element);
92
- const or = offset(this.element)
93
- const o = offset(item)
94
- this.indicator.setAttribute('style', 'width: ' + o.width + 'px; left: ' + (o.left - or.left) + 'px;')
60
+ updateIndicator (name) {
61
+ name = name ?? this.selectedName
62
+
63
+ const item = this.item[name]
64
+
65
+ if (!item) return
66
+
67
+ this.selected = item
68
+ const oElement = offset(this.element)
69
+ const oItem = offset(item)
70
+
71
+ const label = item.querySelector('label')
72
+ const oLabel = label ? offset(label) : null
73
+ const width = oLabel?.width ?? this.options.indicator.size
74
+
75
+ const style = this.options.style === 'secondary'
76
+ ? `width: ${oItem.width}px; left: ${oItem.left - oElement.left}px;`
77
+ : `width: ${width}px; left: ${oItem.left - oElement.left + (oItem.width / 2) - (width / 2)}px;`
78
+
79
+ this.indicator.setAttribute('style', style)
80
+ }
95
81
 
96
- if (!silent) { this.emit('select', item.dataset.name) }
82
+ addListener (item) {
83
+ item.addEventListener('click', (ev) => {
84
+ this.select(item.name)
85
+ })
97
86
  }
98
87
  }
99
88