Elemento de archivo
Muestra un archivo —un glifo que dice su formato o una imagen pequeña del archivo, su nombre y lo que el producto dice de él— con las acciones para quitarlo y para volver a intentarlo, como fila de una columna de archivos o como mosaico de una tira de imágenes. Se puede pulsar para abrir el archivo. Nunca lee, conserva ni envía el archivo por sí mismo.
- Categoría
- Comunicación
- Tokens
comp.file-item- Nivel
- Base
- Se usa en
- Chat composer, File upload
- Web
tanrei-file-itemschedule - SwiftUI
TanreiFileItemradio_button_unchecked - Jetpack Compose
TanreiFileItemradio_button_unchecked - Flutter
TanreiFileItemradio_button_unchecked - React Native
FileItemradio_button_unchecked
Generado a partir de docs/status/status.json, specs/file-item.spec.json
Un archivo como fila y archivos como mosaicos
Un elemento de archivo es un archivo, mostrado. Antes de su nombre hay un glifo que dice el formato del archivo, o una imagen pequeña del archivo. Debajo del nombre hay una línea con lo que tu producto dice de él: su formato, su tamaño, en qué punto está su envío o qué ha fallado. Al final están las dos acciones que tiene un archivo: quitarlo y volver a intentarlo.
Tiene dos formas:
row, la predeterminada: una línea que ocupa la anchura que le da su lugar. Para una columna de archivos.tile: un recuadro con la anchura y la altura que tú das, con el nombre debajo. Para una tira de imágenes.
Muestra, y no hace nada más
Un elemento de archivo no lee un solo byte de un archivo, no conserva ningún archivo y no envía nada. Tampoco quita nada: su acción de quitar te dice que la persona lo pidió, y eres tú quien retira el elemento. Lo que muestra es lo que dicen sus propiedades.
Se usa en el control de subida de archivos, donde cada archivo elegido es un elemento de archivo. Úsalo por separado allí donde tu producto muestre archivos que ya tiene: los adjuntos de un mensaje, los documentos de un expediente, los archivos de una solicitud que ya se envió.
Usa otra cosa cuando:
- Las personas eligen archivos y tú los enumeras. Eso es un control de subida de archivos, que contiene los elementos de archivo por ti.
- Las personas ponen los archivos en un orden. Eso es una lista reordenable cuyos elementos contienen los elementos de archivo; consulta Archivos en un orden que las personas cambian.
- Las personas seleccionan entre archivos. Eso es una lista con selección. Un elemento de archivo no tiene estado seleccionado.
- La imagen es el contenido, lo que se va a mirar. La imagen de un elemento de archivo ocupa el lugar de un glifo y no tiene texto alternativo.
En la web es <tanrei-file-item>. Las demás plataformas todavía no lo han implementado.
Da name y los textos que tengas. value es lo que click, remove y retry te devuelven.
<ul class="attachments" aria-label="Archivos adjuntos">
<li>
<tanrei-file-item value="a" name="brief.pdf" format-text="PDF" size-text="820 KB"
href="/files/brief.pdf" remove-label="Quitar {name}"></tanrei-file-item>
</li>
<li>
<tanrei-file-item value="b" name="floor-plan.png" size-text="3,4 MB"
status="uploading" status-text="Subiendo" progress="0.4"
remove-label="Quitar {name}" retry-label="Reintentar {name}"></tanrei-file-item>
</li>
</ul>
<script type="module">
import '@tanrei/web/components/file-item';
const list = document.querySelector('.attachments');
// Un elemento de archivo nunca se quita a sí mismo. Lo retiras tú, dejas de enviar el archivo y mueves el foco.
list.addEventListener('remove', (event) => {
cancel(event.detail.value);
event.target.closest('li').remove();
});
list.addEventListener('retry', (event) => send(event.detail.value));
</script>import { FileItem } from '@tanrei/react';
<ul aria-label="Archivos adjuntos">
{files.map((file) => (
<li key={file.id}>
<FileItem value={file.id} name={file.name} sizeText={file.sizeText}
status={file.status} statusText={file.statusText} progress={file.progress}
errorText={file.errorText} retryable={file.retryable}
removeLabel="Quitar {name}" retryLabel="Reintentar {name}"
onRemove={() => remove(file.id)} onRetry={() => retry(file.id)} />
</li>
))}
</ul>removeLabel y retryLabel se pueden dar una sola vez para todo el producto con setWords(). Todos los demás textos son de la instancia.
Una fila en cada estado: en espera, enviada al 40%, en curso, completada, fallida y reintentable, fallida definitivamente
Anatomía
Anatomía
row, tal como lo dibuja el paquete web.| Parte | Descripción |
|---|---|
1 container | The body: the glyph or the picture, and the texts. One part, and the one that is pressed where the file item is pressable. The actions stand beside it, never inside it. |
2 media | The box of the glyph or the picture: the leading box of a row, the whole box of a tile. |
3 icon · opcional | The glyph of the file's format, by its name in the system's icon set; or the product's own glyph. Hidden from assistive technology. |
4 preview · opcional | The picture of an image file, in the glyph's place. |
5 headline · opcional | The file's name. |
6 supporting-text · opcional | The second line: the format, the size and the status in words, or the error text in the status's place. |
7 status-icon · opcional | The mark before the words of a file that is done or failed. |
8 progress · opcional | A thin bar while the file is being sent: how far it has come, or that it is under way. |
9 action · opcional | The actions: retry (while it failed and can be tried again) and remove. Icon-only, each with its own state layer and focus ring. |
10 focus-ring | The system's focus indicator around the body or an action that has keyboard focus. |
Propiedades
| Propiedad | Tipo | Valor predeterminado | Descripción |
|---|---|---|---|
form | row | tile | "row" | How the file is shown. row: one line across the width the layout gives — the glyph or a small picture, the name, the second line, the bar, the actions at the end — for a column of files. tile: a box of a width and a height, holding the picture or the glyph, with the texts beneath it and the actions at its corner — for a strip of attached pictures. The product chooses by where the file stands. A design system may add values. |
value | string | "" | What identifies the file to the product: given back by click, remove and retry. |
name | string | "" | The file's name as the person knows it ("report-2026.pdf"). The file item's name for assistive technology in every form, also where it is not drawn. |
mediaType | string | "" | The file's kind as the platform reports it ("image/png"), from which the glyph is chosen. Empty, the kind is read from the end of name. |
glyph | string | "" | The name of a glyph of the system's icon set, drawn in place of the one the file's format would choose. Empty lets the format choose. |
formatText | string | "" | The file's format in the product's words ("PDF", "Spreadsheet"), drawn first on the second line. Empty draws none: the file item has no word for a format. |
sizeText | string | "" | The file's size as text, formatted by the product for the reader's locale ("1.2 MB"). Empty draws none. |
status | pending | uploading | done | error | "pending" | Where the file stands. pending: chosen or kept, and nothing is happening to it — the whole life of a file in a form that is submitted as one, and of a file that is only shown. uploading: the product is sending it; the bar is drawn. done: the product has it. error: it failed or was refused; errorText says why. |
statusText | string | "" | The status in the product's words ("Waiting", "Uploading", "Uploaded"), drawn last on the second line and read with the file. The mark and its color are never the only sign of a status. |
progress | number | null | How far the sending has come, from 0 to 1, while status is uploading. Null draws the bar as under way without saying how far. Ignored in every other status. |
errorText | string | "" | Why the file failed and what to do, in the product's words ("Larger than 10 MB", "The connection was lost"). Drawn in the status's place while status is error, in every form, and never cut. |
retryable | boolean | false | Whether a failed file offers the retry action. True for a failure that trying again may cure (a lost connection); false for one it cannot (a file that is too large). |
preview | boolean | false | Whether a picture of the file is drawn in the glyph's place, where the file is an image and the product gave an address (previewSrc) or the file itself in the platform's idiom. False draws the glyph, also for an image. The picture is drawn by the platform; the file item reads no file. |
previewSrc | string | "" | The address of a picture of the file, as the platform's images take one: a small rendition the product's server made of a file it already has. With preview it is drawn for a file of any format. Empty, the picture comes from the file itself where the product gave it. |
fit | cover | contain | "cover" | How the picture fills its box. cover: it fills the box and what does not fit is cut at the edges, for photographs in a strip. contain: the whole picture is drawn inside the box, on the box's ground, for a picture whose edges matter — a scan, a signature, a diagram. |
nameHidden | boolean | false | In the tile form: the name is not drawn beneath a tile that draws a picture, for a dense strip of pictures. The name stays the file item's name for assistive technology, and is drawn all the same wherever no picture is (FIT-8). Not read in the row form. |
width | number | null | In the tile form: the width of the box, in the platform's layout unit. Null makes it as wide as it is high. |
height | number | null | In the tile form: the height of the box, in the platform's layout unit. Null reads comp.file-item.tile.media.height. |
interactive | boolean | false | Makes the body — the glyph or the picture, and the texts — one pressable action that emits click, for a product that opens the file where it is: an image in an Image preview, a document in a viewer. The actions stay their own. A file item whose action is to go to the file takes href instead and is a link. |
href | string | "" | The destination: the address of the file, as the platform's links take one. Not empty, it makes the body a link — to a file the product already has, to open or to download — whether interactive is set or not. |
target | same | new | "same" | Where the destination opens. same: where the person is. new: a new context — a new tab or window on the web, outside the current screen elsewhere — which a row marks and targetLabel says. Ignored without href. |
targetLabel | string | "" | What assistive technology reads after the link's name while target is new ("opens in a new tab"). The product's words. |
removeLabel | string | "" | The accessible name of the remove action: the whole name in the product's language with one place, {name}, which the file item fills with the file's name ("Remove {name}", "{name}を削除"), so that the actions of two files are told apart by their names and the product still writes one word, not one per file. Empty reads the product's words. |
retryLabel | string | "" | The accessible name of the retry action, with the place {name} filled by the file's name as removeLabel is ("Retry {name}", "{name}を再試行"). Empty reads the product's words. |
disabled | boolean | false | The actions are disabled and the body cannot be pressed. What the file item shows of the file stays as it is and stays readable. |
readOnly | boolean | false | The file is shown and cannot be taken back: no remove action and no retry action is drawn. For a file of a record that is only read. The body can still be pressed where interactive or href says so. |
Slots
| Slot | Descripción |
|---|---|
icon | A glyph of the product's own in place of the format's glyph, where a name in the system's icon set (glyph) is not enough. Decorative. |
Eventos
| Evento | Descripción |
|---|---|
click | The body of a pressable file item was activated by pointer, touch, keyboard or assistive technology. Carries value. A link emits it before its destination opens; a product that takes the navigation itself cancels it. |
remove | The person asked to take this file back, by its remove action. Carries value. The file item removes nothing: whoever holds it removes it — and stops sending the file, if it was — and moves focus. |
retry | The person asked to try a failed file again, by its retry action. Carries value. The product sends the file again and sets status. |
Estados
Comportamiento
Requisitos en formato EARS. Cada implementación de plataforma se prueba contra estos identificadores. El texto de los requisitos se muestra tal como está en la especificación, en inglés.
| ID | Requisito |
|---|---|
FIT-1 | THE file item SHALL show one file in the form that form names: a row (FIT-2) or a tile (FIT-3). In both it SHALL draw the same parts from the same props — the glyph of the file's format or a picture of the file (FIT-5, FIT-6), its name, a second line (FIT-4), a bar while it is sent (FIT-10) and its actions (FIT-11) — so that a form changes where the parts stand and how large they are, never what is known of the file. THE file item SHALL draw no container, fill or edge around the whole, SHALL hold one file and never a list of files, and SHALL NOT sort, group, number or count itself among others: how file items are arranged is the layout's, or the component's that holds them. |
FIT-2 | WHILE form is row THE file item SHALL be as wide as its layout gives it and as tall as its parts, and SHALL lay out from its start edge: the glyph in a box of comp.file-item.row.icon.size — or, WHILE preview is true, a square of comp.file-item.row.media.height with corners of comp.file-item.row.media.shape and the ground comp.file-item.media.color, holding the picture, or the glyph centred where no picture is drawn (FIT-6); comp.file-item.row.container.gap after it the texts, taking the room that is left; and comp.file-item.row.container.gap after them the actions (FIT-11), with the glyph or the square and the actions centred on the row's first two lines. The first line SHALL be name in comp.file-item.headline.typescale and comp.file-item.headline.color, drawn whole: it SHALL wrap, breaking inside a word where it must, and SHALL never be cut with an ellipsis, because the end of a file's name says what kind of file it is and a row has the room. WHILE form is row THE file item SHALL NOT read width, height or nameHidden, and in debug builds SHALL report nameHidden. |
FIT-3 | WHILE form is tile THE file item SHALL draw a box height high — comp.file-item.tile.media.height WHILE height is null — and width wide, as wide as it is high WHILE width is null, with corners of comp.file-item.tile.container.shape and the ground comp.file-item.media.color, holding the picture clipped to those corners (FIT-6) or, where no picture is drawn, the glyph centred at comp.file-item.tile.icon.size; and beneath the box, comp.file-item.tile.container.gap from it and as wide as it, the name on one line (FIT-9) and the second line (FIT-4). The file item SHALL be exactly as wide as the box. It SHALL draw the actions inside the box at its top end corner, comp.file-item.tile.action.inset from the top and from the end edge, the retry action before the remove action (FIT-11), each on a disc of the tile's action container color so that it is read over any picture; and SHALL draw the box no narrower than both actions, the space between them and the inset on each side need, and no lower than one action and the inset above and below it, in debug builds reporting a width or a height that is less. WHERE its layout gives the tile less room than width THE file item SHALL draw the box as wide as that room and as high as keeps the proportion of width to height, and SHALL never be wider than its layout. |
FIT-4 | THE file item SHALL draw below the name one line in comp.file-item.supporting-text.typescale that wraps and is never cut: formatText, sizeText and statusText, each WHILE it is not empty, in that order, with a middle dot and a space on each side between two that are drawn, in comp.file-item.supporting-text.color; and WHILE status is error and errorText is not empty, errorText in statusText's place, in comp.file-item.error.supporting-text.color. WHILE status is done or error THE file item SHALL draw before the words of the status or the error, comp.file-item.status.icon.gap from them, a mark at comp.file-item.status.icon.size by its name in the system's icon set and through the platform's icon helper — the checked-circle glyph in comp.file-item.done.icon.color WHILE status is done, the error glyph in comp.file-item.error.icon.color WHILE status is error — and SHALL keep the mark from assistive technology, which is told the status by the words. WHILE the line would hold nothing THE file item SHALL draw none and keep no room for it. A status SHALL never be told by the mark or its color alone: WHILE status is done or error and the product gives no words for it (statusText, errorText) THE file item SHALL still render, with the mark alone on the line, and in debug builds report it. THE file item SHALL draw the second line in every form and whatever nameHidden says: what went wrong is never hidden. |
FIT-5 | THE file item SHALL choose the glyph from the file's format, in one of ten kinds, by mediaType — read without regard to case, without anything after a semicolon and without the white space around it — and, WHERE mediaType is empty, is application/octet-stream or is on no list below, by the end of name after its last dot, without regard to case, the first kind that matches in this order, each kind by a closed list of media types and a closed list of endings: pdf (application/pdf; pdf); spreadsheet (text/csv, text/tab-separated-values, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.oasis.opendocument.spreadsheet, application/vnd.apple.numbers, application/x-iwork-numbers-sffnumbers; xls, xlsx, ods, numbers, csv, tsv); presentation (application/vnd.ms-powerpoint, application/vnd.openxmlformats-officedocument.presentationml.presentation, application/vnd.oasis.opendocument.presentation, application/vnd.apple.keynote, application/x-iwork-keynote-sffkey; ppt, pptx, odp, key); archive (application/zip, application/x-zip-compressed, application/x-tar, application/gzip, application/x-gzip, application/x-bzip2, application/x-xz, application/x-7z-compressed, application/vnd.rar, application/x-rar-compressed; zip, tar, gz, tgz, bz2, xz, 7z, rar); code (text/html, text/css, text/javascript, application/javascript, application/x-javascript, text/typescript, application/typescript, text/jsx, text/tsx, application/json, application/xml, text/xml, text/yaml, text/x-yaml, application/yaml, application/x-yaml, application/x-sh, text/x-sh, text/x-shellscript, text/x-python, text/x-script.python, text/x-ruby, application/x-ruby, text/x-go, text/x-rust, text/x-java, text/x-java-source, text/x-kotlin, text/x-swift, text/x-c, text/x-chdr, text/x-csrc, text/x-c++, text/x-c++src, text/x-csharp, text/x-php, application/x-php, application/x-httpd-php, application/sql, text/x-sql; html, css, js, mjs, ts, tsx, jsx, json, xml, yaml, yml, sh, py, rb, go, rs, java, kt, swift, c, h, cpp, cs, php, sql); image (every media type that begins with image/; png, jpg, jpeg, gif, webp, avif, svg, bmp, tif, tiff, heic, heif, ico); video (every media type that begins with video/; mp4, mov, m4v, webm, mkv, avi); audio (every media type that begins with audio/; mp3, wav, m4a, aac, ogg, oga, flac, opus); document (every media type that begins with text/ and is on no list above, application/rtf, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.oasis.opendocument.text, application/vnd.apple.pages, application/x-iwork-pages-sffpages; txt, md, rtf, doc, docx, odt, pages); and other for everything else, a name without a dot among them. A media type that is on no list SHALL choose nothing by itself: the ending decides, and then other. video/mp2t SHALL choose nothing by itself either, though it begins with video/: platforms guess it from the ending .ts, which TypeScript files share with MPEG transport streams, so the media type is no surer than the ending and the ending decides. The lists are the whole of the rule on every platform, so that one file draws one glyph wherever it is shown; a platform SHALL add no media type and no ending of its own. It SHALL draw, by its name in the system's icon set and through the platform's icon helper: picture_as_pdf, table, slideshow, folder_zip, code, image, movie, music_note, description and draft, in the order of the kinds. WHILE glyph is not empty THE file item SHALL draw that glyph in the format's place, and WHILE the icon slot holds a glyph SHALL draw the slot's in the place of both. THE file item SHALL draw every such glyph in comp.file-item.icon.color, whatever the format — a format has no color of its own, because a color says one thing wherever it is used and a format is not a status — and SHALL keep it from assistive technology: the name says which file it is, and formatText says its format in words where the product has them. THE file item SHALL NOT open the file to learn its format, and SHALL NOT change the glyph because of status. |
FIT-6 | WHILE preview is true THE file item SHALL draw a picture of the file in the glyph's place: the picture at previewSrc WHILE previewSrc is not empty, whatever the file's format; otherwise, WHILE the file's kind is image (FIT-5) and the product gave the file item the file itself in the platform's idiom, the platform's own drawing of that file (FIT-7). It SHALL fill the box as fit names — cover: scaled to fill the box and centred, what does not fit cut at the box's edges; contain: scaled to stand whole inside the box, centred on the box's ground — never stretched out of its proportion and never drawn larger than the box. Until the picture can be drawn, and IF it cannot be drawn — an address that does not answer, a format the platform does not draw, a file that is not a picture after all — THE file item SHALL draw the glyph of the file's format in its place, SHALL draw no sign of loading and no sign of the failure, SHALL NOT set status and SHALL emit nothing for it, and in debug builds SHALL report a previewSrc that could not be drawn. WHEN the picture can be drawn THE file item SHALL draw it at once in the glyph's place, without a motion and without changing the size of anything. THE file item SHALL keep the picture from assistive technology: it stands where the glyph stood, and the file is named by name. WHILE preview is false, WHILE preview is true and neither an address nor a file was given, and for a file that is not an image and has no previewSrc, THE file item SHALL draw the glyph. THE file item SHALL draw no picture of a video, of a page of a document or of anything else it would have to open and read to draw. |
FIT-7 | THE file item SHALL NOT read a file: it SHALL open no connection for a file, SHALL NOT read a file's bytes into memory of its own, SHALL NOT copy, store, resize or encode a file, and SHALL make of the file the product gave it nothing but what the platform needs to draw the picture of FIT-6. WHERE the platform draws a picture of a file from an address it makes for the file's handle (the web's object URL) THE file item SHALL make that address itself, at most one per file item; SHALL make it only WHILE FIT-6 has it draw the picture from the file — preview is true, previewSrc is empty, the kind is image — and only once the file item is in or near what is in view; SHALL give it to nothing but its own picture; and SHALL release it WHEN the file item is taken out of the page or the screen, WHEN the product gives it another file or none, and WHEN preview becomes false, previewSrc is given or the kind is no longer image. WHERE the platform makes a small picture of a file itself (a thumbnail the system gives for a handle) THE file item SHALL ask for one no larger than its box and SHALL cancel the request on the same occasions. A file item whose preview is false SHALL cost what its texts cost: no address, no picture and no request is made for it, however many there are. |
FIT-8 | WHILE form is tile and nameHidden is true and the box draws a picture THE file item SHALL NOT draw the name beneath the box and SHALL keep no room for it. WHILE the box draws no picture — preview is false, the picture is not drawn yet or cannot be drawn — THE file item SHALL draw the name whatever nameHidden says, because a glyph of a format does not tell two files of that format apart. In every case name SHALL stay the file item's name for assistive technology (FIT-19), and the second line SHALL be drawn (FIT-4). IF name is empty THE file item SHALL still render and in debug builds report that the file has no name. |
FIT-9 | WHILE form is tile THE file item SHALL draw the name on one line in comp.file-item.headline.typescale and comp.file-item.headline.color, no wider than the box. WHERE the name does not fit THE file item SHALL cut it in the middle and never at its end: the ending of the name — from its last dot, WHERE that dot is not the name's first character and is among its last eight — SHALL stay drawn, the start of the name SHALL be drawn as far as the room that is left allows, and an ellipsis SHALL stand between the two, so that two pictures from one camera are still told from a document of the same name; a name with no such ending SHALL be cut at its end, with an ellipsis. The ellipsis is a mark of the platform's text layout and not a word. The whole name SHALL reach assistive technology, and the cut SHALL be made in the drawing alone: THE file item SHALL NOT change name. The second line of a tile SHALL wrap inside the box's width and SHALL never be cut (FIT-4). |
FIT-10 | WHILE status is uploading THE file item SHALL draw a bar comp.file-item.progress.thickness high: a track in comp.file-item.progress.track.color and over it, from the track's start, an indicator in comp.file-item.progress.indicator.color across the fraction progress gives, clamped to 0 and 1, moving to a new value over comp.file-item.motion.progress-duration with comp.file-item.motion.progress-easing. WHILE form is row the bar SHALL stand comp.file-item.progress.gap below the texts and as wide as them, with ends rounded by comp.file-item.progress.shape; WHILE form is tile it SHALL lie along the bottom edge of the box, inside it and as wide as it, clipped by the box's corners, over the picture or the ground. WHILE progress is null THE file item SHALL draw the bar as a linear progress indicator draws its indeterminate form (PRG-2), once per comp.file-item.motion.cycle-duration with comp.file-item.motion.cycle-easing, and SHALL NOT run it while the file item is not visible. WHERE reduced motion is requested THE file item SHALL show a new value at once and draw the indeterminate bar as PRG-7 says. In every other status THE file item SHALL draw no bar and, in a row, keep no room for one. THE file item SHALL never move the bar by itself: progress is the product's report of its own sending. |
FIT-11 | WHILE readOnly is false THE file item SHALL draw a remove action, and before it, comp.file-item.action.gap from it, a retry action WHILE status is error and retryable is true: each an icon-only button, a square of comp.file-item.action.size with corners of comp.file-item.action.shape, filled with the action container color of its form, holding the icon set's close glyph (remove) or refresh glyph (retry) at comp.file-item.action.icon.size in the action icon color of its form — at the end of a row (FIT-2), at the top end corner of a tile (FIT-3). WHEN the person activates one by pointer, touch, Enter or Space THE file item SHALL emit remove or retry exactly once with value and do nothing else: it SHALL NOT take itself away, change its status or move focus because of the activation. The actions SHALL NOT be inside the body (FIT-12) and SHALL NOT activate it. Each SHALL be a stop in the focus order after the body, retry before remove; THE file item SHALL handle no arrow key, Delete or Backspace, SHALL hold no selected state and draw no handle, and SHALL NOT be moved by dragging: an order that people change is the List's, in whose rows a file item is content. |
FIT-12 | WHILE interactive is true and href is empty THE file item SHALL make its body — the glyph or the picture, and the texts — exactly one focusable element with the button role, before the actions in the focus order, and WHEN the person activates it by pointer, touch, Enter or Space SHALL emit click exactly once with value. It SHALL open nothing itself: the product opens the file where it means to. WHILE interactive is false and href is empty THE file item's body SHALL NOT be focusable, SHALL NOT emit click, and SHALL draw no hover, focus or press answer. In a tile the body is the box and the texts beneath it; a press on an action's visible bounds SHALL go to that action and never to the body under it (FIT-18). |
FIT-13 | WHILE href is not empty THE file item SHALL make its body a link, whether interactive is true or false, as every control with a destination is: the platform's own link to href, with the link role and not the button role; activated by pointer, touch or Enter and not by Space; emitting click exactly once with value and then opening href where target names, unless the product cancelled that click, and never holding the navigation back for sys.motion.duration.press-hold; drawn from the same tokens in every state as a pressable body. WHILE target is new THE file item SHALL open href in a new context, SHALL expose targetLabel as the link's description after its name and role — in debug builds reporting an empty one — and WHILE form is row SHALL draw, comp.file-item.row.container.gap after the texts and before the actions, the glyph open_in_new of the system's icon set through the icon helper at comp.file-item.action.icon.size in comp.file-item.icon.color, hidden from assistive technology; a tile has no such place and draws none. WHILE disabled is true THE file item's link SHALL NOT be followed by any means the platform gives a link, SHALL keep the link role with the disabled state and no destination, and SHALL NOT be focusable. IF href is only white space, names a script to run, or cannot be read as an address THE file item SHALL be what interactive makes it, without a destination, and in the last two cases report it in debug builds. THE file item SHALL load nothing from href and SHALL NOT learn the file's name, size or format from it. |
FIT-14 | WHILE the body of a pressable file item is hovered, keyboard-focused or pressed THE file item SHALL render the body's container color from the component tokens of its form in the highest-precedence active state, with precedence pressed over focused over hovered, as a layer over the glyph or the picture and the texts — in a row over the body's bounds grown by comp.file-item.row.container.outset on every side, with corners of comp.file-item.row.container.shape, taking no room; in a tile over the box, with the box's corners. WHILE an action is hovered, keyboard-focused or pressed THE file item SHALL render that action's container, glyph and opacity from the action parts of the same tokens, with the same precedence. Focus gained by pointer or touch SHALL NOT select the focused state. The name, the second line, the glyph, the picture, the bar and the part that is not under the pointer, the press or the focus SHALL NOT change. WHEN the body or an action receives keyboard focus THE file item SHALL show the focus ring around it without animation — the system's focus indicator, sys.focus.offset from the part 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. |
FIT-15 | WHEN the body of a pressable file item or one of its actions is pressed by pointer, touch, Enter or Space THE file item 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. A body that is a link is not pressed by Space (FIT-13). |
FIT-16 | WHILE the body of a pressable file item or one of its actions is pressed THE file item 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 part 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; glyph, 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.file-item.motion.feedback-duration with comp.file-item.motion.state-easing, fades over comp.file-item.motion.state-duration with comp.file-item.motion.state-easing once the press has ended and press-hold has passed, and appears whole where motion is reduced. |
FIT-17 | THE file item SHALL ease the corners of a tile's box, of a row's picture, of the body's state layer and of its actions 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 the keyboard focus of its body and of an action 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. |
FIT-18 | WHERE the visual size of an action, or of the body of a pressable file item, is below the minimum target THE file item 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. WHILE the extended hit areas of two parts overlap — the retry and the remove action, an action and the body, or the actions of two file items — THE file item SHALL give a press on a part's visible bounds to that part, a press on an action's visible bounds to the action even where it lies over the body, and a press between two actions to the nearer one. THE file item SHALL set two actions that stand side by side — the retry and the remove action — apart by comp.file-item.action.gap, or by twice the amount by which the minimum target in force exceeds comp.file-item.action.size where that is more, so that the hit area of each reaches the minimum target on its own half of the space between them; it SHALL NOT shrink the hit area of either below the minimum target to keep them nearer, and the hit area of the action at the item's end SHALL still reach no further than the item's end edge. |
FIT-19 | THE file item SHALL expose itself to assistive technology as a group named by name, in every form and whatever nameHidden says, read in this order: name; formatText, sizeText, then statusText or — WHILE status is error — errorText; then, WHILE status is uploading, the bar as a progress bar named by name whose value is progress as a share of 0 to 1, or busy WHILE progress is null; then the retry action WHERE it is drawn, as a button named retryLabel, and the remove action WHERE it is drawn, as a button named removeLabel, each with its place {name} filled by name, so that "Remove brief.pdf" is the action's name and two files' actions are told apart wherever names are listed; neither action SHALL carry the name a second time as a description. WHILE the body is pressable it SHALL be a button, or a link (FIT-13), named by name and described by the second line's texts. WHILE a component holds the file item as one of the items of a list of its own THE file item SHALL be exposed as an item of that list in the group's place, by the word of that component and through no prop of its own. The glyph, the picture, the status mark and the mark of a new context SHALL be kept from assistive technology. THE file item SHALL have no live region and SHALL announce nothing — not that it appeared, not a change of status or of progress: what is said of many files is said once, by whoever holds them. |
FIT-20 | THE file item SHALL have no words of its own: it SHALL take removeLabel and retryLabel from the instance's prop and, WHILE that is empty, from the product's words of the keys removeLabel and retryLabel, and name, formatText, sizeText, statusText, errorText and targetLabel from the product alone, and from nowhere else. IF neither gives removeLabel or retryLabel THE file item SHALL still draw the action, expose it without a name, and in debug builds report the missing word once per page or screen, naming the prop. IF the word given has no place {name} THE file item SHALL name the action with it as it is written and in debug builds report that every file's action has the same name; another text between braces, and a brace that opens or closes nothing, SHALL be kept as written and reported. THE file item SHALL build no word from mediaType, from the end of name or from a number: it SHALL NOT write a format, a size or a share of progress in words. |
FIT-21 | WHILE disabled is true THE file item SHALL render each action from the disabled tokens of its form and disable it, so that it leaves the focus order — an action keeps the container it has at rest, none in a row and the disc in a tile, and only its glyph fades, as a quiet icon-only button grows no fill when it is disabled; SHALL make the body not pressable and not focusable, drawing no hover, focus or press answer on it; and SHALL emit neither click, remove nor retry. The name, the second line, the glyph, the picture, the status mark and the bar SHALL stay drawn as they are and readable by assistive technology: what was chosen is still what was chosen. |
FIT-22 | WHILE readOnly is true THE file item SHALL draw neither the remove action nor the retry action, SHALL keep no room for them — a row's texts reach its end edge — and SHALL emit neither remove nor retry. Everything else SHALL hold as without it: the status, the bar and the error are drawn, and the body is pressable WHERE interactive or href makes it so. |
FIT-23 | WHEN the colors of the body or of an action change between states THE file item SHALL animate the change over comp.file-item.motion.state-duration with comp.file-item.motion.state-easing, and SHALL change them at once where motion is reduced. A change of form, of status, of a text, of the glyph or of the picture SHALL be drawn at once, without a motion of the file item's own. THE file item SHALL NOT run a picture that moves: WHERE the platform can hold a moving picture still it SHALL draw its first frame, and where it cannot (the web's image element) it SHALL leave the picture to the platform and state that in its README. |
FIT-24 | WHILE the text size is enlarged THE file item SHALL grow with its texts: a row's lines wrap and are never cut, its glyph keeps its box, its picture comp.file-item.row.media.height and its actions comp.file-item.action.size; a tile's box keeps the size the product or the token gives, its name stays one line and grows in height, and its second line wraps beneath it. WHERE what stands beside a row's texts — its glyph or picture, the mark of a new context, its actions and the gaps between them — would leave the texts less than half the width of the row (a narrow screen, enlarged text) THE file item SHALL place the actions on a line of their own below the texts and the bar, at the row's end and in the same order, the line as tall as the minimum target in force, so that the name and the second line take the whole width after the glyph; otherwise a row's actions SHALL stay at its end beside its first lines. The answer SHALL be the same wherever the actions stand now, so that placing them does not change it. At 200 % in a width of 320 no text SHALL be lost or lie over another part, a tile SHALL be no wider than its layout (FIT-3), and nothing SHALL need scrolling in two directions. |
FIT-25 | 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 file item SHALL draw its texts and glyphs in the platform's text color, a link's name in the platform's link color; SHALL draw the bar with its indicator in the platform's highlight color on a track edged in the text color; SHALL draw a tile's box and a row's picture box with an edge in the text color, since their ground is gone; SHALL draw each action of a tile on the platform's surface color with an edge in the text color; SHALL draw disabled actions in the platform's disabled text color; SHALL leave a picture as it is; and SHALL rely on no color of its own to tell a failed file from another: its words and its mark's shape do. |
FIT-26 | WHERE the layout direction is right-to-left THE file item SHALL mirror its layout: a row's glyph or picture at the right, its texts after it toward the left, the mark of a new context and the actions at the left with remove outermost; a tile's actions at the top left corner of its box with remove outermost; the status mark at the right of its words; and the bar filling — and its indeterminate segment moving — from right to left. A picture SHALL never be mirrored, and a ripple SHALL still grow from the point of contact. |
FIT-27 | THE file item 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 file item is shown THE file item SHALL draw itself for the new direction at once, without a motion of its own, keeping its focus. |
FIT-28 | THE file item SHALL lay out each text it draws — the name, the format, the size, the status and the error — as text of its own direction, isolated from the text around it: each takes the base direction of its first strong character, or the layout direction where it has none, so that a file name in Latin letters keeps its order, its dot and its extension in a right-to-left row, and the cut of FIT-9 keeps the name's own ending wherever that is drawn. WHERE the layout direction is right-to-left a glyph SHALL be mirrored exactly when the system's icon set marks its name as mirrored or the product forces it, by the icon helper and inside its own box; THE file item SHALL mirror no glyph itself. |
FIT-29 | WHEN form, status, fit or target names a value the file item does not know THE file item SHALL behave as row, pending, cover and same; IF width or height is given and is not a number above zero THE file item SHALL behave as if it were null; IF glyph names a glyph the icon set does not have THE file item SHALL draw nothing in its box and keep the box; and in each case debug builds SHALL report it. IF preview is true WHILE previewSrc is empty and the product gave no file THE file item SHALL draw the glyph and report nothing: a product may give the file later. |
FIT-30 | WHEN a prop changes while the file item is shown THE file item SHALL draw and expose the new value at once, keeping its focus, and SHALL announce nothing (FIT-19). WHEN the retry action leaves — status is no longer error, retryable or readOnly changed — while focus is on it THE file item SHALL move focus to its remove action, or to its body WHERE that is pressable and no remove action is drawn. THE file item SHALL NOT move focus otherwise, and where focus goes when a file item itself is taken away is its holder's to say. |
FIT-31 | WHILE the system's icon set cannot yet draw a glyph (its font is still loading) THE file item SHALL draw nothing in that glyph's place, never the glyph's name as text, SHALL keep the glyph's box, and SHALL draw the glyph once the set can; removeLabel and retryLabel SHALL still reach assistive technology. |
FIT-32 | IF the file item holds a child that is not the glyph of its icon slot THE file item SHALL NOT draw it and in debug builds report it: the file item has no place for content of the product's — a menu of further actions, a caption, a checkbox — and a product that needs one puts it beside the file item, in its own layout or in the trailing place of a List's row. A platform that cannot inspect its content SHALL state the rule in its README and docs page. |
FIT-33 | THE file item SHALL NOT upload and SHALL NOT know more of a file than its props say: it SHALL send no file or part of one to anyone, SHALL keep no file beyond the handle the product gave it for FIT-6, SHALL set neither status nor progress itself, SHALL take name and mediaType, WHERE the product left them empty and gave the file itself, from what the platform reports of that file without opening it, and nothing else from it, and SHALL load nothing about a destination. This holds on every platform. |
Correspondencia de nombres por plataforma
Paridad no significa API idénticas. Cada plataforma expresa el mismo contrato con su propio estilo.
| Especificación | Web | SwiftUI | Jetpack Compose | Flutter | React Native |
|---|---|---|---|---|---|
| Componente | tanrei-file-item | TanreiFileItem | TanreiFileItem | TanreiFileItem | FileItem |
form · Propiedad | form | form | form | form | form |
value · Propiedad | value | id | key | key | value |
name · Propiedad | name | name | name | name | name |
mediaType · Propiedad | mediaType | mediaType | mediaType | mediaType | mediaType |
glyph · Propiedad | glyph | glyph | glyph | glyph | glyph |
formatText · Propiedad | formatText | formatText | formatText | formatText | formatText |
sizeText · Propiedad | sizeText | sizeText | sizeText | sizeText | sizeText |
status · Propiedad | status | status | status | status | status |
statusText · Propiedad | statusText | statusText | statusText | statusText | statusText |
progress · Propiedad | progress | progress | progress | progress | progress |
errorText · Propiedad | errorText | errorText | errorText | errorText | errorText |
retryable · Propiedad | retryable | isRetryable | retryable | retryable | retryable |
preview · Propiedad | preview | showsPreview | showPreview | showPreview | preview |
previewSrc · Propiedad | previewSrc | previewURL | previewModel | previewImage | previewSource |
fit · Propiedad | fit | contentMode | contentScale | fit | resizeMode |
nameHidden · Propiedad | nameHidden | isNameHidden | nameHidden | nameHidden | nameHidden |
width · Propiedad | width | width | width | width | width |
height · Propiedad | height | height | height | height | height |
interactive · Propiedad | interactive | action | onClick | onPressed | onPress |
href · Propiedad | href | destination | href | href | href |
target · Propiedad | target | opens | target | target | target |
targetLabel · Propiedad | targetLabel | targetLabel | targetLabel | targetLabel | targetLabel |
removeLabel · Propiedad | removeLabel | removeLabel | removeContentDescription | removeSemanticLabel | removeAccessibilityLabel |
retryLabel · Propiedad | retryLabel | retryLabel | retryContentDescription | retrySemanticLabel | retryAccessibilityLabel |
disabled · Propiedad | disabled | disabled | enabled | enabled | disabled |
readOnly · Propiedad | readOnly | isReadOnly | readOnly | readOnly | readOnly |
click · Evento | click | action | onClick | onPressed | onPress |
remove · Evento | remove | onRemove | onRemove | onRemove | onRemove |
retry · Evento | retry | onRetry | onRetry | onRetry | onRetry |
| Notas | The shadow-root form: a part with states and actions of its own. Class TanreiFileItem; React FileItem. <tanrei-file-item name="brief.pdf" size-text="820 KB" remove-label="Remove"></tanrei-file-item>; a tile: <tanrei-file-item form="tile" preview width="160" height="90" name="floor-plan.png"></tanrei-file-item>. Attributes media-type, format-text, size-text, status-text, error-text, preview-src, name-hidden, target-label, remove-label, retry-label, readonly; progress absent for null; width and height are numbers of CSS pixels, as an image's, and are the box of the tile alone. **The file**: the property file (a File or null, never an attribute) is the platform's handle. With preview and an image kind and no preview-src, the element creates one object URL for it when it first comes near the viewport (an IntersectionObserver), gives it to its own <img part="preview" alt="" decoding="async"> and to nothing else, and revokes it in disconnectedCallback, when file is set again and when preview, preview-src or the kind stops asking for it (FIT-7); reconnected, it makes a new one when it is next in view. name and media-type left empty are read from file.name and file.type (FIT-33). file is also what a File upload submits for the item (FUP-31). **The body** is <div part="container">, or <button part="container"> with interactive, or <a part="container" href> with href (the shared link primitive; web-only rel and download are forwarded to the anchor, and download is how a link saves the file in place of opening it); the two actions are native buttons beside it in the shadow root, with aria-label — the product's sentence with the file's name filled in — never inside it. In a tile the actions are placed over the box and come after the body in the DOM, so the order of focus is the order read. click, remove and retry are CustomEvents that bubble and are composed, with detail.value; click is cancelable for a link. The host has role="group" and aria-label from name; a File upload that holds it sets role="listitem" on it through an internal channel that is not part of its public surface (FIT-19). The cut of a tile's name (FIT-9) is two spans — the start, which shrinks with an ellipsis, and the ending, which does not — inside one <bdi>. Parts: container, media, icon, preview, headline, supporting-text, status-icon, progress, action. The bar is <tanrei-progress-indicator> (the small linear one), drawn from this component's own bar tokens. No form participation: a file item submits nothing; what holds it does. | TanreiFileItem(name: "brief.pdf", sizeText: "820 KB", onRemove: { }); a tile: TanreiFileItem(name:, form: .tile, width: 160, height: 90, showsPreview: true, file: url). interactive is whether action is given (a nil action is not pressable); destination makes it a Link. The file is a URL: the picture is QLThumbnailGenerator's thumbnail for the box's size at the display's scale, asked for when the view appears and cancelled when it disappears (FIT-7); previewURL goes through AsyncImage. contentMode is .fill for cover and .fit for contain. disabled follows .disabled(_:). The middle cut is .truncationMode(.middle), which keeps the ending. | TanreiFileItem(name = "brief.pdf", sizeText = "820 KB", onRemove = { }). interactive is whether onClick is given; disabled is the inverse flag enabled. The file is a content Uri: the picture is ContentResolver.loadThumbnail(uri, size, signal) for the box's size, started in a LaunchedEffect keyed by the Uri and cancelled when the item leaves composition (FIT-7); previewModel is whatever the product's image loader takes, drawn through a painter slot so that the package depends on no loader. contentScale is Crop for cover and Fit for contain. The middle cut is TextOverflow.MiddleEllipsis. A link has no link role: Compose has none for a clickable element. | TanreiFileItem(name: 'brief.pdf', sizeText: '820 KB', onRemove: () {}). interactive is whether onPressed is given; disabled is the inverse flag enabled. The framework has no thumbnail of a file by its handle: previewImage is an ImageProvider the product gives (a FileImage with ResizeImage for a local picture, a NetworkImage for one its server made), and the file item makes none itself — FIT-7's address is the product's on this platform, and the README says so. fit is BoxFit.cover or BoxFit.contain. The middle cut is drawn by measuring with a TextPainter. A link opens through the opener the app provides. | <FileItem name="brief.pdf" sizeText="820 KB" onRemove={…} />. interactive is whether onPress is given. previewSource is an Image source ({ uri }): for a picked file the product passes the picker's uri, which the platform's image view draws scaled down without the file item reading it; no address is made (FIT-7). resizeMode is cover or contain. The middle cut is ellipsizeMode="middle". A link opens through Linking. |
Tokens
| Token | Alias de | Valor resuelto (claro) |
|---|---|---|
--tanrei-comp-file-item-action-gap | sys.space.space200 | 16px |
--tanrei-comp-file-item-action-icon-size | sys.icon.small | 20px |
--tanrei-comp-file-item-action-shape | sys.shape.corner.full | 9999px |
--tanrei-comp-file-item-action-size | — | 32px |
--tanrei-comp-file-item-disabled-opacity | — | 1 |
--tanrei-comp-file-item-done-icon-color | sys.color.success | |
--tanrei-comp-file-item-error-icon-color | sys.color.error | |
--tanrei-comp-file-item-error-supporting-text-color | sys.color.error | |
--tanrei-comp-file-item-focused-opacity | — | 1 |
--tanrei-comp-file-item-headline-color | sys.color.on-surface | |
--tanrei-comp-file-item-hovered-opacity | — | 1 |
--tanrei-comp-file-item-icon-color | sys.color.on-surface-variant | |
--tanrei-comp-file-item-media-color | sys.color.surface-container | |
--tanrei-comp-file-item-motion-cycle-duration | sys.motion.duration.extra-long4 | 1000ms |
--tanrei-comp-file-item-motion-cycle-easing | sys.motion.easing.standard | cubic-bezier(0.2, 0, 0, 1) |
--tanrei-comp-file-item-motion-feedback-duration | sys.motion.role.feedback | 450ms |
--tanrei-comp-file-item-motion-progress-duration | sys.motion.duration.medium2 | 300ms |
--tanrei-comp-file-item-motion-progress-easing | sys.motion.easing.standard | cubic-bezier(0.2, 0, 0, 1) |
--tanrei-comp-file-item-motion-state-duration | sys.motion.role.state.large | 250ms |
--tanrei-comp-file-item-motion-state-easing | sys.motion.easing.state | cubic-bezier(0.2, 0, 0, 1) |
--tanrei-comp-file-item-pressed-opacity | — | 1 |
--tanrei-comp-file-item-progress-gap | sys.space.space75 | 6px |
--tanrei-comp-file-item-progress-indicator-color | sys.color.primary | |
--tanrei-comp-file-item-progress-shape | sys.shape.corner.full | 9999px |
--tanrei-comp-file-item-progress-thickness | — | 2px |
--tanrei-comp-file-item-progress-track-color | sys.color.surface-variant | |
--tanrei-comp-file-item-row-action-container-color | — | |
--tanrei-comp-file-item-row-action-icon-color | sys.color.on-surface-variant | |
--tanrei-comp-file-item-row-action-state-layer-color | comp.file-item.row.action.icon.color | |
--tanrei-comp-file-item-row-container-color | — | |
--tanrei-comp-file-item-row-container-gap | sys.space.space150 | 12px |
--tanrei-comp-file-item-row-container-outset | sys.space.space50 | 4px |
--tanrei-comp-file-item-row-container-shape | sys.shape.corner.small | 6px |
--tanrei-comp-file-item-row-disabled-action-container-color | — | |
--tanrei-comp-file-item-row-disabled-action-icon-color | — | |
--tanrei-comp-file-item-row-disabled-action-state-layer-color | — | |
--tanrei-comp-file-item-row-disabled-container-color | — | |
--tanrei-comp-file-item-row-disabled-state-layer-color | — | |
--tanrei-comp-file-item-row-focused-action-container-color | — | |
--tanrei-comp-file-item-row-focused-action-icon-color | — | |
--tanrei-comp-file-item-row-focused-action-state-layer-color | — | |
--tanrei-comp-file-item-row-focused-container-color | — | |
--tanrei-comp-file-item-row-focused-state-layer-color | — | |
--tanrei-comp-file-item-row-hovered-action-container-color | — | |
--tanrei-comp-file-item-row-hovered-action-icon-color | — | |
--tanrei-comp-file-item-row-hovered-action-state-layer-color | — | |
--tanrei-comp-file-item-row-hovered-container-color | — | |
--tanrei-comp-file-item-row-hovered-state-layer-color | — | |
--tanrei-comp-file-item-row-icon-size | sys.icon.medium | 24px |
--tanrei-comp-file-item-row-media-height | — | 40px |
--tanrei-comp-file-item-row-media-shape | sys.shape.corner.small | 6px |
--tanrei-comp-file-item-row-pressed-action-container-color | — | |
--tanrei-comp-file-item-row-pressed-action-icon-color | — | |
--tanrei-comp-file-item-row-pressed-action-state-layer-color | — | |
--tanrei-comp-file-item-row-pressed-container-color | — | |
--tanrei-comp-file-item-row-pressed-state-layer-color | — | |
--tanrei-comp-file-item-row-state-layer-color | comp.file-item.headline.color | |
--tanrei-comp-file-item-status-icon-gap | sys.space.space50 | 4px |
--tanrei-comp-file-item-status-icon-size | sys.icon.extra-small | 16px |
--tanrei-comp-file-item-supporting-text-color | sys.color.on-surface-variant | |
--tanrei-comp-file-item-tile-action-container-color | sys.color.surface-container-lowest | |
--tanrei-comp-file-item-tile-action-icon-color | sys.color.on-surface-variant | |
--tanrei-comp-file-item-tile-action-inset | sys.space.space50 | 4px |
--tanrei-comp-file-item-tile-action-state-layer-color | comp.file-item.tile.action.icon.color | |
--tanrei-comp-file-item-tile-container-color | — | |
--tanrei-comp-file-item-tile-container-gap | sys.space.space75 | 6px |
--tanrei-comp-file-item-tile-container-shape | sys.shape.corner.medium | 8px |
--tanrei-comp-file-item-tile-disabled-action-container-color | — | |
--tanrei-comp-file-item-tile-disabled-action-icon-color | — | |
--tanrei-comp-file-item-tile-disabled-action-state-layer-color | — | |
--tanrei-comp-file-item-tile-disabled-container-color | — | |
--tanrei-comp-file-item-tile-disabled-state-layer-color | — | |
--tanrei-comp-file-item-tile-focused-action-container-color | — | |
--tanrei-comp-file-item-tile-focused-action-icon-color | — | |
--tanrei-comp-file-item-tile-focused-action-state-layer-color | — | |
--tanrei-comp-file-item-tile-focused-container-color | — | |
--tanrei-comp-file-item-tile-focused-state-layer-color | — | |
--tanrei-comp-file-item-tile-hovered-action-container-color | — | |
--tanrei-comp-file-item-tile-hovered-action-icon-color | — | |
--tanrei-comp-file-item-tile-hovered-action-state-layer-color | — | |
--tanrei-comp-file-item-tile-hovered-container-color | — | |
--tanrei-comp-file-item-tile-hovered-state-layer-color | — | |
--tanrei-comp-file-item-tile-icon-size | sys.icon.large | 32px |
--tanrei-comp-file-item-tile-media-height | — | 96px |
--tanrei-comp-file-item-tile-pressed-action-container-color | — | |
--tanrei-comp-file-item-tile-pressed-action-icon-color | — | |
--tanrei-comp-file-item-tile-pressed-action-state-layer-color | — | |
--tanrei-comp-file-item-tile-pressed-container-color | — | |
--tanrei-comp-file-item-tile-pressed-state-layer-color | — | |
--tanrei-comp-file-item-tile-state-layer-color | comp.file-item.headline.color | |
--tanrei-comp-file-item-headline-typescale | sys.typescale.body | 400 14px/1.5714 |
--tanrei-comp-file-item-supporting-text-typescale | sys.typescale.body-small | 400 13px/1.5385 |
Fixtures
Representaciones canónicas. Todas las plataformas capturan cada fixture con el mismo identificador para poder comparar los resultados.
form: row (31)
row
value: a name: brief.pdf sizeText: 820 KB removeLabel: Remove {name} retryLabel: Retry {name} row-format
value: a name: brief.pdf formatText: PDF sizeText: 820 KB status: pending statusText: Waiting removeLabel: Remove {name} retryLabel: Retry {name} row-uploading
value: b name: floor-plan.png sizeText: 3.4 MB status: uploading statusText: Uploading progress: 0.4 removeLabel: Remove {name} retryLabel: Retry {name} row-uploading-indeterminate
value: c name: survey.pdf sizeText: 1.1 MB status: uploading statusText: Uploading removeLabel: Remove {name} retryLabel: Retry {name} row-done
value: d name: contract.pdf sizeText: 2.0 MB status: done statusText: Uploaded removeLabel: Remove {name} retryLabel: Retry {name} row-error-retryable
value: e name: site-photo.png sizeText: 6.8 MB status: error errorText: The connection was lost. retryable: true removeLabel: Remove {name} retryLabel: Retry {name} row-error
value: f name: scan-archive.pdf sizeText: 48 MB status: error errorText: Larger than 10 MB. removeLabel: Remove {name} retryLabel: Retry {name} kind-image
value: image name: floor-plan.png removeLabel: Remove {name} retryLabel: Retry {name} kind-video
value: video name: walkthrough.mp4 removeLabel: Remove {name} retryLabel: Retry {name} kind-audio
value: audio name: interview.m4a removeLabel: Remove {name} retryLabel: Retry {name} kind-pdf
value: pdf name: brief.pdf removeLabel: Remove {name} retryLabel: Retry {name} kind-spreadsheet
value: spreadsheet name: budget.xlsx removeLabel: Remove {name} retryLabel: Retry {name} kind-presentation
value: presentation name: kickoff.pptx removeLabel: Remove {name} retryLabel: Retry {name} kind-archive
value: archive name: site-photos.zip removeLabel: Remove {name} retryLabel: Retry {name} kind-code
value: code name: config.json removeLabel: Remove {name} retryLabel: Retry {name} kind-document
value: document name: minutes.docx removeLabel: Remove {name} retryLabel: Retry {name} kind-other
value: other name: README removeLabel: Remove {name} retryLabel: Retry {name} row-media-type
value: a name: export mediaType: text/csv sizeText: 12 KB removeLabel: Remove {name} retryLabel: Retry {name} row-glyph
value: a name: keys.pem glyph: key sizeText: 2 KB removeLabel: Remove {name} retryLabel: Retry {name} row-icon-slot
value: a name: model.glb sizeText: 14 MB removeLabel: Remove {name} retryLabel: Retry {name} slots: icon row-preview
value: b name: floor-plan.png sizeText: 3.4 MB preview: true previewSrc: fixtures/avatar.png removeLabel: Remove {name} retryLabel: Retry {name} row-preview-glyph
value: a name: brief.pdf sizeText: 820 KB preview: true removeLabel: Remove {name} retryLabel: Retry {name} row-interactive
value: b name: floor-plan.png sizeText: 3.4 MB preview: true previewSrc: fixtures/avatar.png interactive: true removeLabel: Remove {name} retryLabel: Retry {name} row-link
value: d name: contract.pdf formatText: PDF sizeText: 2.0 MB href: /files/contract.pdf readOnly: true row-link-new
value: d name: contract.pdf sizeText: 2.0 MB href: /files/contract.pdf target: new targetLabel: opens in a new tab removeLabel: Remove {name} retryLabel: Retry {name} row-disabled
value: e name: site-photo.png sizeText: 6.8 MB status: error errorText: The connection was lost. retryable: true removeLabel: Remove {name} retryLabel: Retry {name} disabled: true row-read-only
value: d name: contract.pdf sizeText: 2.0 MB status: done statusText: Uploaded readOnly: true row-without-words
value: e name: site-photo.png status: error retryable: true row-long-text
value: a name: municipal-planning-application-supportin… formatText: PDF sizeText: 9.6 MB status: error errorText: This file is larger than 10 MB. Export i… retryable: true removeLabel: Remove {name} retryLabel: Retry {name} row-rtl
value: b name: floor-plan.png sizeText: 3.4 MB status: uploading statusText: Uploading progress: 0.4 removeLabel: Remove {name} retryLabel: Retry {name} direction: rtl row-rtl-error
value: e name: site-photo.png sizeText: 6.8 MB status: error errorText: The connection was lost. retryable: true href: /files/site-photo.png target: new targetLabel: opens in a new tab removeLabel: Remove {name} retryLabel: Retry {name} direction: rtl form: tile (15)
tile
form: tile value: a name: brief.pdf sizeText: 820 KB removeLabel: Remove {name} retryLabel: Retry {name} tile-preview
form: tile value: b name: floor-plan.png preview: true previewSrc: fixtures/avatar.png removeLabel: Remove {name} retryLabel: Retry {name} tile-preview-pending
form: tile value: b name: floor-plan.png preview: true removeLabel: Remove {name} retryLabel: Retry {name} tile-size-cover
form: tile value: b name: floor-plan.png preview: true previewSrc: fixtures/avatar.png width: 160 height: 90 removeLabel: Remove {name} retryLabel: Retry {name} tile-size-contain
form: tile value: b name: floor-plan.png preview: true previewSrc: fixtures/avatar.png fit: contain width: 160 height: 90 removeLabel: Remove {name} retryLabel: Retry {name} tile-name-hidden
form: tile value: b name: floor-plan.png preview: true previewSrc: fixtures/avatar.png nameHidden: true removeLabel: Remove {name} retryLabel: Retry {name} tile-name-hidden-glyph
form: tile value: a name: brief.pdf nameHidden: true removeLabel: Remove {name} retryLabel: Retry {name} tile-uploading
form: tile value: b name: floor-plan.png status: uploading statusText: Uploading progress: 0.4 preview: true previewSrc: fixtures/avatar.png removeLabel: Remove {name} retryLabel: Retry {name} tile-done
form: tile value: b name: floor-plan.png status: done statusText: Uploaded preview: true previewSrc: fixtures/avatar.png removeLabel: Remove {name} retryLabel: Retry {name} tile-error-retryable
form: tile value: e name: site-photo.png status: error errorText: The connection was lost. retryable: true preview: true previewSrc: fixtures/avatar.png nameHidden: true removeLabel: Remove {name} retryLabel: Retry {name} tile-interactive
form: tile value: b name: floor-plan.png preview: true previewSrc: fixtures/avatar.png interactive: true removeLabel: Remove {name} retryLabel: Retry {name} tile-disabled
form: tile value: e name: site-photo.png status: error errorText: The connection was lost. retryable: true preview: true previewSrc: fixtures/avatar.png removeLabel: Remove {name} retryLabel: Retry {name} disabled: true tile-read-only
form: tile value: b name: floor-plan.png preview: true previewSrc: fixtures/avatar.png href: /files/floor-plan.png readOnly: true tile-long-name
form: tile value: b name: IMG_20260914_103322_HDR_edited_copy_2.jp… sizeText: 12.4 MB preview: true previewSrc: fixtures/avatar.png removeLabel: Remove {name} retryLabel: Retry {name} tile-rtl
form: tile value: e name: site-photo.png status: error errorText: The connection was lost. retryable: true preview: true previewSrc: fixtures/avatar.png removeLabel: Remove {name} retryLabel: Retry {name} direction: rtl Generado a partir de specs/file-item.spec.json, tokens/comp/file-item.tokens.json, design/tokens/
Los mismos tres archivos como filas y como mosaicos
| Aspecto | row (la predeterminada) |
tile |
|---|---|---|
| Úsala para | Una columna de archivos de cualquier categoría. | Una tira de imágenes. |
| Anchura | La que le da su lugar. | La del recuadro: width, nunca más ancho que su lugar. |
| El glifo o la imagen | Antes del nombre. Con preview, un cuadrado pequeño. |
Todo el recuadro, de width por height. |
| El nombre | Salta de línea y nunca se corta. | Una línea debajo del recuadro, cortada por el medio para que se conserve su terminación. |
| La segunda línea | Debajo del nombre. | Debajo del recuadro, y salta de línea dentro de su anchura. |
| La barra | Debajo de los textos. | A lo largo del borde inferior del recuadro. |
| Las acciones | Al final: reintentar y después quitar. | En el recuadro, en su esquina superior del lado final. |
width y height son números, y solo se leen en la forma de mosaico. Sin height, el recuadro tiene la altura que dice el token comp.file-item.tile.media.height; sin width, es cuadrado. Elige la proporción de las imágenes que tienes: width="160" height="90" para capturas de pantalla, un cuadrado para retratos de personas. Un recuadro nunca es más estrecho de lo que necesitan sus dos acciones.
No hay una tercera forma, compacta. Un archivo en una sola línea es una fila sin nada en su segunda línea.
Cada parte se muestra cuando la das. Dos propiedades que se activan o no, preview y nameHidden, cambian lo que se muestra. Ninguna propiedad enumera las partes que se muestran.
| Parte | Se muestra cuando |
|---|---|
| El glifo | Siempre, donde no se dibuja ninguna imagen. |
| La imagen | preview está definido y hay una imagen que dibujar. |
| El nombre | Siempre en una fila. En un mosaico, salvo que nameHidden esté definido y se dibuje una imagen. |
| El formato con palabras | Das formatText. Tanrei no tiene ninguna palabra para un formato. |
| El tamaño | Das sizeText, con el formato del idioma de quien lo lee. |
| El estado con palabras | Das statusText. |
| El error | status es error y das errorText. Ocupa el lugar del estado, en todas las formas, y nunca se corta. |
| La barra | status es uploading. Llena hasta progress, o indeterminada mientras progress no está definido. |
Un archivo completado y un archivo fallido llevan una marca antes de las palabras de su estado: una marca de verificación y una marca de error. El glifo que precede al nombre no cambia con el estado. Así la persona aprende un lugar para cada cosa: antes del nombre, qué es el archivo; antes del estado, cómo va.
nameHidden es para una tira densa de imágenes. Solo oculta el nombre cuando hay una imagen dibujada. Un mosaico que muestra un glifo conserva su nombre, porque el glifo de un formato no distingue dos archivos del mismo formato. En todos los casos, el nombre sigue siendo el nombre del elemento para la tecnología de apoyo.
Hay diez categorías de glifo. Cada categoría tiene una lista de tipos de medio y una lista de extensiones de archivo. El glifo se elige a partir de mediaType. Cuando el tipo de medio está vacío, es application/octet-stream o no figura en ninguna de estas listas, se elige a partir de la extensión de name. Las categorías se comprueban en este orden. Las listas son fijas y las mismas en todas las plataformas, de modo que un mismo archivo dibuja el mismo glifo dondequiera que se muestre. video/mp2t tampoco decide nada: las plataformas lo deducen de la terminación .ts, que los archivos de TypeScript comparten con los flujos de vídeo, así que index.ts dibuja el glifo de código.
Las diez categorías
| Categoría | Glifo | Tipos de medio | Terminaciones |
|---|---|---|---|
picture_as_pdf |
application/pdf |
||
| spreadsheet | table |
text/csv, text/tab-separated-values, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.oasis.opendocument.spreadsheet, application/vnd.apple.numbers, application/x-iwork-numbers-sffnumbers |
xls, xlsx, ods, numbers, csv, tsv |
| presentation | slideshow |
application/vnd.ms-powerpoint, application/vnd.openxmlformats-officedocument.presentationml.presentation, application/vnd.oasis.opendocument.presentation, application/vnd.apple.keynote, application/x-iwork-keynote-sffkey |
ppt, pptx, odp, key |
| archive | folder_zip |
application/zip, application/x-zip-compressed, application/x-tar, application/gzip, application/x-gzip, application/x-bzip2, application/x-xz, application/x-7z-compressed, application/vnd.rar, application/x-rar-compressed |
zip, tar, gz, tgz, bz2, xz, 7z, rar |
| code | code |
text/html, text/css, text/javascript, application/javascript, application/x-javascript, text/typescript, application/typescript, text/jsx, text/tsx, application/json, application/xml, text/xml, text/yaml, text/x-yaml, application/yaml, application/x-yaml, application/x-sh, text/x-sh, text/x-shellscript, text/x-python, text/x-script.python, text/x-ruby, application/x-ruby, text/x-go, text/x-rust, text/x-java, text/x-java-source, text/x-kotlin, text/x-swift, text/x-c, text/x-chdr, text/x-csrc, text/x-c++, text/x-c++src, text/x-csharp, text/x-php, application/x-php, application/x-httpd-php, application/sql, text/x-sql |
html, css, js, mjs, ts, tsx, jsx, json, xml, yaml, yml, sh, py, rb, go, rs, java, kt, swift, c, h, cpp, cs, php, sql |
| image | image |
Todos los tipos que empiezan por image/ |
png, jpg, jpeg, gif, webp, avif, svg, bmp, tif, tiff, heic, heif, ico |
| video | movie |
Todos los tipos que empiezan por video/ |
mp4, mov, m4v, webm, mkv, avi |
| audio | music_note |
Todos los tipos que empiezan por audio/ |
mp3, wav, m4a, aac, ogg, oga, flac, opus |
| document | description |
Todos los demás tipos que empiezan por text/, y application/rtf, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.oasis.opendocument.text, application/vnd.apple.pages, application/x-iwork-pages-sffpages |
txt, md, rtf, doc, docx, odt, pages |
| other | draft |
— | Todo lo demás, y un nombre sin punto |
- El tipo de medio decide antes que la terminación. Un archivo cuyo tipo de medio figura en una lista es de esa categoría, termine como termine su nombre.
- El archivo nunca se abre para averiguar su formato.
- Para un formato propio, indica un glifo del conjunto de iconos con
glyph, o pon el tuyo en el sloticon. - Todos los glifos tienen un solo color. Un formato no tiene color propio: un color significa lo mismo dondequiera que se use, y un formato no es un estado.
- Di el formato con palabras mediante
formatTextdonde importe. El glifo está oculto para la tecnología de apoyo.
preview dibuja una imagen del archivo en el lugar del glifo. Tiene dos orígenes:
previewSrc: la dirección de una versión pequeña del archivo que generó tu servidor. Se dibuja para un archivo de cualquier formato.- El propio archivo, cuando
previewSrcestá vacío y el archivo es una imagen. En la web, asignas elFilea la propiedadfile.
fit dice cómo llena la imagen su recuadro. cover, el valor predeterminado, llena el recuadro y recorta lo que no cabe; úsalo para fotografías. contain muestra la imagen entera sobre el fondo del recuadro; úsalo para documentos escaneados, firmas y diagramas, donde los bordes importan.
Un recuadro de 160 por 90: cover, contain y el nombre oculto
Lo que cuesta una vista previa:
| La imagen procede de | Lo que cuesta |
|---|---|
Con preview desactivado, el valor predeterminado |
Nada. Cien elementos de archivo cuestan lo que cuestan sus textos. |
Con previewSrc |
Una solicitud de imagen por cada elemento, que hace la carga de imágenes propia de la plataforma. |
| Con el propio archivo | Una dirección para el archivo, que el elemento crea cuando entra por primera vez en la vista o se acerca a ella, y que libera cuando el elemento sale de la página, cuando le das otro archivo o ninguno, y cuando ya no se pide la vista previa. El decodificador de imágenes de la plataforma lee el archivo para dibujarlo. El elemento no lee nada por sí mismo. |
- Solo se dibujan a partir del archivo las imágenes. Un fotograma de un vídeo o una página de un documento exigirían abrir y leer el archivo, cosa que ningún componente de Tanrei hace. Para esos casos, da
previewSrc. - Hasta que la imagen se puede dibujar, y si no se puede, se dibuja el glifo del formato. No hay indicador giratorio ni marca de imagen rota, y
statusno se toca: una miniatura que no se cargó no es un fallo del archivo. - La imagen no tiene texto alternativo. Ocupa el lugar que ocupaba el glifo, y el archivo recibe su nombre de
name.
De forma predeterminada, el cuerpo de un elemento de archivo no recibe el foco y no responde a nada. El elemento solo contiene sus acciones.
Un cuerpo que es un botón, un enlace que se abre en una pestaña nueva y un archivo de solo lectura
| Propiedad | El cuerpo es | Úsala para |
|---|---|---|
interactive |
Un botón. Emite click con value. |
Abrir el archivo allí donde está la persona: una imagen en un visor propio, un documento en un panel. |
href |
Un enlace al archivo. Primero emite click; cancélalo para encargarte tú de la navegación. |
Un archivo que tu servidor ya tiene. Con target="new", da targetLabel. |
| Ninguna de las dos | No se puede pulsar. | Un archivo que solo aparece en una lista. |
El cuerpo es el glifo o la imagen, y los textos. Las acciones están a su lado y nunca dentro de él, así que un elemento de archivo pulsable tiene tres paradas como máximo: el cuerpo, reintentar y quitar.
readOnly no dibuja ninguna de las dos acciones ni les reserva sitio. Úsalo para los archivos de un expediente que solo se lee. El cuerpo se puede seguir pulsando.
disabled deshabilita las acciones y el cuerpo. Lo que el elemento muestra se queda como está y sigue siendo legible. Una acción deshabilitada conserva el fondo que tiene en reposo, ninguno en una fila y su disco en un mosaico: solo se atenúa su glifo.
Un elemento de archivo no tiene tirador ni orden propio. Reordenar es cosa de la lista: pon cada elemento de archivo en un elemento de una lista reordenable. La lista dibuja el tirador junto al elemento de archivo, permite arrastrar el elemento entero y abre desde el tirador su menú de movimientos; el elemento de archivo conserva su glifo, sus textos, su barra y sus acciones.
Archivos en un orden que las personas cambian: elementos de archivo en una lista reordenable
<tanrei-list reorderable gap="small" label="Attachments" drag-handle-label="Reorder {label}"
move-to-start-label="Move to top" move-before-label="Move up"
move-after-label="Move down" move-to-end-label="Move to bottom"
lifted-text="{label} lifted: {position} of {count}"
moved-text="{label}: {position} of {count}"
cancelled-text="{label} returned to {position} of {count}">
<tanrei-list-item><tanrei-file-item name="cover-letter.pdf" size-text="120 KB" remove-label="Remove {name}"></tanrei-file-item></tanrei-list-item>
…
</tanrei-list>La lista no mueve nada por sí misma: con move, pon los elementos en el nuevo orden. Anuncia cada movimiento y mantiene el foco en el tirador del elemento movido; consulta la lista. Cada elemento de la lista se nombra por su archivo (el nombre del archivo es el texto del contenido, así que no hace falta nada más). Una carga de archivos dispone sus archivos de la misma manera.
El elemento de archivo no incluye textos propios. Dos se pueden dar una sola vez para todo el producto con setWords(); todos los demás textos son propiedades de la instancia.
| Propiedad | Clave de los textos del producto | Sin ella |
|---|---|---|
removeLabel |
removeLabel |
La acción de quitar se dibuja y no tiene nombre. Una compilación de depuración lo notifica. |
retryLabel |
retryLabel |
La acción de reintentar se dibuja y no tiene nombre. Una compilación de depuración lo notifica. |
El nombre de cada acción lleva el nombre de su archivo: removeLabel y retryLabel son frases con el marcador {name}, que el elemento de archivo rellena («Quitar {name}»). Una frase basta para todos los archivos, y una persona oye «Quitar brief.pdf, botón» —en el orden de tu idioma—, también cuando un lector de pantalla enumera los botones de la página. Una frase sin {name} da el mismo nombre a la acción de cada archivo, y una compilación de depuración lo notifica.
En un diseño de derecha a izquierda, el glifo o la imagen están a la derecha y las acciones a la izquierda, con la de quitar en el extremo; una barra se llena desde la derecha, y las acciones de un mosaico están en su esquina superior izquierda. Una imagen nunca se refleja. Un nombre de archivo en letras latinas conserva su propio orden, con su punto y su extensión. De los diez glifos de formato solo se refleja el de other, porque el conjunto de iconos lo marca así.
- Da
statusTexta un archivo completado yerrorTexta uno fallido. Un estado nunca se dice solo con una marca o un color. - Define
retryablesolo para un fallo que un nuevo intento pueda remediar. Un archivo demasiado grande volverá a ser demasiado grande. - Da tú formato al tamaño. Si un megabyte son 1000 o 1024 kilobytes es decisión de tu producto.
- Pon los elementos de archivo que van juntos en una lista tuya, un
<ul>con nombre, o en un control de subida de archivos. - Mueve tú el foco después de quitar un elemento. Por sí solo, un elemento de archivo no puede saber qué tiene al lado.
- No esperes que el elemento se quite a sí mismo, cambie su estado o mueva su barra. Dibuja lo que tú defines.
- No uses
nameHiddenpara archivos que no son imágenes. Sus mosaicos conservan el nombre de todos modos. - No pongas dentro un menú, una casilla de verificación ni una leyenda. Su único slot es el del glifo. Las demás acciones sobre un archivo van al lado del elemento.
- No lo uses como la fila de una lista en la que las personas seleccionan o reordenan. Esa es la fila de la lista.
- Rol
group- Etiquetado
- A group named by the file's name — also in a tile that does not draw it — reading the name, the format, the size and the status or the error in words, a progress bar named by the file while it is sent, and its actions: buttons named retryLabel and removeLabel, each with the file's name in its place ({name}). A pressable body is a button, or a link, named by the file's name and described by the second line. Inside a File upload the file item is an item of the upload's list in the group's place (FUP-25).
- Objetivo mínimo
- El área de pulsación cumple el tamaño mínimo de objetivo aunque el tamaño visual sea menor. minimum 32px · pointer 44px · spacing 8px · touch 48px
Teclado
| Teclas | Acción |
|---|---|
| Tab / Shift+Tab | Moves focus to the body, where the file item is pressable, then to its retry action where it has one, then to its remove action. A file item that is not pressable and is read-only is no stop at all. |
| Enter / Space | On a pressable body: emits click, for the product to open the file. On an action: asks whoever holds the file item to retry or to remove the file. |
| Enter | On a body that is a link: follows it. Space does what it does on any link (FIT-13). |
Notas
- The name is the name in every form (FIT-8, FIT-19): hiding it in a strip of pictures hides it from sight alone, and only behind a picture that is drawn. A picture is no text alternative for a name, and the file item asks for no description of the picture: the picture stands for the file, which has a name. A product that shows the picture as content — to be looked at — shows it in an Image preview, whose images have their own alternative text.
- Status is never color alone (WCAG 1.4.1): a done or failed file has words, and its mark has a shape of its own. The glyph before the name says the format and never the status, so that a person learns one place for each.
- A failure is never hidden (WCAG 3.3.1): errorText is drawn in every form, wraps and is never cut, also beneath a tile whose name is hidden.
- A format has no color. Ten colors for ten kinds would be ten meanings a person must learn, would compete with the two status colors on the same line, and would say nothing to a person who does not tell them apart; the glyph's shape and, where the product has them, the format's words carry it.
- The remove and retry actions are named by one sentence of the product's with the file's name in it, so a person tabbing through a list, or listing the buttons of the page, hears "Remove brief.pdf, button" — in the order of the product's language — without the product writing a sentence per file.
- Nothing is announced by a file item (FIT-19). A component that holds file items — a File upload, a chat composer — has one live region for all of them and says what was added, finished and failed there; a product that arranges file items itself does the same with a region of its own.
- A cut name (FIT-9) is cut for sight alone and keeps its ending. The whole name is the accessible name; on the web it is also the body's or the name's `title` only where the product asks for one, because a tooltip is not reachable by touch and is no substitute for the row form, which never cuts.
- A picture that moves (an animated image) is the platform's to hold still or not (FIT-23). On the web an image element plays it; a product whose strip must not move gives a still `previewSrc`.
- Without script, and until the component is defined, on the web: nothing is drawn, because the name is an attribute. A page that must list files where script does not run writes its own links to them, as it would without Tanrei.
- Compose and React Native: the group is a node with the name as its content description (Compose) or a labelled container (React Native), and the actions keep their own nodes.
Generado a partir de specs/file-item.spec.json, tokens/sys/measure.tokens.json
- Por sí solo, un elemento de archivo es un grupo que recibe su nombre del nombre del archivo. En un control de subida de archivos es un elemento de la lista del control.
- Un cuerpo pulsable es un solo botón o un solo enlace, que recibe su nombre del nombre del archivo y su descripción de la segunda línea. Va antes que las acciones en el orden del foco. Un enlace se activa con Enter y no con Espacio, y un enlace que se abre en una pestaña nueva dice
targetLabeldespués de su nombre. - Las acciones son botones que reciben su nombre de
removeLabelyretryLabel, con el nombre del archivo en el marcador{name}. Reintentar va antes que quitar. - La barra es una barra de progreso que recibe su nombre del archivo. Un error es el texto de la segunda línea, y se lee en el lugar del estado.
- El glifo, la imagen y la marca de estado están ocultos para la tecnología de apoyo. Las palabras dicen lo que muestran.
- Un elemento de archivo no anuncia nada. Quien tiene muchos tiene una única región activa para todos ellos, como la tiene el control de subida de archivos.
- El nombre completo siempre llega a la tecnología de apoyo, también donde un mosaico lo corta y donde
nameHiddenlo oculta. - Con el texto al 200%, una fila salta de línea y no pierde nada. Donde el glifo y las acciones dejarían al nombre menos de la mitad de la fila, las acciones pasan a una línea propia bajo los textos, al final de la fila, y el nombre ocupa todo el ancho. El recuadro de un mosaico conserva su tamaño y sus textos crecen debajo de él.
- En colores forzados, el recuadro y los discos de las acciones de un mosaico conservan un borde, y la barra sigue siendo visible. Una imagen se deja como está.
- Los cambios de color entre estados se animan durante un tiempo breve, y son inmediatos donde el movimiento está reducido.
Carencias conocidas en la web:
- Una imagen que se mueve, como un GIF animado, la reproduce el elemento de imagen del navegador. El elemento de archivo no puede dejarla quieta. Donde eso importe, da una versión fija de la imagen como
previewSrc. - Antes de que el elemento esté definido no se dibuja nada, porque el nombre es un atributo y no texto del documento. Una página que debe enumerar archivos donde no se ejecutan scripts escribe sus propios enlaces.
- Da
name, siempre. - Da
removeLabelyretryLabel, en el elemento o una sola vez consetWords(). - Di con palabras cada estado y cada fallo:
statusTextyerrorText. - Con
target="new", datargetLabel. - Da a un grupo de elementos de archivo una lista y un nombre tuyos, y anuncia lo que se añadió, terminó o falló en una única región activa tuya. Un control de subida de archivos hace ambas cosas por ti.
- Después de quitar un elemento, mueve el foco a la acción de quitar del archivo siguiente, o a lo que añadió los archivos.