Skip to content

Commit

Permalink
fix(input-number): add increase
Browse files Browse the repository at this point in the history
  • Loading branch information
koory1st committed Nov 29, 2023
1 parent 4dee114 commit 14ceb34
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 10 deletions.
3 changes: 2 additions & 1 deletion packages/all/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
"link",
"radio",
"scrollbar",
"input"
"input",
"input-number"
],
"exports": {
".": {
Expand Down
139 changes: 131 additions & 8 deletions packages/input-number/src/lib/input-number.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import a2s from '@svelement-ui/util-array-2-class-string';
import a2st from '@svelement-ui/util-array-2-style-string';
import { createEventDispatcher, onMount, tick } from 'svelte';
import { isNull, isNumber, isUndefined } from '@svelement-ui/utils';
import { isNull, isNumber, isUndefined, isString } from '@svelement-ui/utils';
import { SvelIcon, ArrowDown, Minus, ArrowUp, Plus } from '@svelement-ui/icon';
import SvelInput from '@svelement-ui/input';
Expand All @@ -17,6 +17,13 @@
export let precision = null;
export let max = Infinity;
export let min = -Infinity;
/** @type {number | null | 'max' | 'min'} */
export let valueOnClear = null;
/** @type {number | null} */
export let step = 1;
/** @type {number} */
export let readonly = false;
export let disabled = false;
const dispatch = createEventDispatcher();
Expand All @@ -28,7 +35,6 @@
let inputRef;
let dataCurrentValue = value;
$: dataCurrentValue = value;
let dataUserInput = null;
function getDisplayValue(dataCurrentValue, dataUserInput) {
Expand All @@ -48,7 +54,11 @@
return currentValue;
}
$: displayValue = getDisplayValue(dataCurrentValue, dataUserInput);
let displayValue;
$: {
displayValue = getDisplayValue(dataCurrentValue, dataUserInput);
console.log('%c ---> displayValue: ', 'color:#F0F;', displayValue);
}
function setCurrentValue(v, emitChange) {
const oldVal = dataCurrentValue;
Expand All @@ -73,18 +83,117 @@
if (max < min) {
throw new Error('[InputNumber] min should not be greater than max.');
}
let newVal = Number(value);
if (isNull(value) || Number.isNaN(newVal)) {
let newVal = Number(v);
if (isNull(v) || Number.isNaN(newVal)) {
return null;
}
if (v === '') {
if (valueOnClear === null) {
return null;
}
newVal = isString(valueOnClear) ? { min, max }[valueOnClear] : valueOnClear;
}
// todo:
return newVal;
}
function handleInput(v) {
function handleInput({ detail: v }) {
dataUserInput = v;
const newVal = value === '' ? null : Number(value);
const newVal = v === '' ? null : Number(v);
dispatch('input', newVal);
setCurrentValue(newVal, false);
}
function handleInputChange(e) {
const v = e.detail.target.value;
const newVal = v !== '' ? Number(v) : '';
if ((isNumber(newVal) && !Number.isNaN(newVal)) || v === '') {
setCurrentValue(newVal, true);
}
dataUserInput = null;
}
function handleKeyDown({ detail: { key, ctrlKey } }) {
if (ctrlKey) {
return;
}
if (key === 'ArrowUp') {
increase();
return;
}
if (key === 'ArrowUp') {
increase();
return;
}
if (key === 'ArrowDown') {
// d();
return;
}
}
const getPrecision = (v) => {
if (isNumber(v)) return 0;
const valueString = v.toString();
const dotPosition = valueString.indexOf('.');
let precision = 0;
if (dotPosition !== -1) {
precision = valueString.length - dotPosition - 1;
}
return precision;
};
let inputNumberDisabled = false;
$: minDisabled = isNumber(value) && value <= min;
$: maxDisabled = isNumber(value) && value >= max;
function increase() {
if (readonly || inputNumberDisabled || maxDisabled) return;
const value = Number(displayValue) || 0;
const newVal = ensurePrecision(value);
setCurrentValue(newVal, true);
dispatch('input', dataCurrentValue);
}
function ensurePrecision(val, coefficient = 1) {
if (!isNumber(val)) return dataCurrentValue;
// Solve the accuracy problem of JS decimal calculation by converting the value to integer.
return toPrecision(val + step * coefficient);
}
function toPrecision(num, pre) {
if (isUndefined(pre)) pre = numPrecision;
if (pre === 0) return Math.round(num);
let snum = String(num);
const pointPos = snum.indexOf('.');
if (pointPos === -1) return num;
const nums = snum.replace('.', '').split('');
const datum = nums[pointPos + pre];
if (!datum) return num;
const length = snum.length;
if (snum.charAt(length - 1) === '5') {
snum = `${snum.slice(0, Math.max(0, length - 1))}6`;
}
return Number.parseFloat(Number(snum).toFixed(pre));
}
function getNumPrecision(step, precision) {
const stepPrecision = getPrecision(step);
if (!isUndefined(precision)) {
if (stepPrecision > precision) {
console.log('[InputNumber]precision should not be less than the decimal places of step');
}
return precision;
} else {
return Math.max(getPrecision(value), stepPrecision);
}
}
$: numPrecision = getNumPrecision(step, precision);
function handleIncreaseKeyDown(e) {
console.log('%c ---> e: ', 'color:#F0F;', e);
}
</script>

<div class={classString}>
Expand All @@ -97,7 +206,14 @@
<Minus />
</SvelIcon>
</span>
<span aria-label="increase number" class={increaseClass} role="button">
<span
aria-label="increase number"
class={increaseClass}
role="button"
tabindex="0"
on:click={increase}
on:keydown={handleIncreaseKeyDown}
>
<SvelIcon>
{#if controlsAtRight}
<ArrowUp />
Expand All @@ -109,8 +225,15 @@
<SvelInput
bind:this={inputRef}
bind:value={displayValue}
{disabled}
{max}
{min}
on:change={handleInputChange}
on:input={handleInput}
on:keydown={handleKeyDown}
{placeholder}
{readonly}
{step}
type="number"
/>
</div>
17 changes: 16 additions & 1 deletion packages/input-number/src/routes/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
<script>
import SvelInputNumber from '$lib/index.js';
function input(v) {
console.log('%c ---> v: ', 'color:#F0F;', v);
}
function change(v) {
console.log('%c ---> v: ', 'color:#F0F;', v);
}
let value;
let value2;
</script>

<SvelInputNumber>111</SvelInputNumber>
{value}
<SvelInputNumber bind:value on:change={change} on:input={input} />

{value2}
<SvelInputNumber bind:value={value2} on:change={change} on:input={input} precision={2} step={0.1} />

0 comments on commit 14ceb34

Please sign in to comment.