material 0.8.9 → 0.9.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.
Files changed (61) hide show
  1. package/index.js +24 -9
  2. package/package.json +1 -1
  3. package/scripts/doccoAssistant.js +25 -0
  4. package/src/appbar.js +2 -4
  5. package/src/badge.js +6 -13
  6. package/src/button.js +10 -18
  7. package/src/calendar.js +23 -48
  8. package/src/card.js +2 -4
  9. package/src/checkbox.js +2 -7
  10. package/src/class/component.js +19 -0
  11. package/src/class/control.js +33 -0
  12. package/src/component.js +7 -41
  13. package/src/datehour.js +2 -4
  14. package/src/dialog.js +3 -5
  15. package/src/drawer.js +12 -12
  16. package/src/element.js +16 -20
  17. package/src/file.js +6 -4
  18. package/src/form/build.js +2 -2
  19. package/src/form.js +9 -22
  20. package/src/icon.js +6 -34
  21. package/src/image.js +1 -3
  22. package/src/item.js +3 -3
  23. package/src/link.js +1 -3
  24. package/src/list/build.js +2 -2
  25. package/src/list/render.js +2 -2
  26. package/src/list/select.js +4 -2
  27. package/src/list/update.js +2 -2
  28. package/src/list.js +12 -13
  29. package/src/loader.js +4 -7
  30. package/src/loading.js +2 -8
  31. package/src/map.js +27 -32
  32. package/src/menu.js +78 -19
  33. package/src/mixin/build.js +68 -0
  34. package/src/mixin/emitter.js +0 -2
  35. package/src/mixin/position.js +20 -9
  36. package/src/module/build.js +51 -46
  37. package/src/module/clone.js +15 -0
  38. package/src/module/dot.js +15 -9
  39. package/src/module/events.js +2 -0
  40. package/src/module/layout.js +76 -0
  41. package/src/module/merge.js +22 -0
  42. package/src/navigation.js +4 -3
  43. package/src/progress.js +9 -24
  44. package/src/search.js +3 -2
  45. package/src/select.js +2 -2
  46. package/src/selecter.js +5 -4
  47. package/src/selector.js +23 -41
  48. package/src/slider.js +33 -55
  49. package/src/snackbar.js +1 -1
  50. package/src/switch.js +1 -1
  51. package/src/switcher.js +1 -1
  52. package/src/tabs.js +12 -19
  53. package/src/tabview.js +1 -1
  54. package/src/text.js +2 -4
  55. package/src/textfield.js +1 -3
  56. package/src/toolbar.js +6 -20
  57. package/src/tooltip.js +14 -24
  58. package/src/tree.js +10 -14
  59. package/src/view.js +2 -2
  60. package/src/divider.js +0 -60
  61. package/src/layout.js +0 -106
@@ -1,67 +1,72 @@
1
1
  import * as css from './css'
2
2
  import dataset from './dataset'
3
+ import { create } from '../module/layout'
3
4
 
