Skip to content

Commit

Permalink
feat(forms): new component: Quantity Selector (#860)
Browse files Browse the repository at this point in the history
Co-authored-by: Mewen Le Hô <[email protected]>
Co-authored-by: Julien Déramond <[email protected]>
  • Loading branch information
3 people authored Feb 24, 2022
1 parent 2f5ab48 commit 1bfc839
Show file tree
Hide file tree
Showing 16 changed files with 709 additions and 9 deletions.
14 changes: 7 additions & 7 deletions .bundlewatch.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
},
{
"path": "./dist/css/boosted-reboot.min.css",
"maxSize": "3.3 kB"
"maxSize": "3.31 kB"
},
{
"path": "./dist/css/boosted-utilities.css",
Expand All @@ -26,35 +26,35 @@
},
{
"path": "./dist/css/boosted.css",
"maxSize": "29.4 kB"
"maxSize": "29.74 kB"
},
{
"path": "./dist/css/boosted.min.css",
"maxSize": "27.1 kB"
"maxSize": "27.46 kB"
},
{
"path": "./dist/js/boosted.bundle.js",
"maxSize": "46.7 kB"
},
{
"path": "./dist/js/boosted.bundle.min.js",
"maxSize": "23.8 kB"
"maxSize": "24.05 kB"
},
{
"path": "./dist/js/boosted.esm.js",
"maxSize": "31.25 kB"
},
{
"path": "./dist/js/boosted.esm.min.js",
"maxSize": "19.3 kB"
"maxSize": "19.49 kB"
},
{
"path": "./dist/js/boosted.js",
"maxSize": "32.0 kB"
"maxSize": "32.04 kB"
},
{
"path": "./dist/js/boosted.min.js",
"maxSize": "17.1 kB"
"maxSize": "17.24 kB"
}
],
"ci": {
Expand Down
1 change: 1 addition & 0 deletions js/index.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export { default as Dropdown } from './src/dropdown'
export { default as Modal } from './src/modal'
export { default as Offcanvas } from './src/offcanvas'
export { default as Popover } from './src/popover'
export { default as QuantitySelector } from './src/quantity-selector' // Boosted mod
export { default as ScrollSpy } from './src/scrollspy'
export { default as Tab } from './src/tab'
export { default as Toast } from './src/toast'
Expand Down
2 changes: 2 additions & 0 deletions js/index.umd.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import Dropdown from './src/dropdown'
import Modal from './src/modal'
import Offcanvas from './src/offcanvas'
import Popover from './src/popover'
import QuantitySelector from './src/quantity-selector' // Boosted mod
import ScrollSpy from './src/scrollspy'
import Tab from './src/tab'
import Toast from './src/toast'
Expand All @@ -28,6 +29,7 @@ export default {
Modal,
Offcanvas,
Popover,
QuantitySelector, // Boosted mod
ScrollSpy,
Tab,
Toast,
Expand Down
154 changes: 154 additions & 0 deletions js/src/quantity-selector.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/**
* --------------------------------------------------------------------------
* Boosted (v5.1.3): quantity-selector.js
* Licensed under MIT (https://github.com/Orange-OpenSource/Orange-Boosted-Bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/

import { defineJQueryPlugin } from './util/index'
import EventHandler from './dom/event-handler'
import BaseComponent from './base-component'
import SelectorEngine from './dom/selector-engine'

/**
* Constants
*/

const NAME = 'quantityselector'
const DATA_KEY = 'bs.quantityselector'
const EVENT_KEY = `.${DATA_KEY}`
const DATA_API_KEY = '.data-api'

const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`
const EVENT_CHANGE_DATA_API = `change${EVENT_KEY}${DATA_API_KEY}`
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`

const SELECTOR_STEP_UP_BUTTON = '[data-bs-step="up"]'
const SELECTOR_STEP_DOWN_BUTTON = '[data-bs-step="down"]'
const SELECTOR_COUNTER_INPUT = '[data-bs-step="counter"]'
const SELECTOR_INPUT_GROUP = '.input-group'

/**
* Class definition
*/

class QuantitySelector extends BaseComponent {
// Getters
static get NAME() {
return NAME
}

// Public
ValueOnLoad(element) {
const counterInput = element.querySelector(SELECTOR_COUNTER_INPUT)
const btnUp = element.querySelector(SELECTOR_STEP_UP_BUTTON)
const btnDown = element.querySelector(SELECTOR_STEP_DOWN_BUTTON)

const min = counterInput.getAttribute('min')
const max = counterInput.getAttribute('max')
const step = Number(counterInput.getAttribute('step'))

if (Number(counterInput.value) - step < min) {
btnDown.setAttribute('disabled', '')
}

if (Number(counterInput.value) + step > max) {
btnUp.setAttribute('disabled', '')
}
}

// Static
static StepUp(event) {
const parent = event.target.closest(SELECTOR_INPUT_GROUP)
const counterInput = parent.querySelector(SELECTOR_COUNTER_INPUT)

const max = counterInput.getAttribute('max')
const step = Number(counterInput.getAttribute('step'))
const round = Number(counterInput.getAttribute('data-bs-round'))

const eventChange = new Event('change')

if (Number(counterInput.value) < max) {
counterInput.value = (Number(counterInput.value) + step).toFixed(round).toString()
}

counterInput.dispatchEvent(eventChange)
}

static StepDown(event) {
const parent = event.target.closest(SELECTOR_INPUT_GROUP)
const counterInput = parent.querySelector(SELECTOR_COUNTER_INPUT)

const min = counterInput.getAttribute('min')
const step = Number(counterInput.getAttribute('step'))
const round = Number(counterInput.getAttribute('data-bs-round'))

const eventChange = new Event('change')

if (Number(counterInput.value) > min) {
counterInput.value = (Number(counterInput.value) - step).toFixed(round).toString()
}

counterInput.dispatchEvent(eventChange)
}

static CheckIfDisabledOnChange(event) {
const parent = event.target.closest(SELECTOR_INPUT_GROUP)
const counterInput = parent.querySelector(SELECTOR_COUNTER_INPUT)
const btnUp = parent.querySelector(SELECTOR_STEP_UP_BUTTON)
const btnDown = parent.querySelector(SELECTOR_STEP_DOWN_BUTTON)

const min = counterInput.getAttribute('min')
const max = counterInput.getAttribute('max')
const step = Number(counterInput.getAttribute('step'))

btnUp.removeAttribute('disabled', '')
btnDown.removeAttribute('disabled', '')

if (Number(counterInput.value) - step < min) {
btnDown.setAttribute('disabled', '')
}

if (Number(counterInput.value) + step > max) {
btnUp.setAttribute('disabled', '')
}
}

static jQueryInterface(config) {
return this.each(function () {
const data = QuantitySelector.getOrCreateInstance(this, config)

if (typeof config !== 'string') {
return
}

if (typeof data[config] === 'undefined') {
throw new TypeError(`No method named "${config}"`)
}

data[config]()
})
}
}

/**
* Data API implementation
*/

EventHandler.on(document, EVENT_CHANGE_DATA_API, SELECTOR_COUNTER_INPUT, QuantitySelector.CheckIfDisabledOnChange)
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_STEP_UP_BUTTON, QuantitySelector.StepUp)
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_STEP_DOWN_BUTTON, QuantitySelector.StepDown)

EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
for (const el of SelectorEngine.find(SELECTOR_INPUT_GROUP)) {
QuantitySelector.getOrCreateInstance(el).ValueOnLoad(el)
}
})

/**
* jQuery
*/

defineJQueryPlugin(QuantitySelector)

export default QuantitySelector
Loading

0 comments on commit 1bfc839

Please sign in to comment.