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

بطاقة الرابط

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

content_copyعرض بتنسيق Markdown
الفئة
التنقل
الرموز
comp.link-card
المستوى
أساسي

نظرة عامة

Web
tanrei-link-card
schedule
SwiftUI
TanreiLinkCard
radio_button_unchecked
Jetpack Compose
TanreiLinkCard
radio_button_unchecked
Flutter
TanreiLinkCard
radio_button_unchecked
React Native
LinkCard
radio_button_unchecked

مولَّد من docs/status/status.json, specs/link-card.spec.json

بطاقة رابط بكل أجزائها

بطاقة الرابط (link card) تعرض الوجهة شيئًا قائمًا بذاته: عنوانها، وجملة عنها، وصورة حيث تكون لها صورة، والموقع الذي هي فيه. وهي رابط واحد. الكتلة كلها تُضغط، ولا شيء في داخلها يُضغط وحده.

  • العبارة التي في جملة وتقود إلى مكان ما رابط.
  • المجموعة من محتواك أنت التي تقود إلى مكان ما بطاقة لها وجهة.
  • المعاينة التي لها أزرارها (حفظ، مشاركة، تجاهل) بطاقة تحمل رابطًا وتلك الأزرار.

المكوّن لا يجلب شيئًا. يرسم القيم التي تعطيه إياها، ولا يسأل الوجهة ولا خادمًا وسيطًا (proxy) ولا أي خدمة عن شيء يخص href. والطلبات الوحيدة التي يرسلها هي طلبا الصورة وأيقونة الموقع اللتين تسلّمهما إليه. وكيف يحصل الموقع على القيم مذكور تحت الحصول على القيم.

على الويب هي <tanrei-link-card> حول عنصر anchor الذي تكتبه أنت. وليس للعنصر جذر ظل (shadow root)، فالبطاقة رابط قبل أن يعمل أي سكربت. والمنصات الأخرى لم تنفّذها بعد.

الاستخدام

<link rel="stylesheet" href="@tanrei/web/icons.css" />
<link rel="stylesheet" href="@tanrei/web/link-card.css" />

<tanrei-link-card>
  <a href="https://example.com/articles/designing-with-tokens" data-external="true">
    <span data-part="body">
      <span data-part="title" dir="auto">التصميم بالرموز</span>
      <span data-part="description" dir="auto">كيف تصير بضعة أقراص ضبط نظامًا كاملًا.</span>
      <span data-part="site">
        <img data-part="site-icon" src="/link-pictures/icon.png" alt=""
             loading="lazy" decoding="async" referrerpolicy="no-referrer" />
        <span data-part="site-name"><span dir="auto">Example Journal</span></span>
        <span data-part="address"><bdi data-part="host" dir="ltr"><span>example.</span><span>com</span></bdi></span>
      </span>
      <span data-part="words">رابط خارجي</span>
    </span>
    <img data-part="media" src="/link-pictures/picture.png" alt="" width="1200" height="630"
         loading="lazy" decoding="async" referrerpolicy="no-referrer" />
  </a>
</tanrei-link-card>

<script type="module">
  import '@tanrei/web/components/link-card';
</script>
import { LinkCard } from '@tanrei/react';
import '@tanrei/web/icons.css';
import '@tanrei/web/link-card.css';

<LinkCard
  href={link.href}
  headline={link.title}
  description={link.description}
  siteName={link.siteName}
  image={link.image?.src}
  siteIcon={link.siteIcon?.src}
  external="on"
  externalLabel="رابط خارجي"
/>

لا تكتب ذلك الترميز (markup) بيدك. الدالتان linkCardToHtml() و linkCardToNodes() في @tanrei/web/links تكتبانه من القيم، فتكون البطاقة كاملة في الرسم الأول ومع إيقاف السكربتات.

بطاقة يبنيها السكربت

العنصر <tanrei-link-card> الذي لا يحمل عنصر anchor يبني واحدًا من خصائص HTML التي عليه. وكل قيمة تُكتب نصًّا، لا ترميزًا أبدًا.

<tanrei-link-card
  href="https://example.com/articles/designing-with-tokens"
  headline="التصميم بالرموز"
  description="كيف تصير بضعة أقراص ضبط نظامًا كاملًا."
  site-name="Example Journal"
></tanrei-link-card>

خاصية HTML التي تحمل العنوان هي headline، لأن الخاصية title في HTML نفسها كانت ستعرض تلميحًا فوق البطاقة. وهذه الهيئة لا تُرسم إلا بعد أن يعمل السكربت. فاكتب الترميز عند البناء في صفحة محتوى.

المواصفات

مظهران

البنية

الخصائص

الخاصية النوع القيمة الافتراضية الوصف
href string "" The destination: an address as the platform's links take one (a URL; on the web a path or a fragment as well). It is also the one thing the card reads the host from (LKC-8). A link card without a destination is not a link and is not drawn as a card (LKC-27).
target same | new "same" Where the destination opens. same: where the person is — the same tab on the web, the app's own handling of the address elsewhere. new: a new context — a new tab or window on the web, outside the current screen elsewhere — which the card marks with the glyph open_in_new at the end of its site line and says through targetLabel (LKC-23).
targetLabel string "" What assistive technology reads at the end of the card's description while target is new ("opens in a new tab"). Tanrei ships no words of its own, so the product gives them in its language. Required while target is new; ignored otherwise.
external auto | on | off "auto" Whether the destination is on another site than the one the person is on: the same prop, with the same values and the same rule, as the Link's (LNK-30). auto: the card decides as the Link does, where the platform can tell. on: it is external, whatever the address. off: it is not. An external card that opens where the person is draws the arrow at the end of its site line and says so through externalLabel (LKC-24). It changes nothing else: the host is drawn whether the destination is external or not.
externalLabel string "" What assistive technology reads at the end of the card's description while the destination is external and target is same ("external link"), in the product's language. Empty, the words the product has set once for every external link are read, as for the Link (LNK-34). Ignored while target is new.
title string "" The destination's title: what the page calls itself. Plain text; it is the card's accessible name. Drawn on at most two lines by default. Empty, the address is drawn in its place (LKC-5).
description string "" A sentence or two about the destination. Plain text; it is the first part of the card's description for assistive technology. Drawn on at most two lines by default; empty, nothing is drawn for it.
image string "" The address of a picture that stands for the destination. It is drawn beside the text in a wide card and above it in a narrow one, cropped to its box. The card asks for this address and for nothing else about the destination (LKC-14); a site should keep the picture among its own files rather than name the destination's. Empty, or failing to load, the card is drawn without a picture.
imageAlt string "" What the picture shows, in the product's language, where that is worth saying. Empty — the usual case — the picture is decoration: the title and the description already say where the card leads. Never drawn; read as part of the description (LKC-25).
siteName string "" What the destination's site calls itself ("Example Journal"). Plain text, drawn before the host on the site line and cut first when the line is short. It never replaces the host, and it is not drawn where it only repeats it (LKC-7).
siteIcon string "" The address of the destination site's small icon, given to the card and never looked up by it: the same value, resolved the same way, as the Link's site icon. Drawn at the start of the site line; empty or failing to load, nothing is drawn in its place.
variant outlined | filled "outlined" How the card is set apart. outlined: the surface inside one hairline, for running text and the page's own surface. filled: a tone of the surface and no edge, where one more line would crowd. It changes colors and the edge only. A design system may add values.

