التخطّي إلى المحتوى
menumenu tanreiexpand_morecontrasttranslate
tanreiexpand_more
البدءWebReactSwiftUIJetpack ComposeFlutterReact Nativeالإعدادات الجاهزةنظام التصميم الخاص بكاستخدام Tanrei مع وكلاء الذكاء الاصطناعيالعلامة التجاريةرموز التصميمأنظمة التصميم والتخصيصTheme Studioاللونالطباعةالأيقوناتالشكلالارتفاعالحركةحالات التفاعلالسلوكالتخطيطإمكانية الوصولالكلماترموز الألوانرموز السلّم الطباعيرموز الشكلرموز الارتفاعرموز الحركةرموز الحالةرموز التباعد والقياسالمكوّناتالزرزر الإجراء الرئيسيالزر المقسَّممجموعة الأزرارزر مع قائمةشريط الأدواتزر النسخخانة الاختيارزر الاختيارمفتاح التبديلالرقاقةقائمة الخياراتشريط التمريرحقل شريط التمريرالتقويمDateTimePickerمجموعة الحقولمجموعة أزرار الاختيارمجموعة خانات الاختيارعنصر الاختيارحقل الاختيارشريط القوائمرفع الملفاتمنتقي الملفات متقدّمساحة الإفلاتحقل إدخال النص متقدّمحقل النصحقل الرقاقاتالحقلمربع التحرير والسرد متقدّمحقل التحرير والسردحقل إدخال العدد متقدّمحقل العددحقل إدخال اللون متقدّمحقل اللونحقل إدخال الرمز لمرة واحدة متقدّمحقل الرمز لمرة واحدةحقل إدخال النص المدمج متقدّممربع كتابة الرسائلالبطاقةالفاصلالطبقة النمطية متقدّممربع الحوارالقائمة (list)صف القائمةاللوحة السفليةاللوحة الجانبيةالعرض الدوّاركتلة الشيفرةالجدولاللوحة المنبثقةالخطواتالأكورديونقائمة الوصفالشكل التوضيحيهيكل التطبيقرأس الصفحةالعرض الشجريالخط الزمنيمعاينة الصورمقبض تغيير الحجمالإطار القابل لتغيير الحجممنطقة التمريرالشارةمؤشر التقدمالعدّادعارض الأرقام المتحرّكمؤشر التحميلشريط الإشعار (Snackbar)التلميحاختصار لوحة المفاتيحالوسمالشيفرة المضمَّنةالتنويهالصورة الرمزيةالحالة الفارغةمجموعة الوسومهيكل التحميلعنصر الملفمربع اللونالنص المتحركعلامات التبويبعرض التبويباتشريط التطبيقشريط التنقلدرج التنقلالبحثالرابطالتنقل بين الصفحاتروابط السابق والتاليمؤشر الخطواتمسار التنقلجدول المحتوياتبطاقة الرابطقائمة FABالحالةكيف يُبنى Tanreiالمساهمةالترخيص والإسناد
الرئيسيةالمكوّناتاللوحة المنبثقة

اللوحة المنبثقة

تعرض محتوى يقرؤه الشخص ويعمل فيه على سطح صغير يُفتح بجانب عنصر التحكم الذي ضغطه ويبقى معه، من دون تعتيم بقية الصفحة أو حجبها. وفي نافذة مضغوطة، على سطح نمطي بمظهر اللوحة السفلية.

content_copyعرض بتنسيق Markdown
الفئة
الاحتواء
الرموز
comp.popover
المستوى
أساسي

نظرة عامة

Web
tanrei-popover
schedule
SwiftUI
tanreiPopover
radio_button_unchecked
Jetpack Compose
TanreiPopover
radio_button_unchecked
Flutter
TanreiPopover
radio_button_unchecked
React Native
Popover
radio_button_unchecked

مولَّد من docs/status/status.json, specs/popover.spec.json

اضغط زرًّا: ملاحظة فيها رابط، ونموذج قصير له إجراءات

التخزين

الملفات في المهملات تبقى محسوبة من مساحة تخزينك إلى أن تُحذف. كيف تُحسب مساحة التخزين

إعادة تسميةإلغاءإعادة تسمية

استخدم اللوحة المنبثقة (popover) لمحتوى يعمل فيه الشخص بجانب عنصر التحكم الذي فتحها: بضعة إعدادات، أو نموذج قصير، أو لوحة مشاركة، أو ملاحظة تحتاج إلى رابط أو زر. وتبقى بقية الصفحة حولها صالحة للاستخدام. وفي نافذة مضغوطة تأخذ بدلًا من ذلك مظهر اللوحة السفلية عند الحافة السفلية للنافذة، كما تفعل هناك كل لوحة منبثقة وكل مربع حوار في Tanrei.

الاستخدام

عنصر التحكم من عندك. على الويب تسمّيه بالخاصية anchor، وهي المعرّف id للعنصر الذي تقف اللوحة المنبثقة بجانبه. وذلك العنصر هو عنصر الفتح (opener) أيضًا: تخبر اللوحة المنبثقة التقنيات المساعدة بأنه يفتح مربع حوار وهل ذلك المربع مفتوح، وتعيد التركيز إليه. وحيث يكون حقلٌ عنصرَ ارتكاز السطح وزرٌّ داخل الحقل هو ما يفتحه، سمِّ الزر بالخاصية opener.

اللوحة المنبثقة مُتحكَّم بها (controlled)، كما هي قائمة الخيارات. أنت تضبط open حين يُضغط عنصر الفتح، وتعيدها إلى false حين تُصدر اللوحة المنبثقة الحدث close. ولا تُفتح من تلقاء نفسها أبدًا، لا بالتحويم ولا بالتركيز ولا بعد مدة. ويحمل الحدث close سببًا: escape، أو outside، أو focus-out، أو close (زر الإغلاق فيها)، أو anchor-hidden. والإجراء لا يغلق اللوحة المنبثقة أبدًا؛ معالج الحدث عندك هو الذي يغلقها. وحين تُعرض لوحةً سفلية في نافذة مضغوطة، تُرسل outside عند الضغط على حجابها، ولا تُرسل focus-out ولا anchor-hidden أبدًا.

أعطها اسمًا: بالخاصية headline حيث ترسم عنوانًا رئيسيًّا، وبالخاصية label حيث لا ترسمه.

أما SwiftUI و Compose و Flutter و React Native فمخطَّط لها: الأسماء التي بجانب كل منصة في أعلى هذه الصفحة هي ما تعطيها إياه المواصفة، ولا شيء منها متاح هناك بعد.

<tanrei-button id="share" variant="outlined">مشاركة</tanrei-button>

<!-- anchor هي المعرّف id لعنصر التحكم الذي تقف بجانبه. -->
<tanrei-popover id="share-panel" anchor="share" headline="مشاركة هذه الصفحة" closable close-label="إغلاق المشاركة">
  يستطيع قراءتها كل من لديه الرابط.
  <tanrei-button slot="actions" dismissive>إيقاف المشاركة</tanrei-button>
  <tanrei-button slot="actions" confirming>نسخ الرابط</tanrei-button>
</tanrei-popover>

<!-- سطح تحت حقل: بعرض الحقل، والتركيز يبقى في الحقل. -->
<tanrei-text-field id="city" label="المدينة"></tanrei-text-field>
<tanrei-popover anchor="city" label="الاقتراحات" width="anchor" initial-focus="anchor" no-inset>…</tanrei-popover>

<script type="module">
  import '@tanrei/web/components/popover';

  const opener = document.querySelector('#share');
  const panel = document.querySelector('#share-panel');
  // عنصر الفتح يبدّلها. الضغط على عنصر الفتح ليس «خارجها» أبدًا، فلا تغلقها ضغطة واحدة ثم تفتحها من جديد.
  opener.addEventListener('click', () => (panel.open = !panel.open));
  // المفتاح Escape، أو ضغط في الخارج، أو خروج التركيز، أو زر الإغلاق، أو غياب عنصر الارتكاز عن النظر.
  panel.addEventListener('close', (e) => {
    console.log(e.detail.reason);
    panel.open = false;
  });
  // الإجراء لا يغلقها: يغلقها المعالج، حين ينتهي العمل.
  panel.querySelector('[confirming]').addEventListener('click', async () => {
    await navigator.clipboard.writeText(location.href);
    panel.open = false;
  });
</script>
import { useState } from 'react';
import { Button, Popover } from '@tanrei/react';

const [open, setOpen] = useState(false);

<Button id="share" variant="outlined" onClick={() => setOpen(!open)}>مشاركة</Button>
<Popover anchor="share" open={open} headline="مشاركة هذه الصفحة" closable closeLabel="إغلاق المشاركة" onClose={() => setOpen(false)}>
  يستطيع قراءتها كل من لديه الرابط.
  <Button slot="actions" dismissive onClick={stopSharing}>إيقاف المشاركة</Button>
  <Button slot="actions" confirming onClick={copyLink}>نسخ الرابط</Button>
</Popover>

المواصفات

الموضع، وسهم، ولوحة منبثقة بعرض عنصر ارتكازها

فوق، في الوسطالمهملات تبقى محسوبة من مساحة التخزين.بجانبه، عند النهايةالمهملات تبقى محسوبة من مساحة التخزين.بعرض هذا الزرالمهملات تبقى محسوبة من مساحة التخزين.

أين تقف

الخاصية placement تسمّي جهة من عنصر الارتكاز وكيف تُحاذى اللوحة المنبثقة على امتداد تلك الجهة. والقيم الثلاث عشرة هي قيم التلميح، وتُقرأ بالطريقة نفسها.

