حقل الإكمال التلقائي
Combobox / Autocompleterole="combobox"
اسمه كمانكومبوبوكس، أوتوكومبليت، الإكمال التلقائي، حقل بحث بقائمة، قائمة منسدلة قابلة للكتابة، حقل اقتراحات، autocomplete، typeahead، autosuggest، searchable select، filterable dropdown، lookup field
حقل الإكمال التلقائي حقل نصّ قابل للتحرير مربوط بلائحة خيارات تضيق مع كل حرف يكتبه المستخدم، وينتهي دائماً باختيار عنصر واحد من مجموعة تعرفها الواجهة سلفاً. وثلاثة عناصر تشبهه على الشاشة. الأوّل القائمة المنسدلة العادية (select): ليس فيها نصّ قابل للتحرير، والكتابة داخلها تنقل التحديد إلى أقرب خيار مطابق ولا تُصفّي اللائحة. والدور لا يفصل بينهما، لأن HTML يمنح <select> ذا السطر الواحد الدور نفسه role="combobox" الذي تعطيه ARIA 1.2 للنسخة المصنوعة يدوياً؛ والفارق وجود <input> يقبل التحرير وقيمة aria-autocomplete التي تصف نوع الإكمال. والثاني حقل البحث: يأخذ نصّاً حرّاً ويرسله استعلاماً، وما يخرج منه جملة كتبها المستخدم لا معرّف صفّ في قاعدة بيانات، ولهذا يصحّ فيه ما لا يطابق شيئاً. والثالث القائمة (menu): بنودها role="menuitem" تُطلق أوامر ولا تحمل قيمة، ولوحة الأوامر تُحسب معها رغم أنها تُبنى غالباً بدوري combobox و listbox، لأن Enter فيها يُنفّذ إجراءً بدل أن يكتب قيمة. ويحسم الأمر ما يبقى في الحقل بعد Enter: معرّف خيار يعني حقل إكمال، ونصّ كتبه المستخدم يعني حقل بحث، وحقل فارغ مع أمر جرى تنفيذه يعني قائمة.
لو قلت عليه…
العيّنة الحيّة
تفاعل مع الديمو. كل الأجزاء حقيقية ومرقّمة.
تشريح العنصر: كل جزء واسمه
مرّر على أي سطر ليتحدّد مكانه في الديمو فوق.
برومبت البناء
سلوكه في الاتجاه من اليمين لليسار
الجزء ده حصري عندنا.
محاذاة اللائحة والطبقة العليا
ينعكساللائحة تلتصق بالحافّة المنطقية الأولى للحقل: يمينه في العربية ويساره في الإنجليزية، فاكتبها inset-inline-start: 0 داخل حاوية position: relative. والفخّ في طريقة رفعها فوق بقيّة الصفحة: createPortal إلى document.body ينقل العقدة خارج شجرتك فتنقطع وراثة dir="rtl"، فيرتدّ النصّ إلى محاذاة اليسار، وتقرأ Floating UI قيمة direction بـ getComputedStyle من العنصر العائم نفسه فتحسبه ltr وتضع المحاذاة المنطقية start في الجهة الخطأ. ضع سمة dir على عنصر الـ portal نفسه، أو على <html> حتى لا يفلت منها شيء. والمخرج النظيف سمة popover مع CSS anchor positioning: الأولى ترفع الصندوق إلى الطبقة العليا وقت الرسم وهو باقٍ في مكانه من الشجرة فتسلم الوراثة، والثانية تحاذيه مع حقل يقع في أي موضع من المستند، و position-area تقبل الكلمات المنطقية مثل block-end span-inline-end فتنعكس وحدها.
مؤشّر التحميل
لا ينعكسموضع مؤشّر التحميل ينعكس، ورسمته لا تنعكس. ثبّته بـ inset-inline-end حتى ينتقل إلى يسار الحقل في العربية، ولا تضع scaleX(-1) عليه ولا على أي عنصر يحويه: قلب المحور يعكس اتجاه الدوران فيلفّ عكس عقارب الساعة ويبدو معطوباً. والقاعدة الشاملة [dir="rtl"] svg { transform: scaleX(-1) } هي السبب المعتاد، فاقصر القلب على صنف تضعه على الأسهم وحدها. والمؤشّر المرسوم بـ conic-gradient لا تمسّه قيمة direction إطلاقاً، لأن زوايا التدرّج المخروطي تدور مع عقارب الساعة من الأعلى دائماً وليس للتدرّجات صيغة منطقية أصلاً، لكنه يبقى عرضة للقلب نفسه لو طاله scaleX.
التمييز داخل الكلمة
لا ينعكستمييز مقطع من كلمة عربية يقطعها إلى صناديق سطرية، وهذا وحده لا يكسر الوصل، لأن المتصفّح يصل الحروف عبر حدّ العنصر ما دامت خصائص الخطّ متطابقة ولا يفصل بين الطرفين هامش ولا إطار ولا حشو على المحور السطري. لكن إعطاء المقطع المميّز font-weight: 700 يجلب وجهاً آخر من الخطّ فينقطع الوصل وتظهر «الدوحة» مقطوعة عند موضع المطابقة، وكذلك يفعل letter-spacing و padding داخل السطر. اقصر التمييز على background-color و color. ولا تلفّ المقطع بـ <bdi> ولا تضع عليه unicode-bidi: isolate، فالعزل حدّ اتجاه يقطع الوصل ويجعل المقطع مقطعاً ثنائي الاتجاه مستقلاً قد يُعاد ترتيبه بعيداً عن بقيّة الكلمة.
استعلام عربي فوق تسميات لاتينية
لا ينعكسالمطابقة تفشل في العربية قبل أن يصل الدور إلى الاتجاه: «احمد» لا تطابق «أحمد» لأن includes تقارن نقاط الترميز. و Intl.Collator يسوّي بين أ و إ و ا على sensitivity: "base"، لكنه يبقي آ و ٱ مختلفتين، وهو على أي حال يقارن السلاسل كاملة ولا يبحث عن مقطع داخلها. وحّد الطرفين قبل المقارنة: انزع التشكيل بحذف المدى U+064B إلى U+0652، واحذف التطويل U+0640، وردّ أ إ آ ٱ إلى ا و ى إلى ي، وحوّل الأرقام العربية والفارسية إلى ASCII، مع toLowerCase للطرف اللاتيني. ولفّ الرمز اللاتيني في الصفّ المختلط بـ <bdi>، وإلا جرّته الأرقام أو الفاصلة المجاورة إلى الطرف الآخر من السطر.
مؤشّر النصّ ومفاتيحه
لا ينعكسالحقل يملك مؤشّر النصّ، فتبقى ArrowLeft و ArrowRight للتنقّل بين الحروف ولا تُسنَدان إلى اللائحة إطلاقاً، ولا يحتاج الأمر إلى شرط على الاتجاه في أي مكان. و Home و End هنا تذهبان إلى أوّل النصّ وآخره لا إلى أوّل خيار وآخره، وهذا عكس ما يفعله listbox المجرّد. و selectionStart و selectionEnd إزاحتان منطقيتان داخل السلسلة لا تتغيّران مع اتجاه الصفحة، لكن موضع المؤشّر البصري في نصّ مختلط لا يتزايد معهما، فلا تحسب إحداثيّه بقياس عرض المقطع الذي قبله. ولو كان الحقل نفسه يقبل العربية والرموز اللاتينية معاً، فسمة dir="auto" عليه هي الحلّ: يقرأ المتصفّح أوّل حرف قويّ في القيمة ويضبط اتجاه الحقل عليه، متجاوزاً الأرقام وعلامات الترقيم في طريقه إليه.
أسماؤه في الكود
كل سطر هو كلمة مكتبة واحدة عن نفس الشيء. خد السطر اللي بيكلّم مشروعك.
شوف كمان
آخر تحديث · 2026-08-19