beyond-rails 0.0.185 → 0.0.190
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/src/js/components/Alert.js +1 -1
- data/src/js/components/Autocomplete.js +1 -1
- data/src/js/components/AutocompleteMenu.js +1 -1
- data/src/js/components/BarChart.js +452 -0
- data/src/js/components/Btn.js +1 -1
- data/src/js/components/Checkbox.js +1 -1
- data/src/js/components/DateInput.js +1 -1
- data/src/js/components/DateMenu.js +1 -1
- data/src/js/components/DateTimeRanger.js +1 -1
- data/src/js/components/Datepicker.js +1 -1
- data/src/js/components/DatepickerBtnArrow.js +1 -1
- data/src/js/components/Dropdown.js +1 -1
- data/src/js/components/LineChart.js +535 -0
- data/src/js/components/Menu.js +1 -1
- data/src/js/components/Modal.js +64 -13
- data/src/js/components/Navbar.js +1 -1
- data/src/js/components/Radio.js +1 -1
- data/src/js/components/SearchDropdown.js +1 -1
- data/src/js/components/Sidebar.js +1 -1
- data/src/js/components/Tabbox.js +1 -1
- data/src/js/components/TimeInput.js +1 -1
- data/src/js/components/TimeMenu.js +1 -1
- data/src/js/components/Timepicker.js +1 -1
- data/src/js/components/Toast.js +1 -1
- data/src/js/components/ToastItem.js +1 -1
- data/src/js/components/Tooltip.js +1 -1
- data/src/js/decorators/chartCommon.js +218 -0
- data/src/js/{utils → decorators}/supportDom.js +1 -1
- data/src/js/index.js +6 -2
- data/src/js/jquery/bindModalFn.js +57 -6
- data/src/js/utils/index.js +10 -1
- data/src/js/utils/isDef.js +3 -0
- data/src/js/utils/isInt.js +3 -0
- data/src/js/utils/isUndef.js +3 -0
- data/src/sass/_beyond.scss +2 -0
- data/src/sass/abstracts/_variables.scss +5 -0
- data/src/sass/components/_breadcrumb.scss +3 -0
- data/src/sass/components/_chart.scss +14 -0
- data/src/sass/components/_mega-menu.scss +57 -0
- data/src/sass/components/_modal.scss +12 -1
- data/src/sass/components/_nav.scss +1 -0
- data/src/sass/layout/_flex-util.scss +3 -0
- metadata +34 -15
data/src/js/components/Menu.js
CHANGED
data/src/js/components/Modal.js
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
import supportDom from '../
|
1
|
+
import supportDom from '../decorators/supportDom'
|
2
2
|
import { noop } from '../utils'
|
3
3
|
|
4
|
+
let globalModalId = 0
|
5
|
+
|
4
6
|
@supportDom
|
5
7
|
export default class Modal {
|
6
8
|
|
@@ -15,19 +17,41 @@ export default class Modal {
|
|
15
17
|
}
|
16
18
|
|
17
19
|
init() {
|
18
|
-
this.
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
}
|
20
|
+
this.bindEvents()
|
21
|
+
}
|
22
|
+
|
23
|
+
bindEvents() {
|
24
|
+
this.setModalDom()
|
24
25
|
this.closeBtn = this.modal.querySelector('[data-close]')
|
25
26
|
this.cancelBtn = this.modal.querySelector('[data-cancel]')
|
26
27
|
this.confirmBtn = this.modal.querySelector('[data-confirm]')
|
27
28
|
this.addEvents()
|
28
29
|
}
|
29
30
|
|
30
|
-
|
31
|
+
setModalDom() {
|
32
|
+
const { modalOpener, modal } = this.dom.dataset
|
33
|
+
|
34
|
+
if (modalOpener) {
|
35
|
+
this.modalId = this.dom.dataset.modalOpener
|
36
|
+
const selector = `[data-modal="${this.modalId}"]`
|
37
|
+
this.modal = document.querySelector(selector)
|
38
|
+
return
|
39
|
+
}
|
40
|
+
|
41
|
+
if (modal) {
|
42
|
+
this.modalId = modal
|
43
|
+
}
|
44
|
+
else {
|
45
|
+
this.modalId = `modal-${++globalModalId}`
|
46
|
+
this.dom.dataset.modal = this.modalId
|
47
|
+
}
|
48
|
+
this.modal = this.dom
|
49
|
+
}
|
50
|
+
|
51
|
+
show(html) {
|
52
|
+
if (html) {
|
53
|
+
this.replace(html)
|
54
|
+
}
|
31
55
|
this.isVisible = true
|
32
56
|
this.modal.style.display = 'block'
|
33
57
|
setTimeout(() => {
|
@@ -43,20 +67,47 @@ export default class Modal {
|
|
43
67
|
}, 300)
|
44
68
|
}
|
45
69
|
|
70
|
+
replace(html) {
|
71
|
+
this.destroy()
|
72
|
+
this.modalId = null
|
73
|
+
|
74
|
+
// replace with new dom
|
75
|
+
const div = document.createElement('div')
|
76
|
+
div.innerHTML = html.trim()
|
77
|
+
const dom = div.firstChild
|
78
|
+
this.dom.parentNode.replaceChild(dom, this.dom)
|
79
|
+
|
80
|
+
this.dom = dom
|
81
|
+
this.dom._modal = this
|
82
|
+
this.init()
|
83
|
+
}
|
84
|
+
|
85
|
+
visible() {
|
86
|
+
return this.isVisible
|
87
|
+
}
|
88
|
+
|
89
|
+
addEventIfDomExists(dom, event, cb) {
|
90
|
+
if (dom) {
|
91
|
+
this.addEvent(dom, event, cb)
|
92
|
+
}
|
93
|
+
}
|
94
|
+
|
46
95
|
addEvents() {
|
47
|
-
|
96
|
+
if (this.dom.dataset.modalOpener) {
|
97
|
+
this.addEventIfDomExists(this.dom, 'click', () => this.show())
|
98
|
+
}
|
48
99
|
|
49
|
-
this.
|
100
|
+
this.addEventIfDomExists(this.closeBtn, 'click', () => {
|
50
101
|
this.hide()
|
51
102
|
this.options.cancel('close')
|
52
103
|
})
|
53
104
|
|
54
|
-
this.
|
105
|
+
this.addEventIfDomExists(this.cancelBtn, 'click', () => {
|
55
106
|
this.hide()
|
56
107
|
this.options.cancel('cancel')
|
57
108
|
})
|
58
109
|
|
59
|
-
this.
|
110
|
+
this.addEventIfDomExists(this.modal, 'click', event => {
|
60
111
|
// is backdrop
|
61
112
|
if (event.target.dataset.modal === this.modalId) {
|
62
113
|
this.hide()
|
@@ -64,7 +115,7 @@ export default class Modal {
|
|
64
115
|
}
|
65
116
|
})
|
66
117
|
|
67
|
-
this.
|
118
|
+
this.addEventIfDomExists(this.confirmBtn, 'click', () => {
|
68
119
|
if (typeof this.options.confirm === 'function') {
|
69
120
|
this.options.confirm()
|
70
121
|
}
|
data/src/js/components/Navbar.js
CHANGED
data/src/js/components/Radio.js
CHANGED
data/src/js/components/Tabbox.js
CHANGED
data/src/js/components/Toast.js
CHANGED
@@ -0,0 +1,218 @@
|
|
1
|
+
import isDef from '../utils/isDef'
|
2
|
+
import isUndef from '../utils/isUndef'
|
3
|
+
import { getDomPos, range, toPixel, isFunction } from '../utils'
|
4
|
+
|
5
|
+
export default function chartCommon(target) {
|
6
|
+
|
7
|
+
return class extends target {
|
8
|
+
|
9
|
+
init() {
|
10
|
+
this.layers = []
|
11
|
+
if (isFunction(super.init)) {
|
12
|
+
super.init()
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
get firstLayer() {
|
17
|
+
return this.layers[0]
|
18
|
+
}
|
19
|
+
|
20
|
+
addLayer() {
|
21
|
+
const { dom } = this
|
22
|
+
const canvas = document.createElement('canvas')
|
23
|
+
canvas.style.position = 'absolute'
|
24
|
+
canvas.style.top = 0
|
25
|
+
canvas.style.left = 0
|
26
|
+
canvas.style.right = 0
|
27
|
+
canvas.style.bottom = 0
|
28
|
+
const ctx = canvas.getContext('2d')
|
29
|
+
|
30
|
+
this.setCanvasSize(canvas)
|
31
|
+
this.layers.push({ canvas, ctx })
|
32
|
+
|
33
|
+
dom.style.position = 'relative'
|
34
|
+
dom.appendChild(canvas)
|
35
|
+
}
|
36
|
+
|
37
|
+
bindMedia() {
|
38
|
+
if (this.media) {
|
39
|
+
return
|
40
|
+
}
|
41
|
+
this.media = window.matchMedia(`(resolution: ${this.dpr}dppx)`)
|
42
|
+
this._handleDprChange = this.handleDprChange.bind(this)
|
43
|
+
this.media.addListener(this._handleDprChange)
|
44
|
+
}
|
45
|
+
|
46
|
+
clear() {
|
47
|
+
const { ctx } = this
|
48
|
+
ctx.fillStyle = this.bgColor
|
49
|
+
ctx.fillRect(0, 0, this.width, this.height)
|
50
|
+
}
|
51
|
+
|
52
|
+
fillCircle(ctx, x, y, radius, style, alpha) {
|
53
|
+
ctx.save()
|
54
|
+
ctx.beginPath()
|
55
|
+
ctx.arc(x, y, radius, 0, 2 * Math.PI)
|
56
|
+
ctx.fillStyle = style
|
57
|
+
ctx.globalAlpha = alpha || 1
|
58
|
+
ctx.fill()
|
59
|
+
ctx.closePath()
|
60
|
+
ctx.restore()
|
61
|
+
}
|
62
|
+
|
63
|
+
getAutoStep(firstValue, lastValue, pointsLength) {
|
64
|
+
return (lastValue - firstValue) / (pointsLength - 1)
|
65
|
+
}
|
66
|
+
|
67
|
+
getHighestCanvas() {
|
68
|
+
const { layers, canvas } = this
|
69
|
+
if (layers.length === 0) {
|
70
|
+
return canvas
|
71
|
+
}
|
72
|
+
return layers[layers.length - 1].canvas
|
73
|
+
}
|
74
|
+
|
75
|
+
// real position in window including scrolling distance
|
76
|
+
getMousePos(canvasMousePos) {
|
77
|
+
const domPos = getDomPos(this.dom)
|
78
|
+
return {
|
79
|
+
x: domPos.x + canvasMousePos.x,
|
80
|
+
y: domPos.y + canvasMousePos.y
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
84
|
+
getMousePosInCanvas(event) {
|
85
|
+
const rect = this.canvas.getBoundingClientRect()
|
86
|
+
return {
|
87
|
+
x: event.clientX - rect.left,
|
88
|
+
y: event.clientY - rect.top
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
getLengthTotalData(gap, gutter, values, measureLength, toLabel) {
|
93
|
+
|
94
|
+
const valueCount = values.length
|
95
|
+
const marked = {}
|
96
|
+
|
97
|
+
// mark the first and last
|
98
|
+
marked[0] = true
|
99
|
+
marked[valueCount - 1] = true
|
100
|
+
|
101
|
+
// Check whether a value can be marked next
|
102
|
+
// For example, gap is 2
|
103
|
+
//
|
104
|
+
// values: 1 2 3 4 5 6 7
|
105
|
+
// marked: v v
|
106
|
+
//
|
107
|
+
// 4 will only be marked because it has enough gap on left and right side.
|
108
|
+
const hasGap = index => {
|
109
|
+
return range(index - gap, index).every(i => isUndef(marked[i])) &&
|
110
|
+
range(index + 1, index + gap + 1).every(i => isUndef(marked[i]))
|
111
|
+
}
|
112
|
+
|
113
|
+
return values.reduce((res, value, i) => {
|
114
|
+
|
115
|
+
if (i === 0) {
|
116
|
+
const label = toLabel(value)
|
117
|
+
const length = measureLength(label)
|
118
|
+
const lengthTotal = res.lengthTotal + length + gutter
|
119
|
+
const rows = res.rows.slice()
|
120
|
+
rows.push({ label, length, value })
|
121
|
+
return { lengthTotal, rows }
|
122
|
+
}
|
123
|
+
if (i === (valueCount - 1)) {
|
124
|
+
const label = toLabel(value)
|
125
|
+
const length = measureLength(label)
|
126
|
+
const lengthTotal = res.lengthTotal + length
|
127
|
+
const rows = res.rows.slice()
|
128
|
+
rows.push({ label, length, value })
|
129
|
+
return { lengthTotal, rows }
|
130
|
+
}
|
131
|
+
if (hasGap(i)) {
|
132
|
+
const label = toLabel(value)
|
133
|
+
marked[i] = true
|
134
|
+
const length = measureLength(label)
|
135
|
+
const lengthTotal = res.lengthTotal + length + gutter
|
136
|
+
const rows = res.rows.slice()
|
137
|
+
rows.push({ label, length, value })
|
138
|
+
return { lengthTotal, rows }
|
139
|
+
}
|
140
|
+
return res
|
141
|
+
}, {
|
142
|
+
lengthTotal: 0,
|
143
|
+
rows: []
|
144
|
+
})
|
145
|
+
}
|
146
|
+
|
147
|
+
getStepStartEnd(step, firstValue, lastValue) {
|
148
|
+
|
149
|
+
const stepStart = parseInt(firstValue / step, 10) * step
|
150
|
+
let stepEnd = parseInt(lastValue / step, 10) * step
|
151
|
+
|
152
|
+
if (stepEnd < lastValue) {
|
153
|
+
stepEnd += step
|
154
|
+
}
|
155
|
+
return [stepStart, stepEnd]
|
156
|
+
}
|
157
|
+
|
158
|
+
raf(fn) {
|
159
|
+
if (isDef(window.requestAnimationFrame)) {
|
160
|
+
return window.requestAnimationFrame(fn)
|
161
|
+
}
|
162
|
+
return fn()
|
163
|
+
}
|
164
|
+
|
165
|
+
removeAllLayers() {
|
166
|
+
const { dom } = this
|
167
|
+
this.layers.forEach(layer => {
|
168
|
+
const { canvas } = layer
|
169
|
+
if (dom.contains(canvas)) {
|
170
|
+
dom.removeChild(canvas)
|
171
|
+
}
|
172
|
+
})
|
173
|
+
}
|
174
|
+
|
175
|
+
setCanvas() {
|
176
|
+
const canvas = document.createElement('canvas')
|
177
|
+
const ctx = canvas.getContext('2d')
|
178
|
+
|
179
|
+
this.canvas = canvas
|
180
|
+
this.ctx = ctx
|
181
|
+
this.setCanvasFontSize(this.canvas, this.fontSize)
|
182
|
+
this.setCanvasSize(canvas)
|
183
|
+
|
184
|
+
this.dom.appendChild(canvas)
|
185
|
+
}
|
186
|
+
|
187
|
+
setCanvasFontSize(canvas, fontSize) {
|
188
|
+
const ctx = canvas.getContext('2d')
|
189
|
+
const args = ctx.font.split(' ')
|
190
|
+
ctx.font = fontSize + 'px ' + args[args.length - 1]
|
191
|
+
}
|
192
|
+
|
193
|
+
setCanvasSize(canvas) {
|
194
|
+
const { dpr, width, height } = this
|
195
|
+
|
196
|
+
// https://coderwall.com/p/vmkk6a/how-to-make-the-canvas-not-look-like-crap-on-retina
|
197
|
+
canvas.width = width * dpr
|
198
|
+
canvas.height = height * dpr
|
199
|
+
canvas.style.width = toPixel(width)
|
200
|
+
canvas.style.height = toPixel(height)
|
201
|
+
canvas.getContext('2d').scale(dpr, dpr)
|
202
|
+
}
|
203
|
+
|
204
|
+
setDomWidthIfNeeded() {
|
205
|
+
if (isUndef(this.options.width)) {
|
206
|
+
this.width = this.dom.offsetWidth
|
207
|
+
}
|
208
|
+
}
|
209
|
+
|
210
|
+
setDpr() {
|
211
|
+
this.dpr = window.devicePixelRatio || 1
|
212
|
+
}
|
213
|
+
|
214
|
+
unbindMedia() {
|
215
|
+
this.media.removeListener(this._handleDprChange)
|
216
|
+
}
|
217
|
+
}
|
218
|
+
}
|
data/src/js/index.js
CHANGED
@@ -6,19 +6,21 @@ import './polyfills/nodeRemove'
|
|
6
6
|
import './polyfills/elementDataset'
|
7
7
|
import Alert from './components/Alert'
|
8
8
|
import Autocomplete from './components/Autocomplete'
|
9
|
+
import BarChart from './components/BarChart'
|
9
10
|
import Btn from './components/Btn'
|
10
11
|
import Checkbox from './components/Checkbox'
|
11
12
|
import DateTimeRanger from './components/DateTimeRanger'
|
12
13
|
import Datepicker from './components/Datepicker'
|
13
14
|
import Dropdown from './components/Dropdown'
|
15
|
+
import LineChart from './components/LineChart'
|
14
16
|
import Menu from './components/Menu'
|
15
17
|
import Modal from './components/Modal'
|
16
18
|
import Navbar from './components/Navbar'
|
17
19
|
import Radio from './components/Radio'
|
18
20
|
import SearchDropdown from './components/SearchDropdown'
|
19
21
|
import Sidebar from './components/Sidebar'
|
20
|
-
import Timepicker from './components/Timepicker'
|
21
22
|
import Tabbox from './components/Tabbox'
|
23
|
+
import Timepicker from './components/Timepicker'
|
22
24
|
import Toast from './components/Toast'
|
23
25
|
import Tooltip from './components/Tooltip'
|
24
26
|
import bind from './utils/bind'
|
@@ -28,19 +30,21 @@ import unbindAll from './utils/unbindAll'
|
|
28
30
|
export {
|
29
31
|
Alert,
|
30
32
|
Autocomplete,
|
33
|
+
BarChart,
|
31
34
|
Btn,
|
32
35
|
Checkbox,
|
33
36
|
DateTimeRanger,
|
34
37
|
Datepicker,
|
35
38
|
Dropdown,
|
39
|
+
LineChart,
|
36
40
|
Menu,
|
37
41
|
Modal,
|
38
42
|
Navbar,
|
39
43
|
Radio,
|
40
44
|
SearchDropdown,
|
41
45
|
Sidebar,
|
42
|
-
Timepicker,
|
43
46
|
Tabbox,
|
47
|
+
Timepicker,
|
44
48
|
Toast,
|
45
49
|
Tooltip,
|
46
50
|
bind,
|