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
InicioComponentesBotón de acción principal

Botón de acción principal

Realiza la acción más importante de una pantalla desde un contenedor elevado que flota sobre el contenido, con su nombre escrito o contraído hasta dejar solo su icono.

content_copyVer en Markdown
Categoría
Acciones
Tokens
comp.main-action-button
Nivel
Base

Descripción general

Web
tanrei-main-action-button
schedule
SwiftUI
TanreiMainActionButton
radio_button_unchecked
Jetpack Compose
TanreiMainActionButton
radio_button_unchecked
Flutter
TanreiMainActionButton
radio_button_unchecked
React Native
MainActionButton
radio_button_unchecked

Generado a partir de docs/status/status.json, specs/main-action-button.spec.json

Extendido y contraído

editedit

El botón de acción principal es la acción para la que existe una pantalla: Redactar en un buzón de correo, Nuevo evento en un calendario, Añadir en una lista. Se apoya en un contenedor elevado que flota sobre el contenido, de modo que sigue al alcance mientras el contenido se desplaza por debajo.

Es un solo botón con dos formas. Extendido (la forma predeterminada) muestra su icono y su etiqueta. Contraído muestra solo el icono, en un cuadrado tan alto como la forma extendida, que en el sistema predeterminado es un círculo. Es el producto el que lo pasa de una forma a la otra: por ejemplo, lo contrae mientras el contenido se desplaza y lo extiende de nuevo al volver arriba. Es una acción, nunca un conmutador: contraerlo cambia su forma, no su significado, y la etiqueta sigue siendo su nombre accesible en ambas formas.

En la web es <tanrei-main-action-button>, y en React, MainActionButton. SwiftUI, Compose, Flutter y React Native aún no lo han implementado.

Uso

La etiqueta es una propiedad, no contenido, porque hace falta en ambas formas: se dibuja mientras el botón está extendido y es siempre el nombre accesible. El icono es un glifo del conjunto de iconos. El botón no se coloca a sí mismo: lo sitúa tu diseño, normalmente en la esquina inferior del lado de fin de la pantalla, sin tapar una barra de navegación.

<tanrei-main-action-button class="primary-action" label="Redactar">
  <span slot="icon">edit</span>
</tanrei-main-action-button>

<!-- Contraído: el atributo es el inverso de la propiedad extended. -->
<tanrei-main-action-button label="Redactar" collapsed><span slot="icon">edit</span></tanrei-main-action-button>

<!-- Un glifo que apunta hacia donde lleva la acción va después de la etiqueta. -->
<tanrei-main-action-button label="Siguiente" icon-position="trailing"><span slot="icon">arrow_forward</span></tanrei-main-action-button>

<style>
  /* El elemento no coloca nada: la página lo sitúa en la esquina inferior del lado de fin. */
  tanrei-main-action-button.primary-action {
    position: fixed;
    inset-inline-end: var(--tanrei-sys-space-space400);
    inset-block-end: var(--tanrei-sys-space-space400);
  }
</style>

<script type="module">
  import '@tanrei/web/components/main-action-button';
  const compose = document.querySelector('tanrei-main-action-button.primary-action');
  compose.addEventListener('click', newMessage);
  // extended es una propiedad cuyo valor predeterminado es true; contráelo desde fuera, por ejemplo mientras la página está desplazada.
  addEventListener('scroll', () => (compose.extended = scrollY === 0), { passive: true });
</script>
import { MainActionButton } from '@tanrei/react';

<MainActionButton className="primary-action" label="Redactar" extended={atTop} onClick={newMessage}>
  <span slot="icon">edit</span>
</MainActionButton>

<MainActionButton variant="tonal" label="Siguiente" iconPosition="trailing" onClick={next}>
  <span slot="icon">arrow_forward</span>
</MainActionButton>

Adónde fueron a parar el FAB y el FAB extendido

El botón de acción principal sustituye al botón de acción flotante y al FAB extendido. Lo que eran dos componentes que un producto intercambiaba son ahora dos formas de uno solo.

Antes Ahora
Botón de acción flotante (fab) Un botón de acción principal contraído: extended en false
FAB extendido (extended-fab) Un botón de acción principal extendido (la forma predeterminada)
El expanded del FAB extendido extended
comp.fab.*, comp.extended-fab.* comp.main-action-button.*