القيمة أين
bottom-start (الافتراضية)، bottom، bottom-end تحت عنصر الارتكاز: مع تطابق حافتي البداية، أو في الوسط، أو مع تطابق حافتي النهاية
top-start، top، top-end فوق عنصر الارتكاز، بالطرق الثلاث نفسها
start، start-top، start-bottom بجانب عنصر الارتكاز عند بدايته: في الوسط، أو مع تطابق الحافتين العلويتين، أو مع تطابق الحافتين السفليتين
end، end-top، end-bottom بجانب عنصر الارتكاز عند نهايته، بالطرق الثلاث نفسها
auto أول جهة فيها متّسع من الأسفل ثم الأعلى ثم النهاية ثم البداية

البداية والنهاية تتبعان اتجاه التخطيط. والخاصية offset هي المسافة إلى عنصر الارتكاز بوحدات التخطيط في المنصة، وتأخذ قيمة comp.popover.offset حين تتركها. والخاصية crossOffset تحرّك اللوحة المنبثقة على امتداد جهتها، ولا تُخرجها أبدًا عن جهة عنصر الارتكاز.

تُبقي اللوحة المنبثقة المسافة comp.popover.window-margin بينها وبين حواف النافذة من الداخل بهذه الخطوات، وبهذا الترتيب:

  1. تنقلب إلى الجهة المقابلة حين لا يكون في الجهة المفضَّلة متّسع، وتحتفظ بمحاذاتها.
  2. حيث لا متّسع في أي من الجهتين، تأخذ الجهة الأوسع وتُحدّ بذلك المتّسع. وعندئذ يُمرَّر محتواها.
  3. تنزاح على امتداد جهتها بقدر ما يطلبه الهامش.
  4. في نافذة أصغر من أدنى حجم لها، تغطي عنصر الارتكاز ولا تخرج من النافذة.

تتبع عنصر الارتكاز حين يتحرك، وتحتفظ بالجهة التي هي فيها ما دام في تلك الجهة متّسع. وحين لا يبقى أي جزء من عنصر الارتكاز مرئيًّا، تُصدر الحدث close بالسبب anchor-hidden.

الحجم

عرض اللوحة المنبثقة عرض محتواها، بين comp.popover.container.min-width (160) و container.max-width (400). ومع width="anchor" يكون عرضها عرض عنصر الارتكاز، لسطح ينسدل من حقل. ولا تزيد أبدًا على عرض النافذة ناقصًا الهامشين.

ارتفاعها ارتفاع أجزائها، إلى حدّ container.max-height (480) وإلى حدّ المتّسع الذي في جهتها. وما زاد على ذلك يُمرَّر فيه المحتوى بين الترويسة والإجراءات، وهما تبقيان في مكانهما. وما دام المحتوى يُمرَّر يُرسم فاصل تحت الترويسة وآخر فوق الإجراءات. اضبط dividerVisibility على scroll (divider-visibility على الويب) ليُرسم فاصل الترويسة فقط بعد أن يُمرَّر المحتوى، وفاصل الإجراءات فقط ما دام تحتها محتوى آخر؛ ويختار cupertino و m3-like ذلك لكل اللوحات المنبثقة. وترسمه SwiftUI و Compose و Flutter و React Native على هذا النحو إلى أن تلحق.

اضبط inset على false (على الويب: no-inset) لمحتوى له حشو من عنده أو يبلغ الحواف، كالقائمة.

الأجزاء

الجزء ما هو
الترويسة العنوان الرئيسي، وزر الإغلاق ما دامت closable بالقيمة true. تبقى في مكانها حين يُمرَّر المحتوى
المحتوى المنفذ الافتراضي. أي شيء، ومنه الروابط والحقول وعناصر التحكم الأخرى
الإجراءات أزرار Tanrei في المنفذ actions، يُعلَّم كل منها بالخاصية confirming أو dismissive حيث يكون كذلك. توضع كما تضعها مجموعة الأزرار، وتتراصّ عموديًّا حين لا تعود تسمية تتّسع
السهم مثلث اختياري يشير إلى عنصر الارتكاز. الخاصية arrow تفعّله للوحة منبثقة واحدة، والرمز comp.popover.arrow.visible يفعّله لنظام تصميم كامل

الإجراء الذي بلا variant يأخذ قيمة comp.popover.actions.variant (وهي tonal في النظام الافتراضي). وزر الإغلاق زر صغير بأيقونة فقط، طرازه قيمة comp.popover.close-button.variant: وهو tonal في النظام الافتراضي، مثل كل أزرار الإغلاق في Tanrei، كي يُقرأ عنصرَ تحكم فوق أي محتوى. ويحتفظ الإعدادان المسبقان m3-like وcupertino بالرمز وحده بلا خلفية (text).

الحركة

تظهر اللوحة المنبثقة كما يظهر كل سطح في Tanrei: تظهر تدريجيًّا وهي تكبر قليلًا (من 96 % في النظام الافتراضي) من منتصف الحافة المواجهة لعنصر الارتكاز، وتعود عند الإغلاق من الطريق نفسه، أسرع قليلًا. والحركة التي تُقاطَع تنعكس من حيث هي. وحيث الحركة مقلَّلة تظهر وتختفي تدريجيًّا فقط. وفي الإعداد المسبق m3-like تنبسط بدلًا من ذلك من تلك الحافة، كما تفعل قوائم Material. واللوحة المنبثقة المكتوبة بالسمة open في ترميز الصفحة حاضرةٌ منذ الإطار الأول، بلا حركة.

في نافذة مضغوطة

في نافذة أضيق من comp.popover.compact.window-width (600 في النظام الافتراضي)، تأخذ اللوحة المنبثقة مظهر اللوحة السفلية. هذه قاعدة Tanrei لكل لوحة منبثقة ولكل مربع حوار في نافذة مضغوطة. فأنت تفتح اللوحة المنبثقة نفسها بالخصائص والأحداث نفسها؛ ولا يتغير إلا طريقة رسمها.

  • تقع عند الحافة السفلية للنافذة، بعرض النافذة حتى comp.bottom-sheet.container.max-width، بلون اللوحة السفلية وارتفاعها (elevation). وتأخذ زاويتاها العلويتان comp.bottom-sheet.container.shape، وزاويتاها السفليتان قائمتان. وحين تظهر لوحة المفاتيح على الشاشة تستقر فوقها.
  • ارتفاعها بقدر أجزائها، ولا يزيد أبدًا على النافذة ناقصًا comp.bottom-sheet.container.margin-block-start في الأعلى. وما زاد على ذلك يُمرَّر فيه المحتوى بين الرأس والإجراءات.
  • ليس لها سهم ولا مقبض سحب، ولا تتبع السحب. ولا تنطبق عليها placement وoffset وcrossOffset وwidth.
  • هي نمطية: يعتّم حجاب اللوحة السفلية الصفحة، ويصير كل ما خلفها خاملًا، ويبقى التركيز داخلها. ويغلقها المفتاح Escape، والرجوع، والضغط على الحجاب، وزر الإغلاق.
  • تصعد من الحافة السفلية بحركة اللوحة السفلية، وتنزل عائدة حين تُغلق. وحيث الحركة مقلَّلة تظهر وتختفي تدريجيًّا في مكانها.
  • وإذا تجاوز عرض النافذة هذه القيمة واللوحة مفتوحة، تغيّر شكلها فورًا من دون حركة، ويبقى التركيز حيث كان.

اضبط compactPresentation على own (compact-presentation="own" على الويب) لتُبقي لوحة منبثقة واحدة بجانب عنصر ارتكازها في كل نافذة، لسطح يجب أن يبقى بجانب ما ينتمي إليه. واللوحة المنبثقة التي initialFocus="anchor" فيها تبقى دائمًا بجانب عنصر ارتكازها، لأن الحقل الذي يكتب فيه الشخص يجب أن يبقى صالحًا للاستخدام. ونظام التصميم الذي لا يريد اللوحات السفلية أبدًا يضبط comp.popover.compact.window-width على 0.

وقوائم الخيارات ليست لوحات منبثقة هنا: قائمة الخيارات، وقائمة عنصر الاختيار (select) أو مربع التحرير والسرد (combobox)، وقائمة الزر تبقى بجانب عنصر التحكم الخاص بها في كل نافذة.

البنية

الجزء الوصف
1 anchor The element the popover stands beside: the product's own control (a Button, an icon-only Button, a chip, a field). The popover reads its place, never draws or restyles it. It is also the opener — the element a person presses to open the popover, which carries the open state and takes focus back — unless the product names another element as the opener (a field that anchors the surface, with a button inside it that opens it).
2 scrim · اختياري In a compact window only, while the popover is presented as a sheet: the bottom sheet's scrim over everything behind it (POP-40). It blocks presses and asks the popover to close when pressed.
3 container The raised surface that holds everything else, placed on one side of the anchor and aligned along it; in a compact window, with the bottom sheet's appearance at the window's bottom edge (POP-39). It answers no pointer and no press itself and has no states: what is operated is inside it.
4 arrow · اختياري A triangle on the container's edge that faces the anchor, pointing at it; one shape with the container.
5 header · اختياري The row at the top that holds the headline and the close button. It stays in place while the content scrolls.
6 headline · اختياري What the popover is about ("Filters", "Share this page"). It is the popover's accessible name where it is given.
7 close-button · اختياري An icon-only Button of the small size showing the close glyph at the end of the header, in the variant comp.popover.close-button.variant names (tonal in the default system, as every host's close button is). The popover places it and chooses its variant; everything else it reads from Button's own tokens.
8 content Whatever the product puts in the popover: text, links, fields, a list, a few settings. The popover insets it, hands it a content color and scrolls it between the header and the actions; it does not lay it out.
9 divider · اختياري Hairlines across the container below the header and above the actions, drawn only while the content scrolls: for as long as it does in the default system, or only while content lies beyond each line under dividerVisibility scroll.
10 actions · اختياري Tanrei Buttons at the foot of the popover, each marked confirming or dismissive where it is one, laid out as a Button group. A Button whose variant the product did not set is tonal in the default system. Optional: a popover whose content acts at once (a setting, a link) needs none.

الخصائص

الخاصية النوع القيمة الافتراضية الوصف
open boolean false Whether the popover is shown. The product opens it when its opener is pressed, and never on hover or on focus. Where open is a plain value (web, Compose, React Native) the product closes the popover by setting it to false when the popover emits close; where it is a binding or a controller (SwiftUI, Flutter) the popover closes itself through it (POP-21).
placement top | top-start | top-end | bottom | bottom-start | bottom-end | start | start-top | start-bottom | end | end-top | end-bottom | auto "bottom-start" Where the popover prefers to stand: a side of the anchor, and how it lines up along that side (POP-2). The thirteen values are the tooltip's, read the same way; the menu's four are among them. top and bottom centre it above or below the anchor; with -start or -end its start or end edge meets the anchor's. start and end centre it beside the anchor; with -top or -bottom its top or bottom edge meets the anchor's. auto takes the first side with room (POP-3). Start and end follow the layout direction. The popover flips to the opposite side when the preferred one has no room, keeping the alignment (POP-5). The default is the menu's: below the anchor, start edges aligned.
offset number null The distance between the anchor's edge and the popover, in the platform's layout units; 0 lets them touch. Null takes comp.popover.offset, the system's answer for every popover. Set it only where one anchor's box is not what the eye takes for its edge.
crossOffset number 0 How far the popover moves along the side it stands on, in the platform's layout units, from where placement puts it: positive towards the end for a popover above or below, towards the bottom for one beside. It never moves the popover off the anchor's side (POP-4).
arrow boolean null Whether the popover draws an arrow that points at the anchor. Null, the default, takes comp.popover.arrow.visible, the system's choice, which is off in the default system (POP-10).
width content | anchor "content" What decides the container's width. content: as wide as its content, between comp.popover.container.min-width and comp.popover.container.max-width. anchor: as wide as the anchor, for a surface that drops from a field and should read as its continuation (POP-7). A structural choice drawn by code, not a token axis.
compactPresentation sheet | own "sheet" How the popover is presented in a compact window, one narrower than comp.popover.compact.window-width. sheet: with the bottom sheet's appearance at the window's bottom edge, as a modal dialog (POP-39 to POP-41), as every popover and every dialog of Tanrei is there. own: as a popover in every window, beside its anchor and not modal, narrowing to the window (POP-43), for a surface that must stay beside what it belongs to (a note beside the word it explains). initialFocus anchor keeps the popover's own presentation whatever this says. A structural choice drawn by code, not a token axis.
inset boolean true Insets the content by the container's paddings. Set it to false for content that pads itself or reaches the edges (a list whose rows carry their own padding, an image); the header and the actions keep their insets.
initialFocus popover | anchor "popover" Where focus is when the popover has opened. popover: focus moves into it (POP-19), which is right whenever the opener is a button. anchor: focus stays where it is, for a popover that opens under a field the person is typing in, whose keys the field keeps; Tab then moves into the popover (POP-20). It also keeps the popover beside its anchor in a compact window (POP-43): a modal sheet would make the field inert.
headline string "" What the popover is about, drawn in its header and used as its accessible name. Empty draws no headline; the popover is then named by label.
label string "" Names the popover for assistive technology where it draws no headline ("Text formatting"). Never drawn. Required while headline is empty; ignored while headline is given.
closable boolean false Draws the close button at the end of the header. Escape and a press outside already close a popover, so the button is for a popover large enough to cover what a person would press outside it, and for touch, where there is no Escape.
closeLabel string "" The close button's accessible name ("Close filters"). Required while closable is true.
dividerVisibility auto | always | scroll "auto" When the dividers below the header and above the actions are drawn while the content scrolls between them. always: both, for as long as the content scrolls, wherever it is scrolled to. scroll: each only while content lies beyond it — below the header while the content is not at its top, above the actions while more of it lies below. auto takes comp.popover.divider.visibility, the design system's answer (always in the default system). Under every choice a popover whose parts all fit draws none.

المنافذ

المنفذ الوصف
default The content, below the header. A fixture's content string is plain text, which takes sys.typescale.body in the content color (POP-14).
actions The action items: Tanrei Buttons, each marked confirming or dismissive where it is one. The popover places them (POP-15) and gives those without a variant its own (POP-16). A fixture fills it through its items.

الأحداث

الحدث الوصف
close The popover asks to be closed, every overlay opened from inside it with it: Escape or the platform's back, a press outside, focus leaving it, its close button, or its anchor going out of sight. Carries which of these it was, named escape, back, outside, focus-out, close or anchor-hidden (in the platform's casing). An action never causes it (POP-17). A popover presented as a sheet sends escape, back, outside (a press on its scrim) or close, never focus-out or anchor-hidden (POP-40).

العناصر

أنواع العناصر التي يكررها المكوّن. يسرد كل نموذج اختبار عناصره بالترتيب، وتسمّي كل منصة كل نوع بأسلوبها.

action

One action at the foot of the popover: a Tanrei Button, placed by the popover as a Button group places its items and given the popover's variant unless the product set one.

الخاصية النوع القيمة الافتراضية الوصف
variant string "" The Button's variant (filled, tonal, elevated, outlined, text, or one a system added). Empty, the default: the popover gives it the variant comp.popover.actions.variant names, tonal in the default system (POP-16). Set it to give one action another look.
disabled boolean false As the Button's disabled. A disabled action keeps its place and its share of the width.
confirming boolean false The action completes what the popover is for (Apply, Save, Share). Placed at the end of a row and at the top of a column (BGR-13, BGR-14). It decides the place only, never the look (BGR-19).
dismissive boolean false The action backs out (Cancel, Reset). Placed at the start of a row and at the bottom of a column (BGR-13, BGR-14). It decides the place only, never the look (BGR-19).
المنفذ الوصف
label The Button's label, as its default slot. A fixture item's content is this label.
الحدث الوصف
click The action was activated, as the Button's click. The popover does not close by itself (POP-17).
المواصفة Web SwiftUI Jetpack Compose Flutter React Native
العنصر tanrei-button TanreiButton TanreiButton TanreiButton Button
variant · الخاصية variant variant variant variant variant
disabled · الخاصية disabled disabled enabled onPressed disabled
confirming · الخاصية confirming tanreiGroupPlacement(.confirming) Modifier.confirming() TanreiButtonGroupItem.placement confirming
dismissive · الخاصية dismissive tanreiGroupPlacement(.dismissive) Modifier.dismissive() TanreiButtonGroupItem.placement dismissive
click · الحدث click action onClick onPressed onPress
ملاحظات A tanrei-button child with slot="actions": its label is its content. confirming and dismissive are boolean attributes that the popover reads, as the button group does. A Button without a variant attribute takes the popover's variant through the internal controller the group already gives its items (POP-16); the attribute, once written, wins. A TanreiButton in the actions: builder. The flags are the button group's .tanreiGroupPlacement(_:) modifier (one enum: both cannot be set). A Button created with variant: nil reads the popover's variant from an environment value the popover sets (internal to the package). A TanreiButton in the actions lambda, whose receiver is the button group's scope, so the flags are its Modifier.confirming() and Modifier.dismissive(). enabled is disabled's inverse. variant: TanreiButtonVariant? = null takes the popover's from a CompositionLocal (internal to the library). A TanreiButton in actions:; a null onPressed disables it. The flags are the button group's TanreiButtonGroupItem(placement:, child:) (one enum: both cannot be set). A Button with variant: null takes the popover's from an InheritedWidget (internal to the package). A Button in the actions prop. confirming and dismissive are props the popover reads from its actions, as the button group reads them. A Button with no variant takes the popover's from a React context (internal to the package).

الحالات

السلوك

متطلبات بصيغة EARS. يُختبر تنفيذ كل منصة مقابل هذه المعرّفات. يُعرض نص المتطلبات كما ورد في ملف المواصفة، بالإنجليزية.

المعرّف المتطلب
POP-1 WHEN open becomes true THE popover SHALL present its container in the platform's overlay layer, the one the menu's surface uses (the web's top layer through the popover API, an overlay SwiftUI draws above its anchor, Compose's Popup, Flutter's Overlay, React Native's overlay layer that TanreiProvider renders), above the other content of its window at comp.popover.container.elevation; WHILE it is open beside its anchor — in every window but a compact one where it is a sheet (POP-39, POP-40) — THE popover SHALL NOT trap focus, SHALL NOT make any other part of the window inert, unscrollable or hidden from assistive technology and SHALL draw no scrim: it is an operated overlay that is not modal. WHEN open becomes false THE popover SHALL remove the container.
POP-2 THE popover SHALL read placement as a side and an alignment along that side, as the tooltip reads the same thirteen values (TIP-22): top and bottom SHALL put the container above or below the anchor with its centre on the anchor's, top-start and bottom-start with its start edge on the anchor's start edge, and top-end and bottom-end with its end edge on the anchor's end edge; start and end SHALL put it beside the anchor, on the side the layout direction gives that name, with its centre on the anchor's, start-top and end-top with its top edge on the anchor's top edge, and start-bottom and end-bottom with its bottom edge on the anchor's bottom edge. WHEN placement changes while the popover is shown THE popover SHALL take its new place at once, without a motion, keeping its focus.
POP-3 WHILE placement is auto THE popover SHALL try the sides in the order bottom, top, end, start and SHALL take the first that has room for the container within comp.popover.window-margin, or the one with the most room WHEN none has, with its start edge on the anchor's start edge for bottom and top and its top edge on the anchor's top edge for end and start, and SHALL then shift, hold and follow as POP-5 says, keeping the side it took for as long as that side has room.
POP-4 THE popover SHALL take the distance between the anchor's edge and the nearest part of itself — the container's edge, or the arrow's tip while an arrow is drawn — from offset, a number of the platform's layout units used as given, so that 0 lets the two touch, and from comp.popover.offset WHILE offset is null; it SHALL then move the container along its side by crossOffset, before the shift of POP-5, and by no more than leaves comp.popover.arrow.width of the container beside the anchor, so that the popover still stands on the anchor's side and an arrow can still reach the anchor. IF offset is negative or not a finite number THE popover SHALL use comp.popover.offset in its place, IF crossOffset is not a finite number THE popover SHALL use 0, and in debug builds it SHALL report the value it ignored.
POP-5 THE popover SHALL keep its container at least comp.popover.window-margin inside the window's safe area by these steps, in this order: WHEN the preferred side has no room for the container and the opposite side has, it SHALL flip to the opposite side, keeping the alignment; WHEN neither has room it SHALL use the one of the two with more room and limit the container to that room (POP-7 for its width, POP-8 for its height); it SHALL then shift along the side as far as the margin asks and no farther; and WHERE the container is still larger than the room on its side (a window smaller than the popover's least size) it SHALL move the container back into the margin over the anchor, its top and start edges first, rather than leave the window. It SHALL follow the anchor when the anchor moves (scrolling, resizing, layout), taking these steps again from the side it is on, which it SHALL keep for as long as that side has room, so that a page that scrolls does not throw the popover from side to side. WHEN the anchor is removed, hidden, scrolled out of the window, or scrolled out of sight inside a scrolling ancestor so that no part of it can be seen THE popover SHALL emit close once with the reason anchor-hidden and be closed as POP-21 says, because a surface with nothing beside it no longer says what it belongs to.
POP-6 THE popover SHALL fill its container with comp.popover.container.color, raise it by comp.popover.container.elevation, round it by comp.popover.container.shape eased by sys.shape.corner-smoothing (0 is a quarter circle, 0.6 the iOS continuous corner; a platform with only the OS curve draws it for any amount above 0), and clip its header, content and actions to that shape. THE popover SHALL NOT change anything the container draws under a pointer, a press or focus: the container has no hovered, focused or pressed state and draws no state layer.
POP-7 WHILE width is content THE popover SHALL make its container as wide as its widest part (its header, its content, or its actions in one row at their own widths) and its paddings, at least comp.popover.container.min-width and at most comp.popover.container.max-width, wrapping content that would be wider; WHILE width is anchor it SHALL make the container as wide as the anchor, and at least comp.popover.container.min-width where the anchor is narrower, comp.popover.container.max-width not applying, and SHALL follow the anchor's width as it changes. In either case the container SHALL never be wider than the window's safe area less comp.popover.window-margin on each side, narrowing below comp.popover.container.min-width where the window asks it to.
POP-8 THE popover SHALL make its container as tall as its parts and its paddings, at most comp.popover.container.max-height and at most the room its side leaves within comp.popover.window-margin (POP-5). WHEN its parts do not fit in that height THE popover SHALL keep the header and the actions in place and scroll the content between them, SHALL let keyboard focus and assistive technology scroll it, and SHALL draw a divider of comp.popover.divider.width in comp.popover.divider.color across the container below the header and another above the actions: WHILE its divider visibility (POP-38) is always, both for as long as the content scrolls, wherever it is scrolled to, at its top included; WHILE it is scroll, the one below the header only WHILE the content is scrolled away from its top and the one above the actions only WHILE more of it lies below; WHILE everything fits, or there is no header or no action on that side of the content, THE popover SHALL draw no divider there. WHEN the header and the actions alone leave no room for the content (large text in a short window) THE popover SHALL scroll all of its parts together instead, so that nothing is cut off or unreachable. The dividers SHALL be hidden from assistive technology and SHALL show and hide at once, without motion.
POP-9 THE popover SHALL lay out, top to bottom, inside comp.popover.container.padding-block at the top and bottom edges of its container: WHILE headline is not empty or closable is true, the header (POP-11); then the content, comp.popover.container.gap below the header where there is one; then, WHILE the popover has at least one action, the actions, comp.popover.actions.margin-block-start below the content, or below the header where there is no content. WHILE inset is true THE popover SHALL inset the content by comp.popover.container.padding-inline from the container's start and end edges; WHILE inset is false it SHALL let the content reach the container's start and end edges — and its top and bottom edges where no header or no action stands there, the block padding then not applying on that side — clipped by the container's shape, the header and the actions keeping their own insets.
POP-10 THE popover SHALL draw an arrow WHILE arrow is true, and WHILE arrow is null and comp.popover.arrow.visible is on, and none otherwise. WHILE it draws one THE popover SHALL draw a triangle comp.popover.arrow.width wide at its base and comp.popover.arrow.height tall on the container's edge that faces the anchor, as one shape with the container — the container's color and elevation, with no seam and no shadow between the two — its tip pointing at the middle of the part of the anchor's edge that the container stands beside, and SHALL keep its base at least comp.popover.arrow.inset, and at least the corner's radius, from each end of that edge, standing at the edge's middle where the edge is too short for both; the container SHALL stand comp.popover.arrow.height farther from the anchor, so that the tip keeps the offset (POP-4). WHEN the container flips, shifts or follows the anchor (POP-5) the arrow SHALL move with it to the edge that now faces the anchor and point at the anchor again, and WHILE the container covers the anchor (POP-5) THE popover SHALL draw no arrow. The arrow SHALL take no press of its own and SHALL be hidden from assistive technology.
POP-11 WHILE headline is not empty or closable is true THE popover SHALL draw the header as one row: the headline from comp.popover.container.padding-inline after the container's start edge, taking the width the close button leaves, and, WHILE closable is true, the close button (POP-13) at the row's end, comp.popover.header.gap after the headline and with its edge comp.popover.container.padding-inline before the container's end edge, both aligned to the row's first line; the header SHALL be as tall as the taller of the two and SHALL stay in place while the content scrolls (POP-8).
POP-12 WHILE headline is not empty THE popover SHALL draw it in comp.popover.headline.typescale and comp.popover.headline.color, wrapping onto more lines rather than truncating and growing the header with it, and SHALL expose it as a heading. THE popover SHALL set the headline's letter-spacing by the script of its text, as every title is set (PRS-20): no negative letter-spacing WHERE its language is Chinese, Japanese or Korean, and none WHERE its script joins its letters or stacks marks on them.
POP-13 WHILE closable is true THE popover SHALL draw at the end of its header an icon-only Button of the small size showing the glyph close of the system's icon set and named by closeLabel, in the variant comp.popover.close-button.variant names, given through the channel a Button reads from the component that places it, and otherwise unrestyled: it reads Button's own tokens, answers hover, focus and press as any Button does and keeps its own minimum target (BTN-5); WHEN the user activates it THE popover SHALL emit close exactly once with the reason close. WHILE closable is true and closeLabel is empty it SHALL still draw the button, and in debug builds report that the button has no accessible name. THE popover SHALL draw no close mark of its own (no path, shape or character of its own).
POP-14 THE popover SHALL hand its content comp.popover.content.color as the platform's inherited foreground (the web's inherited color, SwiftUI's foreground style, Compose's content color, Flutter's default text and icon style, React Native's Tanrei text context); plain text given as content, where the platform must style it, SHALL take sys.typescale.body. THE popover SHALL NOT lay out, restyle or mirror the content itself, and SHALL let it hold any element that takes input — links, Buttons, fields, a list, a menu's or another popover's opener.
POP-15 WHILE the popover has at least one action THE popover SHALL lay out its actions as a standard Button group lays out its items (BGR-12 to BGR-19), comp.popover.actions.gap apart and comp.popover.container.padding-inline from the container's start and end edges, in the order the group gives them — dismissive at the start and confirming at the end of a row, confirming on top and dismissive at the bottom of a column, unflagged actions between them in the order given — with focus and reading order following that order (BGR-15). WHILE comp.popover.actions.arrangement is fill it SHALL make them a full-width group across the container's inner width, the actions sharing a row equally (BGR-17) or each as wide as the column; WHILE it is end it SHALL keep them at their own widths, the row aligned to the end, and a column as wide as its widest action and aligned to the end. It SHALL place them in a row WHILE every action's label fits its share on one line (fill) or the row at its own widths fits the inner width (end), and otherwise in a column, re-deciding when the container's width or the text size changes.
POP-16 WHILE an action's variant is empty THE popover SHALL give that Button the variant comp.popover.actions.variant names, through the channel a Button reads from the component that places it, so that the Button renders from that variant's tokens and states as it would with the variant set; WHILE an action's variant is set THE popover SHALL leave it as set. THE popover SHALL NOT change an action's size or tokens, and SHALL NOT change its look or emphasis for its confirming or dismissive (BGR-19).
POP-17 WHEN the user activates an action THE popover SHALL let the Button emit its own click and SHALL NOT close, emit close or otherwise answer it itself, whether the action is confirming, dismissive or neither; the product closes the popover from the action's handler by setting open to false, and focus then returns as POP-22 says.
POP-18 THE popover SHALL be shown exactly while open is true: it SHALL NOT open or close itself when a pointer enters or leaves its anchor or its container, when focus arrives at its anchor, on a long-press or after a time, and SHALL have no show or hide delay; the product sets open when the opener is activated by pointer, touch, Enter or Space, and sets it to false when the opener is activated again. THE popover SHALL expose on its opener that it opens a dialog, whether that dialog is open and which element it is, where the platform has those properties (aria-haspopup with the value dialog, aria-expanded and aria-controls on the web), and SHALL NOT change the opener's accessible name, role or look. The opener is the anchor unless the product names another element as the opener, in which case the container is placed against the anchor (POP-2 to POP-5) and everything this spec says of the opener holds for that element.
POP-19 WHEN open becomes true WHILE initialFocus is popover THE popover SHALL move focus to the element in it that the product marked for initial focus (the platform's own mark, named in the platform notes) or, without one, to its container, so that assistive technology reads its name first and the next Tab reaches its first focusable element; it SHALL show a focus indicator on the container only when the popover was opened from the keyboard, as sys.behavior.focus-style names. WHEN open becomes true WHILE initialFocus is anchor THE popover SHALL leave focus where it is and SHALL take no key from the element that has it except Escape (POP-23). Focus SHALL move when the popover opens, not when its motion ends; a popover mounted with open true SHALL NOT move focus.
POP-20 WHILE the popover is open THE popover SHALL stand in the focus order and in the reading order of assistive technology directly after its opener, wherever the platform draws it: Tab from the opener SHALL move to the popover's first focusable element, Shift+Tab from that element SHALL move back to the opener, Tab and Shift+Tab inside the popover SHALL move through its close button, its content's focusable elements and its actions in the order they are placed, and Tab from its last focusable element SHALL move to the element that follows the opener in the page's order, which closes the popover as focus leaving it does (POP-21). Focus on the opener SHALL count as focus that has not left the popover, so that Shift+Tab to the opener leaves the popover open. THE popover SHALL NOT wrap focus from its last element to its first.
POP-21 WHEN the user presses Escape or the platform's back (Android's back gesture or button, the iOS accessibility escape gesture), presses outside the container, its arrow, its anchor, its opener and every overlay opened from inside it (POP-24), moves focus to an element outside all of those, or activates the close button (POP-13), or WHEN the anchor goes out of sight (POP-5) THE popover SHALL emit close once with that reason (escape, back, outside, focus-out, close or anchor-hidden) and SHALL be closed: through its binding or controller where open is one (SwiftUI, Flutter), and by the product setting open to false where open is a plain value (web, Compose, React Native). A press on the opener or the anchor is never a press outside: the product's own handler closes the popover from it (POP-18), so that one press never closes and opens it again. Focus leaving the window (another window or application taking it) SHALL NOT count as focus leaving the popover, and neither SHALL a move of an assistive technology's reading cursor that moves no input focus. Whether a press outside also reaches the element under it SHALL follow the platform and be stated in its README, as for the menu (MNU-5).
POP-22 WHEN the popover closes THE popover SHALL return focus to its opener IF focus was inside the popover or an overlay opened from inside it, or was lost with it (a press outside that landed on nothing focusable), and SHALL leave focus where the person put it IF the close came from focus moving to, or a press landing on, another focusable element; WHERE the opener no longer exists or cannot take focus it SHALL fall to the platform's default for a closed overlay. It SHALL show the opener's focus indicator only when the close came from the keyboard. Focus SHALL move when the popover closes, not when its motion ends.
POP-23 WHILE the popover is open, WHEN the user presses Escape or the platform's back and neither an overlay opened from inside it nor an element inside it has taken the key for itself (an open menu, a tooltip, a field composing text or clearing its value) THE popover SHALL take the key and close as POP-21 says, and SHALL let it go no further, so that it does not also close a dialog or a sheet the popover stands in; WHILE several overlays are open Escape SHALL close only the topmost.
POP-24 WHEN an overlay opens from an element inside the popover's container — a menu, a tooltip, a docked picker or a select's surface, another popover, a dialog or a modal sheet — THE popover SHALL treat it as its own: a press inside it SHALL NOT count as a press outside, focus moving into it SHALL NOT count as focus leaving, and the popover SHALL stay open under it, inert with the rest of the window WHILE that overlay is modal. WHEN that overlay closes THE popover SHALL receive back the focus it returns. WHEN the popover is closed, for a reason POP-21 names or because the product sets open to false, THE popover SHALL close every overlay opened from inside it that is not modal with it at once, their own close events carrying no reason of the person's, and SHALL return focus to its own opener as POP-22 says, not to an opener inside it. WHEN a popover is opened from inside a popover that was itself opened from inside a popover THE popover SHALL still work, and in debug builds SHALL report the depth.
POP-25 WHERE the popover's anchor is inside a modal overlay (a dialog, a modal sheet) THE popover SHALL be presented above that overlay and belong to it: operable while the rest of the window is inert, and in that overlay's focus loop directly after its opener (POP-20). WHEN a popover opens while another popover that it was not opened from is open THE popover SHALL be drawn above it; THE popover SHALL NOT close another popover by opening — the press or the focus that opened it closes the other as POP-21 says — so that the product that sets two open at once has two.
POP-26 WHEN the popover opens beside its anchor THE popover SHALL make its container appear as every anchored surface appears: from sys.motion.appear.opacity, sys.motion.appear.scale, sys.motion.appear.distance toward the anchor and sys.motion.appear.blur to whole, grown from the middle of the edge that faces the anchor — from its own centre WHERE sys.motion.appear.origin is center, and WHILE it covers its anchor (POP-5) — over comp.popover.motion.open-duration with comp.popover.motion.open-easing, and WHEN it closes THE popover SHALL take it back the same way to where it started, over comp.popover.motion.close-duration with comp.popover.motion.close-easing. WHERE sys.behavior.appearance is unfold the scale SHALL apply along the axis that leaves the anchor only, so that the container unfolds from that edge at its full width. WHERE motion is reduced THE popover SHALL only fade it in and out, over sys.motion.role.reduced, with no scale, distance or blur. WHEN it is mounted with open true THE popover SHALL appear without its motion while the document has not yet been first painted, and with it when it is mounted after that. The motion SHALL be drawn only: the place POP-5 gives and the room the popover is measured for are those of the popover at rest.
POP-27 WHEN the popover is told to close while it is still opening, or to open while it is still closing THE popover SHALL turn round from the opacity and the size it has reached, without first jumping to the start or the end of either motion, and SHALL take no longer over the rest than the whole duration of the motion it turns to. WHILE the popover is closed or closing THE popover SHALL take no pointer input and no focus — a press reaches what lies under it — and WHILE it is closed it SHALL take no room in the layout, draw nothing and expose nothing to assistive technology.
POP-28 THE popover SHALL expose its container as a dialog named by headline or, WHILE headline is empty, by label: one that is not modal, hiding nothing outside it from assistive technology, WHILE it stands beside its anchor, and a modal dialog WHILE it is presented as a sheet (POP-40); the close button SHALL be named by closeLabel, each action by its own label, and the arrow and the dividers SHALL be hidden. THE popover SHALL NOT expose its text as its anchor's description: what describes an anchor is a tooltip.
POP-29 IF headline and label are both empty THE popover SHALL still open, and in debug builds SHALL report that it has no accessible name. IF the popover opens with no content, no headline and no action THE popover SHALL draw nothing, take no focus and expose nothing, and in debug builds SHALL report an empty popover. IF no anchor can be found when open becomes true THE popover SHALL stay closed, emit nothing, and in debug builds report the missing anchor.
POP-30 WHILE the text size is enlarged THE popover SHALL keep its width limits (POP-7), wrap its headline and let its content wrap, grow its container's height with them up to the limits of POP-8 and scroll beyond them, stack its actions once a label no longer fits its share (POP-15), and SHALL NOT scale the close button, the arrow, the offset or the window margin beyond what the platform's layout units do. Nothing in the header or the actions SHALL be clipped or truncated.
POP-32 WHERE the platform draws with a person's own forced colors (the web's forced-colors mode, and a platform's equivalent where it has one) THE popover SHALL draw an edge sys.border.hairline wide in the platform's text color round its container and its arrow, as one outline, because the mode removes the shadow and may give the container the page's color; its headline and plain text SHALL take the platform's text color.
POP-33 THE popover SHALL take its layout direction from where it is used — the direction of the nearest ancestor that sets one, and the platform's own where none does — and SHALL have no direction setting of its own; WHEN that direction changes while the popover is shown THE popover SHALL draw itself for the new direction at once, without a motion of its own, keeping its open state and its focus, the container placed again by the new direction (POP-34).
POP-34 WHEN the layout direction is right-to-left THE popover SHALL take the side start as the anchor's right side and the side end as its left, SHALL take the alignments -start and -end of a popover above or below as the right and the left edges, and a positive crossOffset of such a popover as a move towards the left, flipping and shifting from there as POP-5 says; it SHALL leave the sides top and bottom, the alignments -top and -bottom, a crossOffset beside the anchor and the centring on the anchor as they are, and SHALL keep auto's order of sides by their names (POP-3). It SHALL mirror its header — the headline at the right, the close button at the left — apply its paddings by logical start and end, and place its actions as a Button group places them right to left (BGR-8); it SHALL NOT mirror the glyph close, the arrow's shape, or its content, which follows the layout direction itself.
POP-35 THE popover SHALL lay out its headline as text of its own direction, isolated from the text around it: it takes the base direction of its first strong character, or the layout direction where it has none, so that a left-to-right word, a number with its sign or unit, a telephone number and an address keep their own order in a right-to-left layout and reorder nothing beside them; THE popover SHALL still place the headline and align its lines by the layout direction, not by the text's own.
POP-36 WHILE the on-screen keyboard is shown THE popover SHALL take the keyboard's top edge as an edge of the window's safe area (POP-5), and SHALL keep to the visible part of the window wherever that is smaller than the window: it SHALL flip, shift or shorten so that no part of it is under the keyboard, and SHALL scroll the focused element into the room left; WHEN the keyboard hides it SHALL take its place again by POP-5. It SHALL move as the platform moves content for its keyboard, and at once where motion is reduced.
POP-37 WHEN placement, width or initialFocus names a value the popover does not define THE popover SHALL render with the default value, and in debug builds report the unknown value.
POP-38 THE popover SHALL draw its dividers (POP-8) as its dividerVisibility names: WHILE dividerVisibility is auto, as comp.popover.divider.visibility names, which follows sys.behavior.divider-visibility unless a design system sets the popover apart; WHILE dividerVisibility is always or scroll, as that value names, whatever the tokens say. WHEN dividerVisibility, or the token it follows, changes THE popover SHALL draw the other form at once, moving no part and keeping the scroll position and focus; WHEN dividerVisibility names a value the popover does not define THE popover SHALL treat it as auto and in debug builds report the unknown value. A platform that cannot draw a choice SHALL fall back to the first value, always, and state that in its README.
POP-39 WHILE the window is narrower than comp.popover.compact.window-width (a compact window), compactPresentation is sheet and initialFocus is popover THE popover SHALL present its container with the bottom sheet's appearance (BSH-7) instead of beside its anchor: at the window's bottom edge, as wide as the window but no wider than comp.bottom-sheet.container.max-width and centred in it, filled with comp.bottom-sheet.container.color, raised by comp.bottom-sheet.container.elevation, its top corners rounded by comp.bottom-sheet.container.shape eased by sys.shape.corner-smoothing and its bottom corners square, its color reaching under the bottom system inset and its parts above it, and sitting on the on-screen keyboard while it is shown; as tall as its parts, but never taller than the window below its top system inset less comp.bottom-sheet.container.margin-block-start, its content scrolling beyond that as POP-8 says. It SHALL draw no arrow and no drag handle, follow no drag, close on no swipe, and ignore placement, offset, crossOffset and width there; its header, content and actions SHALL keep their own tokens and layout (POP-9 to POP-17, POP-38) across the sheet's width. WHERE comp.popover.compact.window-width is 0 no window is compact.
POP-40 WHILE the popover is presented as a sheet (POP-39) THE popover SHALL be a modal overlay, as a modal bottom sheet is (BSH-2): it SHALL draw comp.bottom-sheet.scrim.color with comp.bottom-sheet.scrim.blur over the whole window behind it (MDL-1), make everything outside it and the overlays opened from inside it inert, keep the content behind it from scrolling, keep focus inside it — Tab and Shift+Tab wrap between its last and first focusable elements — and expose its container as a modal dialog (POP-28). WHEN it opens it SHALL move focus into it as POP-19 says for initialFocus popover — mounted with open true as well, because everything behind it is then inert (as a modal sheet does, BSH-3) — and WHEN it closes it SHALL return focus to its opener as POP-22 says. A press on the scrim SHALL ask to close with the reason outside, Escape with escape (POP-23) and the platform's back with back, and the close button with close (POP-21); since focus cannot leave it and it does not stand beside its anchor, it SHALL NOT ask with focus-out or anchor-hidden and SHALL NOT follow its anchor. Its opener SHALL still say that it opens a dialog and whether it is open (POP-18).
POP-41 WHEN the popover opens as a sheet (POP-39) THE popover SHALL slide its container up from below the window's bottom edge into its place while fading the scrim in, as a modal bottom sheet opens (BSH-1), over comp.bottom-sheet.motion.enter-duration with comp.bottom-sheet.motion.enter-easing, and WHEN it closes there it SHALL slide the container down out of view while fading the scrim out, over comp.bottom-sheet.motion.exit-duration with comp.bottom-sheet.motion.exit-easing, turning round from where it has got to as POP-27 says. WHERE motion is reduced it SHALL fade in and out in place without sliding, or appear and disappear at once on a platform whose reduced-motion setting removes every animation (Android's). Focus SHALL move when it opens or closes, not when its motion ends.
POP-42 WHEN the window's width crosses comp.popover.compact.window-width, or compactPresentation or initialFocus changes, while the popover is open THE popover SHALL take the other presentation at once, without a motion — beside its anchor and not modal (POP-1 to POP-5), or as a sheet (POP-39, POP-40) — keeping its open state, its scroll position and the element in it that has focus, and SHALL emit nothing; IF focus is outside it (on its opener) as it becomes a sheet THE popover SHALL move focus into it as POP-19 says, because the opener is then inert.
POP-43 WHILE compactPresentation is own, or initialFocus is anchor, THE popover SHALL stay an anchored popover that is not modal in every window, compact ones included: WHERE the window is narrower or shorter than the container wants THE popover SHALL narrow and shorten the container as POP-7 and POP-8 say, cover its anchor as POP-5 says where it must, and scroll, and SHALL NOT draw a scrim or trap focus. A popover whose initialFocus is anchor stays beside its anchor because focus stays in the element the person is typing in, which a modal sheet would make inert. WHEN compactPresentation names a value the popover does not define THE popover SHALL treat it as sheet and in debug builds report the unknown value.
POP-44 WHERE the platform has ARIA attributes (the web), WHEN the product sets an aria- attribute on the host, by the attribute or by the ARIA property that reflects it, THE popover SHALL move it to the data-aria- attribute of the same name, so that the host is no second node with its name, description or state, and SHALL expose it on its dialog (POP-28), beside its anchor and as a sheet alike — an id reference by the elements it names in the host's tree or a tree around it, a description after its own. WHILE headline or label is not empty it is the dialog's name (POP-28), over a name given so; WHILE both are empty, a name given so is the dialog's name and SHALL NOT be reported as having none in debug builds. WHEN the product removes the aria- attribute or its data-aria- twin, or sets the ARIA property that reflects it (ariaLabel, ariaDescribedByElements…) to null, THE popover SHALL take it off that element.

مطابقة الأسماء بين المنصات

التكافؤ لا يعني واجهات برمجية متطابقة. تعبّر كل منصة عن العقد نفسه بأسلوبها.

المواصفة Web SwiftUI Jetpack Compose Flutter React Native
المكوّن tanrei-popover tanreiPopover TanreiPopover TanreiPopover Popover
open · الخاصية open isPresented visible controller visible
placement · الخاصية placement placement placement placement placement
offset · الخاصية offset offset offset offset offset
crossOffset · الخاصية crossOffset crossOffset crossOffset crossOffset crossOffset
arrow · الخاصية arrow arrow arrow arrow arrow
width · الخاصية width width width width width
compactPresentation · الخاصية compactPresentation compactPresentation compactPresentation compactPresentation compactPresentation
inset · الخاصية inset inset inset inset inset
initialFocus · الخاصية initialFocus initialFocus initialFocus initialFocus initialFocus
headline · الخاصية headline headline headline headline headline
label · الخاصية label accessibilityLabel contentDescription semanticLabel accessibilityLabel
closable · الخاصية closable closable closable showCloseButton closable
closeLabel · الخاصية closeLabel closeLabel closeLabel closeButtonSemanticLabel closeLabel
dividerVisibility · الخاصية dividerVisibility dividerVisibility dividerVisibility dividerVisibility dividerVisibility
close · الحدث close onClose onDismissRequest onClose onClose
ملاحظات <tanrei-popover anchor="…"> names its anchor as the menu does: anchor is the id of the anchor element in the popover's own tree, and anchorElement a property for an element that an id cannot reach (another shadow root); opener and openerElement name a separate opener, as the docked picker's do (POP-18). The popover sets aria-haspopup="dialog", aria-controls and aria-expanded on the opener and removes them when it is disconnected. Attributes are kebab-case (cross-offset, initial-focus, close-label, compact-presentation); offset and crossOffset are number properties in CSS pixels parsed as the tooltip's are, so an empty attribute is not a number; arrow is true, false or null — absent for null, present for true and ="false" for false; inset is a boolean property that defaults to true, whose attribute is the inverse no-inset. close is a CustomEvent whose detail.reason is escape, back, outside, focus-out, close or anchor-hidden; the product sets open to false from it. Slots: default and actions. The container is a popover="manual" element with role="dialog" and no aria-modal in the shadow root, so it is in the top layer (above an open modal <dialog> when the element is a descendant of that dialog, which it must be to be operable there, POP-25); manual and not auto, because the popover implements its own light dismiss so that close carries a reason and so that an overlay opened from inside it is not closed by the browser's own rule. It is placed with CSS anchor positioning where the browser has it and by measuring otherwise, and follows its anchor with the shared FollowController. The container and the arrow are one painted shape, so the elevation's ring and shadows run round both. Focus order (POP-20): the top layer does not change the tab order, so where the element does not directly follow its opener in the document the popover moves focus itself — Tab on the opener while open goes to the first tabbable element of the popover, Shift+Tab from that element to the opener, and Tab from the last to the element after the opener. The autofocus attribute on a slotted element marks initial focus; the container has tabindex="-1". A press outside also reaches the element under it. Under forced-colors: active the painted shape takes a CanvasText outline (POP-32). The inline attribute, for tests, draws the open container in place. Snapshot harness: a stage of 480 × 480 with a medium outlined tanrei-button labelled "Storage" at its centre and the popover open against it; width-anchor gives the button a width of 240; the screenshot is the stage. dividerVisibility is the divider-visibility attribute (auto, always, scroll); auto reads --tanrei-comp-popover-divider-visibility from the cascade with a style query, and where the browser has none the popover writes the name it read on its clip when it lays out. Compact (POP-39 to POP-42): a media query cannot read a custom property, so the popover reads the resolved comp.popover.compact.window-width through a probe and matches it with matchMedia('(width < …px)'), presenting again at once on change. As a sheet the container is a native <dialog> opened with showModal() in the shadow root, in place of the popover="manual" element: in the top layer over ::backdrop (the scrim), the rest of the page inert and held from scrolling. The slotted content is the same, and the element that had focus is focused again across the change. The keyboard's cover is read from visualViewport. The inline attribute keeps the anchored presentation in every window. Snapshot harness: the compact- fixtures are the real overlay in a 360 × 640 window, and the screenshot is the window. A modifier on the anchor: .tanreiPopover(isPresented: Binding<Bool>, headline:, accessibilityLabel:, placement:, offset: CGFloat? = nil, crossOffset:, arrow: Bool? = nil, width:, inset:, initialFocus:, closable:, closeLabel:, onClose:, actions:, content:); a separate opener is named with .tanreiPopoverOpener(_:) on that view. Dismissal writes false to the binding and then calls onClose with the reason. Drawn in an overlay above the window's content, anchored with anchor preferences, as the tooltip is, not with .popover: the system's is modal at compact widths and its arrow, placement and motion cannot be given by tokens. Initial focus is .defaultFocus or an @AccessibilityFocusState the product passes; the container is an accessibility container with the header trait on the headline, placed after the opener with accessibilitySortPriority; the iOS escape gesture is .accessibilityAction(.escape). A press outside does not reach what is under it. Snapshot harness: the anchor and the open popover in a fixed 480 × 480 frame. Not built on this platform yet: dividerVisibility (auto, always, scroll; POP-38) — the dividers still follow the scroll position, as scroll does. compactPresentation is compactPresentation: TanreiPopoverCompactPresentation = .sheet; in a horizontally compact size class the sheet form is a sheet the popover draws with the bottom sheet's tokens, as SwiftUI's own popover adapts (presentationCompactAdaptation), not .popover. Compose idiom, as the menu: TanreiPopover(visible, onDismissRequest, headline, contentDescription, placement, offset: Dp? = null, crossOffset, arrow: Boolean? = null, width, inset, initialFocus: TanreiPopoverInitialFocus, initialFocusRequester: FocusRequester? = null, closable, closeLabel, actions, content) inside the anchor's Box, shown in a Popup with a PopupPositionProvider of its own. visible rather than calling it only while open, so that the close motion can run. The caller closes it, so close is onDismissRequest and it carries the reason. The Popup is focusable while initialFocus is popover, so back reaches it; because a focusable popup is a window of its own, the popover moves focus itself at its ends (POP-20): Tab from its last element clears the popup's focus, asks the anchor's FocusManager to move next and reports focus-out. paneTitle is the headline or contentDescription. A press outside does not reach what is under it. Snapshot harness: the anchor and TanreiPopoverContent in place in a 480 × 480 dp box; the popup itself is covered by instrumented tests. Not built on this platform yet: dividerVisibility (auto, always, scroll; POP-38) — the dividers still follow the scroll position, as scroll does. compactPresentation is compactPresentation: TanreiPopoverCompactPresentation = Sheet; the sheet form is shown in a Dialog window whose own dim is off, Tanrei drawing the bottom sheet's scrim. Flutter idiom, as TanreiMenuAnchor: TanreiPopover(controller:, placement:, offset:, crossOffset:, arrow:, width:, inset:, initialFocus:, headline:, semanticLabel:, showCloseButton:, closeButtonSemanticLabel:, onClose:, actions: […], content:, builder:) wraps the anchor that builder returns; TanreiPopoverController.open() and .close() are open, and onClose carries the reason. Shown with an OverlayPortal and a CompositedTransformFollower: the portal's child stays where it is declared in the widget, focus and semantics trees, so the popover follows its anchor in traversal and reading order without more (POP-20). Outside presses are a TapRegion whose group the overlays opened from inside it join (POP-24); a press outside also reaches what is under it. autofocus: true on a descendant marks initial focus; Semantics(scopesRoute: false, namesRoute: true, label:) names the container. Snapshot harness: the anchor and the open popover in a 480 × 480 box. Not built on this platform yet: dividerVisibility (auto, always, scroll; POP-38) — the dividers still follow the scroll position, as scroll does. compactPresentation is compactPresentation: TanreiPopoverCompactPresentation.sheet; the sheet form is a modal route drawn with the bottom sheet's tokens. <Popover visible anchorRef openerRef? onClose headline …>{content}</Popover>, presented on the overlay layer that TanreiProvider renders (not a Modal, which would make the rest of the screen unreachable) and placed by measuring the anchor (measureInWindow), again on layout, scroll and keyboard events; Android's back button (BackHandler) is close with the reason back, and the iOS escape gesture is onAccessibilityEscape. Controlled: the caller sets visible to false from onClose. accessibilityViewIsModal stays false; the container is given accessibility focus when it opens and the opener when it closes. A hardware keyboard's Tab order follows the native view order, which the overlay layer puts last: the README states that the popover is reached from its opener by the focus it takes on opening, and returns to the opener on leaving. A press outside closes the popover and does not reach what is under it. Follows the app's direction where an ancestor's is not known. Not built on this platform yet: dividerVisibility (auto, always, scroll; POP-38) — the dividers still follow the scroll position, as scroll does. compactPresentation is a string prop ('sheet' | 'own'); the sheet form is presented in a Modal whose own dim and transition are off, with accessibilityViewIsModal true.

الرموز

الرمز يشير إلى القيمة المحلولة (فاتح)
--tanrei-comp-popover-actions-arrangement — 0
--tanrei-comp-popover-actions-gap sys.space.space200 16px
--tanrei-comp-popover-actions-margin-block-start sys.space.space200 16px
--tanrei-comp-popover-actions-variant — 1
--tanrei-comp-popover-arrow-height sys.space.space75 6px
--tanrei-comp-popover-arrow-inset sys.space.space100 8px
--tanrei-comp-popover-arrow-visible — 0
--tanrei-comp-popover-arrow-width sys.space.space150 12px
--tanrei-comp-popover-close-button-variant — 1
--tanrei-comp-popover-compact-window-width sys.breakpoint.medium 600px
--tanrei-comp-popover-container-color sys.color.surface-bright #ffffff
--tanrei-comp-popover-container-elevation sys.elevation.level2 0px 0px 0px 1px rgb(0 0 0 / 0.08), 0px 1px 2px 0px rgb(0 0 0 / 0.04)
--tanrei-comp-popover-container-gap sys.space.space150 12px
--tanrei-comp-popover-container-max-height — 480px
--tanrei-comp-popover-container-max-width — 400px
--tanrei-comp-popover-container-min-width — 160px
--tanrei-comp-popover-container-padding-block sys.space.space200 16px
--tanrei-comp-popover-container-padding-inline sys.space.space200 16px
--tanrei-comp-popover-container-shape sys.shape.corner.medium 8px
--tanrei-comp-popover-content-color sys.color.on-surface #1b1b1b
--tanrei-comp-popover-divider-color sys.color.outline-variant #000000 · 8%
--tanrei-comp-popover-divider-visibility sys.behavior.divider-visibility 0
--tanrei-comp-popover-divider-width sys.border.hairline 1px
--tanrei-comp-popover-header-gap sys.space.space100 8px
--tanrei-comp-popover-headline-color sys.color.on-surface #1b1b1b
--tanrei-comp-popover-motion-close-duration sys.motion.role.appear.anchored.exit 250ms
--tanrei-comp-popover-motion-close-easing sys.motion.easing.exit cubic-bezier(0.3, 0, 1, 1)
--tanrei-comp-popover-motion-open-duration sys.motion.role.appear.anchored.enter 300ms
--tanrei-comp-popover-motion-open-easing sys.motion.easing.enter cubic-bezier(0.2, 0, 0, 1)
--tanrei-comp-popover-offset sys.space.space50 4px
--tanrei-comp-popover-window-margin sys.space.space100 8px
--tanrei-comp-popover-headline-typescale sys.typescale.heading-6 500 14px/1.4286

نماذج الاختبار

عروض مرجعية. تلتقط كل المنصات لقطة لكل نموذج بالمعرّف نفسه حتى يمكن مقارنة النتائج.

مولَّد من specs/popover.spec.json, tokens/comp/popover.tokens.json, design/tokens/

ما يرسمه الويب بطريقة مختلفة

  • اللوحة المنبثقة عنصر له popover="manual" في الطبقة العليا (top layer). وداخل عنصر <dialog> نمطي يجب أن تكون من فروع ذلك العنصر ليمكن العمل فيها هناك.
  • في النافذة المضغوطة تكون اللوحة السفلية عنصر <dialog> أصليًّا يُفتح بالدالة showModal()، وحجابها هو ::backdrop الخاص بمربع الحوار.
  • الضغط في الخارج يغلق اللوحة المنبثقة ويصل أيضًا إلى العنصر الذي تحته.
  • ليس للويب إيماءة رجوع خاصة به، فلا يحمل الحدث close السبب back أبدًا.
  • الخاصيتان anchorElement و openerElement هما لعنصر لا يبلغه معرّف id، كعنصر في جذر ظل (shadow root) آخر.
  • الخاصية arrow قيمتها غير مضبوطة أو true أو false: تغيب خاصية HTML (attribute)، أو تُكتب arrow، أو تُكتب arrow="false".
  • علِّم العنصر الذي يأخذ التركيز عند الفتح بالخاصية autofocus.
  • في الألوان المفروضة (forced colors) تكتسب الحاوية وسهمها حدًّا بلون النص.

الإرشادات

تلميح أم لوحة منبثقة أم قائمة خيارات أم مربع حوار

الجانب التلميح اللوحة المنبثقة قائمة الخيارات مربع الحوار
ما يفتحه التحويم، أو تركيز لوحة المفاتيح، أو الضغط المطوَّل ضغط على عنصر الفتح ضغط على عنصر الارتكاز المنتج
ما يحمله وصف لعنصر ارتكازه محتوى يعمل فيه الشخص عناصر فقط قرار
هل يأخذ التركيز لا، أبدًا نعم، وتعيده نعم، وتعيده نعم، ويحتفظ به
هل يحجب الصفحة لا لا (نعم حين تكون لوحة سفلية في نافذة مضغوطة) لا نعم
  1. إن كان يقول ما هو عنصر التحكم فقط، ولا شيء فيه يُضغط، فهو تلميح.
  2. إن كان قائمة أوامر أو خيارات، فهو قائمة خيارات.
  3. إن كان الشخص لا يستطيع أن يكمل من دون أن يجيب عنه، فهو مربع حوار.
  4. وإلا فهو لوحة منبثقة.

افعل

  • افتحها بضغط على عنصر تحكم، وأغلقها حين يُضغط ذلك العنصر مرة أخرى.
  • أبقِ المحتوى قصيرًا. مهمة واحدة، وبضعة حقول على الأكثر.
  • أضف closable حين تكون اللوحة المنبثقة كبيرة حتى تغطي ما كان الشخص سيضغطه خارجها، وفي اللمس، حيث لا مفتاح Escape.
  • استخدم width="anchor" و initialFocus="anchor" لسطح تحت حقل يكتب فيه الشخص.
  • لا تضبط compactPresentation على own إلا للوحة منبثقة يجب أن تبقى في النافذة المضغوطة أيضًا بجانب ما تنتمي إليه، مثل ملاحظة بجانب الكلمة التي تشرحها.
  • أبقِ تسميات الإجراءات قصيرة. التسمية الأعرض من اللوحة المنبثقة لا تلتفّ.

لا تفعل

  • لا تفتح لوحة منبثقة بالتحويم أو بالتركيز. لا يمكن بلوغها باللمس، والسطح الذي يأخذ التركيز لأن المؤشر مرّ به فخّ.
  • لا تضع في لوحة منبثقة ما يضيع على الشخص بضغطة شاردة واحدة خارجها. النموذج الطويل مكانه مربع حوار أو لوحة سفلية أو جانبية.
  • لا تضع داخل لوحة منبثقة أكثر من لوحة منبثقة واحدة. كل مستوى ضغطة أخرى على المفتاح Escape.
  • لا تستخدم لوحة منبثقة لشيء يجب أن يجيب عنه الشخص قبل أن يكمل. ذاك مربع حوار.

إمكانية الوصول

الدور
dialog
التسمية
The popover is a dialog that is not modal — a modal one while it is a sheet in a compact window (POP-40) — named by its headline, or by label where it draws none. The headline is also exposed as a heading. The opener keeps its own name and role and exposes that it opens a dialog and whether it is open. The close button is named by closeLabel and each action by its own label; confirming and dismissive are not announced, and the actions are read in the order they are placed (BGR-15). The arrow and the dividers are decorative. The popover is not its anchor's description.
الحد الأدنى للهدف
تستوفي مساحة اللمس الحد الأدنى لحجم الهدف حتى لو كان الحجم المرئي أصغر. minimum 32px · pointer 44px · spacing 8px · touch 48px

لوحة المفاتيح

المفاتيح الإجراء
Enter / Space on the opener The product opens the popover; focus moves into it (to the element the product marked, otherwise to the container). Pressed again while it is open, the product closes it.
Tab / Shift+Tab Move through the popover's close button, its content and its actions; the popover comes directly after its opener in the order. Shift+Tab from its first element returns to the opener and leaves it open; Tab from its last element moves on to what follows the opener and closes it. Focus is never kept in. As a sheet in a compact window (POP-40) it keeps focus in: Tab and Shift+Tab wrap.
Escape Closes the popover and returns focus to its opener; with overlays opened from inside it, only the topmost. It goes no further: a dialog the popover stands in stays open. As a sheet, a press on the scrim closes it too.
Enter / Space Activate the focused close button (close, reason close) or action (its click; the popover does not close by itself, POP-17). The popover adds no default action to Enter.

ملاحظات

  • The popover has no target of its own; its close button and its actions are Tanrei Buttons, which meet the minimum target themselves (BTN-5). comp.popover.actions.gap keeps each action's whole target in a column in the default system. The opener is the product's control and keeps its own target.
  • Tooltip, popover, menu, dialog — which one. A tooltip describes its anchor, opens on hover and focus, never takes focus and holds nothing a person can operate (TIP-13). A popover is opened by a press, takes focus and holds content a person operates. A menu is a list of commands or choices, moved through with the arrow keys; it holds only its items. A dialog stops the task until it is answered. A note that needs a link or a button is a popover, never a tooltip.
  • Never open a popover on hover or on focus (POP-18): what appears that way must be dismissible, hoverable and persistent (WCAG 1.4.13) and cannot be reached by touch, and a surface that takes focus because the pointer passed is a trap. Open it from a press.
  • Focus: the popover is an operated overlay that is not modal. It moves focus in when it opens and returns it to the opener when it closes, but does not keep it: Tab leaves it, which closes it. An open surface nobody is in would cover content the keyboard user has moved on to, and a pointer user closes it by pressing elsewhere; focus leaving is the keyboard's form of the same thing. This is the menu's rule, the docked picker's and the docked search view's.
  • Initial focus goes to the container unless the product marks an element (POP-19), as for the dialog: assistive technology reads the popover's name first, and a field that takes focus by itself would raise the on-screen keyboard over a popover the person has not read. Mark the first field of a short form.
  • initialFocus anchor is for a surface under a field the person is typing in (suggestions, a format hint with a link). Focus stays in the field, so the field's own keys keep working; the popover is still next in the Tab order, and still closes when focus leaves both.
  • Reading order: the popover follows its opener for a screen reader as it does for Tab (POP-20). On the web, place the element directly after its anchor in the document where the layout allows; where it cannot be, the opener's aria-controls and the focus that moves in carry a person there.
  • A press outside closes the popover. Do not put in a popover what a person would lose by one stray press: a long form belongs in a dialog or a sheet. Where open is a plain value the product may also answer close with the reason outside by leaving the popover open; do that only with a visible way to close it (closable, or a dismissive action).
  • Keep nesting shallow: an overlay opened from a popover works at any depth (POP-24), but each level is one more thing Escape must be pressed for. One popover inside a popover is the most a product should need; a debug build reports a third.
  • Not modal means the rest of the page can still be read and scrolled, and a screen reader's cursor can leave the popover without closing it (POP-21). Nothing a person must answer before going on belongs in a popover.
  • Text size and small windows: at 200% text the popover wraps, grows to its limits and scrolls. In a compact window it is a sheet across the window's width (POP-39); one that keeps its own presentation is, at a window 320 wide, the window's width less the margins (POP-43). It never needs scrolling in two directions.
  • A compact window (POP-39 to POP-42): there a popover takes the bottom sheet's appearance, as every popover and every dialog of Tanrei does, and becomes a modal dialog — a scrim, everything behind it inert, focus kept in, Escape, back or a press on the scrim to close it. Modal because the sheet form is what the platforms make of a popover on a phone, and they make it modal: iOS adapts a popover to a sheet in a compact size class (UIPopoverPresentationController's adaptive sheet; SwiftUI's presentationCompactAdaptation), and Apple's guidelines present a popover's content in a compact view as a modal sheet; React Spectrum presents a popover as a modal on mobile; Material's bottom sheet that stands in for a menu or a dialog on mobile is a modal one. A surface over a scrim that left the page operable would show one thing and do another (WAI-ARIA APG, dialog: a modal dialog makes what is behind it inert). The opener still says it opens a dialog. Set compactPresentation to own for a popover that must stay beside what it belongs to; initialFocus anchor always keeps it there, because the field being typed in must stay usable.
  • Forced colors (POP-32): the container gains an edge in the text color, because its shadow is removed. Contrast in the default system: on-surface on surface-bright is held to 4.5:1 by the token invariants; the container is told from the page by its elevation's ring and shadow, which are not held to a contrast of their own, as for the menu.

مولَّد من specs/popover.spec.json, tokens/sys/measure.tokens.json

ما يتكفل به المكوّن

  • الحاوية مربع حوار غير نمطي، اسمه قيمة headline أو قيمة label. ولا يُخفى شيء خارجها ولا يُجعل خاملًا (inert).
  • حين تُعرض لوحةً سفلية في نافذة مضغوطة، تكون الحاوية مربع حوار نمطيًّا: كل ما خارجها خامل، والمفتاحان Tab وShift+Tab يدوران داخلها. وعند الإغلاق يعود التركيز إلى عنصر الفتح.
  • عنصر الفتح يعرض للتقنيات المساعدة أنه يفتح مربع حوار وهل ذلك المربع مفتوح. واسمه ودوره لا يتغيران.
  • الفتح ينقل التركيز إلى العنصر الذي علّمته، أو إلى الحاوية، فيُقرأ اسم اللوحة المنبثقة أولًا. ولا يظهر مؤشر التركيز على الحاوية إلا حين تُفتح اللوحة المنبثقة من لوحة المفاتيح.
  • تأتي اللوحة المنبثقة بعد عنصر الفتح مباشرة في ترتيب المفتاح Tab، أينما كانت في المستند. والمفتاح Tab من آخر عنصر فيها ينتقل إلى ما يلي عنصر الفتح، فتُغلق. ولا يُحصر التركيز فيها أبدًا.
  • المفتاح Escape يغلق التراكب الأعلى فقط، ولا يذهب أبعد من ذلك: مربع الحوار الذي تقف فيه اللوحة المنبثقة يبقى مفتوحًا.
  • الإغلاق يعيد التركيز إلى عنصر الفتح إن كان التركيز داخل اللوحة المنبثقة. وإن نقل الشخص التركيز إلى مكان آخر، بقي هناك.
  • التراكب الذي يُفتح من داخل اللوحة المنبثقة، كقائمة خيارات أو تلميح، تابع لها: الضغط أو التركيز فيه لا يغلق اللوحة المنبثقة.
  • عند تكبير النص إلى 200% يلتفّ نص اللوحة المنبثقة، وتكبر إلى حدودها، ويُمرَّر محتواها. وفي النافذة المضغوطة تكون لوحة سفلية بعرض النافذة كله. أما اللوحة المنبثقة التي تحتفظ بعرضها الخاص، ففي نافذة عرضها 320 يكون عرضها عرض النافذة ناقصًا الهامشين.

ما عليك فعله

  • أعطِ اللوحة المنبثقة headline أو label، وأعطها closeLabel ما دامت closable مفعَّلة.
  • اضبط open عند الضغط على عنصر الفتح، واضبطها على false عند الحدث close.
  • على الويب، ضع عنصر اللوحة المنبثقة بعد عنصر الفتح مباشرة في المستند حيث تستطيع، فيتبع ترتيب القراءة في قارئ الشاشة ترتيب المفتاح Tab.
  • علِّم الحقل الأول في نموذج قصير ليأخذ التركيز الأول. واترك اللوحة المنبثقة التي محتواها نص بلا تعليم.