4
- import Layout from '../layout'
5
+ /**
6
+ * Builds a UI component instance.
7
+ * @param {object} instance - The component instance to build.
8
+ */
9
+ const build = (instance) => {
10
+ const { tag = 'div', class: customClass, data, base, container, schema, icon, label, show } = instance.options
11
+ const { defaults = {} } = instance.constructor
5
12
 
6
- export default {
7
- build () {
8
- this.element = document.createElement(this.options.tag || 'div')
13
+ instance.element = document.createElement(tag)
9
14
 
10
- const defaults = this.constructor.defaults || {}
15
+ if (defaults.base) css.add(instance.element, defaults.base)
16
+ if (defaults.class) css.add(instance.element, defaults.class)
11
17
 
12
- if (defaults.base) css.add(this.element, defaults.base)
13
- if (defaults.class) css.add(this.element, defaults.class)
14
-
15
- if (this.options.class !== defaults.class) {
16
- css.add(this.element, this.options.class)
17
- }
18
+ if (customClass !== defaults.class) {
19
+ css.add(instance.element, customClass)
20
+ }
18
21
 
19
- if (this.options.data) {
20
- dataset(this.element, this.options.data)
21
- }
22
+ if (data) {
23
+ dataset(instance.element, data)
24
+ }
22
25
 
23
- if (this.options.base === 'view' || this.options.base === 'app') {
24
- this.container = this.options.container || document.body
25
- } else {
26
- this.container = this.options.container
27
- }
26
+ setupContainer(instance, base, container)
28
27
 
29
- if (this.container) this.appendTo(this.container)
28
+ if (schema) {
29
+ setupLayout(instance, schema)
30
+ }
30
31
 
31
- if (this.options.layout) {
32
- this.layout = new Layout(this.options.layout, this.element)
33
- this.ui = this.layout.component
34
- }
32
+ instance.ui = instance.ui || {}
35
33
 
36
- this.ui = this.ui || {}
34
+ if (icon) buildIcon(instance)
35
+ if (label) buildLabel(instance)
37
36
 
38
- if (this.options.icon) this.buildIcon()
39
- if (this.options.label) this.buildLabel()
37
+ if (show === true && instance.show) instance.show()
38
+ }
40
39
 
41
- if (this.options.show === true && this.show) this.show()
42
- },
40
+ const setupContainer = (instance, base, container) => {
41
+ instance.container = (base === 'view' || base === 'app') ? container || document.body : container
42
+ if (instance.container) instance.container.appendChild(instance.element)
43
+ }
43
44
 
44
- buildLabel () {
45
- if (!this.options.label) return
45
+ const setupLayout = (instance, schema) => {
46
+ instance.layout = create(schema, instance.element)
47
+ instance.ui = instance.layout.component
48
+ }
46
49
 
47
- this.ui.label = document.createElement('label')
48
- this.ui.label.classList.add('label')
49
- this.ui.label.innerHTML = this.options.label
50
+ function buildLabel ({ ui, options, element }) {
51
+ const { label } = options
52
+ if (!label) return
50
53
 
51
- this.element.appendChild(this.ui.label)
52
- },
54
+ ui.label = document.createElement('label')
55
+ ui.label.classList.add('label')
56
+ ui.label.innerHTML = label
53
57
 
54
- buildIcon () {
55
- if (!this.options.icon) return
58
+ element.appendChild(ui.label)
59
+ }
56
60
 
57
- this.ui.icon = document.createElement('i')
58
- this.ui.icon.classList.add('icon')
59
- this.ui.icon.innerHTML = this.options.icon
61
+ function buildIcon ({ ui, options, element }) {
62
+ const { icon } = options
63
+ if (!icon) return
60
64
 
61
- this.element.appendChild(this.ui.icon)
62
- },
65
+ ui.icon = document.createElement('i')
66
+ ui.icon.classList.add('icon')
67
+ ui.icon.innerHTML = icon
63
68
 
64
- appendTo (container) {
65
- container.appendChild(this.element)
66
- }
69
+ element.appendChild(ui.icon)
67
70
  }
71
+
72
+ export default build
@@ -0,0 +1,15 @@
1
+ const deepClone = obj => {
2
+ if (typeof obj !== 'object' || obj === null) {
3
+ return obj // Return the value if obj is not an object
4
+ }
5
+
6
+ const clone = Array.isArray(obj) ? [] : {}
7
+
8
+ Object.entries(obj).forEach(([key, value]) => {
9
+ clone[key] = deepClone(value)
10
+ })
11
+
12
+ return clone
13
+ }
14
+
15
+ export default deepClone
package/src/module/dot.js CHANGED
@@ -17,16 +17,22 @@
17
17
  * // flatComplex is now { 'a': [{ b: 1 }, { c: 2 }], 'd': [Date Object] }
18
18
  */
19
19
 
20
- const dot = (obj, base = '') => {
21
- return Object.entries(obj).reduce((acc, [key, value]) => {
22
- const newKey = base ? `${base}.${key}` : key
23
- if (value && typeof value === 'object' && !Array.isArray(value)) {
24
- Object.assign(acc, dot(value, newKey))
25
- } else {
26
- acc[newKey] = value
20
+ function dot (obj) {
21
+ const res = {}
22
+ function recurse (obj, current) {
23
+ for (const key in obj) {
24
+ const value = obj[key]
25
+ const newKey = (current ? current + '.' + key : key)
26
+ if (value && typeof value === 'object') {
27
+ recurse(value, newKey)
28
+ } else {
29
+ res[newKey] = value
30
+ }
27
31
  }
28
- return acc
29
- }, {})
32
+ }
33
+
34
+ recurse(obj)
35
+ return res
30
36
  }
31
37
 
32
38
  export default dot
@@ -33,6 +33,8 @@ const events = {
33
33
  } else if (f && bound) {
34
34
  handler = f.bind(bound)
35
35
  } else {
36
+ // throw new Error('Cannot bind function for eventDef')
37
+ // console.trace('Cannot bind function for eventDef')
36
38
  return // Cannot bind function for eventDef
37
39
  }
38
40
 
@@ -0,0 +1,76 @@
1
+ import { is as isObject } from '../module/object'
2
+
3
+ const components = []
4
+
5
+ /**
6
+ * Recursively creates components based on a provided schema.
7
+ *
8
+ * @param {Array} schema - An array of components or sub-schemas.
9
+ * @param {HTMLElement} container - The container for the current level of components.
10
+ * @param {Object} [structure={}] - An accumulator object for components, keyed by name.
11
+ * @param {number} [level=0] - The current level of recursion.
12
+ * @returns {Object} The structure containing all created components.
13
+ */
14
+ function create (schema, container, structure = {}, level = 0) {
15
+ level++
16
+ let component
17
+ const object = {}
18
+ const fragment = document.createDocumentFragment()
19
+
20
+ for (let i = 0; i < schema.length; i++) {
21
+ var name
22
+ let options = {}
23
+
24
+ if (schema[i] instanceof Object && typeof schema[i] === 'function') {
25
+ if (isObject(schema[i + 1])) {
26
+ options = schema[i + 1]
27
+ } else if (isObject(schema[i + 2])) {
28
+ options = schema[i + 2]
29
+ }
30
+
31
+ if (typeof schema[i + 1] === 'string') {
32
+ name = schema[i + 1]
33
+ if (!schema[i].isElement && !schema[i].isComponent) {
34
+ options.name = name
35
+ }
36
+ }
37
+
38
+ component = new schema[i](options)
39
+
40
+ const element = component.element || component
41
+ if (level === 1) structure.element = element
42
+
43
+ if (name) {
44
+ structure[name] = component
45
+ components.push([name, component])
46
+ }
47
+
48
+ if (component) {
49
+ if (component.insert) component.insert(fragment)
50
+ else fragment.appendChild(element)
51
+
52
+ if (component.onInserted) component.onInserted(fragment)
53
+ }
54
+ } else if (Array.isArray(schema[i])) {
55
+ if (!component) component = container
56
+ create(schema[i], component, structure, level)
57
+ }
58
+ }
59
+
60
+ if (container && fragment.hasChildNodes()) {
61
+ const wrapper = container.element || container
62
+ wrapper.appendChild(fragment)
63
+ }
64
+
65
+ function get (name) {
66
+ return structure[name] || null
67
+ }
68
+
69
+ object.component = structure
70
+ object.components = components
71
+ object.get = get
72
+
73
+ return object
74
+ }
75
+
76
+ export { create }
@@ -0,0 +1,22 @@
1
+ // deep merge
2
+ const isObject = item =>
3
+ item && typeof item === 'object' && !Array.isArray(item)
4
+
5
+ const merge = (target, ...sources) => {
6
+ sources.forEach(source => {
7
+ if (isObject(source)) {
8
+ Object.keys(source).forEach(key => {
9
+ const sourceValue = source[key]
10
+ if (isObject(sourceValue)) {
11
+ if (!isObject(target[key])) target[key] = {}
12
+ merge(target[key], sourceValue)
13
+ } else {
14
+ target[key] = sourceValue
15
+ }
16
+ })
17
+ }
18
+ })
19
+ return target
20
+ }
21
+
22
+ export default merge
package/src/navigation.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import EventEmitter from './mixin/emitter'
2
2
 
3
3
  import * as css from './module/css'
4
- import build from './module/build'
4
+ import build from './mixin/build'
5
5
  import events from './module/events'
6
6
  import display from './mixin/display'
7
7
  import Element from './element'
@@ -25,18 +25,19 @@ class Navigation extends EventEmitter {
25
25
 
26
26
  this.init(options)
27
27
  this.build()
28
- events.attach(this.options.events, this)
29
28
  this.setup()
30
29
  }
31
30
 
32
31
  init (options) {
33
32
  this.options = { ...Navigation.defaults, ...options }
34
33
  Object.assign(this, build, display)
34
+
35
35
  this.items = []
36
36
  }
37
37
 
38
38
  setup () {
39
- console.log('setup', this.options)
39
+ events.attach(this.options.events, this)
40
+
40
41
  if (this.options.type) css.add(this.element, 'type-' + this.options.type)
41
42
  if (this.options.type === 'rail') this.show()
42
43
  if (this.options.items) this.render(this.options.items)
package/src/progress.js CHANGED
@@ -3,23 +3,17 @@ import create from './element/create'
3
3
  import classify from './module/classify'
4
4
  import insert from './element/insert'
5
5
 
6
- const defaults = {
7
- prefix: 'material',
8
- class: 'progress',
9
- tag: 'div',
10
- progress: '0%',
11
- circular: `<svg class="progress" width="65px" height="65px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg">
6
+ class Spinner {
7
+ static defaults = {
8
+ prefix: 'material',
9
+ class: 'progress',
10
+ tag: 'div',
11
+ progress: '0%',
12
+ circular: `<svg class="progress" width="65px" height="65px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg">
12
13
  <circle class="path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle>
13
14
  </svg>`
14
- }
15
-
16
- class Spinner {
17
- static uid = "material-spinner";
15
+ }
18
16
 
19
- /**
20
- * init
21
- * @return {Object} The class options
22
- */
23
17
  constructor (options) {
24
18
  this.init(options)
25
19
  this.build()
@@ -27,14 +21,9 @@ class Spinner {
27
21
  return this
28
22
  }
29
23
 
30
- /**
31
- * [init description]
32
- * @param {?} options [description]
33
- * @return {?} [description]
34
- */
35
24
  init (options) {
36
25
  // merge options
37
- this.options = Object.assign({}, defaults, options || {})
26
+ this.options = { ...Spinner.defaults, ...options }
38
27
 
39
28
  // define class
40
29
 
@@ -42,10 +31,6 @@ class Spinner {
42
31
  Object.assign(this, insert)
43
32
  }
44
33
 
45
- /**
46
- * Build function for item
47
- * @return {Object} This class instance
48
- */
49
34
  build (options) {
50
35
  this.element = create(this.options.tag)
51
36
  classify(this.element, this.options)
package/src/search.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import EventEmitter from './mixin/emitter'
2
2
 
3
- import build from './module/build'
3
+ import build from './mixin/build'
4
4
  import display from './mixin/display'
5
5
  import events from './module/events'
6
6
 
@@ -36,8 +36,9 @@ class Search extends EventEmitter {
36
36
  }
37
37
 
38
38
  setup () {
39
- this.input = this.ui.input
40
39
  events.attach(this.options.events, this)
40
+
41
+ this.input = this.ui.input
41
42
  }
42
43
 
43
44
  set (value) {
package/src/select.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import EventEmitter from './mixin/emitter'
2
2
  // modules
3
- import build from './module/build'
3
+ import build from './mixin/build'
4
4
  import events from './module/events'
5
5
  import attributes from './module/attributes'
6
6
  import dataset from './module/dataset'
@@ -24,7 +24,7 @@ class Select extends EventEmitter {
24
24
  }
25
25
 
26
26
  init (options) {
27
- this.options = Object.assign({}, Select.defaults, options || {})
27
+ this.options = { ...Select.defaults, ...options }
28
28
  Object.assign(this, build, dataset)
29
29
  }
30
30
 
package/src/selecter.js CHANGED
@@ -5,7 +5,7 @@ import dataset from './module/dataset'
5
5
  import attributes from './module/attributes'
6
6
  import * as css from './module/css'
7
7
  // components
8
- import Layout from './layout'
8
+ import { create } from './module/layout'
9
9
  import Element from './element'
10
10
  import Button from './button'
11
11
 
@@ -39,15 +39,16 @@ class Selecter extends EventEmitter {
39
39
  this.init(options)
40
40
  this.build()
41
41
  this.setup()
42
- events.attach(this.options.events, this)
43
42
  }
44
43
 
45
44
  init (options) {
46
- this.options = Object.assign({}, Selecter.defaults, options || {})
45
+ this.options = { ...Selecter.defaults, ...options }
47
46
  Object.assign(this, dataset)
48
47
  }
49
48
 
50
49
  setup () {
50
+ events.attach(this.options.events, this)
51
+
51
52
  if (this.options.data) {
52
53
  dataset(this.element, this.options.data)
53
54
  }
@@ -87,7 +88,7 @@ class Selecter extends EventEmitter {
87
88
  css.add(this.element, this.options.class)
88
89
  }
89
90
 
90
- this.layout = new Layout(this.options.layout, this.element)
91
+ this.layout = create(this.options.layout, this.element)
91
92
  this.ui = this.layout.component
92
93
 
93
94
  // console.log('ui', this.ui)
package/src/selector.js CHANGED
@@ -1,53 +1,32 @@
1
1
  import emitter from './module/emitter'
2
2
  import events from './module/events'
3
3
 
4
- const defaults = {
5
- class: 'selector',
6
- tag: 'div',
7
- styles: ['style', 'color'],
8
- modules: ['border', 'label', 'resizer'],
9
- resizer: {
10
- keepRatio: true,
11
- minWidth: 10,
12
- minHeight: 10
13
- },
14
- events: [
15
- ['resizer.pointerdown', 'onPointerDown']
16
- ]
17
-
18
- }
19
-
20
4
  class Selector {
21
- static uid = "material-selector";
22
-
23
- static isComponent () {
24
- return true
5
+ static defaults = {
6
+ class: 'selector',
7
+ tag: 'div',
8
+ styles: ['style', 'color'],
9
+ modules: ['border', 'label', 'resizer'],
10
+ resizer: {
11
+ keepRatio: true,
12
+ minWidth: 10,
13
+ minHeight: 10
14
+ },
15
+ events: [
16
+ ['resizer.pointerdown', 'onPointerDown']
17
+ ]
25
18
  }
26
19
 
27
- /**
28
- * Constructor
29
- * @param {Object} options - Component options
30
- * @return {Object} Class instance
31
- */
32
20
  constructor (options) {
33
21
  // console.log('constructor')
34
- this.options = Object.assign({}, defaults, options || {})
35
- Object.assign(this, emitter, attach)
36
- // console.log('options', options)
37
-
38
- this.init()
39
-
40
- return this
41
- }
42
-
43
- init () {
22
+ this.init(options)
44
23
  this.build()
45
24
  this.setup()
46
- events.attach(this.options.events, this)
25
+ }
47
26
 
48
- if (this.options.container) {
49
- this.options.container.appendChild(this.element)
50
- }
27
+ init (options) {
28
+ this.options = Object.assign({}, Selector.defaults, options || {})
29
+ Object.assign(this, emitter, attach)
51
30
  }
52
31
 
53
32
  /**
@@ -81,12 +60,15 @@ class Selector {
81
60
  this.element.appendChild(this.resizer)
82
61
  }
83
62
 
84
- return this
63
+ if (this.options.container) {
64
+ this.options.container.appendChild(this.element)
65
+ }
85
66
  }
86
67
 
87
68
  setup () {
88
- if (!this.options.src) return
69
+ events.attach(this.options.events, this)
89
70
 
71
+ if (!this.options.src) return
90
72
  this.setTarget(this.options.element)
91
73
  }
92
74
 
package/src/slider.js CHANGED
@@ -12,75 +12,53 @@ import emitter from './module/emitter'
12
12
 
13
13
  import icon from './skin/material/icon/pin.svg'
14
14
 
15
- const defaults = {
16
- prefix: 'material',
17
- class: 'slider',
18
- type: 'control',
19
- label: null,
20
- checked: false,
21
- error: false,
22
- value: false,
23
- range: [0, 100],
24
- step: 5,
25
- modules: [control, emitter],
26
- mixins: [],
27
- build: ['$root.material-slider', {},
28
- ['label$label.slider-label', {}],
29
- ['input$input'],
30
- ['$control.slider-control', {},
31
- ['$track.slider-track', {},
32
- ['canvas$canvas.slider-canvas', {}],
33
- ['$trackvalue.slider-track-value', {}],
34
- ['$knob.slider-knob', {}],
35
- ['$marker.slider-marker', {},
36
- ['$value.slider-value', {}]
15
+ class Slider {
16
+ static defaults = {
17
+ class: 'slider',
18
+ type: 'control',
19
+ label: null,
20
+ checked: false,
21
+ error: false,
22
+ value: false,
23
+ range: [0, 100],
24
+ step: 5,
25
+ modules: [control, emitter],
26
+ mixins: [],
27
+ build: ['$root.material-slider', {},
28
+ ['label$label.slider-label', {}],
29
+ ['input$input'],
30
+ ['$control.slider-control', {},
31
+ ['$track.slider-track', {},
32
+ ['canvas$canvas.slider-canvas', {}],
33
+ ['$trackvalue.slider-track-value', {}],
34
+ ['$knob.slider-knob', {}],
35
+ ['$marker.slider-marker', {},
36
+ ['$value.slider-value', {}]
37
+ ]
37
38
  ]
38
39
  ]
40
+ ],
41
+ events: [
42
+ ['element.input.focus', 'focus'],
43
+ ['element.input.blur', 'blur']
39
44
  ]
40
- ],
41
- events: [
42
- ['element.input.focus', 'focus'],
43
- ['element.input.blur', 'blur']
44
- ]
45
- }
46
-
47
- /**
48
- * Switch class
49
- * @class
50
- * @extends Control
51
- */
52
- class Slider {
53
- static uid = "material-slider";
45
+ }
54
46
 
55
- /**
56
- * init
57
- * @return {Object} The class options
58
- */
59
47
  constructor (options) {
60
- this.options = Object.assign({}, defaults, options || {})
61
-
62
48
  this.init(this.options)
63
49
  this.build(this.options)
64
- events.attach(this.options.events, this)
65
-
66
- return this
50
+ this.setup()
67
51
  }
68
52
 
69
- /**
70
- * Constructor
71
- * @param {Object} options The class options
72
- * @return {Object} This class instance
73
- */
74
53
  init (options) {
54
+ this.options = Object.assign({}, Slider.defaults, options || {})
75
55
  init(this)
56
+ }
76
57
 
77
- return this
58
+ setup () {
59
+ events.attach(this.options.events, this)
78
60
  }
79
61
 
80
- /**
81
- * build method
82
- * @return {Object} The class instance
83
- */
84
62
  build () {
85
63
  this.element = build(this.options.build)
86
64
  this.element = this.element.root
package/src/snackbar.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // base class
2
2
  import EventEmitter from './mixin/emitter'
3
3
  // related modules
4
- import build from './module/build'
4
+ import build from './mixin/build'
5
5
  import events from './module/events'
6
6
  import display from './mixin/display'
7
7
  // ui element
package/src/switch.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // base
2
2
  import EventEmitter from './mixin/emitter'
3
3
  // module
4
- import build from './module/build'
4
+ import build from './mixin/build'
5
5
  import dataset from './module/dataset'
6
6
  import events from './module/events'
7
7
  import attributes from './module/attributes'
package/src/switcher.js CHANGED
@@ -23,7 +23,7 @@ class Switcher extends EventEmitter {
23
23
  }
24
24
 
25
25
  init (options) {
26
- this.options = Object.assign({}, Switcher.defaults, options || {})
26
+ this.options = { ...Switcher.defaults, ...options }
27
27
  }
28
28
 
29
29
  build () {