-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #60 from OptimistikSAS/issues/39
#39 opacity button/stroke size/radius button don’t allow the 0 value
- Loading branch information
Showing
10 changed files
with
275 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import PlainNumberSpinBox from '../src/plain/PlainNumberSpinBox.js'; | ||
/** | ||
* @class ElixNumberSpinBox | ||
*/ | ||
export default class ElixNumberSpinBox extends PlainNumberSpinBox {} | ||
|
||
customElements.define('elix-number-spin-box', ElixNumberSpinBox); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,248 @@ | ||
/* eslint-disable class-methods-use-this */ | ||
/* eslint-disable node/no-unpublished-import */ | ||
import { | ||
defaultState, | ||
setState, | ||
state, | ||
stateEffects | ||
} from 'elix/src/base/internal.js'; | ||
import { | ||
SpinBox | ||
} from 'elix/src/base/SpinBox.js'; | ||
|
||
/** | ||
* @class NumberSpinBox | ||
*/ | ||
class NumberSpinBox extends SpinBox { | ||
/** | ||
* @function attributeChangedCallback | ||
* @param {string} name | ||
* @param {string} oldValue | ||
* @param {string} newValue | ||
* @returns {void} | ||
*/ | ||
attributeChangedCallback (name, oldValue, newValue) { | ||
if (name === 'max') { | ||
this.max = parseFloat(newValue); | ||
} else if (name === 'min') { | ||
this.min = parseFloat(newValue); | ||
} else if (name === 'step') { | ||
this.step = parseFloat(newValue); | ||
} else { | ||
super.attributeChangedCallback(name, oldValue, newValue); | ||
} | ||
} | ||
/** | ||
* @function observedAttributes | ||
* @returns {any} observed | ||
*/ | ||
get [defaultState] () { | ||
return Object.assign(super[defaultState], { | ||
max: null, | ||
min: null, | ||
step: 1 | ||
}); | ||
} | ||
|
||
/** | ||
* @function formatValue | ||
* Format the numeric value as a string. | ||
* | ||
* This is used after incrementing/decrementing the value to reformat the | ||
* value as a string. | ||
* | ||
* @param {number} value | ||
* @param {number} precision | ||
* @returns {number} | ||
*/ | ||
formatValue (value, precision) { | ||
return Number(value).toFixed(precision); | ||
} | ||
|
||
/** | ||
* The maximum allowable value of the `value` property. | ||
* | ||
* @type {number|null} | ||
* @default 1 | ||
*/ | ||
get max () { | ||
return this[state].max; | ||
} | ||
/** | ||
* The maximum allowable value of the `value` property. | ||
* | ||
* @type {number|null} | ||
* @default 1 | ||
*/ | ||
set max (max) { | ||
this[setState]({ | ||
max | ||
}); | ||
} | ||
|
||
/** | ||
* The minimum allowable value of the `value` property. | ||
* | ||
* @type {number|null} | ||
* @default 1 | ||
*/ | ||
get min () { | ||
return this[state].min; | ||
} | ||
/** | ||
* @function set | ||
* @returns {void} | ||
*/ | ||
set min (min) { | ||
this[setState]({ | ||
min | ||
}); | ||
} | ||
|
||
/** | ||
* @function parseValue | ||
* @param {number} value | ||
* @param {number} precision | ||
* @returns {int} | ||
*/ | ||
parseValue (value, precision) { | ||
const parsed = precision === 0 ? parseInt(value) : parseFloat(value); | ||
return isNaN(parsed) ? 0 : parsed; | ||
} | ||
/** | ||
* @function stateEffects | ||
* @param {any} state | ||
* @param {any} changed | ||
* @returns {any} | ||
*/ | ||
[stateEffects] (state, changed) { | ||
const effects = super[stateEffects]; | ||
// If step changed, calculate its precision (number of digits after | ||
// the decimal). | ||
if (changed.step) { | ||
const { | ||
step | ||
} = state; | ||
const decimalRegex = /\.(\d)+$/; | ||
const match = decimalRegex.exec(String(step)); | ||
const precision = match && match[1] ? match[1].length : 0; | ||
Object.assign(effects, { | ||
precision | ||
}); | ||
} | ||
|
||
if (changed.max || changed.min || changed.value) { | ||
// The value is valid if it falls between the min and max. | ||
// TODO: We need a way to let other classes/mixins on the prototype chain | ||
// contribute to validity -- if someone else thinks the value is invalid, | ||
// we should respect that, even if the value falls within the min/max | ||
// bounds. | ||
const { | ||
max, | ||
min, | ||
precision, | ||
value | ||
} = state; | ||
const parsed = parseInt(value, precision); | ||
if (value !== '' && isNaN(parsed)) { | ||
Object.assign(effects, { | ||
valid: false, | ||
validationMessage: 'Value must be a number' | ||
}); | ||
} else if (!(max === null || parsed <= max)) { | ||
Object.assign(effects, { | ||
valid: false, | ||
validationMessage: `Value must be less than or equal to ${max}.` | ||
}); | ||
} else if (!(min === null || parsed >= min)) { | ||
Object.assign(effects, { | ||
valid: false, | ||
validationMessage: `Value must be greater than or equal to ${min}.` | ||
}); | ||
} else { | ||
Object.assign(effects, { | ||
valid: true, | ||
validationMessage: '' | ||
}); | ||
} | ||
// We can only go up if we're below max. | ||
Object.assign(effects, { | ||
canGoUp: isNaN(parsed) || state.max === null || parsed <= state.max | ||
}); | ||
|
||
// We can only go down if we're above min. | ||
Object.assign(effects, { | ||
canGoDown: isNaN(parsed) || state.min === null || parsed >= state.min | ||
}); | ||
} | ||
|
||
return effects; | ||
} | ||
|
||
/** | ||
* @function get | ||
* @returns {any} | ||
*/ | ||
get step () { | ||
return this[state].step; | ||
} | ||
/** | ||
* @function set | ||
* @returns {void} | ||
*/ | ||
set step (step) { | ||
if (!isNaN(step)) { | ||
this[setState]({ | ||
step | ||
}); | ||
} | ||
} | ||
|
||
/** | ||
* @function stepDown | ||
* @returns {void} | ||
*/ | ||
stepDown () { | ||
super.stepDown(); | ||
const { | ||
max, | ||
precision, | ||
value | ||
} = this[state]; | ||
let result = this.parseValue(value, precision) - this.step; | ||
if (max !== null) { | ||
result = Math.min(result, max); | ||
} | ||
const { | ||
min | ||
} = this[state]; | ||
if (min === null || result >= min) { | ||
this.value = this.formatValue(result, precision); | ||
} | ||
} | ||
|
||
/** | ||
* @function stepUp | ||
* @returns {void} | ||
*/ | ||
stepUp () { | ||
super.stepUp(); | ||
const { | ||
min, | ||
precision, | ||
value | ||
} = this[state]; | ||
let result = this.parseValue(value, precision) + this.step; | ||
if (min !== null) { | ||
result = Math.max(result, min); | ||
} | ||
const { | ||
max | ||
} = this[state]; | ||
if (max === null || result <= max) { | ||
this.value = this.formatValue(result, precision); | ||
} | ||
} | ||
} | ||
|
||
export default NumberSpinBox; |
10 changes: 10 additions & 0 deletions
10
src/editor/dialogs/se-elix/src/plain/PlainNumberSpinBox.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/* eslint-disable node/no-unpublished-import */ | ||
import PlainSpinBoxMixin from 'elix/src/plain/PlainSpinBoxMixin.js'; | ||
import NumberSpinBox from '../base/NumberSpinBox.js'; | ||
|
||
/** | ||
* @class PlainNumberSpinBox | ||
*/ | ||
class PlainNumberSpinBox extends PlainSpinBoxMixin(NumberSpinBox) {} | ||
|
||
export default PlainNumberSpinBox; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters