input-number —— إدخال الأرقام
يضيف إدخال الأرقام ثلاثة أشياء فوق حقل الإدخال: الخطو (الجمع والطرح وفق step)، الحدّ (عدم تجاوز min/max)، والدقة (المنازل العشرية). يستخرج core/input-number هذه الأمور الثلاثة كحسابات نقية، ولا تتجاوز طبقة UI ربط أحداث زرَّي الزيادة والنقصان.
متى يُستخدم
Section titled “متى يُستخدم”- تنفّذ الأطراف المختلفة
LhInputNumber: اختيار الكمية، إدخال المبالغ، حجم التصفّح. - لا ينبغي استخدامه: الأرقام النصية البحتة (استخدم
core/input، فقد يرغب المستخدم في إدخال «حوالي 10» وهي ليست قيمة صارمة)، والاختيار على هيئة منزلق (استخدمcore/slider، فهو أوضح).
طريقة الاستيراد
Section titled “طريقة الاستيراد”import { incrementValue, decrementValue, shouldDisableIncrement, shouldDisableDecrement, getDisplayValue, getInputNumberAria,} from '@lh-ui/share/core/input-number'import type { LhInputNumberState } from '@lh-ui/share/core/input-number'القصد التصميمي
Section titled “القصد التصميمي”ثلاثة خطوط دفاع في incrementValue / decrementValue:
- القيمة الابتدائية null: عندما يكون
value === nullتُعامل زيادة على أنهاstepونقصان على أنه-step، لا الانطلاق من الصفر—فالمستخدم الذي لم يُدخِل قيمة بعد ويضغط الزائد يجب أن يقفز عند «خطوة واحدة» لا عند «min». - تنقية الدقة: يُنقَّى
precisionعبرsafePrecisionفيshared/sanitizeإلى عدد صحيح ضمن[0, 100]، تفادياً لرمي خطأ RangeError منtoFixed(101). وهذا الخط الدفاعي مشترك معcore/statistic. - احتياط النتيجة غير المحدودة: يرجع
clampSafeالداخلي عند كون النتيجة NaN إلىclamp(0, min, max)—فالخصائص القذرة (step: NaN) لن تجعل القيمة NaN تنتقل إلى العرض.
حكم shouldDisableIncrement هو value !== null && value >= max: فلا تعطيل عند null (الضغط سيصبح القيمة step)، وإنما عند بلوغ الحد الأعلى. ولا يجوز حذف !== null وإلا سيكون زر الزيادة رمادياً عند الإدخال الفارغ.
جدول الدوال
Section titled “جدول الدوال”| الدالة | التوقيع | الإرجاع | الوظيفة |
|---|---|---|---|
incrementValue |
(value: number | null, step: number, min: number, max: number, precision?: number) => number |
القيمة الجديدة | زيادة بمقدار step |
decrementValue |
(value: number | null, step: number, min: number, max: number, precision?: number) => number |
القيمة الجديدة | نقصان بمقدار step |
shouldDisableIncrement |
(state: LhInputNumberState) => boolean |
قيمة منطقية | معطّل أو عند بلوغ الحد الأعلى |
shouldDisableDecrement |
(state: LhInputNumberState) => boolean |
قيمة منطقية | معطّل أو عند بلوغ الحد الأدنى |
getDisplayValue |
(value: number | null, _placeholder: string) => string |
سلسلة العرض | تحويل القيمة إلى سلسلة، و |
clampValue |
نفس shared/sanitize.clamp |
القيمة المحدودة | إعادة تصدير اسم بديل للتوافق |
لاحظ أن المعامل الثاني لـ getDisplayValue وهو _placeholder ذو شرطة سفلية وغير مستخدم في جسم الدالة—فعرض العنصر النائب (placeholder) مسؤولية طبقة UI (فالعنصر النائب ينتمي إلى «تنبيه عند انعدام القيمة»، وهو أمر مختلف عن «عرض القيمة»).
تعريفات الأنواع
Section titled “تعريفات الأنواع”export interface LhInputNumberState { value: number | null min: number max: number step: number disabled: boolean size: LhComponentSize controls: boolean // هل تُعرض زرّا الزيادة والنقصان precision: number | undefined placeholder: string}إمكانية الوصول
Section titled “إمكانية الوصول”يُخرج getInputNumberAria دلالات spinbutton وفق APG:
getInputNumberAria({ value: 5, min: 0, max: 10, step: 1 })// { role: 'spinbutton', 'aria-valuemin': 0, 'aria-valuemax': 10, 'aria-valuenow': 5 }
getInputNumberAria({ value: null, min: 0, max: 10, step: 1 })// { role: 'spinbutton', 'aria-valuemin': 0, 'aria-valuemax': 10 } —— null لا تحمل valuenow- لا تُضاف
aria-valuenowإلا عندvalue != null؛ فتعليقaria-valuenow="NaN"على القيمة الفارغة يجعل قارئ الشاشة يعلن شيئاً شاذاً. - التعطيل يضيف
aria-disabled(لا الاعتماد على disabled الأصلي، لأن بعض الأطراف تستخدم عناصر تحكم مخصّصة). ariaValueTextيضيفaria-valuetext—ويُستخدم عندما لا تكفي القيمة العددية وحدها للتعبير عن الدلالة (مثل «3 أيام» بدلاً من «3»)، وهو مقدَّم على valuenow في الإعلان.
أمثلة الاستخدام
Section titled “أمثلة الاستخدام”import { incrementValue, shouldDisableIncrement } from '@lh-ui/share/core/input-number'
incrementValue(4, 1, 0, 10) // 5incrementValue(null, 2, 0, 10) // 2 (القيمة null تنطلق من step)incrementValue(9, 1, 0, 10) // 10 (الحد الأقصى clamp)incrementValue(9, 1, 0, 10, 2) // 10، وبعد toFixed(2) يُحوَّل إلى NumberdecrementValue(null, 2, 0, 10) // -2 (قبل clamp كان -2، ثم يُ clamp إلى 0)
shouldDisableIncrement({ value: 10, max: 10, min: 0, step: 1, disabled: false, ... }) // trueshouldDisableIncrement({ value: null, max: 10, ... }) // false<!-- Vue3 --><div :class="['lh-input-number', `lh-input-number--${size}`]"> <button v-if="controls" class="lh-input-number__decrease" :disabled="shouldDisableDecrement(state)" aria-label="نقصان" @click="emit('update:modelValue', decrementValue(modelValue, step, min, max, precision))" >−</button> <input class="lh-input-number__input" v-bind="getInputNumberAria({ value: modelValue, min, max, step, disabled })" /> <button v-if="controls" class="lh-input-number__increase" :disabled="shouldDisableIncrement(state)">+</button></div>// Reactconst next = incrementValue(value, step, min, max, precision)return <button onClick={() => onChange(next)} disabled={shouldDisableIncrement(state)}>+</button>// uniapp: زرّا الزيادة والنقصان عبر view + @tap؛ وتُكتب القيمة بعد تغيّر الخطوة بأسلوب متحكَّم به، انتبه لسباق إدخال لوحة المفاتيح مع الزرالأنماط والرموز
Section titled “الأنماط والرموز”| اسم الصنف | الدلالة |
|---|---|
.lh-input-number |
الصنف الأساسي |
.lh-input-number--{small|large} |
حجم معياري (medium هو الافتراضي، بلا صنف تعديل) |
.lh-input-number--disabled |
الحالة المعطّلة |
.lh-input-number__input |
منطقة الإدخال الوسطى |
.lh-input-number__increase / __decrease |
زرّا الزيادة والنقصان |
الارتفاع 32px (وهو ضمن قائمة الاختلافات في «مشروع رموز الارتفاع» إلى جانب input بـ 37px وselect بـ 32px).
ملاحظات
Section titled “ملاحظات”stepصفر أو سالب: لا يتحققincrementValueمن صحة step، فـstep: 0يجعل القيمة ثابتة؛ وعلى طبقة UI ضمان كون step موجباً.- علاقة الدقة بـ step: يدير
precisionعدد منازل العرض فقط، دون محاذاة تلقائية مع step. فـstep: 0.5معprecision: 0ستجعلincrementValue(0, 0.5, ...)يُعرض كـ1(يُحسب أولاً ثم يُقرَّب). - دلالة القيمة الفارغة:
value === nullشيء آخر عنvalue === 0، فالأولى «غير مُدخَلة». وتُعيدgetDisplayValue(null)سلسلة فارغة لا'0'. - التراكم العشري: مشكلة
0.1 + 0.2الكلاسيكية موجودة فعلاً في الخطو؛ ومسارtoFixedالخاص بـprecisionهو خط الدفاع الوحيد، فبضبط precision يكون الأمر مستقراً، وبدونه قد تحصل انحرافات.
@lh-ui/share/core/input-number → incrementValue( )(填好参数后点运行)Copyright © 2024-2026 FengMo WenXue