calc-input: یه input که فرمول ریاضی قبول میکنه
خلاصهٔ کاملتر
Bramus تو این پست یه Custom Element جدید به اسم معرفی کرده. Custom Element یعنی تگ HTML سفارشی که خودت با JavaScript تعریفش میکنی. نویسنده میگه داشت یه وباپ با کلی فیلد عددی میساخت که مقدارشون باید از یه سند دیگه حساب میشد، مثلاً یه عدد تقسیم بر ۳ منهای یه عدد دیگه. با معمولی باید مدام میرفتی سراغ ماشینحساب و نتیجه رو کپی میکردی. بدتر اینکه بعداً فقط عدد نهایی رو میدیدی و نمیدونستی از چه فرمولی اومده.
حالا با فرمول رو مستقیم تو فیلد مینویسی. وقتی فیلد focus داره، فرمول (مثلاً 2 + 3) دیده میشه و وقتی blur میشه، یعنی از فیلد بیرون میای، نتیجه (5) نمایش داده میشه. دوباره که کلیک کنی فرمول برمیگرده تا بتونی چکش کنی یا تغییرش بدی. از عملگرهای +، -، *، /، %، ^ و **، پرانتزهای تودرتو، اعداد اعشاری و توابعی مثل sqrt، abs، round، floor، ceil، min، max و pow پشتیبانی میکنه. محاسبه با یه recursive-descent parser امن انجام میشه و خبری از eval() نیست، یعنی کاربر نمیتونه کد دلخواه اجرا کنه.
پشت صحنه، این المان سه تا معمولی تو Light DOM میسازه (یعنی بدون Shadow DOM، مستقیم تو خود صفحه) و هر بار فقط یکیشون دیده میشه:
<calc-input name="size" value="2 + 3">
<input type="text" name="size" hidden>
<input type="text" name="size--formula" hidden>
<input type="text" name="size--result">
</calc-input>چون اینها input واقعیان، ارسال فرم و اعتبارسنجی بومی HTML بدون دردسر کار میکنه. اگه یه فرمول ناقص مثل 2 + بنویسی، فیلد با حاشیه قرمز میمونه و با setCustomValidity() جلوی ارسال فرم گرفته میشه.
با ویژگی submit تعیین میکنی چی به سرور بره: formula (پیشفرض) یا result که هر سه فیلد رو میفرستن ولی فیلد اصلی رو با فرمول یا نتیجه پر میکنن، و formula-only یا result-only که فقط فیلد اصلی رو میفرستن. جداکننده -- هم با ویژگی separator عوض میشه. برای استایل، المان از display: contents استفاده میکنه، پس هر CSSی که روی خود calc-input بذاری، مثل border و padding، به input داخلی میرسه. یه نکته جالب هم اینکه اسم اول پروژه formula-input بود ولی تو npm گرفته شده بود و همین شد بهونه ساخت ابزار CLI به اسم caniname.
نکات کلیدی:
- پکیج calc-input از npm یا CDN نصب میشه
- محاسبه با recursive-descent parser انجام میشه، نه eval()
- سه input متنی تو Light DOM میسازه، پس فرم و validation بومی کار میکنن
- ویژگی submit چهار حالت داره: formula، result، formula-only و result-only
- با display: contents استایلها مستقیم به input داخلی میرسن




