Skip to content

Commit 8ee13da

Browse files
committed
refactor(LoadingButton): simplify component
1 parent 5133973 commit 8ee13da

File tree

3 files changed

+25
-176
lines changed

3 files changed

+25
-176
lines changed

docs/content/4.0/components/loading-buttons.md

Lines changed: 8 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ toc: true
1010
## Basic example
1111

1212
{{< example >}}
13-
<button type="button" class="btn btn-primary btn-loading">Submit</button>
13+
<button type="button" class="btn btn-primary btn-loading" data-coreui-timeout="2000">Submit</button>
1414
<button type="button" class="btn btn-outline-primary btn-loading">Submit</button>
1515
<button type="button" class="btn btn-ghost-primary btn-loading">Submit</button>
1616
{{< /example >}}
@@ -33,12 +33,6 @@ toc: true
3333
<button type="button" class="btn btn-ghost-warning btn-loading" data-coreui-spinner-type="grow">Submit</button>
3434
{{< /example >}}
3535

36-
## Progress Bar
37-
38-
{{< example >}}
39-
<button type="button" class="btn btn-danger btn-loading" data-coreui-progress="true">Submit</button>
40-
<button type="button" class="btn btn-danger btn-loading" data-coreui-progress="true" data-coreui-spinner="false">Submit</button>
41-
{{< /example >}}
4236

4337
## Usage
4438

@@ -57,9 +51,9 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap
5751
</thead>
5852
<tbody>
5953
<tr>
60-
<td><code>percent</code></td>
61-
<td>number</td>
62-
<td><code>0</code></td>
54+
<td><code>disabledOnLoading</code></td>
55+
<td>boolean</td>
56+
<td><code>false</code></td>
6357
<td></td>
6458
</tr>
6559
<tr>
@@ -76,8 +70,8 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap
7670
</tr>
7771
<tr>
7872
<td><code>timeout</code></td>
79-
<td>number</td>
80-
<td><code>1000</code></td>
73+
<td>boolean | number</td>
74+
<td><code>false</code></td>
8175
<td></td>
8276
</tr>
8377
</tbody>
@@ -97,43 +91,12 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap
9791
<td><code>start</code></td>
9892
<td>
9993
Starts loading.
100-
Shows the multi select's options.
10194
</td>
10295
</tr>
10396
<tr>
10497
<td><code>stop</code></td>
10598
<td>
106-
Stops loading and reset the percent of loaded to the initial value.
107-
</td>
108-
</tr>
109-
<tr>
110-
<td><code>pause</code></td>
111-
<td>
112-
Pauses loading.
113-
</td>
114-
</tr>
115-
<tr>
116-
<td><code>resume</code></td>
117-
<td>
118-
Resumes loading.
119-
</td>
120-
</tr>
121-
<tr>
122-
<td><code>complete</code></td>
123-
<td>
124-
Sets the percent of loaded to the 100%.
125-
</td>
126-
</tr>
127-
<tr>
128-
<td><code>update</code></td>
129-
<td>
130-
Updates the configuration of loading button.
131-
</td>
132-
</tr>
133-
<tr>
134-
<td><code>updatePercent</code></td>
135-
<td>
136-
Sets the percent of loaded to the provided value.
99+
Stops loading.
137100
</td>
138101
</tr>
139102
<tr>
@@ -185,20 +148,12 @@ Multi Select component exposes a few events for hooking into multi select functi
185148
Fires immediately when the stop method is called.
186149
</td>
187150
</tr>
188-
<tr>
189-
<td>
190-
<code>complete.coreui.loading-button</code>
191-
</td>
192-
<td>
193-
Fires immediately when the loading process is completed.
194-
</td>
195-
</tr>
196151
</tbody>
197152
</table>
198153

199154
```js
200155
var myBtnLoading = document.getElementById('myBtnLoading')
201-
myBtnLoading.addEventListener('complete.coreui.loading-button', function () {
156+
myBtnLoading.addEventListener('stop.coreui.loading-button', function () {
202157
// do something...
203158
})
204159
```