الأحداث

الحدث الوصف
click The card was activated by pointer, touch, Enter or assistive technology. It is emitted before the destination opens; a product that takes the navigation itself (a client-side router) cancels it (LKC-22).

الحالات

السلوك

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

المعرّف المتطلب
LKC-1 WHILE href is a destination THE link card SHALL be the platform's own link to it (the web's anchor element in the document itself, not in a shadow root; SwiftUI's Link; on Compose, Flutter and React Native an element with the platform's link semantics whose address is opened by the platform's opener), so that whatever the platform gives a link — on the web its context menu, opening in a new tab or window, copying and dragging its address, the address shown before it is followed, a crawler and a search index that read it, and a link that works before any script has run — is the platform's, and not the link card's to draw or to take over; it SHALL be exactly one focusable element with the link role, and everything it draws SHALL be the presentational content of that one element.
LKC-2 THE link card SHALL lay itself out as a block in the flow of its container: it SHALL take the whole inline size the container gives it, with its start edge on the start edge of the text around it, SHALL bring no outer space of its own (PRS-15: the space between it and its neighbours is its container's), SHALL never be wider than its container, and SHALL be exactly as tall as what it holds, with no height of its own. It SHALL draw a container with corners comp.link-card.container.shape, filled with the container color of its variant (comp.link-card.outlined.container.color for outlined, comp.link-card.filled.container.color for filled), SHALL clip everything it draws to that shape, SHALL draw the outline of its variant (comp.link-card.outlined.outline.color, comp.link-card.filled.outline.color) comp.link-card.outline.width wide inside the container's size and above the picture, and SHALL draw no elevation.
LKC-3 THE link card SHALL draw its text in a body padded by comp.link-card.container.padding on every side: from top to bottom the title (LKC-4, LKC-5); the description where there is one (LKC-6), comp.link-card.title.gap below the title; and the site line where there is one (LKC-7), comp.link-card.site.gap below the text above it. A part that is not drawn SHALL take no room and leave no gap, and the body SHALL place its text at the start edge in every layout.
LKC-4 THE link card SHALL draw title in comp.link-card.title.typescale and in the title color of its variant and state (comp.link-card.outlined.title.color for outlined, comp.link-card.filled.title.color for filled), on at most comp.link-card.title.max-lines lines: a longer title SHALL be cut at the end of its last drawn line, where its own direction ends, with an ellipsis, and a run with no place to break that is longer than the line SHALL break inside the run rather than overflow. THE link card SHALL draw no underline under the title, SHALL expose the whole title to assistive technology whatever part of it is drawn, and SHALL NOT expose it as a heading. THE link card SHALL set the title'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.
LKC-5 WHILE title is empty or only white space THE link card SHALL draw the address of href, as it was given, in the title's place and style — as one left-to-right run that may break anywhere, held to the same number of lines — SHALL be named by that address, and in debug builds SHALL report that a link card has no title.
LKC-6 WHILE description is not empty THE link card SHALL draw it in comp.link-card.description.typescale and in the description color of its variant and state (comp.link-card.outlined.description.color for outlined, comp.link-card.filled.description.color for filled), on at most comp.link-card.description.max-lines lines, cut as LKC-4 cuts the title, and SHALL expose the whole of it; WHILE description is empty or only white space it SHALL draw nothing for it.
LKC-7 WHERE the link card has a host (LKC-8), a site name or a mark (LKC-23, LKC-24) THE link card SHALL draw a site line in comp.link-card.site.typescale and in the site color of its variant and state (comp.link-card.outlined.site.color for outlined, comp.link-card.filled.site.color for filled), holding in reading order the site icon (LKC-10), the site's name, the host and the mark, comp.link-card.site.item-gap apart and each centred on the height of the line's first row; WHERE both the site's name and the host are drawn it SHALL draw a middle dot between them, kept from assistive technology. THE link card SHALL draw siteName as the site's name, on one line, and SHALL NOT draw it WHILE it is empty or says only what the host says (the same characters without regard to case, with or without a leading "www."). WHERE the line is too narrow THE site's name SHALL give way first — cut at its own end with an ellipsis, and left out together with the dot where not even its first character and an ellipsis fit — and THE host SHALL never be cut, shortened or ended with an ellipsis: a host longer than the line SHALL run onto further lines, breaking after a dot and, where one label is longer than the line, inside it, with the mark after its last character.
LKC-8 THE link card SHALL compute the host it draws from href and from nothing else: the host name the platform's address parser reads from href, in lower case, followed by a colon and the port where href names a port that is not its scheme's own; never a user name or a password written before the host, never a path, a query or a fragment; and never anything taken from title, description, siteName or any other value it is given. No prop SHALL set, replace or hide the host. WHILE href has no host of its own — a path, a fragment, an address relative to the page, a scheme that has none — THE link card SHALL draw no host.
LKC-9 WHERE a label of the host is the ASCII form of an internationalised name (it begins with "xn--") THE link card SHALL draw the whole host in its Unicode form only WHILE every such label of it (a) decodes, and encodes back to exactly the label it was; (b) holds nothing but letters, combining marks, the digits 0 to 9 and the hyphen; (c) has all of its letters in one script, or in one of the sets a single writing system uses together — Latin with Han, Hiragana and Katakana; Latin with Han and Hangul; Latin with Han and Bopomofo — where the Latin of each set is the ASCII letters a to z alone, so that a Latin letter with a mark beside Han keeps the ASCII form; and (d) is not written wholly in Cyrillic or wholly in Greek under a last label that is ASCII. In every other case THE link card SHALL draw the whole host in the ASCII form the address parser gives, never a part of it in each form. THE link card SHALL draw the host as one left-to-right run, isolated from the text beside it, with its labels in the address's own order, in every layout direction. A platform that cannot decode a label or cannot tell the script of a character SHALL draw the ASCII form always, and state that in its README.
LKC-10 WHILE siteIcon is not empty and its picture has not failed THE link card SHALL keep, at the start of the site line, a square box comp.link-card.site.icon.size a side, and once the picture has loaded SHALL draw it there, scaled to fit inside the box with its proportions kept, clipped to corners comp.link-card.site.icon.shape, and kept from assistive technology. WHILE siteIcon is empty, or IF its picture cannot be loaded, THE link card SHALL draw no icon, no glyph in its place and no box, SHALL NOT ask for it again by itself, and for a failure SHALL report the address in debug builds.
LKC-11 WHILE image is not empty and its picture has not failed THE link card SHALL draw a picture box (LKC-12 says where and how large) filled with comp.link-card.media.container.color, and once the picture has loaded SHALL draw it over the whole box, scaled so that it covers the box with its proportions kept and its centre on the box's centre, clipped by the box and by the card's corners where the box meets them. THE link card SHALL NOT mirror, tint or otherwise change the picture in any layout direction, scheme or state. WHILE image is empty THE link card SHALL draw no picture box and ask for nothing.
LKC-12 WHILE the link card has a picture box and its own inline size is at least comp.link-card.layout.beside-min-width multiplied by the scale of the text THE link card SHALL draw the box beside the body, at the card's end edge, comp.link-card.media.width wide and as tall as the card, whose height is the body's; WHILE it is narrower THE link card SHALL draw the box above the body, across the card's whole inline size, as tall as that size divided by comp.link-card.media.aspect-ratio. THE link card SHALL choose between the two from its own inline size alone, never from the window's, and WHEN that size crosses the boundary SHALL draw the other layout at once, without a motion, keeping its focus and its state.
LKC-13 WHILE image is not empty and its picture has not yet loaded THE link card SHALL draw the picture box at its final size, so that nothing changes place when the picture arrives; WHEN the picture has loaded THE link card SHALL draw it at once, without a motion; IF the picture cannot be loaded THE link card SHALL be drawn as a link card without a picture, SHALL draw no broken-picture mark, no alternative text and no address in the picture's place, SHALL NOT ask for the picture again by itself, and in debug builds SHALL report the address that failed. WHEN image changes THE link card SHALL draw the box of LKC-11 until the new picture has loaded.
LKC-14 THE link card SHALL NOT ask the network, a cache, a proxy or any service for href, for the page at href, or for anything it could learn from that page — its title, its description, its picture, its icon — at any time: until a person activates it, nothing it does reaches the destination, and it SHALL draw only what it was given. The only addresses THE link card SHALL ask for are image and siteIcon, each as a picture: WHERE the platform lets a request withhold the page it comes from THE link card SHALL withhold it (the web: no referrer); WHERE the platform can put a request off THE link card SHALL ask only once the card is near what is shown; and it SHALL draw what arrives as a picture and nothing else — never as a document, a frame, markup, or anything that can run or lay out content of its own. IF image or siteIcon names a script to run, or something the platform cannot read as the address of a picture, THE link card SHALL treat that value as empty and in debug builds report it; and in debug builds it SHALL report an image or a siteIcon that is asked of another party than the one the page or the app itself comes from, because every reader would then tell that party what they are reading (LNK-35).
LKC-15 THE link card SHALL draw and expose title, description, siteName and imageAlt as plain text: a character that would begin markup elsewhere is drawn as the character it is, and nothing in them is parsed, linked, styled or run. Before drawing and exposing each of them THE link card SHALL read a line break or a tab as one space, SHALL drop every other control character, and SHALL drop the characters that embed, override or isolate the direction of text (U+202A to U+202E and U+2066 to U+2069), so that no value can reorder itself or the text beside it; it SHALL keep every other character, the marks that only state a direction and the joiners a script needs included.
LKC-16 WHILE hovered, keyboard-focused or pressed THE link card SHALL render its container, outline, title, description, site line and opacity from the component tokens of the highest-precedence active state, with precedence pressed over focused over hovered; focus gained by pointer or touch SHALL NOT select the focused state. THE link card SHALL draw the answer to a state behind its text and SHALL NOT draw it over the picture or the site icon, which take the card's opacity and are otherwise drawn as at rest.
LKC-17 WHEN the link card receives keyboard focus THE link card SHALL show the focus ring without animation — the system's focus indicator around the whole card, sys.focus.offset from the container and following its corners, sys.focus.outer-width wide in the color role focus-ring, with the inner stroke of sys.focus.inner-width where the system has one; focus gained by pointer or touch SHALL NOT show it.
LKC-18 WHEN the link card is pressed by pointer, touch or Enter THE link card SHALL show the pressed state without delay and SHALL keep it visible for at least sys.motion.duration.press-hold, even when the press ends sooner.
LKC-19 WHILE pressed THE link card SHALL answer as sys.behavior.pressed-feedback names: overlay applies the pressed tokens to the whole container at once; ripple grows the pressed state layer from the point of contact (from the center for keyboard activation); dim applies the pressed opacity to the whole control and draws no state layer; none draws no answer to the press. Under ripple and dim only the container color stays with the state under the press; title, description, site line, outline, opacity and shape still come from the pressed tokens. Under none every part stays with the state under the press. The ripple grows over comp.link-card.motion.feedback-duration with comp.link-card.motion.state-easing, fades over comp.link-card.motion.state-duration with comp.link-card.motion.state-easing once the press has ended and press-hold has passed, and appears whole where motion is reduced.
LKC-20 THE link card SHALL ease its container corners 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 show its keyboard focus as sys.behavior.focus-style names (ring or glow); a platform that cannot draw a choice SHALL fall back to the first value and state that in its README.
LKC-21 WHERE the visual size of the link card is below the minimum target THE link card SHALL extend its hit area on both axes to sys.target.touch for touch input and sys.target.pointer for fine pointers, without changing its visual size; a platform that cannot tell the input type SHALL use sys.target.touch.
LKC-22 WHEN the user activates the link card by pointer, touch or Enter THE link card SHALL emit click exactly once and then open href where target names, unless the product cancelled that click, in which case it SHALL open nothing: the product's own router has taken the navigation. It SHALL NOT hold the navigation back for sys.motion.duration.press-hold. THE link card SHALL NOT be activated by Space, which on the web scrolls the page as it does on any link, and SHALL NOT show the pressed state for it; WHERE the platform gives its links other keys or gestures (on the web a modified or a middle click that opens a new tab, on Apple platforms a long press that previews) THE link card SHALL leave them to the platform.
LKC-23 WHILE target is new THE link card SHALL open href in a new context — on the web a new tab or window that is given no handle to the page that opened it; on the other platforms outside the screen the person is on, as the platform's opener decides — and SHALL draw the glyph open_in_new of the system's icon set at the end of the site line (LKC-7), in a box as large as the font size of that line's text, in the site color of its variant and state, through the icon helper, which mirrors it in a right-to-left layout because the icon set marks its name, and hidden from assistive technology; a link card with neither a host nor a site name draws a site line that holds the mark alone. No prop SHALL hide the mark or force it. THE link card SHALL expose targetLabel as part of its description (LKC-25), and WHILE targetLabel is empty SHALL still render and in debug builds report that a link that opens a new context does not say so. WHILE target is same THE link card SHALL draw no such mark and SHALL ignore targetLabel.
LKC-24 THE link card SHALL treat its destination as external exactly as the Link does (LNK-30) and SHALL have no rule of its own for it: as its external prop names — on, off, or under auto exactly when the platform can tell that href is on another site than the one the person is on, from the same declaration of the product's own site that the Link reads. WHILE the destination is external and target is same THE link card SHALL draw the glyph arrow_outward of the system's icon set in the place and manner of LKC-23's mark, kept from assistive technology, and SHALL expose externalLabel — or, WHILE externalLabel is empty, the words the product has set once for every external link (LNK-34) — as the last part of its description (LKC-25); WHILE target is new THE link card SHALL draw LKC-23's mark alone, never two, and expose targetLabel and not externalLabel. Being external SHALL change nothing else: not the host, which is drawn for a destination on the product's own site as well, not where the destination opens, and nothing about how any address is requested.
LKC-25 THE link card SHALL expose the title — or, WHILE title is empty, the address (LKC-5) — as its accessible name and add nothing to it. THE link card SHALL expose as its description, in this order and leaving out what it does not have: the description, the alternative text of the picture (imageAlt), the site's name where it is drawn, the host as it is drawn, and last targetLabel WHILE target is new, or the words of LKC-24 WHILE the destination is external and target is same. THE picture SHALL be kept from assistive technology as a picture in every case — imageAlt, where the product gives it, is read as part of the description — and the site icon, the middle dot and every mark SHALL be kept from it.
LKC-26 THE link card SHALL draw no state for a destination already visited: its colors say what it is and what state it is in, and are the same before and after it has been followed.
LKC-27 IF href is empty or only white space, or names a script to run rather than a place to go (the web's javascript: scheme), or cannot be read as an address by the platform, THE link card SHALL NOT be a link and SHALL NOT be drawn as a card: it SHALL draw its title, where it has one, as plain text in the style of the text around it and nothing else — no container, no description, no picture, no site line, no state — SHALL expose no role, SHALL NOT be focusable, SHALL emit nothing and ask for nothing, and in debug builds report it. WHEN target names a value the link card does not define THE link card SHALL behave as same, WHEN external names one it SHALL treat it as auto, and WHEN variant names a value the active design system does not have it SHALL render with the default variant's tokens; in debug builds it SHALL report the unknown value.
LKC-28 WHEN the colors of the link card change between states THE link card SHALL animate the change over comp.link-card.motion.state-duration with comp.link-card.motion.state-easing, and SHALL change them at once where motion is reduced.
LKC-29 WHILE the text size is enlarged THE link card SHALL grow its title, its description, its site line and the mark with it, SHALL keep its paddings, gaps, edge, the site icon's box and comp.link-card.media.width, SHALL keep counting lines by comp.link-card.title.max-lines and comp.link-card.description.max-lines, and SHALL grow in height; it SHALL set no fixed height, SHALL draw the picture above the text sooner (LKC-12), and SHALL need no sideways scrolling of what holds it at a width of 320 points with text at 200 %.
LKC-30 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 link card SHALL draw an edge comp.link-card.outline.width wide in the platform's text color in both looks, so that a look whose fill the mode removes is still a bounded block; SHALL draw its title in the platform's link color and its description and site line in the platform's text color; SHALL draw its focus ring in the platform's highlight color; SHALL draw no fill in the picture box; and SHALL leave the picture and the site icon as they are.
LKC-31 THE link card 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 link card is shown THE link card SHALL draw itself for the new direction at once, without a motion of its own, keeping its focus.
LKC-32 WHERE the layout direction is right-to-left THE link card SHALL apply its paddings by logical start and end and mirror its layout: the picture beside the text stands at the left, the text begins at the right, and the site line runs from the right — icon, site's name, host, mark. Top and bottom SHALL NOT change. THE link card SHALL NOT mirror the picture or the site icon, SHALL NOT mirror a glyph itself (the icon helper mirrors a mark whose name the icon set marks, inside its own box), SHALL keep the host a left-to-right run (LKC-9), and SHALL grow a ripple from the point of contact as in left-to-right.
LKC-33 THE link card SHALL lay out its title, its description and its site's name as text of their own direction, each isolated from the others and from the text around the card: each takes the base direction of its first strong character, or the layout direction where it has none, so that a left-to-right name, a number with its unit and a version keep their own order in a right-to-left layout and reorder nothing beside them; THE link card SHALL still place each and align its lines by the layout direction, not by the text's own, and SHALL cut each where its own direction ends (LKC-4).
LKC-34 WHEN href, title, description, image, imageAlt, siteName, siteIcon, target, targetLabel, external, externalLabel or variant changes while the link card is shown THE link card SHALL draw and expose the new value at once, without a motion, keeping its focus, and SHALL NOT announce the change by itself.
LKC-35 THE link card SHALL hold no interactive element — no button, no second link, no field, nothing else that takes focus — and SHALL offer no place to put one: its parts are the values it is given. A platform whose link card is drawn on the product's own elements (the web) SHALL report in debug builds an interactive element found inside it, and SHALL keep the card one link.
LKC-36 WHERE the platform shows a page before its script has run, or without it (the web), THE link card SHALL already be drawn whole and at rest from what is in the document — its container, its text, its site line, its picture box and the layout of LKC-12 — SHALL be a link that can be followed, and SHALL move nothing when its script arrives. Script SHALL add only what the document cannot hold: the answer to a press beyond a plain state change, the host computed anew from href (LKC-8, LKC-9), the cleaning of LKC-15 for values given by script, the name and the description as LKC-25 divides them, the failures of LKC-10 and LKC-13, and every debug report.

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

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

المواصفة Web SwiftUI Jetpack Compose Flutter React Native
المكوّن tanrei-link-card TanreiLinkCard TanreiLinkCard TanreiLinkCard LinkCard
href · الخاصية href destination href href href
target · الخاصية target target target target target
targetLabel · الخاصية targetLabel targetLabel targetLabel targetSemanticLabel targetLabel
external · الخاصية external external external external external
externalLabel · الخاصية externalLabel externalLabel externalLabel externalSemanticLabel externalLabel
title · الخاصية headline title title title title
description · الخاصية description description description description description
image · الخاصية image image image image image
imageAlt · الخاصية imageAlt imageDescription imageDescription imageSemanticLabel imageAccessibilityLabel
siteName · الخاصية siteName siteName siteName siteName siteName
siteIcon · الخاصية siteIcon siteIcon siteIcon siteIcon siteIcon
variant · الخاصية variant variant variant variant variant
click · الحدث click action onClick onPressed onPress
ملاحظات The light-DOM form with an element: <tanrei-link-card> is a custom element with **no shadow root** around the product's own anchor, which stays in the document: <tanrei-link-card variant="outlined"><a href="…"><span data-part="body"><span data-part="title">…</span><span data-part="description">…</span><span data-part="site"><img data-part="site-icon" src="…" alt="" width="16" height="16"><span data-part="site-name">…</span><bdi data-part="host" dir="ltr">…</bdi></span></span><img data-part="media" src="…" alt="" width="…" height="…"></a></tanrei-link-card>; every part but the title is optional. That markup is what a site's build step writes (the package's linkCardToNodes gives it as plain node descriptions, as highlightToNodes does for code), and one stylesheet, @tanrei/web/link-card.css, whose selectors start at tanrei-link-card inside :where(), draws all of it before the element is defined and with scripting off (LKC-36): the layout of LKC-12 is a container query on the element (container-type: inline-size, the boundary written in rem so it follows the text size), the line counts are -webkit-line-clamp/line-clamp, the mark is the anchor's site line's ::after in the icon font (mirrored under :dir(rtl)), and the press-hold is a delayed transition back from :active, as the link's stylesheet has it. For a page built by script, or the React wrapper, the element takes the same values as attributes — href, target (HTML's _blank is read as new), target-label, external, external-label, headline (HTML's global title would show a tooltip over the card), description, image, image-alt, site-name, site-icon, variant — and writes the anchor and its parts itself, as text nodes, never as markup (LKC-15). Once defined the element: computes the host from the anchor's href with URL and the rule of LKC-9 and writes it into the host part, replacing and reporting one that differs; writes data-external on the anchor as the Link's script does, from the same setSiteOrigins() (the build step's markExternalLinks() writes it where the page is made, and only a value the script wrote is ever changed by it); gives the title, description, site and a visually hidden part for the target or external words ids and sets aria-labelledby and aria-describedby; adds noopener to rel for a new context; sets referrerpolicy="no-referrer", loading="lazy" and decoding="async" on both pictures where the markup has not (the build step writes them, so the first request already carries them); removes the media or the icon on its error event; hands presses to the shared press primitive (ripple and dim); and makes the debug reports. rel and download are the anchor's own. click is the anchor's native event; cancelling it cancels the navigation. Pictures are <img> elements and nothing else, so a picture file that holds markup cannot run. React: LinkCard renders the same element and anchor and takes a render prop for a router's link. TanreiLinkCard(destination: URL, title:, description:, image:, imageDescription:, siteName:, siteIcon:, target:, targetLabel:, external:, externalLabel:, variant:, action:), built on SwiftUI's Link, so the address is opened by the environment's openURL and an app that routes addresses itself provides an OpenURLAction. image and siteIcon are URL? drawn with AsyncImage (a picture decoder only; a request without a referrer by nature), the fallback of LKC-13 on its failure phase; an app that already holds the pictures passes Image values through a second initializer. The host comes from URLComponents(url:).host (the encoded form) and the rule of LKC-9 applied with Unicode.Scalar.Properties; the layout of LKC-12 from the card's proposed width (ViewThatFits or a Layout), scaled by the dynamic type size. The isLink trait; the description is the accessibility value, targetLabel the hint. action runs before the address opens and returns whether the link should still open it. Not built on this platform yet. TanreiLinkCard(href, title, description, image, imageDescription, siteName, siteIcon, target, targetLabel, external, externalLabel, variant, onClick = null). The package keeps no image-loading dependency: image and siteIcon are models handed to the painter the app provides through the composition local the avatar uses, and a painter that reports failure draws the card without the picture; the app's loader is what must withhold the referrer and defer the request (LKC-14), and the README says so. The host is java.net.URI(href).host with java.net.IDN and Character.UnicodeScript for LKC-9. The layout of LKC-12 is BoxWithConstraints on the card's own max width, the boundary multiplied by LocalDensity.current.fontScale. The address is opened through LocalUriHandler.current after onClick, which returns false to keep it closed. Compose has no link role for a clickable element: the node drops Role.Button, carries none, and the README says so. Not built on this platform yet. TanreiLinkCard(href: Uri, title:, description:, image:, imageSemanticLabel:, siteName:, siteIcon:, target:, targetSemanticLabel:, external:, externalSemanticLabel:, variant:, onPressed:). image and siteIcon are ImageProvider? values the app builds (a NetworkImage sends no referrer; errorBuilder gives LKC-13's fallback), so the package fetches through nothing of its own. Semantics(link: true) with linkUrl where the engine has it. The host is href.host; Dart's Uri does not decode an internationalised label, so the package carries the small decoder LKC-9 needs and tells scripts with RegExp(unicode: true) property escapes. The layout of LKC-12 is a LayoutBuilder on the card's own constraints, the boundary scaled by MediaQuery.textScalerOf. The address is opened by the opener the app provides, after onPressed, which returns false to keep it closed. Not built on this platform yet. <LinkCard href title description image imageAccessibilityLabel siteName siteIcon target targetLabel external externalLabel variant onPress />: an accessible Pressable with accessibilityRole="link", the description and the host in accessibilityValue, targetLabel as the accessibilityHint. image and siteIcon are ImageSourcePropType values drawn by Image (its onError gives LKC-13's fallback). onPress receives an event whose preventDefault() keeps the address closed; otherwise Linking.openURL(href). The host is read with the runtime's URL; where the runtime cannot tell scripts (no Unicode property escapes) the ASCII form is drawn always and the README says so (LKC-9). The layout of LKC-12 comes from the card's own onLayout width, the boundary multiplied by PixelRatio.getFontScale(). Follows the app's direction where an ancestor's is not known. Not built on this platform yet.

الرموز

الرمز يشير إلى القيمة المحلولة (فاتح)
--tanrei-comp-link-card-container-padding sys.space.space200 16px
--tanrei-comp-link-card-container-shape sys.shape.corner.medium 8px
--tanrei-comp-link-card-description-max-lines — 2
--tanrei-comp-link-card-filled-container-color sys.color.surface-container-highest #eeeeee
--tanrei-comp-link-card-filled-description-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-link-card-filled-focused-container-color — #d9d9d9
--tanrei-comp-link-card-filled-focused-description-color — #4b4b4b
--tanrei-comp-link-card-filled-focused-outline-color — #000000 · 0%
--tanrei-comp-link-card-filled-focused-site-color — #4b4b4b
--tanrei-comp-link-card-filled-focused-state-layer-color — #1b1b1b
--tanrei-comp-link-card-filled-focused-title-color — #1b1b1b
--tanrei-comp-link-card-filled-hovered-container-color — #dddddd
--tanrei-comp-link-card-filled-hovered-description-color — #4b4b4b
--tanrei-comp-link-card-filled-hovered-outline-color — #000000 · 0%
--tanrei-comp-link-card-filled-hovered-site-color — #4b4b4b
--tanrei-comp-link-card-filled-hovered-state-layer-color — #1b1b1b
--tanrei-comp-link-card-filled-hovered-title-color — #1b1b1b
--tanrei-comp-link-card-filled-outline-color — #000000 · 0%
--tanrei-comp-link-card-filled-pressed-container-color — #d9d9d9
--tanrei-comp-link-card-filled-pressed-description-color — #4b4b4b
--tanrei-comp-link-card-filled-pressed-outline-color — #000000 · 0%
--tanrei-comp-link-card-filled-pressed-site-color — #4b4b4b
--tanrei-comp-link-card-filled-pressed-state-layer-color — #1b1b1b
--tanrei-comp-link-card-filled-pressed-title-color — #1b1b1b
--tanrei-comp-link-card-filled-site-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-link-card-filled-state-layer-color comp.link-card.filled.title.color #1b1b1b
--tanrei-comp-link-card-filled-title-color sys.color.on-surface #1b1b1b
--tanrei-comp-link-card-focused-opacity — 1
--tanrei-comp-link-card-hovered-opacity — 1
--tanrei-comp-link-card-layout-beside-min-width — 480px
--tanrei-comp-link-card-media-aspect-ratio — 1.9
--tanrei-comp-link-card-media-container-color sys.color.surface-container-high #f3f3f3
--tanrei-comp-link-card-media-width — 192px
--tanrei-comp-link-card-motion-feedback-duration sys.motion.role.feedback 450ms
--tanrei-comp-link-card-motion-state-duration sys.motion.role.state.large 250ms
--tanrei-comp-link-card-motion-state-easing sys.motion.easing.state cubic-bezier(0.2, 0, 0, 1)
--tanrei-comp-link-card-outline-width sys.border.hairline 1px
--tanrei-comp-link-card-outlined-container-color sys.color.surface #ffffff
--tanrei-comp-link-card-outlined-description-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-link-card-outlined-focused-container-color — #e8e8e8
--tanrei-comp-link-card-outlined-focused-description-color — #4b4b4b
--tanrei-comp-link-card-outlined-focused-outline-color — #000000 · 8%
--tanrei-comp-link-card-outlined-focused-site-color — #4b4b4b
--tanrei-comp-link-card-outlined-focused-state-layer-color — #1b1b1b
--tanrei-comp-link-card-outlined-focused-title-color — #1b1b1b
--tanrei-comp-link-card-outlined-hovered-container-color — #ededed
--tanrei-comp-link-card-outlined-hovered-description-color — #4b4b4b
--tanrei-comp-link-card-outlined-hovered-outline-color — #000000 · 8%
--tanrei-comp-link-card-outlined-hovered-site-color — #4b4b4b
--tanrei-comp-link-card-outlined-hovered-state-layer-color — #1b1b1b
--tanrei-comp-link-card-outlined-hovered-title-color — #1b1b1b
--tanrei-comp-link-card-outlined-outline-color sys.color.outline-variant #000000 · 8%
--tanrei-comp-link-card-outlined-pressed-container-color — #e8e8e8
--tanrei-comp-link-card-outlined-pressed-description-color — #4b4b4b
--tanrei-comp-link-card-outlined-pressed-outline-color — #000000 · 8%
--tanrei-comp-link-card-outlined-pressed-site-color — #4b4b4b
--tanrei-comp-link-card-outlined-pressed-state-layer-color — #1b1b1b
--tanrei-comp-link-card-outlined-pressed-title-color — #1b1b1b
--tanrei-comp-link-card-outlined-site-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-link-card-outlined-state-layer-color comp.link-card.outlined.title.color #1b1b1b
--tanrei-comp-link-card-outlined-title-color sys.color.on-surface #1b1b1b
--tanrei-comp-link-card-pressed-opacity — 1
--tanrei-comp-link-card-site-gap sys.space.space100 8px
--tanrei-comp-link-card-site-icon-shape sys.shape.corner.extra-small 3px
--tanrei-comp-link-card-site-icon-size sys.icon.extra-small 16px
--tanrei-comp-link-card-site-item-gap sys.space.space75 6px
--tanrei-comp-link-card-title-gap sys.space.space50 4px
--tanrei-comp-link-card-title-max-lines — 2
--tanrei-comp-link-card-description-typescale sys.typescale.body 400 14px/1.5714
--tanrei-comp-link-card-site-typescale sys.typescale.body-small 400 13px/1.5385
--tanrei-comp-link-card-title-typescale sys.typescale.heading-5 500 16px/1.5

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

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

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

الإرشادات

ما تعطيها إياه

القيمة خاصية HTML تُرسم
href href الوجهة. والمضيف (host) الذي تحت النص يُقرأ منها ولا يُقرأ من شيء غيرها.
title headline العنوان، في سطرين على الأكثر. وهو اسم البطاقة المتاح للتقنيات المساعدة.
description description جملة أو جملتان، في سطرين على الأكثر.
image، imageAlt image، image-alt صورة تغطي صندوقها، مقصوصة عند مركزها. والقيمة imageAlt تُقرأ ولا تُرسم أبدًا.
siteName site-name ما يسمّي الموقع به نفسه، قبل المضيف.
siteIcon site-icon أيقونة الموقع الصغيرة، في بداية سطر الموقع.
target، targetLabel target، target-label القيمة new تفتح تبويبًا جديدًا وترسم علامته. أعطِ الكلمات.
external، externalLabel external، external-label القيمة auto (الافتراضية) أو on أو off، كما في الرابط.
variant variant الطراز outlined (الافتراضي) أو filled.

إلى أين تقود

كل ما عدا ذلك في البطاقة هو ما تقوله الوجهة عن نفسها، والوجهة تستطيع أن تقول أي شيء. ولذلك جزء واحد ليس للوجهة أن تقوله.

  • المضيف يُحسب من href. لا قيمة تعيّنه أو تستبدله أو تخفيه. والمضيف المكتوب في الترميز إذا اختلف يُستبدل حين يُعرَّف العنصر، وتبلّغ عنه بنية التنقيح.
  • اسم الموقع يقف قبل المضيف، لا في مكانه أبدًا. ويُحذف حيث لا يفعل إلا تكرار المضيف.
  • المضيف لا يُقصّ أبدًا. في السطر القصير يتراجع اسم الموقع أولًا، والمضيف الأطول من السطر يلتفّ.
  • المضيف المدوَّل (internationalised) يُعرض بكتابته هو حين يكون ذلك آمنًا فقط: كل جزء منه بكتابة واحدة، أو بالكتابات التي تُكتب بها اليابانية أو الكورية أو الصينية معًا. أما الاسم اللاتيني الذي فيه حرف واحد مستعار، والكلمة السيريلية أو اليونانية تحت نهاية بأحرف ASCII، فتبقى في الصيغة xn--.
  • المضيف يُقرأ للتقنيات المساعدة جزءًا من وصف البطاقة.

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

الأجزاء الناقصة

عنوان فقط، ومسار من عندك

المعطى المرسوم
لا صورة، أو صورة يخفق تحميلها البطاقة نفسها بلا صندوق الصورة. ولا شيء يقف في مكانه.
لا وصف العنوان وسطر الموقع.
عنوان فقط العنوان، والمضيف من عنوان الوجهة.
عنوان وجهة فقط عنوان الوجهة في مكان العنوان. أعطِ عنوانًا: بنية التنقيح تبلّغ عن غيابه.
مسار من عندك (/guides/) لا مضيف، فلا سطر للموقع. عنوان وجملة.
لا وجهة، أو سكربت ليست رابطًا ولا تُرسم بطاقة. العنوان نصًّا عاديًّا.

التخطيط

  • البطاقة كتلة. تأخذ العرض الذي تعطيها إياه حاويتها، وارتفاعها ارتفاع ما تحمله. ولا تأتي بفراغ من عندها حولها.
  • من العرض 480 فصاعدًا تقف الصورة بجانب النص، عند حافة النهاية. وفي الأضيق تقف فوق النص. والبطاقة تقرر من عرضها هي، لا من عرض النافذة، والحد يكبر مع مقاس النص.
  • العنصر حاوية قياس (size container)، فيحتاج إلى عرض من تخطيطه. في صف flex أو خلية grid أعطِه عرضًا.
  • في النص الطويل هي كتلة كالشكل التوضيحي. ولا تقع أبدًا داخل جملة.

تبويب جديد، وموقع آخر

  • القيمة target="new" ترسم open_in_new في نهاية سطر الموقع. أعطِ target-label («يُفتح في تبويب جديد»)؛ فالعلامة وحدها لا تُقرأ.
  • الوجهة التي في موقع آخر وتُفتح حيث الشخص ترسم arrow_outward. وهل هي خارجية أمر تحكمه قاعدة الرابط: القيمة external="auto" تقارن عنوان الوجهة بأصل (origin) الصفحة وبما تعطيه setSiteOrigins(). والكلمات هي external-label، أو التي تعيّنها مرة واحدة بالدالة setExternalLabel().
  • لا علامتان أبدًا. التبويب الجديد يغلب.

لا يتضمن Tanrei أي كلمة. أعطِها بلغة منتجك.

الحصول على القيم

البطاقة ترسم ما تُعطاه. اقرأ الوجهة حيث يُبنى موقعك، لا والصفحة تُقرأ.

الوحدة @tanrei/web/links/node وحدة Node لهذا الغرض. الدالة resolveLinkData() تقرأ الصفحة مرة واحدة، على الجهاز الذي يبني الموقع، وتعيد القيم بالصورة التي تأخذها البطاقة.

import { linkCardToHtml, resolveLinkData } from '@tanrei/web/links/node';

const result = await resolveLinkData(href, { site: ['docs.example.com'], lock: 'link-data.lock.json', pictureDirectory: 'public/link-pictures' });
const html = result.ok ? linkCardToHtml(result.data) : `<a href="${href}">${href}</a>`;
  • ما قُرئ يُحفظ في link-data.lock.json، وهو ملف تودعه في المستودع. والبناء يقرأ ذلك الملف ولا يقرأ الشبكة أبدًا. والأمر tanrei-links update يحدّثه، والتغيير فرق (diff) يراجعه شخص.
  • الصور تُخزَّن بين ملفات موقعك أنت، بعد أن تعيد خطوة الصور عندك ترميزها من جديد. فلا يطلب متصفح القارئ عندئذ إلا من الموقع الذي هو فيه أصلًا.
  • الدالة المساعدة لا تقرأ إلا عناوين https العامة، وتفحص كل إعادة توجيه، وتحدّ الوقت والحجم، وتأخذ كل حقل نصًّا.
  • عنوان الوجهة الذي تخفق قراءته لا يعطي بطاقة. ارسم رابطًا عاديًّا.

ملف README الخاص بالحزمة فيه ذلك كله تحت «Reading a destination where the site is built».

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

افعل

  • أعطِ عنوان الوجهة الحقيقي. لا تضع مضيفًا ولا عنوان وجهة في العنوان أبدًا.
  • أبقِ الصور بين ملفاتك أنت. الصورة المحمَّلة من موقع آخر تخبر ذلك الموقع بمن يقرأ.
  • استخدم outlined في النص المتصل. واستخدم filled حيث تكثر الخطوط في الصفحة أصلًا.

لا تفعل

  • لا تضع زرًّا ولا رابطًا ثانيًا داخل بطاقة رابط. يُجعل خاملًا (inert) ويُبلَّغ عنه.
  • لا تضع في بطاقة رابط نصًّا لا بد للقارئ منه. نصها معاينة وقد يُقصّ.
  • لا تعطِ image-alt إلا إذا كانت الصورة تقول شيئًا لا يقوله العنوان.

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

الدور
link
التسمية
The card is one link. Its name is the title (the address where there is none), and nothing is added to the name. Its description is, in order, the description, the picture's alternative text where the product gives one, the site's name, the host and last — while target is new — targetLabel, or — while the destination is external and target is same — externalLabel or the product's words for every external link. The picture, the site icon, the dot and the marks are decorative. A title that is cut on the screen is exposed whole.
الحد الأدنى للهدف
تستوفي مساحة اللمس الحد الأدنى لحجم الهدف حتى لو كان الحجم المرئي أصغر. minimum 32px · pointer 44px · spacing 8px · touch 48px

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

المفاتيح الإجراء
Tab Moves focus to the card: one stop, whatever it shows.
Enter Follows the link. Space does what it does on any link (on the web it scrolls the page).

ملاحظات

  • A link card is told as a link by being one bounded block that answers the pointer and the keyboard as a whole, not by an underline or a color: it is not a phrase inside a sentence, where WCAG 1.4.1 asks for more than color. In forced colors the title takes the platform's link color and both looks have an edge (LKC-30).
  • The host is for everyone. A reader who cannot see the site line hears the host in the description, computed from the address exactly as the drawn one is (LKC-8, LKC-25); a destination cannot hide where it leads from either.
  • Text that is cut (LKC-4, LKC-6) is a preview of a page, not content of this one: all of it reaches assistive technology, and the whole of it is one press away. Do not put text a reader must have into a link card.
  • The picture is decoration by default, because the title already names the destination; give imageAlt only where the picture says something the text does not. A picture that fails or has not arrived exposes nothing.
  • Nothing inside a link card is a control. A preview with its own buttons (save, share, dismiss) is a Card that holds a Link and those buttons, not a link card.
  • The card keeps its focus ring clear of the picture: the ring is drawn outside the container, so a picture of any color cannot hide it.
  • Text must remain readable at 200% text size: the card has no fixed height, counts lines rather than points, and moves its picture above the text when the text needs the room (LKC-29).
  • Contrast in the default system: the title is the surface's text color and the description and the site line the secondary text color, on fills of the surface ladder — pairs the token invariants hold at 4.5:1 (7:1 in the high-contrast schemes). The outlined look's edge is decorative: the card is found by its text.
  • No visited state (LKC-26).
  • How a state looks is a value decision of the active design system (a state-layer mix in Tanrei, a dim or no hover at all elsewhere). The link card reads the state's tokens and never computes the effect itself.
  • Web: the card is the product's own anchor in the document, wrapped by an element with no shadow root, so it is a link before any script runs and for whatever reads the page as built. Once defined, the element names the anchor by the title's element and describes it by the others (aria-labelledby, aria-describedby with ids it writes); before that the anchor is named by all of its text in reading order, which says the same things in one breath.

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

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

  • البطاقة رابط واحد وموضع توقف واحد للوحة المفاتيح. المفتاح Enter يتبعه. والمفتاح Space يمرّر الصفحة، كما في أي رابط.
  • اسمها هو العنوان، أو عنوان الوجهة حيث لا عنوان. ولا يُضاف إلى الاسم شيء.
  • وصفها هو، بالترتيب: الوصف، ثم النص البديل للصورة، ثم اسم الموقع، ثم المضيف، وأخيرًا كلمات التبويب الجديد أو كلمات الموقع الآخر.
  • العنوان أو الوصف الذي يُقصّ على الشاشة يُعرض كاملًا للتقنيات المساعدة.
  • الصورة وأيقونة الموقع والنقطة والعلامات زخرفة ولا تُقرأ.
  • حلقة التركيز تُرسم خارج البطاقة، فلا تستطيع صورة أن تخفيها.
  • عند تكبير النص إلى 200% في حيّز عرضه 320 تنتقل الصورة إلى فوق النص، ويبقى المضيف كاملًا، ولا شيء يُمرَّر جانبيًّا.
  • في الألوان المفروضة (forced colors) يكون للمظهرين حدّ، ويأخذ العنوان لون الرابط في النظام.
  • في تخطيط من اليمين إلى اليسار تقف الصورة عند اليسار ويبدأ النص من اليمين. والعنوان المكتوب من اليسار إلى اليمين يحتفظ بترتيبه. والمضيف من اليسار إلى اليمين دائمًا.
  • النص الذي تعطيه يُرسم نصًّا عاديًّا. والمحارف التي تعكس ترتيب النص تُسقَط.

ما عليك فعله

  • أعطِ target-label كلما كانت target بالقيمة new، وأعطِ كلمات الروابط الخارجية.
  • أعطِ عنوانًا. عنوان الوجهة اسم ضعيف.
  • أعطِ البطاقة عرضًا من تخطيطها.