Los nombres de Material 3

  • El FAB, el FAB pequeño y el FAB grande de Material 3 son un botón de acción principal contraído en los tamaños medium, small y large. Su FAB extendido es la forma extendida.
  • El expanded de Compose (en ExtendedFloatingActionButton) y el isExtended de Flutter (en FloatingActionButton.extended) son extended.
  • Los colores primary, secondary, tertiary y surface del FAB de Material 3 se corresponden con las variantes filled, tonal y surface y con los valores que añade un preajuste. El preajuste m3-like dibuja las esquinas de cuadrado redondeado y las alturas 56 / 96 de Material mediante los tokens de este componente.
  • En los términos de Material, el botón de acción principal es el FAB. El menú FAB de Material es el menú FAB, un componente de la capa m3-like: lo tienen los sistemas que descienden de ella.

Especificaciones

Variantes

editeditedit

Tamaños, extendido y contraído

editediteditediteditedit

Un icono final, sin icono y deshabilitado

arrow_forwardeditedit

Anatomía

Anatomía

Dibujado sobre el fixture filled-extended, tal como lo dibuja el paquete web.
Parte Descripción
1 container The raised shape that holds the icon and the label, casts the shadow and carries hover, focus and press. Extended it is as wide as its content; collapsed it is a square of its height, a circle under full corners.
2 icon · opcional The glyph that names the action, at the leading or the trailing side of the label; drawn in the label color. Required to collapse.
3 label · opcional Text that names the action. Shown while extended; hidden, but still the accessible name, while collapsed. Required to extend.
4 focus-ring Gap-then-ring indicator shown for keyboard focus.

Medidas

Medidas

Longitud Token Valor (px)
container padding-inline-start-with-icon tanrei.comp.main-action-button.container.padding-inline-start-with-icon.medium 16
container gap tanrei.comp.main-action-button.container.gap.medium 12
container padding-inline-end tanrei.comp.main-action-button.container.padding-inline-end.medium 20
container height tanrei.comp.main-action-button.container.height.medium 56
icon size tanrei.comp.main-action-button.icon.size.medium 24
Dibujado sobre el fixture filled-extended, tal como lo dibuja el paquete web.

Propiedades

Propiedad Tipo Valor predeterminado Descripción
variant filled | tonal | surface "filled" Emphasis. Filled is the screen's main action at full strength; tonal is quieter; surface keeps the container neutral where a colored one would compete with the content beneath (a map, a photo). A design system may add values.
size small | medium | large "medium" Visual height (40 / 56 / 96), which is also the side of the collapsed form, so one button keeps its height while it collapses and extends. Small sits beside a medium one for a related action; large marks the action on a wide or empty screen. The hit area always meets the minimum target. A design system may add values.
extended boolean true Shows the label beside the icon. False collapses the button to its icon (for example while the content scrolls); the label stays the accessible name. It changes the button's form, never its meaning: this is not a toggle. A button without an icon stays extended, and one without a label never extends (MAB-15, MAB-16).
fullWidth boolean false Makes the button take the whole width its container gives it, its icon and label centred: the one action of a screen held across its foot on a narrow screen (MAB-24). A full-width button is always drawn extended, so extended is ignored while it is true.
iconPosition leading | trailing "leading" The side of the label the icon is on, in the reading direction. Trailing is for a glyph that points where the action goes, such as the arrow of Next. Collapsed, the icon is centered whichever side it is on.
disabled boolean false Prevents interaction and removes the button from the focus order. Hiding it when its action is unavailable is usually better than disabling it.
label string "" The visible text while extended, and the accessible name in either form. Required: an icon alone is not a name.

Slots