js/src/loading-button.js

Lines changed: 17 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -26,33 +26,24 @@ const NAME = 'loading-button'
2626
const DATA_KEY = 'coreui.loading-button'
2727
const EVENT_KEY = `.${DATA_KEY}`
2828

29-
const MAX_PERCENT = 100
30-
const MILLISECONDS = 10
31-
const PROGRESS_BAR_BG_COLOR_LIGHT = 'rgba(255, 255, 255, .2)'
32-
const PROGRESS_BAR_BG_COLOR_DARK = 'rgba(0, 0, 0, .2)'
33-
3429
const EVENT_START = `start${EVENT_KEY}`
3530
const EVENT_STOP = `stop${EVENT_KEY}`
36-
const EVENT_COMPLETE = `complete${EVENT_KEY}`
3731

3832
const CLASS_NAME_IS_LOADING = 'is-loading'
39-
const CLASS_NAME_LOADING_BUTTON_PROGRESS = 'btn-loading-progress'
4033
const CLASS_NAME_LOADING_BUTTON_SPINNER = 'btn-loading-spinner'
4134

4235
const Default = {
43-
percent: 0,
44-
progress: false,
36+
disabledOnLoading: true,
4537
spinner: true,
4638
spinnerType: 'border',
47-
timeout: 1000
39+
timeout: false
4840
}
4941

5042
const DefaultType = {
51-
percent: 'number',
52-
progress: 'boolean',
43+
disabledOnLoading: 'boolean',
5344
spinner: 'boolean',
5445
spinnerType: 'string',
55-
timeout: 'number'
46+
timeout: '(boolean|number)'
5647
}
5748

