material 0.9.12 → 0.9.14

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,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 }
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