Slot Descripción
icon The icon (a glyph of the system's icon set).

Eventos

Evento Descripción
click The button was activated by pointer, touch, keyboard or assistive technology.

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
MAB-1 WHEN the user activates the main action button by pointer, touch, Enter or Space THE main action button SHALL emit click exactly once.
MAB-2 WHILE disabled is true THE main action button SHALL NOT emit click, SHALL NOT be focusable and SHALL expose the disabled state to assistive technology.
MAB-3 WHILE hovered, keyboard-focused or pressed THE main action button SHALL render its container, label, icon, elevation and opacity from the component tokens of the highest-precedence active state, with precedence pressed over focused over hovered; focus gained by pointer or touch SHALL NOT select the focused state.
MAB-4 WHEN the main action button receives keyboard focus THE main action button SHALL show the focus ring without animation; focus gained by pointer or touch SHALL NOT show it.
MAB-5 WHERE the visual size is below the minimum target THE main action button 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.
MAB-6 WHILE disabled is true THE main action button SHALL render its container, label, icon, elevation and opacity from the disabled component tokens of its variant.
MAB-7 WHEN variant or size names a value that the active design system does not have THE main action button SHALL render with the default value's tokens, and in debug builds report the unknown value.
MAB-8 WHEN the main action button is pressed by pointer, touch, Enter or Space THE main action button 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.
MAB-9 WHILE pressed THE main action button SHALL answer as sys.behavior.pressed-feedback names: overlay applies the pressed tokens to the whole container at once; ripple grows the pressed state layer from the point of contact (from the center for keyboard activation); dim applies the pressed opacity to the whole control and draws no state layer; none draws no answer to the press. Under ripple and dim only the container color stays with the state under the press; label, icon, elevation, 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.main-action-button.motion.feedback-duration with comp.main-action-button.motion.state-easing, fades over the state duration of its size (comp.main-action-button.motion.state-duration.small, .medium or .large) with comp.main-action-button.motion.state-easing once the press has ended and press-hold has passed, and appears whole where motion is reduced.
MAB-10 THE main action button SHALL ease its container corners by sys.shape.corner-smoothing (0 is a quarter circle, 0.6 the iOS continuous corner; a platform with only the OS curve draws it for any amount above 0) and show its keyboard focus as sys.behavior.focus-style names (ring or glow); a platform that cannot draw a choice SHALL fall back to the first value and state that in its README.
MAB-11 WHILE it is extended THE main action button SHALL draw a container at least the height of its size (comp.main-action-button.container.height.medium for medium, and so on) with the corners of its size (comp.main-action-button.container.shape.medium, and so on), holding its label and, when it has one, its icon on the side iconPosition names (leading: before the label in the reading direction; trailing: after it), the two separated by comp.main-action-button.container.gap.medium (and so on); it SHALL pad the icon's side by comp.main-action-button.container.padding-inline-start-with-icon.medium for a leading icon or comp.main-action-button.container.padding-inline-end-with-icon.medium for a trailing one, a start without an icon by comp.main-action-button.container.padding-inline-start.medium and an end without an icon by comp.main-action-button.container.padding-inline-end.medium, and the top and bottom by at least comp.main-action-button.container.padding-block.medium (and so on for each size), and SHALL be as wide as that content.
MAB-12 THE main action button SHALL set its label in the text style of its size (comp.main-action-button.label.typescale.medium, and so on) and the label color of its variant and state (comp.main-action-button.filled.label.color for filled at rest, and so on), SHALL NOT truncate it (it stays on one line while it fits, wraps when the layout gives it less width, and the container grows in both axes with it), and SHALL draw the icon, in either form, in the same color at the icon size of its size (comp.main-action-button.icon.size.medium, and so on) with the family and fill of an unselected icon, sys.icon.weight, and an optical size clamped between sys.icon.optical-size.min and sys.icon.optical-size.max.
MAB-13 WHILE it is collapsed THE main action button SHALL hide its label and draw a square container whose side is the height of its size (comp.main-action-button.container.height.medium, and so on) with the corners of its size (comp.main-action-button.container.shape.medium, and so on; a circle where they are full, as in the default system) and its icon centered in it whichever side iconPosition names, and SHALL keep label as its accessible name.
MAB-14 WHEN extended changes THE main action button SHALL change its width between the two forms over comp.main-action-button.motion.resize-duration with comp.main-action-button.motion.resize-easing, keeping its height and corners, fading the label out as it narrows and in as it widens, and moving the icon between its side of the label and the center, and SHALL change at once where motion is reduced; which edge stays in place is decided by the layout that holds it, as for any change of its width.
MAB-15 IF the main action button has no icon THEN THE main action button SHALL draw its extended form whatever extended says (there is no empty collapsed form), and in debug builds report it while extended is false.
MAB-16 WHILE label is not empty THE main action button SHALL expose it as its accessible name, in either form, over a name the product gives it on the element (aria-label or aria-labelledby). IF label is empty THEN THE main action button SHALL draw its collapsed form whatever extended says, SHALL expose the name the product gives it on the element — aria-label, or aria-labelledby naming an element — as its accessible name, and WHILE the product gives it none SHALL in debug builds report that it has no accessible name; this holds over MAB-15 when it has no icon either.
MAB-17 THE main action button SHALL cast the elevation of its variant and state (comp.main-action-button.filled.container.elevation for filled at rest, and so on) outside its container without clipping it, in either form and while it changes between them, and WHEN the elevation or the colors change between states SHALL animate the change over the state duration of its size (comp.main-action-button.motion.state-duration.small, .medium or .large) with comp.main-action-button.motion.state-easing, changing them at once where motion is reduced.
MAB-18 THE main action button SHALL NOT position itself: it SHALL lay out at its own size, or across the width of its container while fullWidth is true (MAB-24), where the layout that holds it places it (normally the inline-end bottom corner of the screen, clear of any navigation bar), and SHALL NOT draw a scrim or move content.
MAB-19 WHEN the layout direction is right-to-left THE main action button SHALL mirror the order of its icon and label (a leading icon on the right, a trailing one on the left) and apply its paddings by logical start and end, SHALL NOT mirror the glyph itself (the icon helper mirrors a glyph the icon set marks, MAB-22), and SHALL grow a ripple from the point of contact as in left-to-right.
MAB-20 THE main action button SHALL expose itself to assistive technology as a button named by label with no pressed, selected, checked or expanded state, and WHEN extended changes SHALL NOT change its role, its name or its focus, and SHALL NOT announce the change.
MAB-21 THE main action button 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 main action button is shown THE main action button SHALL draw itself for the new direction at once, without a motion of its own, keeping what it shows and its state.
MAB-22 WHERE the layout direction is right-to-left THE main action button SHALL draw the glyph of its icon slot mirrored left to right exactly when the system's icon set marks that glyph's name as mirrored or the product forces mirroring for that use, and unmirrored when the product forbids it: the icon helper mirrors the glyph inside its own box, about the box's vertical centre line, changing neither its place, size, color and fill nor the order MAB-19 gives. THE main action button SHALL NOT mirror a glyph itself, and SHALL NOT mirror content the product gives as an image or a view of its own rather than by a glyph's name.
MAB-23 THE main action button SHALL lay out its label 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 left-to-right word, a number with its sign or unit, a telephone number and an address keep their own order in a right-to-left layout and reorder nothing beside them; THE main action button SHALL still place the label and align its lines by the layout direction, not by the text's own.
MAB-24 WHILE fullWidth is true THE main action button SHALL take the whole inline size its container gives it and SHALL draw its extended form whatever extended says — the height, corners, paddings, elevation and states of MAB-11 and MAB-17 — with its icon and label centred in that width as one row, in the order MAB-19 gives them; WHERE that width is narrower than the label THE main action button SHALL wrap the label, its lines centred (MAB-12). WHEN extended changes while fullWidth is true THE main action button SHALL NOT change its form, and in debug builds SHALL report that a full-width button does not collapse. MAB-16 holds over this rule: a button with no label draws its collapsed form, at its own size, and is reported.
MAB-25 WHERE the platform has ARIA attributes (the web), WHEN the product sets an aria- attribute on the host, by the attribute or by the ARIA property that reflects it, THE main action button SHALL move it to the data-aria- attribute of the same name, so that the host is no second node with its name, description or state, and SHALL expose it on the element that carries its role — an id reference by the elements it names in the host's tree or a tree around it, an error message as part of the description while the main action button is invalid — except those the main action button owns (aria-disabled), which it SHALL move and not expose. WHEN the product removes the aria- attribute or its data-aria- twin, or sets the ARIA property that reflects it (ariaLabel, ariaDescribedByElements…) to null, THE main action button SHALL take it off that element. WHEN the product sets an aria- attribute the main action button owns THE main action button SHALL report it in debug builds.

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-main-action-button TanreiMainActionButton TanreiMainActionButton TanreiMainActionButton MainActionButton
variant · Propiedad variant variant variant variant variant
size · Propiedad size size size size size
extended · Propiedad extended isExtended expanded isExtended extended
fullWidth · Propiedad fullWidth fullWidth fullWidth fullWidth fullWidth
iconPosition · Propiedad iconPosition iconPosition iconPosition iconPosition iconPosition
disabled · Propiedad disabled disabled enabled onPressed disabled
label · Propiedad label title text label label
click · Evento click action onClick onPressed onPress
Notas The icon is the icon slot (a glyph of the icon font). extended is a boolean property that defaults to true; its attribute is the inverse collapsed, because an HTML boolean attribute cannot default to true. iconPosition is the icon-position attribute. The host has no aria-expanded or aria-pressed (MAB-20). The element is inline; the page positions it (for example with position: fixed or a sticky container). fullWidth is the full-width attribute: the host is then a block-level flex box as wide as its container, and the native <button> fills it (MAB-24). The initializer takes the title first, as Button(_:action:) does, and an optional icon name. disabled follows .disabled(_:). The view is placed by the caller, typically in an .overlay(alignment: .bottomTrailing). Compose idiom (as Material 3's extended FAB composable): expanded collapses it; enabled is the inverse flag; text is a String so it is also the content description. Placed through Scaffold's floatingActionButton slot or by the caller. Flutter idiom (as Material 3's extended FAB): isExtended collapses it and a null onPressed disables it. Placed through Scaffold.floatingActionButton or by the caller; it adds no Hero. The icon is the icon prop (a glyph name). The caller positions it (for example absolutely inside the screen's root view).

Tokens

Token Alias de Valor resuelto (claro)
--tanrei-comp-main-action-button-container-gap-large sys.space.space200 16px
--tanrei-comp-main-action-button-container-gap-medium sys.space.space150 12px
--tanrei-comp-main-action-button-container-gap-small sys.space.space100 8px
--tanrei-comp-main-action-button-container-height-large — 96px
--tanrei-comp-main-action-button-container-height-medium — 56px
--tanrei-comp-main-action-button-container-height-small — 40px
--tanrei-comp-main-action-button-container-padding-block-large — 6px
--tanrei-comp-main-action-button-container-padding-block-medium — 6px
--tanrei-comp-main-action-button-container-padding-block-small — 6px
--tanrei-comp-main-action-button-container-padding-inline-end-with-icon-large sys.space.space400 32px
--tanrei-comp-main-action-button-container-padding-inline-end-with-icon-medium sys.space.space250 20px
--tanrei-comp-main-action-button-container-padding-inline-end-with-icon-small sys.space.space150 12px
--tanrei-comp-main-action-button-container-padding-inline-end-large sys.space.space400 32px
--tanrei-comp-main-action-button-container-padding-inline-end-medium sys.space.space250 20px
--tanrei-comp-main-action-button-container-padding-inline-end-small sys.space.space200 16px
--tanrei-comp-main-action-button-container-padding-inline-start-with-icon-large sys.space.space300 24px
--tanrei-comp-main-action-button-container-padding-inline-start-with-icon-medium sys.space.space200 16px
--tanrei-comp-main-action-button-container-padding-inline-start-with-icon-small sys.space.space150 12px
--tanrei-comp-main-action-button-container-padding-inline-start-large sys.space.space400 32px
--tanrei-comp-main-action-button-container-padding-inline-start-medium sys.space.space250 20px
--tanrei-comp-main-action-button-container-padding-inline-start-small sys.space.space200 16px
--tanrei-comp-main-action-button-container-shape-large sys.shape.corner.full 9999px
--tanrei-comp-main-action-button-container-shape-medium sys.shape.corner.full 9999px
--tanrei-comp-main-action-button-container-shape-small sys.shape.corner.full 9999px
--tanrei-comp-main-action-button-disabled-opacity — 1
--tanrei-comp-main-action-button-filled-container-color sys.color.primary #1b1b1b
--tanrei-comp-main-action-button-filled-container-elevation 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-main-action-button-filled-disabled-container-color — #1b1b1b · 12%
--tanrei-comp-main-action-button-filled-disabled-container-elevation —
--tanrei-comp-main-action-button-filled-disabled-label-color — #1b1b1b · 38%
--tanrei-comp-main-action-button-filled-disabled-state-layer-color — #1b1b1b · 38%
--tanrei-comp-main-action-button-filled-focused-container-color — #323232
--tanrei-comp-main-action-button-filled-focused-container-elevation — 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-main-action-button-filled-focused-label-color — #ffffff
--tanrei-comp-main-action-button-filled-focused-state-layer-color — #ffffff
--tanrei-comp-main-action-button-filled-hovered-container-color — #2d2d2d
--tanrei-comp-main-action-button-filled-hovered-container-elevation — 0px 0px 0px 1px rgb(0 0 0 / 0.08), 0px 1px 1px 0px rgb(0 0 0 / 0.04), 0px 8px 16px -4px rgb(0 0 0 / 0.04), 0px 24px 32px -8px rgb(0 0 0 / 0.06)
--tanrei-comp-main-action-button-filled-hovered-label-color — #ffffff
--tanrei-comp-main-action-button-filled-hovered-state-layer-color — #ffffff
--tanrei-comp-main-action-button-filled-label-color sys.color.on-primary #ffffff
--tanrei-comp-main-action-button-filled-pressed-container-color — #323232
--tanrei-comp-main-action-button-filled-pressed-container-elevation — 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-main-action-button-filled-pressed-label-color — #ffffff
--tanrei-comp-main-action-button-filled-pressed-state-layer-color — #ffffff
--tanrei-comp-main-action-button-filled-state-layer-color comp.main-action-button.filled.label.color #ffffff
--tanrei-comp-main-action-button-focused-opacity — 1
--tanrei-comp-main-action-button-hovered-opacity — 1
--tanrei-comp-main-action-button-icon-size-large sys.icon.large 32px
--tanrei-comp-main-action-button-icon-size-medium sys.icon.medium 24px
--tanrei-comp-main-action-button-icon-size-small sys.icon.medium 24px
--tanrei-comp-main-action-button-motion-feedback-duration sys.motion.role.feedback 450ms
--tanrei-comp-main-action-button-motion-resize-duration sys.motion.role.resize.large 400ms
--tanrei-comp-main-action-button-motion-resize-easing sys.motion.easing.spatial cubic-bezier(0.2, 0, 0, 1)
--tanrei-comp-main-action-button-motion-state-duration-large sys.motion.role.state.large 250ms
--tanrei-comp-main-action-button-motion-state-duration-medium sys.motion.role.state.default 250ms
--tanrei-comp-main-action-button-motion-state-duration-small sys.motion.role.state.compact 200ms
--tanrei-comp-main-action-button-motion-state-easing sys.motion.easing.state cubic-bezier(0.2, 0, 0, 1)
--tanrei-comp-main-action-button-pressed-opacity — 1
--tanrei-comp-main-action-button-surface-container-color sys.color.surface-container-lowest #ffffff
--tanrei-comp-main-action-button-surface-container-elevation 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-main-action-button-surface-disabled-container-color — #1b1b1b · 12%
--tanrei-comp-main-action-button-surface-disabled-container-elevation —
--tanrei-comp-main-action-button-surface-disabled-label-color — #1b1b1b · 38%
--tanrei-comp-main-action-button-surface-disabled-state-layer-color — #1b1b1b · 38%
--tanrei-comp-main-action-button-surface-focused-container-color — #e8e8e8
--tanrei-comp-main-action-button-surface-focused-container-elevation — 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-main-action-button-surface-focused-label-color — #1b1b1b
--tanrei-comp-main-action-button-surface-focused-state-layer-color — #1b1b1b
--tanrei-comp-main-action-button-surface-hovered-container-color — #ededed
--tanrei-comp-main-action-button-surface-hovered-container-elevation — 0px 0px 0px 1px rgb(0 0 0 / 0.08), 0px 1px 1px 0px rgb(0 0 0 / 0.04), 0px 8px 16px -4px rgb(0 0 0 / 0.04), 0px 24px 32px -8px rgb(0 0 0 / 0.06)
--tanrei-comp-main-action-button-surface-hovered-label-color — #1b1b1b
--tanrei-comp-main-action-button-surface-hovered-state-layer-color — #1b1b1b
--tanrei-comp-main-action-button-surface-label-color sys.color.primary #1b1b1b
--tanrei-comp-main-action-button-surface-pressed-container-color — #e8e8e8
--tanrei-comp-main-action-button-surface-pressed-container-elevation — 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-main-action-button-surface-pressed-label-color — #1b1b1b
--tanrei-comp-main-action-button-surface-pressed-state-layer-color — #1b1b1b
--tanrei-comp-main-action-button-surface-state-layer-color comp.main-action-button.surface.label.color #1b1b1b
--tanrei-comp-main-action-button-tonal-container-color sys.color.secondary-container #eeeeee
--tanrei-comp-main-action-button-tonal-container-elevation 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-main-action-button-tonal-disabled-container-color — #1b1b1b · 12%
--tanrei-comp-main-action-button-tonal-disabled-container-elevation —
--tanrei-comp-main-action-button-tonal-disabled-label-color — #1b1b1b · 38%
--tanrei-comp-main-action-button-tonal-disabled-state-layer-color — #1b1b1b · 38%
--tanrei-comp-main-action-button-tonal-focused-container-color — #dadada
--tanrei-comp-main-action-button-tonal-focused-container-elevation — 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-main-action-button-tonal-focused-label-color — #262626
--tanrei-comp-main-action-button-tonal-focused-state-layer-color — #262626
--tanrei-comp-main-action-button-tonal-hovered-container-color — #dedede
--tanrei-comp-main-action-button-tonal-hovered-container-elevation — 0px 0px 0px 1px rgb(0 0 0 / 0.08), 0px 1px 1px 0px rgb(0 0 0 / 0.04), 0px 8px 16px -4px rgb(0 0 0 / 0.04), 0px 24px 32px -8px rgb(0 0 0 / 0.06)
--tanrei-comp-main-action-button-tonal-hovered-label-color — #262626
--tanrei-comp-main-action-button-tonal-hovered-state-layer-color — #262626
--tanrei-comp-main-action-button-tonal-label-color sys.color.on-secondary-container #262626
--tanrei-comp-main-action-button-tonal-pressed-container-color — #dadada
--tanrei-comp-main-action-button-tonal-pressed-container-elevation — 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-main-action-button-tonal-pressed-label-color — #262626
--tanrei-comp-main-action-button-tonal-pressed-state-layer-color — #262626
--tanrei-comp-main-action-button-tonal-state-layer-color comp.main-action-button.tonal.label.color #262626
--tanrei-comp-main-action-button-label-typescale-large sys.typescale.heading-5 500 16px/1.5
--tanrei-comp-main-action-button-label-typescale-medium sys.typescale.label 500 14px/1.4286
--tanrei-comp-main-action-button-label-typescale-small sys.typescale.label 500 14px/1.4286

Fixtures

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

Generado a partir de specs/main-action-button.spec.json, tokens/comp/main-action-button.tokens.json, design/tokens/

Pautas

Cuándo usarlo

Usa un botón de acción principal para la acción por la que la mayoría de las personas llega a la pantalla, cuando deba seguir al alcance sea cual sea el punto al que se hayan desplazado: escribir un mensaje, añadir un elemento, iniciar una grabación. Una pantalla tiene uno o ninguno. Muchas pantallas no necesitan ninguno: una página de ajustes o una vista de lectura no tienen una acción única que merezca flotar sobre ellas.

  • Para una acción que pertenece a un formulario, a un diálogo o a un elemento del contenido, usa un botón donde esté ese contenido.
  • Para varias acciones sobre la pantalla o la selección actual, usa una barra de herramientas.
  • Cuando la acción principal tiene unas pocas formas relacionadas (un documento nuevo, una carpeta o una subida), haz que el botón de acción principal abra una hoja inferior que las enumere. El menú FAB cumple esa función en los sistemas de la capa m3-like, donde vive; el sistema predeterminado no lo tiene.
  • Realiza una acción y no admite destino. Un control que solo lleva a las personas a otro lugar es un enlace: un botón con href.

Extendido o contraído

Empieza con el botón extendido. El nombre escrito es lo que dice a las personas qué hace el botón, y un icono solo no es seguro hasta que lo han aprendido.

Contráelo cuando la etiqueta cueste más de lo que aporta: mientras el contenido se desplaza y el botón lo taparía, o en una ventana estrecha. Extiéndelo de nuevo cuando haya espacio, por ejemplo al volver al principio de la lista. El cambio lo haces tú, definiendo extended; pulsar el botón nunca cambia su forma.

  • El botón conserva su altura y sus esquinas mientras cambia, y qué borde se queda en su sitio lo decide tu diseño. Anclado en el lado de fin, se contrae hacia ese borde.
  • Un botón sin icono permanece extendido, porque no habría nada a lo que contraerlo. Un botón sin etiqueta dibuja la forma contraída y las compilaciones de depuración lo notifican: no tiene nombre.
  • Donde el movimiento está reducido, la forma cambia de inmediato.

Cómo elegir una variante

Variante Énfasis Úsala para
Filled (predeterminada) El más alto La acción principal de la pantalla con toda su fuerza.
Tonal Alto Una acción principal en una pantalla cuyo contenido debe tener el protagonismo.
Surface Neutro Una acción principal sobre un contenido que ya tiene color, como un mapa o una foto, donde un contenedor de color competiría con él.

Un sistema de diseño puede añadir variantes propias.

Cómo elegir un tamaño

Tamaño Altura en el sistema predeterminado Úsalo para
Small 40 Una segunda acción relacionada, junto a una de tamaño medium, o un diseño denso.
Medium (predeterminado) 56 La acción principal de la mayoría de las pantallas.
Large 96 La acción de una pantalla ancha o casi vacía, donde un botón de tamaño medium se perdería.

La altura es también el lado de la forma contraída, de modo que un mismo botón conserva su altura mientras se contrae y se extiende.

Colocación

El botón no dibuja ningún velo ni mueve ningún contenido. Colócalo sobre el contenido, normalmente en la esquina inferior del lado de fin, y mantenlo apartado de una barra de navegación, de una barra de herramientas acoplada y de los márgenes interiores del sistema. Deja espacio al final del contenido que se desplaza, para que el botón nunca tape de forma permanente el último elemento. Su sombra se proyecta fuera de su contenedor: déjale espacio si el contenedor que lo aloja recorta su contenido.

Ancho completo

Añade full-width para que el botón sea tan ancho como su contenedor, con el icono y la etiqueta centrados: la única acción de una pantalla, a lo ancho de su pie en una pantalla estrecha, como Pagar o Enviar. Un botón de ancho completo siempre está extendido: no se contrae mientras el contenido se desplaza, y poner extended en false se informa en las compilaciones de depuración. Conserva la altura, las esquinas y la elevación de su tamaño, y una etiqueta que no cabe pasa a la línea siguiente. Sigue sin colocarse a sí mismo: ponlo en el contenedor que lo sostiene al pie de la pantalla.

Un botón de acción principal de ancho completo

shopping_cart

Recomendado

  • Usa como etiqueta la acción, escrita como un verbo o como un verbo y un sustantivo: Redactar, Nuevo evento, Añadir foto.
  • Elige un glifo que las personas ya asocien con la acción, como edit para escribir o add para crear.
  • Usa iconPosition en trailing para un glifo que apunta hacia donde lleva la acción, como la flecha de Siguiente.
  • Mantenlo en el mismo lugar en todas las pantallas que tengan uno.
  • Ocúltalo cuando su acción no esté disponible en una pantalla. Suele ser mejor para las personas que un botón deshabilitado flotando sobre el contenido.

Evita

  • No pongas dos botones de acción principal del mismo tamaño en una pantalla. Si dos acciones parecen igual de importantes, ninguna es la principal: usa botones en el contenido.
  • No lo uses para acciones menores, destructivas o que solo navegan, como Eliminar, Configuración o Atrás.
  • No lo uses como conmutador, y no cambies su etiqueta ni su icono para mostrar un estado.
  • No lo contraigas en una pantalla que las personas ven por primera vez, cuando nada más dice qué significa el icono.
  • No dejes que tape el contenido que las personas necesitan para decidir si lo pulsan.

Contenido

Las etiquetas se escriben con mayúscula solo en la primera palabra y sin puntuación final. Procura que tengan una o dos palabras. La etiqueta no se trunca: se queda en una línea mientras cabe y salta de línea cuando el diseño le da menos ancho.

Accesibilidad

Rol
button
Etiquetado
label is the accessible name, whether it is shown or collapsed away. The icon is decorative to assistive technology. A tooltip may show the same text to sighted pointer users while it is collapsed, but it never replaces label.
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 Moves focus to the main action button.
Enter / Space Activates it.

Notas

  • It is an action, never a toggle. Collapsing and extending change what is drawn, not what is announced: the role stays button, the name stays label, and there is no expanded state to report (MAB-20).
  • Its place in the focus and reading order is where the layout puts it in the element tree, not where it is drawn. Put it where its action belongs: after the content it acts on, or first when it is the screen's reason to exist.
  • Extended, text must remain readable at 200% text size: the container grows, the label never truncates. Collapsed, the icon is not text: where sizes are points or dp (SwiftUI, Compose, Flutter, React Native), text size leaves the square and the icon as they are; on the web every Tanrei size follows the root font size (rem), so the square and its icon grow together and stay square and whole. Either way the label is still announced.
  • A trailing icon that points (an arrow) keeps its glyph in right-to-left layouts; the product chooses the glyph that points the right way for the direction.
  • How a state looks is a value decision of the active design system; components read the state's tokens and never compute the effect themselves.

Generado a partir de specs/main-action-button.spec.json, tokens/sys/measure.tokens.json

De qué se encarga el componente

  • Es un botón que recibe su nombre de label en ambas formas. El icono queda oculto para la tecnología de apoyo.
  • Contraerlo y extenderlo cambian lo que se dibuja, no lo que se anuncia: el rol, el nombre y el foco siguen como están, no se anuncia nada y no hay estado pulsado ni expandido.
  • Enter y Espacio lo activan. Deshabilitado, no emite nada, sale del orden del foco y se expone como deshabilitado.
  • Su área de pulsación cumple el objetivo mínimo en todos los tamaños, incluido el pequeño.
  • Muestra el indicador de foco solo para el foco del teclado, sin animación.
  • Extendido, el contenedor crece con el tamaño del texto y la etiqueta nunca se trunca. Contraído, el icono no es texto. En la web, todos los tamaños de Tanrei siguen el tamaño de fuente raíz, así que el cuadrado y su icono crecen juntos y el cuadrado sigue siendo un cuadrado.
  • En un diseño de derecha a izquierda, el icono y la etiqueta cambian de lado, y los márgenes interiores cambian con ellos. El glifo en sí solo se refleja cuando el conjunto de iconos lo marca como indicador de una dirección.
  • Las compilaciones de depuración notifican un botón sin etiqueta y un botón contraído sin icono.

Qué debes hacer tú

  • Dale siempre un label, en el idioma de tu producto, incluso cuando solo vaya a estar contraído.
  • Ponlo en el árbol de elementos donde corresponde a su acción: después del contenido sobre el que actúa, o en primer lugar cuando es la razón de ser de la pantalla. La tecnología de apoyo y la tecla Tab llegan a él en el orden del árbol, no donde está dibujado.
  • Cuando esté contraído, plantéate añadir un tooltip con el mismo texto para quienes usan un puntero. El tooltip nunca sustituye a label.
  • Asegúrate de que no oculta el contenido ni el control que tiene el foco del teclado. Deja espacio al final del contenido o aparta el botón.
  • No dependas del color de la variante para transmitir un significado. Dilo en la etiqueta.