5849
/**
@@ -66,10 +57,7 @@ class LoadingButton extends BaseComponent {
6657
super(element)
6758

6859
this._config = this._getConfig(config)
69-
this._pause = false
70-
this._percent = this._config.percent
7160
this._timeout = this._config.timeout
72-
this._progressBar = null
7361
this._spinner = null
7462
this._state = 'idle'
7563

@@ -101,30 +89,35 @@ class LoadingButton extends BaseComponent {
10189
start() {
10290
if (this._state !== 'loading') {
10391
this._createSpinner()
104-
this._createProgressBar()
10592

10693
setTimeout(() => {
10794
this._element.classList.add(CLASS_NAME_IS_LOADING)
108-
this._loading()
10995
EventHandler.trigger(this._element, EVENT_START)
96+
97+
if (this._config.disabledOnLoading) {
98+
this._element.setAttribute('disabled', true)
99+
}
110100
}, 1)
101+
102+
if (this._config.timeout) {
103+
setTimeout(() => {
104+
this.stop()
105+
}, this._config.timeout)
106+
}
111107
}
112108
}
113109

114110
stop() {
115111
this._element.classList.remove(CLASS_NAME_IS_LOADING)
116112
const stoped = () => {
117113
this._removeSpinner()
118-
this._removeProgressBar()
119114
this._state = 'idle'
120115

121-
EventHandler.trigger(this._element, EVENT_STOP)
122-
if (this._percent >= 100) {
123-
EventHandler.trigger(this._element, EVENT_COMPLETE)
116+
if (this._config.disabledOnLoading) {
117+
this._element.removeAttribute('disabled')
124118
}
125119

126-
this._percent = this._config.percent
127-
this._timeout = this._config.timeout
120+
EventHandler.trigger(this._element, EVENT_STOP)
128121
}
129122

130123
if (this._spinner) {
@@ -138,35 +131,11 @@ class LoadingButton extends BaseComponent {
138131
stoped()
139132
}
140133

141-
pause() {
142-
this._pause = true
143-
this._state = 'pause'
144-
}
145-
146-
resume() {
147-
this._pause = false
148-
this._loading()
149-
}
150-
151-
complete() {
152-
this._timeout = 1000
153-
}
154-
155-
updatePercent(percent) {
156-
const diff = (this._percent - percent) / 100
157-
this._timeout *= (1 + diff)
158-
this._percent = percent
159-
}
160-
161134
dispose() {
162135
Data.removeData(this._element, DATA_KEY)
163136
this._element = null
164137
}
165138

166-
update(config) {
167-
this._config = this._getConfig(config)
168-
}
169-
170139
_getConfig(config) {
171140
config = {
172141
...Default,
@@ -178,40 +147,6 @@ class LoadingButton extends BaseComponent {
178147
return config
179148
}
180149

181-
_loading() {
182-
const progress = setInterval(() => {
183-
this._state = 'loading'
184-
if (this._percent >= MAX_PERCENT) {
185-
this.stop()
186-
clearInterval(progress)
187-
return
188-
}
189-
190-
if (this._pause) {
191-
clearInterval(progress)
192-
return
193-
}
194-
195-
const frames = this._timeout / (MAX_PERCENT - this._percent) / MILLISECONDS
196-
this._percent = Math.round((this._percent + (1 / frames)) * 100) / 100
197-
this._timeout -= MILLISECONDS
198-
this._animateProgressBar()
199-
}, MILLISECONDS)
200-
}
201-
202-
_createProgressBar() {
203-
if (this._config.progress) {
204-
const progress = document.createElement('div')
205-
progress.classList.add(CLASS_NAME_LOADING_BUTTON_PROGRESS)
206-
progress.setAttribute('role', 'progressbar')
207-
progress.setAttribute('aria-hidden', 'true')
208-
progress.style.backgroundColor = this._progressBarBg()
209-
210-
this._element.insertBefore(progress, this._element.firstChild)
211-
this._progressBar = progress
212-
}
213-
}
214-
215150
_createSpinner() {
216151
if (this._config.spinner) {
217152
const spinner = document.createElement('span')
@@ -224,46 +159,13 @@ class LoadingButton extends BaseComponent {
224159
}
225160
}
226161

227-
_removeProgressBar() {
228-
if (this._config.progress) {
229-
this._progressBar.remove()
230-
this._progressBar = null
231-
}
232-
}
233-
234162
_removeSpinner() {
235163
if (this._config.spinner) {
236164
this._spinner.remove()
237165
this._spinner = null
238166
}
239167
}
240168

241-
_progressBarBg() {
242-
// The yiq lightness value that determines when the lightness of color changes from "dark" to "light". Acceptable values are between 0 and 255.
243-
const yiqContrastedThreshold = 150
244-
const color = window.getComputedStyle(this._element).getPropertyValue('background-color') === 'rgba(0, 0, 0, 0)' ? 'rgb(255, 255, 255)' : window.getComputedStyle(this._element).getPropertyValue('background-color')
245-
246-
const rgb = color.match(/^rgb?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i)
247-
248-
const r = Number.parseInt(rgb[1], 10)
249-
const g = Number.parseInt(rgb[2], 10)
250-
const b = Number.parseInt(rgb[3], 10)
251-
252-
const yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000
253-
254-
if (yiq > yiqContrastedThreshold) {
255-
return PROGRESS_BAR_BG_COLOR_DARK
256-
}
257-
258-
return PROGRESS_BAR_BG_COLOR_LIGHT
259-
}
260-
261-
_animateProgressBar() {
262-
if (this._config.progress) {
263-
this._progressBar.style.width = `${this._percent}%`
264-
}
265-
}
266-
267169
// Static
268170

269171
static loadingButtonInterface(element, config) {

scss/_loading-button.scss

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,6 @@
77
overflow: hidden;
88
}
99

10-
.btn-loading-progress {
11-
position: absolute;
12-
top: 0;
13-
left: 0;
14-
width: 0%;
15-
height: 100%;
16-
}
17-
1810
.btn-loading-spinner {
1911
margin-right: $spacer;
2012
margin-left: - ($spacer * 2);

0 commit comments

Comments
 (0)