Saltar al contenido
menumenu tanreiexpand_morecontrasttranslate
tanreiexpand_more
Primeros pasosWebReactSwiftUIJetpack ComposeFlutterReact NativePreajustesTu propio sistema de diseñoUsar Tanrei con agentes de IAMarcaTokens de diseñoSistemas de diseño y personalizaciónTheme StudioColorTipografíaIconosFormaElevaciónMovimientoEstados de interacciónComportamientoDiseño de páginaAccesibilidadTextosTokens de colorTokens de la escala tipográficaTokens de formaTokens de elevaciónTokens de movimientoTokens de estadoTokens de espacio y de medidaComponentesBotónBotón de acción principalBotón segmentadoGrupo de botonesBotón con menúBarra de herramientasBotón de copiarCasilla de verificaciónBotón de opciónInterruptorChipMenúControl deslizanteCampo de control deslizanteCalendarioDateTimePickerGrupo de camposGrupo de botones de opciónGrupo de casillas de verificaciónSelectCampo de selecciónBarra de menúsSubida de archivosSelector de archivos AvanzadoZona de soltar archivosEntrada de texto AvanzadoCampo de textoCampo de chipsCampoCuadro combinado AvanzadoCampo de cuadro combinadoEntrada numérica AvanzadoCampo numéricoEntrada de color AvanzadoCampo de colorEntrada de código de un solo uso AvanzadoCampo de código de un solo usoEntrada de texto incrustada AvanzadoCuadro de redacción de chatTarjetaDivisorCapa modal AvanzadoDiálogoListaFila de listaHoja inferiorHoja lateralCarruselBloque de códigoTablaPopoverPasosAcordeónLista de descripcionesFiguraEstructura de la aplicaciónCabecera de páginaVista de árbolLínea de tiempoVista previa de imágenesTirador de tamañoMarco redimensionableÁrea de desplazamientoInsigniaIndicador de progresoMedidorContador animadoIndicador de cargaSnackbarTooltipAtajo de tecladoTagCódigo en líneaCalloutAvatarEstado vacíoGrupo de tagsEsqueletoElemento de archivoMuestraTexto en marquesinaPestañasVista de pestañasBarra de la aplicaciónBarra de navegaciónPanel de navegaciónBúsquedaEnlacePaginaciónEnlaces anterior y siguienteIndicador de pasosRuta de navegaciónTabla de contenidoTarjeta de enlaceMenú FABEstadoCómo se construye TanreiCómo contribuirLicencia y atribución
InicioComponentesBarra de herramientas

Barra de herramientas

Reúne un conjunto de controles relacionados en una sola parada de tabulación, en línea donde su contenido la necesita, acoplada a lo largo del borde inferior o flotando sobre el contenido. Las teclas de flecha mueven el foco entre sus controles, y lo que no cabe pasa a un menú de desbordamiento.

content_copyVer en Markdown
Categoría
Acciones
Tokens
comp.toolbar
Nivel
Base

Descripción general

Web
tanrei-toolbar
schedule
SwiftUI
TanreiToolbar
schedule
Jetpack Compose
TanreiToolbar
schedule
Flutter
TanreiToolbar
schedule
React Native
Toolbar
schedule

Generado a partir de docs/status/status.json, specs/toolbar.spec.json

En línea, acoplada y flotante

format_boldformat_italicformat_underlinedlinkimagearchivedeletemark_email_unreaddrive_file_moveeditink_highlighterink_erasercheck

Uso

Una barra de herramientas reúne un conjunto de controles relacionados: acciones, conmutadores, un botón que abre un menú, un botón con menú. Sus elementos son tus propios Buttons y botones con menú de Tanrei, cada uno con su etiqueta, su clic y su estado. La barra de herramientas los dispone en el orden de lectura, separa los grupos, mueve el foco del teclado entre ellos y oculta en un menú de desbordamiento lo que no cabe. Nunca les cambia el estilo, así que un Button de solo icono en una barra de herramientas se ve y se comporta como en cualquier otro lugar.

Tiene seis tipos de elemento:

  • action: un Button de solo icono. Un conmutador como Negrita es uno con toggle activado.
  • button: un Button con etiqueta, que también puede ser un conmutador, como un filtro que está activado o desactivado.
  • menu-button: un Button con un Menu de Tanrei anclado a él, como Ordenar o Insertar. El menú es tuyo y está junto a su Button. La barra de herramientas no lo dispone.
  • button-with-menu: una acción principal con un menú de acciones relacionadas. Cada mitad es su propia parada de las teclas de flecha.
  • group: una serie de elementos relacionados, como Negrita, Cursiva y Subrayado. No dibuja nada propio. Dale un label cuando la agrupación signifique algo para la persona, como «Estilo del texto».
  • separator: una línea entre dos elementos que no están en grupos. En la web es un divisor, que la barra de herramientas dibuja igual que la línea entre dos grupos.

En línea (predeterminada). Una barra de herramientas en línea está donde la pone tu diseño, en el contenido sobre el que actúa: encima de una tabla, en la parte superior de un editor, junto a una lista como una fila de filtros. Es tan larga como necesitan sus elementos y nunca más larga de lo que permite el diseño. En el sistema predeterminado no tiene superficie, sombra ni borde propios, y sus extremos se alinean con el contenido que la rodea.

Acoplada. Una barra de herramientas acoplada abarca el borde inferior de la pantalla. Su color llega por debajo del indicador de inicio o de la barra de gestos, y sus elementos quedan por encima de él y dentro de los márgenes interiores laterales. La web lee env(safe-area-inset-bottom), SwiftUI coloca la barra con .safeAreaInset(edge: .bottom), Compose recibe windowInsets (las barras de navegación de forma predeterminada) y Flutter lee el margen interior inferior de MediaQuery. React Native toma sus márgenes interiores de la propiedad insets de la barra de herramientas o de TanreiProvider, ya que Tanrei no depende de ninguna biblioteca de área segura.

Flotante. Una barra de herramientas flotante no se coloca sola, como tampoco lo hace un botón de acción principal. La pone tu diseño, normalmente centrada sobre la parte inferior del contenido, o junto al borde de fin del contenido cuando es vertical.

Los ejemplos de Web y React muestran la especificación actual. SwiftUI, Compose, Flutter y React Native van rezagados. Todavía ofrecen la revisión anterior de la barra de herramientas y del botón, en la que una barra de herramientas es acoplada salvo que digas otra cosa, contiene solo Buttons, desplaza lo que no cabe y una acción de solo icono es un botón de icono aparte. Sus ejemplos muestran esa revisión hasta que se pongan al día.

<tanrei-toolbar label="Formato" overflow-label="Más opciones de formato">
  <tanrei-toolbar-group label="Estilo del texto">
    <tanrei-button variant="text" toggle selected label="Negrita"><span slot="icon">format_bold</span></tanrei-button>
    <tanrei-button variant="text" toggle label="Cursiva"><span slot="icon">format_italic</span></tanrei-button>
  </tanrei-toolbar-group>
  <tanrei-toolbar-group>
    <tanrei-button variant="text" label="Insertar enlace"><span slot="icon">link</span></tanrei-button>
    <tanrei-button variant="text" id="insert" label="Insertar"><span slot="icon">add</span></tanrei-button>
    <tanrei-menu anchor="insert">
      <tanrei-menu-item label="Tabla"></tanrei-menu-item>
      <tanrei-menu-item label="Línea horizontal"></tanrei-menu-item>
    </tanrei-menu>
  </tanrei-toolbar-group>
  <tanrei-divider></tanrei-divider>
  <tanrei-button variant="filled" toolbar-overflow="never">Publicar</tanrei-button>
</tanrei-toolbar>

<!-- Acoplada a lo largo del borde inferior de la pantalla. -->
<tanrei-toolbar variant="docked" label="Acciones del mensaje">
  <tanrei-button variant="text" label="Archivar"><span slot="icon">archive</span></tanrei-button>
  <tanrei-button variant="text" label="Eliminar"><span slot="icon">delete</span></tanrei-button>
  <tanrei-button variant="filled">Responder</tanrei-button>
</tanrei-toolbar>

<script type="module">
  import '@tanrei/web/components/toolbar';
  import '@tanrei/web/components/button';
  import '@tanrei/web/components/divider';
  import '@tanrei/web/components/menu';
  // Los elementos son tuyos: la barra de herramientas no añade eventos propios.
  document.querySelector('[label="Insertar enlace"]').addEventListener('click', insertLink);
  const insert = document.querySelector('tanrei-menu[anchor="insert"]');
  document.querySelector('#insert').addEventListener('click', () => (insert.open = !insert.open));
  insert.addEventListener('close', () => (insert.open = false));
</script>
import { Button, Divider, Toolbar, ToolbarGroup } from '@tanrei/react';

<Toolbar label="Formato" overflowLabel="Más opciones de formato">
  <ToolbarGroup label="Estilo del texto">
    <Button variant="text" toggle selected={bold} label="Negrita" onChange={(e) => setBold(e.detail.selected)}><span slot="icon">format_bold</span></Button>
    <Button variant="text" toggle selected={italic} label="Cursiva" onChange={(e) => setItalic(e.detail.selected)}><span slot="icon">format_italic</span></Button>
  </ToolbarGroup>
  <ToolbarGroup>
    <Button variant="text" label="Insertar enlace" onClick={insertLink}><span slot="icon">link</span></Button>
  </ToolbarGroup>
  <Divider />
  <Button variant="filled" toolbar-overflow="never" onClick={publish}>Publicar</Button>
</Toolbar>

<Toolbar variant="docked" label="Acciones del mensaje">
  <Button variant="text" label="Archivar" onClick={archive}><span slot="icon">archive</span></Button>
  <Button variant="filled" onClick={reply}>Responder</Button>
</Toolbar>
import Tanrei

// Una barra de herramientas acoplada se sitúa en el margen inferior del área segura; su fondo llega por debajo de él.
MessageView()
    .safeAreaInset(edge: .bottom, spacing: 0) {
        TanreiToolbar("Acciones del mensaje") {
            TanreiIconButton("Archivar", action: archive) { Image(systemName: "archivebox") }
            TanreiIconButton("Eliminar", action: delete) { Image(systemName: "trash") }
            TanreiButton("Responder", action: reply)
        }
    }

TanreiToolbar("Formato", variant: .floating) {
    TanreiIconButton("Negrita", isSelected: $bold) { Image(systemName: "bold") }
    TanreiIconButton("Insertar enlace", action: insertLink) { Image(systemName: "link") }
}
import androidx.compose.foundation.gestures.Orientation
import io.github.chnotchy.tanrei.components.TanreiButton
import io.github.chnotchy.tanrei.components.TanreiIconButton
import io.github.chnotchy.tanrei.components.TanreiToolbar
import io.github.chnotchy.tanrei.primitives.TanreiText
import io.github.chnotchy.tanrei.tokens.TanreiToolbarVariant

// Una barra de herramientas acoplada aplica a sus elementos el margen interior de WindowInsets.navigationBars salvo que pases windowInsets.
TanreiToolbar(contentDescription = "Acciones del mensaje") {
    TanreiIconButton(onClick = ::archive, contentDescription = "Archivar") { TanreiText("archive") }
    TanreiIconButton(onClick = ::delete, contentDescription = "Eliminar") { TanreiText("delete") }
    TanreiButton(text = "Responder", onClick = ::reply)
}

TanreiToolbar(contentDescription = "Formato", variant = TanreiToolbarVariant.Floating) {
    TanreiIconButton(onClick = {}, contentDescription = "Negrita", checked = bold, onCheckedChange = { bold = it }) {
        TanreiText("format_bold")
    }
    TanreiIconButton(onClick = ::insertLink, contentDescription = "Insertar enlace") { TanreiText("link") }
}

// La orientación vertical es para una barra de herramientas flotante; tu diseño la coloca.
TanreiToolbar(
    contentDescription = "Controles del mapa",
    variant = TanreiToolbarVariant.Floating,
    orientation = Orientation.Vertical,
) {
    TanreiIconButton(onClick = ::zoomIn, contentDescription = "Acercar") { TanreiText("add") }
    TanreiIconButton(onClick = ::zoomOut, contentDescription = "Alejar") { TanreiText("remove") }
}
import 'package:tanrei/tanrei.dart';

TanreiToolbar(
  semanticLabel: 'Acciones del mensaje',
  children: <Widget>[
    TanreiIconButton(onPressed: archive, semanticLabel: 'Archivar', icon: const Icon(AppSymbols.archive)),
    TanreiIconButton(onPressed: delete, semanticLabel: 'Eliminar', icon: const Icon(AppSymbols.delete)),
    TanreiButton(onPressed: reply, child: const Text('Responder')),
  ],
);

TanreiToolbar(
  semanticLabel: 'Controles del mapa',
  variant: TanreiToolbarVariant.floating,
  orientation: Axis.vertical,
  children: <Widget>[
    TanreiIconButton(onPressed: zoomIn, semanticLabel: 'Acercar', icon: const Icon(AppSymbols.add)),
    TanreiIconButton(onPressed: zoomOut, semanticLabel: 'Alejar', icon: const Icon(AppSymbols.remove)),
  ],
);
import { Button, IconButton, Toolbar } from '@tanrei/react-native';

// Los márgenes interiores inferior y laterales vienen de los insets de TanreiProvider; la propiedad insets de la propia barra de herramientas sustituye los lados que nombra.
<Toolbar accessibilityLabel="Acciones del mensaje">
  <IconButton accessibilityLabel="Archivar" onPress={archive}>archive</IconButton>
  <IconButton accessibilityLabel="Eliminar" onPress={remove}>delete</IconButton>
  <Button variant="filled" onPress={reply}>Responder</Button>
</Toolbar>

<Toolbar variant="floating" accessibilityLabel="Formato">
  <IconButton accessibilityLabel="Negrita" toggle selected={bold} onSelectedChange={setBold}>format_bold</IconButton>
  <IconButton accessibilityLabel="Insertar enlace" onPress={insertLink}>link</IconButton>
</Toolbar>

Especificaciones

Grupos y un separador, un botón de menú, un botón con menú, conmutadores con etiqueta y un menú de desbordamiento

undoredosortAbiertasAsignadas a míCon adjuntosarchivedeletemark_email_unreaddrive_file_movelabelflagsnoozeprintattach_fileimagelinkEnviaraddremovemy_locationlayers

Anatomía

Parte Descripción
1 container The surface that holds the items: none of its own in the default system where the toolbar stands inline in the content; a bar across the bottom edge of the screen whose color reaches under the bottom system inset (docked); or a rounded, raised surface over the content (floating).
2 items The controls, in reading order: the product's own Tanrei Buttons, icon-only and labelled, toggles among them, Buttons that open a Menu, and Buttons with menu, alone or in groups. The toolbar lays them out and moves keyboard focus among them; it does not restyle them.
3 separator · opcional A line across the toolbar between two groups, or where a separator item stands, or the empty space that takes its place, as the design system's separation says.
4 overflow-button · opcional The icon-only Button at the end that opens a Menu of the items that do not fit, drawn only while some do not.
5 outline The docked toolbar's top edge, or the edge around a floating or an inline toolbar's whole shape (none in the default system for the last two).

Propiedades

Propiedad Tipo Valor predeterminado Descripción
variant inline | docked | floating "inline" Inline stands in place where the layout puts it, as long as its items need and no longer than the layout allows, with no surface, shadow or edge of its own in the default system (an editor's formatting bar, a table's actions, a row of filters); docked is a full-width bar along the bottom edge of the screen, flush with it; floating is a rounded, raised surface over the content, as long as its items. One product places a toolbar inside its content on one screen, docks it on another and floats it on a third. A design system may add values.
orientation horizontal | vertical "horizontal" The direction the items run. Vertical is for an inline or a floating toolbar beside the content (a floating one on a large screen); a docked toolbar is always horizontal.
label string "" Names the toolbar for assistive technology ("Formatting", "Message actions"). Never drawn. Required.
overflow menu | scroll "menu" What happens when the items do not fit along the toolbar's axis: menu hides items from the end into an overflow menu at the end of the toolbar (TBR-18); scroll keeps every item and scrolls them (TBR-8).
overflowLabel string "" The overflow button's accessible name ("More actions"), in the product's language. Never drawn. Empty takes the product's words. Needed whenever the toolbar may be narrower than its items.
separation auto | divider | gap "auto" How two groups, or a separator item, set items apart: divider draws a line across the toolbar with space on each side, gap leaves empty space and no line. Auto takes comp.toolbar.separation, the design system's answer (divider in the default system).

Slots

Slot Descripción
default Holds the items, in reading order: Tanrei Buttons, icon-only and labelled, Buttons with a Tanrei Menu anchored to them (the Menu beside its Button), Buttons with menu, groups of them and separators.

Elementos

Los tipos de elemento que el componente repite. Un fixture enumera sus elementos en orden; cada plataforma nombra cada tipo según su propio estilo.

action

An icon action: a Button of the text variant and the medium size with an icon and no label, unless the product sets otherwise, laid out by the toolbar and not restyled; a toggle (bold, mute) is one with toggle set.

Propiedad Tipo Valor predeterminado Descripción
label string "" Its accessible name ("Bold"), as the Button's label. Required.
variant filled | tonal | elevated | outlined | text "text" As the Button's variant: text for most actions, filled for the one the toolbar leads to (Done, Send).
toggle boolean false As the Button's toggle: the action switches something on and off.
selected boolean false As the Button's selected: whether a toggle is on.
disabled boolean false As the Button's disabled.
overflow auto | never "auto" Whether the toolbar may hide this item into its overflow menu when space runs out: never keeps it (Send, Done). Read by the toolbar to place the item.
Slot Descripción
icon Its glyph, as the Button's icon slot. A fixture item's content is this glyph.
Evento Descripción
click The action was activated, as the Button's click.
change A toggle was switched, as the Button's change.
Especificación Web SwiftUI Jetpack Compose Flutter React Native
Elemento tanrei-button TanreiButton TanreiButton TanreiButton Button
label · Propiedad label label contentDescription semanticLabel accessibilityLabel
variant · Propiedad variant variant variant variant variant
toggle · Propiedad toggle isSelected onCheckedChange isSelected toggle
selected · Propiedad selected isSelected checked isSelected selected
disabled · Propiedad disabled disabled enabled onPressed disabled
overflow · Propiedad toolbar-overflow toolbarOverflow Modifier.toolbarOverflow TanreiToolbarItem.overflow toolbarOverflow
click · Evento click action onClick onPressed onPress
change · Evento change isSelected onCheckedChange onPressed onSelectedChange
Notas An icon-only <tanrei-button> child; the glyph is its content. An icon-only TanreiButton in the toolbar's view builder; a toggle is its isSelected: initializer. An icon-only TanreiButton called in the toolbar's content lambda. An icon-only TanreiButton in the toolbar's children. An icon-only Button element among the toolbar's children.

button

A labelled action: the button component, medium unless the product sets otherwise, laid out by the toolbar and not restyled.

Propiedad Tipo Valor predeterminado Descripción
variant filled | tonal | elevated | outlined | text "filled" As the button's variant.
toggle boolean false As the button's toggle: a labelled toggle (a filter that is on or off).
selected boolean false As the button's selected: whether a toggle is on.
disabled boolean false As the button's disabled.
overflow auto | never "auto" Whether the toolbar may hide this item into its overflow menu when space runs out: never keeps it (Send, Done). Read by the toolbar to place the item.
Slot Descripción
default Its label, as the button's default slot. A fixture item's content is this label.
Evento Descripción
click The button was activated, as the button's click.
change A toggle was switched, as the button's change.
Especificación Web SwiftUI Jetpack Compose Flutter React Native
Elemento tanrei-button TanreiButton TanreiButton TanreiButton Button
variant · Propiedad variant variant variant variant variant
toggle · Propiedad toggle isSelected onCheckedChange isSelected toggle
selected · Propiedad selected isSelected checked isSelected selected
disabled · Propiedad disabled disabled enabled onPressed disabled
overflow · Propiedad toolbar-overflow toolbarOverflow Modifier.toolbarOverflow TanreiToolbarItem.overflow toolbarOverflow
click · Evento click action onClick onPressed onPress
change · Evento change isSelected onCheckedChange onPressed onSelectedChange
Notas A <tanrei-button> child; the label is its content. A TanreiButton in the toolbar's view builder. A TanreiButton called in the toolbar's content lambda. A TanreiButton in the toolbar's children. A Button element among the toolbar's children.

menu-button

A Button that opens a Tanrei Menu anchored to it (Sort, Insert): icon-only unless the product sets otherwise, laid out by the toolbar as any other item and not restyled. The Menu is the product's, beside it in the toolbar; it is neither laid out nor an item.

Propiedad Tipo Valor predeterminado Descripción
label string "" Its accessible name ("Sort"), as the Button's label. Required.
variant filled | tonal | elevated | outlined | text "text" As the Button's variant.
disabled boolean false As the Button's disabled.
overflow auto | never "auto" Whether the toolbar may hide this item into its overflow menu when space runs out: never keeps it (Send, Done). Read by the toolbar to place the item.
Slot Descripción
icon Its glyph, as the Button's icon slot. A fixture item's content is this glyph.
Evento Descripción
click The button was activated, as the Button's click: the product opens its Menu.
Especificación Web SwiftUI Jetpack Compose Flutter React Native
Elemento tanrei-button TanreiButton TanreiButton TanreiButton Button
label · Propiedad label label contentDescription semanticLabel accessibilityLabel
variant · Propiedad variant variant variant variant variant
disabled · Propiedad disabled disabled enabled onPressed disabled
overflow · Propiedad toolbar-overflow toolbarOverflow Modifier.toolbarOverflow TanreiToolbarItem.overflow toolbarOverflow
click · Evento click action onClick onPressed onPress
Notas A <tanrei-button id> child with a <tanrei-menu anchor="<its id>"> beside it, in the toolbar or in the same group. A TanreiButton with .tanreiMenu { … } attached, in the toolbar's view builder. A TanreiButton with a TanreiMenu anchored to it, called in the toolbar's content lambda. A TanreiButton that opens a TanreiMenu anchored to it, in the toolbar's children. A Button with a Menu anchored to it, among the toolbar's children.

button-with-menu

A Button with menu: a main action and a menu of related ones, each half a stop of the toolbar's arrow keys (TBR-25), laid out by the toolbar and not restyled.

Propiedad Tipo Valor predeterminado Descripción
label string "" The leading half's label ("Save"), as the Button with menu's label.
menuLabel string "" The trailing half's accessible name ("More save options"), as the Button with menu's menuLabel.
variant filled | tonal | elevated | outlined "filled" As the Button with menu's variant.
disabled boolean false As the Button with menu's disabled.
overflow auto | never "auto" Whether the toolbar may hide this item into its overflow menu when space runs out: never keeps it (Send, Done). Read by the toolbar to place the item.
Evento Descripción
click The main action was activated, as the Button with menu's click.
toggle The trailing half asks to open or close the menu, as the Button with menu's toggle.
Especificación Web SwiftUI Jetpack Compose Flutter React Native
Elemento tanrei-button-with-menu TanreiButtonWithMenu TanreiButtonWithMenu TanreiButtonWithMenu ButtonWithMenu
label · Propiedad label title text label label
menuLabel · Propiedad menuLabel menuLabel menuContentDescription menuSemanticLabel menuAccessibilityLabel
variant · Propiedad variant variant variant variant variant
disabled · Propiedad disabled disabled enabled onPressed disabled
overflow · Propiedad toolbar-overflow toolbarOverflow Modifier.toolbarOverflow TanreiToolbarItem.overflow toolbarOverflow
click · Evento click action onClick onPressed onPress
toggle · Evento toggle isMenuPresented onMenuExpandedChange menuController onToggle
Notas A <tanrei-button-with-menu> child, its menu items in slot="menu" as anywhere. A TanreiButtonWithMenu in the toolbar's view builder. A TanreiButtonWithMenu called in the toolbar's content lambda. A TanreiButtonWithMenu in the toolbar's children. A ButtonWithMenu among the toolbar's children.

group · grupo: contiene elementos

A run of related items (Bold, Italic, Underline), optionally named; the toolbar sets it apart from what is next to it as separation says. It draws nothing of its own.

Propiedad Tipo Valor predeterminado Descripción
label string "" Names the group for assistive technology ("Text style"); never drawn. Empty leaves the group unexposed: its items are the toolbar's.
Especificación Web SwiftUI Jetpack Compose Flutter React Native
Elemento tanrei-toolbar-group TanreiToolbarGroup TanreiToolbarGroup TanreiToolbarGroup ToolbarGroup
label · Propiedad label label contentDescription semanticLabel accessibilityLabel
Notas A <tanrei-toolbar-group> child holding items: display: contents, with role="group" and aria-label while its label is not empty. TanreiToolbarGroup(_ label:) { items } in the toolbar's view builder: an accessibility container named by its label, or none without one. TanreiToolbarGroup(contentDescription) { … } in the toolbar's content lambda: a traversal group named by its description, or none without one. TanreiToolbarGroup(semanticLabel:, children:) in the toolbar's children: a semantics container named by its label, or none without one. <ToolbarGroup accessibilityLabel>{items}</ToolbarGroup> among the toolbar's children: a view with role group while it has a label.

separator

A line across the toolbar between two items outside the groups: the toolbar draws it as it draws the line between two groups, and it is never a stop of the arrow keys.

Especificación Web SwiftUI Jetpack Compose Flutter React Native
Elemento tanrei-divider TanreiDivider TanreiDivider TanreiDivider Divider
Notas A <tanrei-divider> child: the toolbar draws the line itself, as between two groups (TBR-23), as an element of its own with role="separator", and leaves the divider unassigned. A TanreiDivider() in the toolbar's view builder; the toolbar draws the line from its own tokens. A TanreiDivider() called in the toolbar's content lambda; the toolbar draws the line from its own tokens. A TanreiDivider() in the toolbar's children; the toolbar draws the line from its own tokens. A Divider among the toolbar's children; the toolbar draws the line from its own tokens.

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
TBR-1 WHILE variant is docked THE toolbar SHALL span the full width of its parent, be at least comp.toolbar.container.size.docked high above the bottom system inset, fill its container with comp.toolbar.container.color.docked, raise it by comp.toolbar.container.elevation.docked, round it by comp.toolbar.container.shape.docked, and draw its top edge comp.toolbar.outline.width thick in comp.toolbar.outline.color.docked.
TBR-2 WHILE variant is docked THE toolbar SHALL lay its items out in one row in reading order, the first comp.toolbar.container.padding-inline.docked from the start edge and the last as far from the end edge, with equal space between neighbours and never less than comp.toolbar.container.gap.docked, each item vertically centered in the row; a toolbar with one item SHALL center it.
TBR-3 WHILE variant is docked THE toolbar SHALL extend its container under the bottom system inset (home indicator, gesture bar, taskbar) and SHALL place its items above that inset and inside the left and right insets, so that its color reaches the screen's bottom edge while no item sits under a system bar.
TBR-4 WHILE variant is floating THE toolbar SHALL fill its container with comp.toolbar.container.color.floating, raise it by comp.toolbar.container.elevation.floating, round it by comp.toolbar.container.shape.floating eased by sys.shape.corner-smoothing, draw an edge comp.toolbar.outline.width thick in comp.toolbar.outline.color.floating around its whole shape, be as long along its axis as its items need — comp.toolbar.container.padding-inline.floating at each end and comp.toolbar.container.gap.floating between neighbours, or as much more as TBR-16 keeps for their targets — and at least comp.toolbar.container.size.floating across it, with every item centered across the axis.
TBR-5 WHILE variant is floating THE toolbar SHALL NOT position itself: it SHALL lay out at its own size where the layout that holds it places it (normally centered above the bottom edge of the content, clear of a navigation bar and of the system inset, or beside the content's end edge for a vertical toolbar), and SHALL NOT draw a scrim, move content or reach under a system inset.
TBR-6 WHILE orientation is vertical and variant is floating or inline THE toolbar SHALL stack its items from top to bottom in the order given, with its variant's paddings and gap along the vertical axis and at least its variant's container size as its width; WHILE orientation is vertical and variant is docked THE toolbar SHALL lay out as a horizontal docked toolbar and in debug builds report that a docked toolbar is horizontal.
TBR-7 WHEN the layout direction is right-to-left THE toolbar SHALL lay out a horizontal toolbar's items from the right edge, in reading order, mirrored; a vertical toolbar SHALL keep its top-to-bottom order.
TBR-8 WHILE overflow is scroll and the items need more length than the toolbar has along its axis THE toolbar SHALL keep every item at its own size and the gap at its minimum, SHALL scroll its items along its axis so that every item stays reachable, and SHALL bring an item that receives keyboard focus fully into view; it SHALL NOT wrap, shrink or hide an item.
TBR-9 THE toolbar SHALL NOT restyle its items: each SHALL render as the Button it is, from its own tokens, variant and size, and SHALL keep its own press, focus, target and disabled behaviour and its own semantics, a toggle Button staying a toggle. Between two items the hit areas SHALL never overlap (as BGR-4): in a docked toolbar they SHALL meet at the middle of the gap, and in a floating or an inline one where the lengths TBR-16 keeps for the two items meet; each item SHALL keep its full target on every side that has no neighbour. In a docked toolbar the gap (at least comp.toolbar.container.gap.docked) is what keeps an item's target whole between its neighbours: at sys.target.touch minus the item's length or more, every item keeps its full target there, as the default system's gap does for every Button size; a layer that narrows that gap narrows the targets between items. In a floating or an inline toolbar TBR-16 keeps it, whatever comp.toolbar.container.gap.floating or comp.toolbar.container.gap.inline is.
TBR-10 THE toolbar SHALL be one Tab stop: the item that had keyboard focus last, or else the first item that is not disabled. Its items are its own and its groups' items, in reading order; a separator and a Menu anchored to an item are none. WHILE an item has keyboard focus, Right Arrow and Left Arrow in a horizontal toolbar (Left Arrow moving to the next item in a right-to-left layout) and Down Arrow and Up Arrow in a vertical one SHALL move focus to the next and previous item that is not disabled, wrapping at the ends, and Home and End to the first and last such item; moving focus SHALL NOT activate an item, and Enter and Space SHALL act on the focused item as that item does. A disabled item SHALL NOT take focus, as its own spec says (BTN-2).
TBR-11 THE toolbar SHALL expose itself as a toolbar named by label, with its orientation, on a platform that has a toolbar role, and on any other platform as a group named by label that contains its items in order; each item SHALL keep its own name, role and state, and the toolbar SHALL add nothing to them.
TBR-12 WHILE label is empty THE toolbar SHALL still render, and in debug builds report that it has no accessible name. IF the toolbar holds no item, or an element that is neither one of its item kinds nor a Menu anchored to one of its items, THE toolbar SHALL still lay it out, and in debug builds report it, because a field or a slider would take the arrow keys the toolbar moves focus with (the WAI-ARIA toolbar pattern).
TBR-13 WHEN variant names a value that the active design system does not have, or orientation a value the component does not define, THE toolbar SHALL render with the default value (inline, horizontal), and in debug builds report the unknown value. A variant value that a layer adds SHALL take the inline structure with its own values, because the structure is not a value a layer can set. WHEN overflow or separation names a value the component does not define THE toolbar SHALL render with menu or auto, and in debug builds report it.
TBR-14 WHILE the text size is enlarged THE toolbar SHALL grow across its axis to hold its items (its size is a minimum) and SHALL NOT scale its items itself; each item grows or keeps its size as its own spec says.
TBR-15 THE toolbar 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 toolbar is shown THE toolbar SHALL draw itself for the new direction at once, without a motion of its own, keeping its focus and the item its Tab stop stands on.
TBR-16 WHILE variant is floating THE toolbar SHALL lay its items comp.toolbar.container.gap.floating apart (and WHILE it is inline comp.toolbar.container.gap.inline apart, TBR-17), measured between their visible bounds along its axis, and SHALL move two neighbours further apart only as far as each needs in order to keep, centred on itself, a length of sys.target.touch along the axis that its neighbour's does not reach into, because items that stand this close cannot extend a hit area over each other (as BGR-3): where the token is 0, as in the default system, an item at least sys.target.touch long touches its neighbour, and a shorter one stands half of what it lacks away from it. THE toolbar SHALL NOT widen, resize or restyle an item to do so (TBR-9), SHALL space its items the same whatever the input type, so that the toolbar does not change with the pointer, and SHALL space them so along the vertical axis WHILE orientation is vertical (TBR-6). A floating toolbar is as long as its items need (TBR-4) and never spreads them across a width; WHILE variant is docked THE toolbar SHALL spread its items across its width and keep comp.toolbar.container.gap.docked as the least space between them (TBR-2), unchanged.
TBR-17 WHILE variant is inline THE toolbar SHALL lay its items out in one line along its axis where the layout places it, as long as its items need and never longer than the layout allows, with comp.toolbar.container.padding-inline.inline at each end, comp.toolbar.container.gap.inline between neighbours spaced as TBR-16 spaces a floating toolbar's, and at least comp.toolbar.container.size.inline across its axis; it SHALL fill its container with comp.toolbar.container.color.inline, raise it by comp.toolbar.container.elevation.inline, round it by comp.toolbar.container.shape.inline and edge it comp.toolbar.outline.width thick in comp.toolbar.outline.color.inline (transparent, none and no edge in the default system), and SHALL NOT read a system inset, position itself or spread its items.
TBR-18 WHILE overflow is menu and the items, at their own sizes and with the least gaps, need more length along the axis than the layout offers the toolbar — the length it would take with every item shown, which a parent as long as its content passes on from further up, so that it can grow while the toolbar and its parent stay as long as the items still shown — THE toolbar SHALL hide items from its end, in reverse reading order and one at a time, skipping every item whose overflow is never, until the items that remain and the overflow button fit; SHALL draw the overflow button after the last item that remains — an icon-only Tanrei Button of the text variant and the medium size, showing the glyph more_horiz in a horizontal toolbar and more_vert in a vertical one, named by overflowLabel or the product's words, exposed as a button that opens a menu, with its expanded state; and SHALL NOT hide an item whose overflow is never even when the items then do not fit, in which case TBR-8 applies to what remains.
TBR-19 THE toolbar SHALL decide which items are hidden before the first frame in which it is drawn, and again in the frame in which its items or the length the layout offers it (TBR-18) change, so that no item is drawn and then hidden in a later frame, and its size across its axis never changes because an item was hidden or shown; hiding and showing items SHALL NOT be animated, because it answers a change of the layout that a motion would lag behind.
TBR-20 WHEN the overflow button is activated THE toolbar SHALL open a Tanrei Menu anchored to it, placed bottom-end (in a vertical toolbar, at the side away from the edge it stands at), holding the hidden items in reading order: an action or a labelled Button as a menu item with its label and its icon, disabled while it is; a toggle as a checkbox item with its selected state; a menu button as a submenu item holding its menu's items; a Button with menu as an item for its main action followed by a submenu item named by its menuLabel; and a separator, or the boundary between two groups, as the menu's separation. Activating a menu item SHALL do exactly what activating the hidden item does — the same click or change, once, from that item — and close the menu.
TBR-21 WHEN the item that is the toolbar's Tab stop, or has keyboard focus, is hidden THE toolbar SHALL make the overflow button the Tab stop and, if focus was on the item, move focus to the overflow button; THE overflow button SHALL be the last stop of the arrow-key order (TBR-10).
TBR-22 THE toolbar SHALL lay out a group's items in its own line, in place, as items of the toolbar (the group draws nothing of its own), SHALL expose a group whose label is not empty as a group named by that label, and a group whose label is empty as nothing (its items are the toolbar's), unless the product names it (TBR-26).
TBR-23 THE toolbar SHALL set two neighbouring groups — or a group and an item outside any group — apart as separation names: WHILE it is divider by a line comp.toolbar.divider.thickness thick and comp.toolbar.divider.length long across the axis, centred, in comp.toolbar.divider.color, with comp.toolbar.group.gap on each side; WHILE it is gap by twice comp.toolbar.group.gap of empty space. A separator item SHALL be drawn the same way wherever it stands. THE toolbar SHALL expose each such line as a separator, SHALL never make it a stop of the arrow keys, and SHALL draw no line at the start or the end of the toolbar, and never two lines side by side.
TBR-24 WHILE an item is the anchor of a Menu THE toolbar SHALL keep it an item of the arrow-key order and SHALL neither lay out nor count the Menu; WHILE that Menu is open its keys SHALL be the Menu's, and WHEN it closes focus SHALL return to its anchor, which stays the Tab stop.
TBR-25 THE toolbar SHALL make each half of a Button with menu a stop of its own in the arrow-key order, the leading half first in reading order, each keeping its own name, role and state.
TBR-26 WHERE the platform has ARIA attributes (the web), the toolbar's host and a group's host carries its role (TBR-11, TBR-22) itself, so what the product writes on it is not moved, but for a name: WHILE label is not empty THE toolbar SHALL hold the product's aria-label and aria-labelledby on that host as their data-aria- twins, so that label is its whole name although the platform gives aria-labelledby the precedence, and WHEN label is emptied SHALL give them back as they were written; WHILE label is empty a name the product gives so — aria-label, or aria-labelledby naming an element — SHALL be its name and SHALL NOT be reported as having none in debug builds (TBR-12). A group whose label is empty and that the product names so SHALL be exposed as a group named by that name, as one with a label is: a group the product names is a named group, and a name on an element with no role would name nothing (TBR-22). WHEN the product removes one, or its data-aria- twin, or sets the ARIA property that reflects it (ariaLabel, ariaLabelledByElements) to null, THE toolbar SHALL take it away.

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-toolbar TanreiToolbar TanreiToolbar TanreiToolbar Toolbar
variant · Propiedad variant variant variant variant variant
orientation · Propiedad orientation orientation orientation orientation orientation
label · Propiedad label label contentDescription semanticLabel accessibilityLabel
overflow · Propiedad overflow overflow overflow overflow overflow
overflowLabel · Propiedad overflowLabel overflowLabel overflowContentDescription overflowSemanticLabel overflowAccessibilityLabel
separation · Propiedad separation separation separation separation separation
Notas The items are <tanrei-button> children, icon-only and labelled, <tanrei-button-with-menu> children, <tanrei-toolbar-group> children holding them, and <tanrei-divider> separators; a <tanrei-menu anchor> child anchored to an item's id is that item's Menu and is not laid out. The host has role="toolbar", aria-orientation and aria-label from label; a group with a label has role="group" and aria-label. The toolbar assigns each of its children, and a group each of its items, to a slot of its own (manual slot assignment), so that the toolbar draws the separations between them and leaves a hidden item unassigned: a hidden item is not drawn and keeps its place, its listeners and its state in the page. The overflow button and its menu are elements of the toolbar's shadow root. The roving Tab stop sets tabindex on the item elements (0 on the Tab stop, -1 on the others): an item delegates focus to the button in its shadow root, and a host whose tabindex is -1 takes that button out of the Tab order; a Button with menu is told which of its halves is the Tab stop through the internal channel (SPB-33). A docked toolbar's bottom inset is env(safe-area-inset-bottom). Snapshot harness: the stages of TBR-1, TBR-4, TBR-6 and TBR-18. TanreiToolbar(_ label: String, variant:, orientation:) { items }, a view builder of TanreiButtons, icon-only and labelled. A docked toolbar is placed with .safeAreaInset(edge: .bottom), its background ignoring the bottom safe area. SwiftUI's own .toolbar with a bottom-bar placement is not used: its bar cannot take the tokens. SwiftUI has no toolbar role: the toolbar is an accessibility container (.accessibilityElement(children: .contain)) labelled by label. The roving Tab stop is one focus group for the keyboard: Full Keyboard Access moves among its items with the arrow keys and leaves it with Tab. Lagging: the inline variant, the overflow menu, groups, separators, menu buttons and Buttons with menu as items are not built on this platform yet; it draws the docked and floating toolbar of icon-only and labelled Buttons, docked by default. .toolbarOverflow(.never) on an item keeps it; the overflow menu is a SwiftUI Menu drawn from the Tanrei Menu's tokens. TanreiToolbar(contentDescription, modifier, variant, orientation, windowInsets) { … }, the items called in its content lambda. windowInsets defaults to WindowInsets.navigationBars for a docked toolbar and to none for a floating one. Compose has no toolbar role: the toolbar is a traversal group (isTraversalGroup) labelled by contentDescription, and the README says so. The roving Tab stop is TanreiRovingFocus, the primitive the list, menu and tabs use, horizontal or vertical by orientation; the toolbar registers each item it holds. Lagging: the inline variant, the overflow menu, groups, separators, menu buttons and Buttons with menu as items are not built on this platform yet; it draws the docked and floating toolbar of icon-only and labelled Buttons, docked by default. Modifier.toolbarOverflow(TanreiToolbarOverflow.Never) on an item keeps it; the overflow menu is a TanreiMenu. TanreiToolbar(semanticLabel:, variant:, orientation:, children: [...]) (orientation is Flutter's Axis). A docked toolbar applies the bottom MediaQuery.padding itself, as SafeArea would, with its color under it. Flutter's widgets library has no toolbar role: the toolbar is a Semantics(container: true, explicitChildNodes: true, label:), and the README says so. The roving Tab stop is TanreiItemGroupMixin, the primitive the list, menu and tabs use, with its item axis set by orientation. Lagging: the inline variant, the overflow menu, groups, separators, menu buttons and Buttons with menu as items are not built on this platform yet; it draws the docked and floating toolbar of icon-only and labelled Buttons, docked by default. An item wrapped in TanreiToolbarItem(overflow: TanreiToolbarOverflow.never, child:) is kept; the overflow menu is a TanreiMenu. <Toolbar variant orientation accessibilityLabel insets>{items}</Toolbar>, the items being Button elements, icon-only and labelled. The view has role="toolbar". A docked toolbar takes the bottom inset from its own insets prop, falling back to TanreiProvider's insets; the package takes no safe-area dependency. The roving Tab stop and the arrow keys work where a hardware keyboard is attached, as the tabs row's do. Lagging: the inline variant, the overflow menu, groups, separators, menu buttons and Buttons with menu as items are not built on this platform yet; it draws the docked and floating toolbar of icon-only and labelled Buttons, docked by default. toolbarOverflow="never" on an item keeps it; the overflow menu is a Menu.

Tokens

Token Alias de Valor resuelto (claro)
--tanrei-comp-toolbar-container-color-docked sys.color.surface #ffffff
--tanrei-comp-toolbar-container-color-floating sys.color.surface-bright #ffffff
--tanrei-comp-toolbar-container-color-inline — #000000 · 0%
--tanrei-comp-toolbar-container-elevation-docked sys.elevation.level0
--tanrei-comp-toolbar-container-elevation-floating sys.elevation.level3 0px 0px 0px 1px rgb(0 0 0 / 0.08), 0px 1px 1px 0px rgb(0 0 0 / 0.04), 0px 4px 8px -4px rgb(0 0 0 / 0.04), 0px 16px 24px -8px rgb(0 0 0 / 0.06)
--tanrei-comp-toolbar-container-elevation-inline sys.elevation.level0
--tanrei-comp-toolbar-container-gap-docked — 16px
--tanrei-comp-toolbar-container-gap-floating sys.space.space0 0px
--tanrei-comp-toolbar-container-gap-inline sys.space.space50 4px
--tanrei-comp-toolbar-container-padding-inline-docked sys.space.space200 16px
--tanrei-comp-toolbar-container-padding-inline-floating sys.space.space150 12px
--tanrei-comp-toolbar-container-padding-inline-inline sys.space.space0 0px
--tanrei-comp-toolbar-container-shape-docked sys.shape.corner.none 0px
--tanrei-comp-toolbar-container-shape-floating sys.shape.corner.full 9999px
--tanrei-comp-toolbar-container-shape-inline sys.shape.corner.medium 8px
--tanrei-comp-toolbar-container-size-docked — 64px
--tanrei-comp-toolbar-container-size-floating — 64px
--tanrei-comp-toolbar-container-size-inline — 40px
--tanrei-comp-toolbar-divider-color sys.color.outline-variant #000000 · 8%
--tanrei-comp-toolbar-divider-length sys.space.space300 24px
--tanrei-comp-toolbar-divider-thickness sys.border.hairline 1px
--tanrei-comp-toolbar-group-gap sys.space.space100 8px
--tanrei-comp-toolbar-outline-color-docked sys.color.outline-variant #000000 · 8%
--tanrei-comp-toolbar-outline-color-floating — #000000 · 0%
--tanrei-comp-toolbar-outline-color-inline — #000000 · 0%
--tanrei-comp-toolbar-outline-width sys.border.hairline 1px
--tanrei-comp-toolbar-separation sys.behavior.separation 0

Fixtures

Representaciones canónicas. Todas las plataformas capturan cada fixture con el mismo identificador para poder comparar los resultados.

Generado a partir de specs/toolbar.spec.json, tokens/comp/toolbar.tokens.json, design/tokens/

Pautas

Cuándo usarlo

Usa una barra de herramientas para un conjunto de controles que actúan sobre lo que la persona tiene delante: Negrita, Cursiva y Enlace encima de un editor; Filtrar, Ordenar y Descargar encima de una tabla; Archivar, Eliminar y Mover para un mensaje abierto; un lápiz y una goma de borrar sobre un dibujo; el zoom y la ubicación en un mapa. Los controles actúan sobre el contenido o la selección actual, no sobre adónde va la persona después.

Para el título de la pantalla, el camino de vuelta y una o dos acciones globales, usa la barra de la aplicación en la parte superior. Para moverte entre los destinos de primer nivel de una aplicación, usa la barra de navegación. Una barra de herramientas acoplada y una barra de navegación nunca comparten pantalla: ambas reclaman el borde inferior.

En línea, acoplada o flotante

Variante Dónde se sitúa Elementos Úsala para
En línea (predeterminada) En su sitio dentro del contenido, donde la pone tu diseño, sin superficie propia en el sistema predeterminado Juntos, tan larga como necesiten, y cada uno con sitio para su propio objetivo táctil Los controles de una parte de la página: el formato de un editor, las acciones de una tabla, una fila de filtros
Acoplada A lo largo del borde inferior, pegada a él, con su color llegando por debajo de la barra del sistema Repartidos a lo ancho, con el mismo espacio entre ellos Las acciones de una pantalla de detalle en un teléfono: un mensaje abierto, una foto, un documento
Flotante Una superficie redondeada y elevada sobre el contenido, colocada por tu diseño Juntos, tan larga como necesiten, y cada uno con sitio para su propio objetivo táctil Herramientas sobre un contenido que debe seguir visible a su alrededor: un lienzo, un mapa

Una barra de herramientas acoplada siempre es horizontal. Una en línea o una flotante puede ser vertical, junto al contenido. Un mismo producto puede poner una barra de herramientas en línea en una pantalla, acoplar otra en una segunda y hacer flotar otra en una tercera. Una variante que añade un sistema de diseño toma la estructura de la barra en línea con sus propios valores.

Una barra de herramientas acoplada reparte sus elementos a lo ancho y nunca los acerca más que su separación (16 en el sistema predeterminado). Una barra de herramientas en línea o flotante junta sus elementos: dos vecinos se separan solo lo que cada uno necesita para conservar un objetivo táctil propio a lo largo de la fila, y nunca menos que la separación (4 en línea y 0 flotante en el sistema predeterminado). Los botones grandes se tocan, los medianos quedan a 8 y los pequeños a 16. La barra de herramientas nunca ensancha un elemento ni le cambia el estilo para lograrlo, y el espaciado es el mismo para un ratón y para el tacto.

Flotante: elementos small, medium y large, y elementos narrow y wide

format_boldformat_italicformat_underlinedformat_boldformat_italicformat_underlinedformat_boldformat_italicformat_underlinedundoredoeditink_erasercheck

Elementos

  • Usa Buttons de solo icono de la variante text para la mayoría de las acciones. Da más peso a la única acción a la que conduce la barra de herramientas, como Enviar o Listo: un botón filled de solo icono, quizá con el ancho wide, o un botón filled con etiqueta cuando una palabra se lee mejor que un icono.
  • Un botón de solo icono narrow conviene a una barra de herramientas con muchas acciones pequeñas. Se dibuja más estrecho que su objetivo, y la barra de herramientas reserva sitio para el objetivo entre sus vecinos.
  • Haz de una acción que activa y desactiva algo (Negrita, Silenciar) un botón de solo icono con toggle. Un filtro que está activado o desactivado es un botón con etiqueta y toggle. Cada uno conserva su propio estado seleccionado y su propio anuncio.
  • Para un control que ofrece a elegir entre varios comandos, ancla un menú a un Button de la barra de herramientas. Para una acción principal con variantes, como Guardar y Guardar como, usa un botón con menú.
  • Mantén estable el orden. Las personas encuentran las acciones por su posición, y una barra de herramientas cuyos elementos se mueven de una pantalla a otra es difícil de aprender.
  • Una barra de herramientas acoplada con un solo elemento lo centra. Piensa si ese elemento no debería estar más bien en el contenido.

Grupos y separadores

Pon los elementos relacionados en un grupo: Negrita, Cursiva y Subrayado; Deshacer y Rehacer; Acercar y Alejar. La barra de herramientas separa dos grupos, y un grupo de un elemento que no está en ningún grupo, igual que el sistema de diseño separa las partes en otros lugares: en el sistema predeterminado, con una línea corta y 8 de espacio a cada lado, o, con un sistema de diseño que separa con espacio, con 16 de espacio vacío y sin línea. Define separation en una barra de herramientas solo por un motivo propio. Un elemento separador dibuja la misma línea entre dos elementos que no están en grupos.

La barra de herramientas nunca dibuja una línea en ninguno de sus extremos, ni dos seguidas. Da a un grupo un label cuando la agrupación signifique algo para la persona («Estilo del texto»), para que un lector de pantalla le dé nombre. Sin etiqueta, el grupo separa sus elementos y no dice nada.

Cuando los elementos no caben

La barra de herramientas nunca hace saltar de línea ni encoge un elemento. Cuando sus elementos necesitan más sitio del que tiene, oculta elementos desde el final, de uno en uno, y muestra un botón de desbordamiento después del último elemento que queda. El botón abre un menú con los elementos ocultos, en su orden, con sus etiquetas, iconos y estados: una acción es un elemento de menú, un conmutador un elemento de casilla de verificación, un botón de menú un submenú, y un botón con menú su acción principal seguida de un submenú. Elegir uno hace exactamente lo que hace el elemento oculto. Da nombre al botón de desbordamiento con overflow-label («Más acciones»), o una sola vez para todo el producto con setWords({ toolbarOverflowLabel: … }).

Marca el elemento que debe quedarse, como Enviar o Listo, con toolbar-overflow="never": la barra de herramientas oculta en su lugar los elementos que tiene delante. Si lo que nunca se oculta sigue sin caber, el resto de la fila se desplaza. Para mantener todos los elementos en la fila y desplazarlos en lugar de ocultar ninguno, define overflow="scroll".

Lo que se oculta se decide antes de dibujar la barra de herramientas, y de nuevo en el fotograma en el que cambia su longitud, así que un elemento nunca se dibuja para ocultarse después, y la fila nunca salta.

Recomendado

  • Da nombre a la barra de herramientas según lo que hacen sus controles: «Formato», «Acciones del mensaje».
  • Deshabilita una acción que no se puede aplicar en ese momento en lugar de quitarla, para que las demás no se muevan.
  • Ordena los elementos de modo que los que las personas más necesitan vayan primero: la barra de herramientas oculta desde el final.
  • Coloca una barra de herramientas flotante de modo que no tape el contenido que las personas necesitan ver mientras la usan, ni una barra de navegación ni el margen interior del sistema.

Evita

  • No pongas un campo de texto, un control deslizante ni un conjunto de chips en una barra de herramientas. Cada uno necesita las teclas de flecha que la barra de herramientas usa para mover el foco. La búsqueda va en la barra de la aplicación o en la página.
  • No uses una barra de herramientas acoplada y una barra de navegación en la misma pantalla.
  • No cambies el estilo de los elementos para que la barra de herramientas parezca destacada. Elige en su lugar la variante tonal o filled para los botones.
  • No pongas destinos de navegación en una barra de herramientas. Sus elementos son controles que actúan sobre el contenido.

Accesibilidad

Rol
toolbar
Etiquetado
label names the toolbar; it is never drawn. A group's label names the group; empty leaves it unexposed. Each item is named by its own label (an icon-only Button's label, a labelled Button's text), and the overflow button by overflowLabel or the product's words. The toolbar adds no name, role or state to its items.
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 into the toolbar (to the item focused last, or the first enabled item) and out of it: the toolbar is one Tab stop.
Right Arrow / Left Arrow (horizontal), Down Arrow / Up Arrow (vertical) Moves focus to the next or previous enabled item — a group's items and each half of a Button with menu included, separators skipped, the overflow button last — wrapping at the ends (Left and Right mirrored in right-to-left layouts).
Home / End Moves focus to the first or last enabled item.
Enter / Space Activates the focused item, as that Button does; on the overflow button, opens the menu of the hidden items.

Notas

  • The toolbar has no target of its own and takes no input: its items are the product's Buttons, icon-only and labelled, which meet the minimum target themselves (BTN-5). A medium item's target (48) fits inside a floating toolbar's 64, and reaches past an inline toolbar's 40 as a Button's does anywhere.
  • The web has the toolbar role (with aria-orientation) and React Native has role toolbar. SwiftUI, Compose and Flutter have no toolbar role: there the toolbar is a group (an accessibility container, a traversal group, a semantics container) named by label, and each README says so.
  • One Tab stop with arrow-key movement is the WAI-ARIA toolbar pattern. It uses the same roving focus the list, menu and tabs use on each platform; a Button outside a toolbar is unchanged.
  • A toolbar holds Buttons, menu buttons, Buttons with menu, groups of them and separators. Anything else is laid out and reported (TBR-12), because a control that uses the arrow keys would take the keys the toolbar moves focus with.
  • A docked toolbar and a navigation bar are not used on the same screen: both claim the bottom edge.
  • How the items look is their own design system's answer; the toolbar reads no state tokens.
  • Hidden items stay reachable: the overflow button is the last stop of the arrow keys, and its menu holds every hidden item with its own name and state; activating one is activating the item.

Generado a partir de specs/toolbar.spec.json, tokens/sys/measure.tokens.json

De qué se encarga el componente

  • La barra de herramientas es una sola parada de tabulación, según el patrón de barra de herramientas de WAI-ARIA. Tab entra en ella por el elemento que tuvo el foco del teclado por última vez o, si no, por el primer elemento que no esté deshabilitado, y el siguiente Tab sale de ella. Cruzar una barra de formato de ocho conmutadores cuesta una pulsación de Tab, no ocho.
  • Dentro, las teclas de flecha de su eje llevan al elemento siguiente o al anterior y pasan de un extremo al otro: Flecha derecha y Flecha izquierda en una barra de herramientas horizontal, Flecha abajo y Flecha arriba en una vertical. Inicio y Fin llevan al primer y al último elemento. En un diseño de derecha a izquierda, Flecha izquierda lleva al elemento siguiente. Los elementos de un grupo son elementos de la barra de herramientas, cada mitad de un botón con menú es una parada propia, los separadores se saltan y el botón de desbordamiento es la última parada.
  • Mover el foco nunca activa un elemento. Enter y Espacio actúan sobre el elemento con foco como lo hace ese elemento, así que un conmutador sigue conmutando.
  • Mientras está abierto un menú anclado a un elemento, las teclas son del menú. Cuando se cierra, el foco vuelve al elemento desde el que se abrió.
  • Cuando el elemento que tiene el foco se oculta porque la barra de herramientas se ha estrechado, el foco pasa al botón de desbordamiento.
  • Las teclas de flecha se saltan los elementos deshabilitados, que nunca son la parada de tabulación, porque un botón deshabilitado no puede recibir el foco.
  • El foco itinerante es el mismo que usan la lista, el menú y las pestañas en cada plataforma.
  • La barra de herramientas se expone como una barra de herramientas que recibe su nombre de label, con su orientación, donde la plataforma tiene un rol de barra de herramientas (la web, React Native). SwiftUI, Compose y Flutter no lo tienen: allí es un grupo que recibe su nombre de label y contiene sus elementos en orden.
  • Un grupo con label se expone como un grupo con ese nombre. Las líneas entre grupos se exponen como separadores.
  • El botón de desbordamiento se expone como un botón que abre un menú, con su estado expandido, y su menú contiene cada elemento oculto con su propio nombre y estado.
  • Cada elemento conserva su propio nombre, rol, estado y objetivo. La barra de herramientas no les añade nada y nunca les cambia el estilo.
  • Entre dos elementos, las áreas de pulsación nunca se solapan. En una barra de herramientas acoplada se encuentran en la mitad de la separación, y la separación del sistema predeterminado (16) es lo bastante ancha para que cada elemento conserve también allí su objetivo táctil completo de 48; un sistema de diseño con una separación más estrecha estrecha los objetivos entre elementos. En una barra de herramientas en línea o flotante, los elementos se separan justo lo necesario para que cada uno conserve a lo largo de la fila la longitud de un objetivo táctil propio, sea cual sea el puntero, de modo que sus vecinos nunca aprietan un botón estrecho o pequeño. En un lado sin vecino, un elemento conserva su objetivo completo.
  • Cuando overflow es scroll y un elemento que recibe el foco del teclado está fuera de la vista por el desplazamiento, la barra de herramientas lo desplaza hasta dejarlo completamente a la vista.
  • Con tamaños de texto mayores, la barra de herramientas crece en perpendicular a su eje para contener sus elementos. No los escala.
  • Las compilaciones de depuración notifican un label que falta, una barra de herramientas sin elementos, un elemento que no es de ninguno de sus tipos, una barra de herramientas acoplada definida como vertical, un nombre que falta para el botón de desbordamiento y una variante, una orientación, un overflow o una separation desconocidos.

Carencias conocidas por plataforma:

  • SwiftUI, Compose y Flutter no tienen rol de barra de herramientas. Un lector de pantalla oye un grupo con nombre, no una barra de herramientas, y el README de cada paquete lo dice. El grupo no expone su orientación.
  • SwiftUI, Compose, Flutter y React Native van rezagados: no tienen la variante en línea, ni grupos ni separadores, ni menú de desbordamiento, y solo aceptan Buttons como elementos.
  • Web: una barra de herramientas acoplada lee env(safe-area-inset-bottom), que es cero salvo que la etiqueta meta viewport de la página tenga viewport-fit=cover.
  • Web: el menú de desbordamiento de una barra de herramientas vertical se abre debajo del botón de desbordamiento, no a su lado, porque el menú no tiene colocación lateral.
  • Web: una barra de herramientas en línea o flotante mide el sitio que puede ocupar a partir de su elemento padre. Una barra de herramientas cuyo sitio lo fijan sus hermanos en una fila flex, y no su padre, decide lo que cabe solo cuando cambia de tamaño su padre o sus elementos.
  • Web: mientras los elementos se desplazan, se recorta todo lo que un elemento sobresale de la barra de herramientas en perpendicular a su eje: su área de pulsación, su anillo de foco o su resplandor, la sombra de un botón elevated. No se muestra ninguna barra de desplazamiento.
  • En SwiftUI, la única parada de tabulación es un grupo de foco para el teclado: Acceso total por teclado se mueve entre sus elementos con las teclas de flecha y sale de él con Tab. Las teclas están probadas como reglas, todavía no con un teclado real.
  • SwiftUI: mientras los elementos se desplazan, el área de pulsación de un elemento del extremo termina en el borde de la barra de herramientas. Cuando un cambio de tamaño hace que los elementos empiecen a desplazarse o dejen de hacerlo, se vuelven a crear, así que un elemento pierde su foco del teclado o una pulsación en curso.
  • En React Native, la parada de tabulación y las teclas de flecha funcionan solo donde hay un teclado físico conectado, como en la fila de pestañas.
  • React Native tiene el rol de barra de herramientas pero no tiene forma de exponer una orientación, así que una barra de herramientas vertical no se anuncia como vertical.
  • React Native: el ancho de la barra de herramientas flotante, las teclas en un teclado físico, el desplazamiento de un elemento con foco hasta dejarlo a la vista y si VoiceOver y TalkBack anuncian la barra de herramientas se han comprobado solo en Jest, no en un dispositivo.
  • Con m3-like, la barra de herramientas dibuja los valores del sistema predeterminado: los valores de la barra de herramientas de Material esperan a que la referencia de fidelidad la cubra. La barra de herramientas vibrante de Material, que cambia el color de sus elementos, no se puede dibujar, porque la barra de herramientas nunca cambia el estilo de sus elementos (laguna de imitación toolbar-vibrant-color).

Qué debes hacer tú

  • Da a la barra de herramientas un label, a cada elemento su propia etiqueta en el idioma de tu producto, incluidas las acciones de solo icono, y al botón de desbordamiento un nombre con overflow-label o con las palabras de tu producto.
  • Pon en ella solo Buttons y botones con menú de Tanrei, sueltos, en grupos o con menús anclados a ellos.
  • Cuando una acción no se pueda aplicar, deshabilítala, y di por qué cerca de ella cuando el motivo no sea evidente.
  • Abre y cierra tú el menú de un botón de menú, como haces con cualquier menú.
  • Coloca una barra de herramientas flotante de modo que no tape contenido que todavía se necesita mientras la barra de herramientas está abierta.