chrome.action

Descripción

Usa la API de chrome.action para controlar el ícono de la extensión en la barra de herramientas de Google Chrome.

Los íconos de acción se muestran en la barra de herramientas del navegador, junto al cuadro multifunción. Después de la instalación, estas tarjetas aparecen en el menú de extensiones (el ícono de la pieza de rompecabezas). Los usuarios pueden fijar el ícono de la extensión en la barra de herramientas.

Disponibilidad

Chrome 88 y versiones posteriores MV3+ .

Manifiesto

Para usar esta API, se deben declarar las siguientes claves en el manifiesto.

"action"

Para usar la API de chrome.action, especifica un "manifest_version" de 3 e incluye la clave "action" en tu archivo de manifiesto.

{
  "name": "Action Extension",
  ...
  "action": {
    "default_icon": {              // optional
      "16": "images/icon16.png",   // optional
      "24": "images/icon24.png",   // optional
      "32": "images/icon32.png"    // optional
    },
    "default_title": "Click Me",   // optional, shown in tooltip
    "default_popup": "popup.html"  // optional
  },
  ...
}

La clave "action" (junto con sus elementos secundarios) es opcional. Cuando no está incluida, la extensión se muestra de todos modos en la barra de herramientas para proporcionar acceso al menú de la extensión. Por este motivo, te recomendamos que siempre incluyas al menos las claves "action" y "default_icon".

Conceptos y uso

Partes de la IU

Ícono

El ícono es la imagen principal en la barra de herramientas de tu extensión y se establece con la tecla "default_icon" de la clave "action" de tu manifiesto. Los íconos deben tener 16 píxeles independientes del dispositivo (DIP) de ancho y alto.

La clave "default_icon" es un diccionario de tamaños para rutas de imágenes. Chrome usa estos íconos para elegir qué escala de imagen usar. Si no se encuentra una coincidencia exacta, Chrome selecciona la más cercana disponible y la ajusta para que se ajuste a la imagen, lo que puede afectar su calidad.

Porque los dispositivos con factores de escala menos comunes, como 1.5x o 1.2x, son cada vez más común, te recomendamos que proporciones varios tamaños para tus íconos. Esto también protege el futuro de tu extensión contra posibles cambios en el tamaño de visualización de los íconos. Sin embargo, si solo proporcionas un tamaño único, la clave "default_icon" también se puede establecer en un con la ruta de acceso a un solo ícono en lugar de a un diccionario.

También puedes llamar a action.setIcon() para configurar el ícono de tu extensión de manera programática especificando una ruta de imagen diferente o proporcionando un icono generado de forma dinámica con el lienzo HTML elemento o, si se configura desde un service worker de extensión, el fuera de pantalla de Canvas.

const canvas = new OffscreenCanvas(16, 16);
const context = canvas.getContext('2d');
context.clearRect(0, 0, 16, 16);
context.fillStyle = '#00FF00';  // Green
context.fillRect(0, 0, 16, 16);
const imageData = context.getImageData(0, 0, 16, 16);
chrome.action.setIcon({imageData: imageData}, () => { /* ... */ });

En el caso de las extensiones empaquetadas (instaladas desde un archivo .crx), las imágenes pueden estar en la mayoría de los formatos que el Blink de procesamiento de imágenes, como PNG, JPEG, BMP, ICO y otros. SVG no es compatible. Las extensiones sin empaquetar deben usar imágenes PNG.

Información sobre la herramienta (título)

El título, o la información sobre la herramienta, aparece cuando el usuario mantiene el puntero del mouse sobre el ícono de la extensión en la barra de herramientas. También se incluye en el texto accesible que dicen los lectores de pantalla cuando el botón no te enfocas en eso.

La información predeterminada sobre la herramienta se establece con el campo "default_title" de la clave "action" en manifest.json. También puedes configurarlo de manera programática llamando a action.setTitle().

Insignia

De manera opcional, las acciones pueden mostrar una "insignia" — un poco de texto en capas sobre el ícono. Esto te permite Actualiza la acción para que muestre una pequeña cantidad de información sobre el estado de la extensión. como un contador. La insignia tiene un componente de texto y un color de fondo. Como el espacio es limitado, recomendamos que el texto de la insignia tenga cuatro o menos caracteres.

Para crear una insignia, configúrala de manera programática llamando a action.setBadgeBackgroundColor() y action.setBadgeText() No hay una configuración de insignia predeterminada en el manifiesto. Valores de color de la insignia Puede ser un array de cuatro números enteros entre 0 y 255 que componen el color RGBA de la insignia o una cadena con un valor de color CSS.

chrome.action.setBadgeBackgroundColor(
  {color: [0, 255, 0, 0]},  // Green
  () => { /* ... */ },
);

chrome.action.setBadgeBackgroundColor(
  {color: '#00FF00'},  // Also green
  () => { /* ... */ },
);

chrome.action.setBadgeBackgroundColor(
  {color: 'green'},  // Also, also green
  () => { /* ... */ },
);

Una ventana emergente de una acción se muestra cuando el usuario hace clic en el botón de acción de la extensión en barra de herramientas. La ventana emergente puede incluir el contenido HTML que quieras, y su tamaño se ajustará automáticamente a fin de ajustarse su contenido. El tamaño de la ventana emergente debe ser de entre 25 x 25 y 800 x 600 píxeles.

Inicialmente, la propiedad "default_popup" configura la ventana emergente en la clave "action" de la Archivo manifest.json. Si está presente, esta propiedad debe apuntar a una ruta de acceso relativa dentro de la extensión. . También se puede actualizar de forma dinámica para que apunte a una ruta relativa diferente usando el action.setPopup().

Casos de uso

Estado por pestaña

Las acciones de extensión pueden tener diferentes estados para cada pestaña. Para establecer un valor para una persona, sigue estos pasos: Usa la propiedad tabId en los métodos de configuración de la API de action. Por ejemplo, para configura el texto de la insignia para una pestaña específica, haz algo como lo siguiente:

function getTabId() { /* ... */}
function getTabBadge() { /* ... */}

chrome.action.setBadgeText(
  {
    text: getTabBadge(tabId),
    tabId: getTabId(),
  },
  () => { ... }
);

Si se omite la propiedad tabId, la configuración se trata como una configuración global. Específico de la pestaña tienen prioridad sobre los globales.

Estado habilitado

De forma predeterminada, las acciones de la barra de herramientas están habilitadas (se puede hacer clic en ellas) en cada pestaña. Puedes controlar esto con el action.enable() y action.disable(). Esto solo afecta si la ventana emergente (si corresponde) o Se envió action.onClicked evento a su extensión. no afecta la presencia de la acción en la barra de herramientas.

Ejemplos

En los siguientes ejemplos, se muestran algunas formas comunes en que se usan las acciones en las extensiones. Para probar esta API, instala el ejemplo de la API de Action desde chrome-extension-samples en un repositorio de confianza.

Mostrar una ventana emergente

Es común que una extensión muestre una ventana emergente cuando el usuario hace clic en la acción de la extensión. Para implementa esto en tu propia extensión, declara la ventana emergente en tu manifest.json y especifica la el contenido que Chrome debería mostrar en la ventana emergente.

// manifest.json
{
  "name": "Action popup demo",
  "version": "1.0",
  "manifest_version": 3,
  "action": {
    "default_title": "Click to view a popup",
    "default_popup": "popup.html"
  }
}
<!-- popup.html -->
<!DOCTYPE html>
<html>
<head>
  <style>
    html {
      min-height: 5em;
      min-width: 10em;
      background: salmon;
    }
  </style>
</head>
<body>
  <p>Hello, world!</p>
</body>
</html>

Insertar una secuencia de comandos de contenido con un clic

Un patrón común para las extensiones es exponer su función principal mediante acción. En el siguiente ejemplo, se muestra este patrón. Cuando el usuario hace clic en la acción, la extensión Inserta una secuencia de comandos de contenido en la página actual. A continuación, la secuencia de comandos de contenido muestra una alerta para verificar. de que todo funcionó según lo esperado.

// manifest.json
{
  "name": "Action script injection demo",
  "version": "1.0",
  "manifest_version": 3,
  "action": {
    "default_title": "Click to show an alert"
  },
  "permissions": ["activeTab", "scripting"],
  "background": {
    "service_worker": "background.js"
  }
}
// background.js
chrome.action.onClicked.addListener((tab) => {
  chrome.scripting.executeScript({
    target: {tabId: tab.id},
    files: ['content.js']
  });
});
// content.js
alert('Hello, world!');

Emula acciones con declareContent

En este ejemplo, se muestra cómo la lógica en segundo plano de una extensión puede (a) inhabilitar una acción de forma predeterminada y (b) Usa declarativeContent para habilitar la acción en sitios específicos.

// service-worker.js

// Wrap in an onInstalled callback to avoid unnecessary work
// every time the service worker is run
chrome.runtime.onInstalled.addListener(() => {
  // Page actions are disabled by default and enabled on select tabs
  chrome.action.disable();

  // Clear all rules to ensure only our expected rules are set
  chrome.declarativeContent.onPageChanged.removeRules(undefined, () => {
    // Declare a rule to enable the action on example.com pages
    let exampleRule = {
      conditions: [
        new chrome.declarativeContent.PageStateMatcher({
          pageUrl: {hostSuffix: '.example.com'},
        })
      ],
      actions: [new chrome.declarativeContent.ShowAction()],
    };

    // Finally, apply our new array of rules
    let rules = [exampleRule];
    chrome.declarativeContent.onPageChanged.addRules(rules);
  });
});

Tipos

OpenPopupOptions

Chrome 99 y versiones posteriores

Propiedades

  • windowId

    número opcional

    El ID de la ventana en la que se abrirá la ventana emergente de acción. Si no se especifica, el valor predeterminado es la ventana activa en este momento.

TabDetails

Propiedades

  • tabId

    número opcional

    El ID de la pestaña para la que se consulta el estado. Si no se especifica ninguna pestaña, se devuelve un estado que no es específico de una pestaña.

UserSettings

Chrome 91 y versiones posteriores

El conjunto de parámetros de configuración especificados por el usuario relacionados con la acción de una extensión.

Propiedades

  • isOnToolbar

    boolean

    Si el ícono de acción de la extensión se puede ver en las ventanas del navegador barra de herramientas de nivel superior (es decir, si el usuario "fijó" la extensión).

Métodos

disable()

Promesa
chrome.action.disable(
  tabId?: number,
  callback?: function,
)

Inhabilita la acción para una pestaña.

Parámetros

  • tabId

    número opcional

    El ID de la pestaña para la que deseas modificar la acción.

  • callback

    función opcional

    El parámetro callback se ve de la siguiente manera:

    () => void

Muestra

  • Promise&lt;void&gt;

    Las promesas son compatibles con Manifest V3 y versiones posteriores, pero se proporcionan devoluciones de llamada para retrocompatibilidad. No puedes usar ambos en la misma llamada a función. El se resuelve con el mismo tipo que se pasa a la devolución de llamada.

enable()

Promesa
chrome.action.enable(
  tabId?: number,
  callback?: function,
)

Habilita la acción para una pestaña. Las acciones están habilitadas de forma predeterminada.

Parámetros

  • tabId

    número opcional

    El ID de la pestaña para la que deseas modificar la acción.

  • callback

    función opcional

    El parámetro callback se ve de la siguiente manera:

    () => void

Muestra

  • Promise&lt;void&gt;

    Las promesas son compatibles con Manifest V3 y versiones posteriores, pero se proporcionan devoluciones de llamada para retrocompatibilidad. No puedes usar ambos en la misma llamada a función. El se resuelve con el mismo tipo que se pasa a la devolución de llamada.

getBadgeBackgroundColor()

Promesa
chrome.action.getBadgeBackgroundColor(
  details: TabDetails,
  callback?: function,
)

Obtiene el color de fondo de la acción.

Parámetros

  • detalles
  • callback

    función opcional

    El parámetro callback se ve de la siguiente manera:

    (result: ColorArray) => void

Muestra

  • Las promesas son compatibles con Manifest V3 y versiones posteriores, pero se proporcionan devoluciones de llamada para retrocompatibilidad. No puedes usar ambos en la misma llamada a función. El se resuelve con el mismo tipo que se pasa a la devolución de llamada.

getBadgeText()

Promesa
chrome.action.getBadgeText(
  details: TabDetails,
  callback?: function,
)

Obtiene el texto de la insignia de la acción. Si no se especifica ninguna pestaña, se mostrará el texto de la insignia que no es específico de una pestaña. Si se habilita displayActionCountAsBadgeText, se mostrará un texto de marcador de posición, a menos que esté presente el permiso declarativeNetRequestFeedback o que se haya proporcionado un texto de insignia específico de la pestaña.

Parámetros

  • detalles
  • callback

    función opcional

    El parámetro callback se ve de la siguiente manera:

    (result: string) => void

    • resultado

      string

Muestra

  • Promesa<string>

    Las promesas son compatibles con Manifest V3 y versiones posteriores, pero se proporcionan devoluciones de llamada para retrocompatibilidad. No puedes usar ambos en la misma llamada a función. El se resuelve con el mismo tipo que se pasa a la devolución de llamada.

getBadgeTextColor()

Promesa Chrome 110 y versiones posteriores .
chrome.action.getBadgeTextColor(
  details: TabDetails,
  callback?: function,
)

Obtiene el color del texto de la acción.

Parámetros

  • detalles
  • callback

    función opcional

    El parámetro callback se ve de la siguiente manera:

    (result: ColorArray) => void

Muestra

  • Las promesas son compatibles con Manifest V3 y versiones posteriores, pero se proporcionan devoluciones de llamada para retrocompatibilidad. No puedes usar ambos en la misma llamada a función. El se resuelve con el mismo tipo que se pasa a la devolución de llamada.

getPopup()

Promesa
chrome.action.getPopup(
  details: TabDetails,
  callback?: function,
)

Obtiene el documento HTML establecido como la ventana emergente para esta acción.

Parámetros

  • detalles
  • callback

    función opcional

    El parámetro callback se ve de la siguiente manera:

    (result: string) => void

    • resultado

      string

Muestra

  • Promesa<string>

    Las promesas son compatibles con Manifest V3 y versiones posteriores, pero se proporcionan devoluciones de llamada para retrocompatibilidad. No puedes usar ambos en la misma llamada a función. El se resuelve con el mismo tipo que se pasa a la devolución de llamada.

getTitle()

Promesa
chrome.action.getTitle(
  details: TabDetails,
  callback?: function,
)

Obtiene el título de la acción.

Parámetros

  • detalles
  • callback

    función opcional

    El parámetro callback se ve de la siguiente manera:

    (result: string) => void

    • resultado

      string

Muestra

  • Promesa<string>

    Las promesas son compatibles con Manifest V3 y versiones posteriores, pero se proporcionan devoluciones de llamada para retrocompatibilidad. No puedes usar ambos en la misma llamada a función. El se resuelve con el mismo tipo que se pasa a la devolución de llamada.

getUserSettings()

Promesa Chrome 91 y versiones posteriores .
chrome.action.getUserSettings(
  callback?: function,
)

Muestra la configuración especificada por el usuario relacionada con la acción de una extensión.

Parámetros

  • callback

    función opcional

    El parámetro callback se ve de la siguiente manera:

    (userSettings: UserSettings) => void

Muestra

  • Promise&lt;UserSettings&gt;

    Las promesas son compatibles con Manifest V3 y versiones posteriores, pero se proporcionan devoluciones de llamada para retrocompatibilidad. No puedes usar ambos en la misma llamada a función. El se resuelve con el mismo tipo que se pasa a la devolución de llamada.

isEnabled()

Promesa Chrome 110 y versiones posteriores .
chrome.action.isEnabled(
  tabId?: number,
  callback?: function,
)

Indica si la acción de extensión está habilitada para una pestaña (o de forma global si no se proporciona un tabId). Las acciones que se habilitan solo con declarativeContent siempre muestran un valor falso.

Parámetros

  • tabId

    número opcional

    El ID de la pestaña en la que quieres comprobar el estado habilitado.

  • callback

    función opcional

    El parámetro callback se ve de la siguiente manera:

    (isEnabled: boolean) => void

    • isEnabled

      boolean

      Es verdadero si la acción de extensión está habilitada.

Muestra

  • Promise&lt;boolean&gt;

    Las promesas son compatibles con Manifest V3 y versiones posteriores, pero se proporcionan devoluciones de llamada para retrocompatibilidad. No puedes usar ambos en la misma llamada a función. El se resuelve con el mismo tipo que se pasa a la devolución de llamada.

openPopup()

Promesa Chrome 127 y versiones posteriores .
chrome.action.openPopup(
  options?: OpenPopupOptions,
  callback?: function,
)

Abre la ventana emergente de la extensión. Entre Chrome 118 y Chrome 126, esto solo está disponible para las extensiones instaladas por políticas.

Parámetros

  • opciones

    Especifica las opciones para abrir la ventana emergente.

  • callback

    función opcional

    El parámetro callback se ve de la siguiente manera:

    () => void

Muestra

  • Promise&lt;void&gt;

    Las promesas son compatibles con Manifest V3 y versiones posteriores, pero se proporcionan devoluciones de llamada para retrocompatibilidad. No puedes usar ambos en la misma llamada a función. El se resuelve con el mismo tipo que se pasa a la devolución de llamada.

setBadgeBackgroundColor()

Promesa
chrome.action.setBadgeBackgroundColor(
  details: object,
  callback?: function,
)

Establece el color de fondo de la insignia.

Parámetros

  • detalles

    objeto

    • color

      string | ColorArray

      Un array de cuatro números enteros en el rango [0,255] que conforman el color RGBA de la insignia. Por ejemplo, el rojo opaco es [255, 0, 0, 255]. También puede ser una cadena con un valor de CSS, donde el rojo opaco es #FF0000 o #F00.

    • tabId

      número opcional

      Limita el cambio al momento en que se selecciona una pestaña en particular. Se restablece automáticamente cuando se cierra la pestaña.

  • callback

    función opcional

    El parámetro callback se ve de la siguiente manera:

    () => void

Muestra

  • Promise&lt;void&gt;

    Las promesas son compatibles con Manifest V3 y versiones posteriores, pero se proporcionan devoluciones de llamada para retrocompatibilidad. No puedes usar ambos en la misma llamada a función. El se resuelve con el mismo tipo que se pasa a la devolución de llamada.

setBadgeText()

Promesa
chrome.action.setBadgeText(
  details: object,
  callback?: function,
)

Establece el texto de la insignia para la acción. La insignia se muestra en la parte superior del ícono.

Parámetros

  • detalles

    objeto

    • tabId

      número opcional

      Limita el cambio al momento en que se selecciona una pestaña en particular. Se restablece automáticamente cuando se cierra la pestaña.

    • texto

      string opcional

      Se puede pasar cualquier cantidad de caracteres, pero solo pueden caber cuatro en el espacio. Si se pasa una cadena vacía (''), se borrará el texto de la insignia. Si se especifica tabId y text tiene un valor nulo, se borra el texto de la pestaña especificada y se establece de forma predeterminada el texto de la insignia global.

  • callback

    función opcional

    El parámetro callback se ve de la siguiente manera:

    () => void

Muestra

  • Promise&lt;void&gt;

    Las promesas son compatibles con Manifest V3 y versiones posteriores, pero se proporcionan devoluciones de llamada para retrocompatibilidad. No puedes usar ambos en la misma llamada a función. El se resuelve con el mismo tipo que se pasa a la devolución de llamada.

setBadgeTextColor()

Promesa Chrome 110 y versiones posteriores .
chrome.action.setBadgeTextColor(
  details: object,
  callback?: function,
)

Establece el color del texto de la insignia.

Parámetros

  • detalles

    objeto

    • color

      string | ColorArray

      Un array de cuatro números enteros en el rango [0,255] que conforman el color RGBA de la insignia. Por ejemplo, el rojo opaco es [255, 0, 0, 255]. También puede ser una cadena con un valor de CSS, donde el rojo opaco es #FF0000 o #F00. Si no estableces este valor, se elegirá automáticamente un color que contrastará con el color de fondo de la insignia para que el texto sea visible. Los colores con valores alfa equivalentes a 0 no se establecerán y mostrarán un error.

    • tabId

      número opcional

      Limita el cambio al momento en que se selecciona una pestaña en particular. Se restablece automáticamente cuando se cierra la pestaña.

  • callback

    función opcional

    El parámetro callback se ve de la siguiente manera:

    () => void

Muestra

  • Promise&lt;void&gt;

    Las promesas son compatibles con Manifest V3 y versiones posteriores, pero se proporcionan devoluciones de llamada para retrocompatibilidad. No puedes usar ambos en la misma llamada a función. El se resuelve con el mismo tipo que se pasa a la devolución de llamada.

setIcon()

Promesa
chrome.action.setIcon(
  details: object,
  callback?: function,
)

Establece el ícono de la acción. El ícono se puede especificar como la ruta de acceso a un archivo de imagen, como los datos de píxeles de un elemento de lienzo o como un diccionario de cualquiera de ellos. Se debe especificar la propiedad path o imageData.

Parámetros

  • detalles

    objeto

    • imageData

      ImageData | objeto opcional

      Un objeto ImageData o un diccionario {size -> ImageData}, que representa el ícono que se debe establecer. Si el ícono se especifica como un diccionario, se elige la imagen real que se usará según la densidad de píxeles de la pantalla. Si la cantidad de píxeles de la imagen que entran en una unidad de espacio de pantalla es igual a scale, se seleccionará la imagen con el tamaño scale * n, donde n es el tamaño del ícono en la IU. Se debe especificar al menos una imagen. Ten en cuenta que 'details.imageData = foo' equivale a 'details.imageData = {'16': foo}"

    • ruta de acceso

      string | objeto opcional

      una ruta de imagen relativa o un diccionario {size -> Relative image path} que apunta al ícono que se debe establecer. Si el ícono se especifica como un diccionario, se elige la imagen real que se usará según la densidad de píxeles de la pantalla. Si la cantidad de píxeles de la imagen que entran en una unidad de espacio de pantalla es igual a scale, se seleccionará la imagen con el tamaño scale * n, donde n es el tamaño del ícono en la IU. Se debe especificar al menos una imagen. Ten en cuenta que 'details.path = foo' equivale a 'details.path = {'16': foo}'

    • tabId

      número opcional

      Limita el cambio al momento en que se selecciona una pestaña en particular. Se restablece automáticamente cuando se cierra la pestaña.

  • callback

    función opcional

    El parámetro callback se ve de la siguiente manera:

    () => void

Muestra

  • Promise&lt;void&gt;

    Chrome 96 y versiones posteriores

    Las promesas son compatibles con Manifest V3 y versiones posteriores, pero se proporcionan devoluciones de llamada para retrocompatibilidad. No puedes usar ambos en la misma llamada a función. El se resuelve con el mismo tipo que se pasa a la devolución de llamada.

setPopup()

Promesa
chrome.action.setPopup(
  details: object,
  callback?: function,
)

Configura el documento HTML para que se abra como una ventana emergente cuando el usuario hace clic en el ícono de la acción.

Parámetros

  • detalles

    objeto

    • ventana emergente

      string

      La ruta de acceso relativa al archivo HTML que se mostrará en una ventana emergente. Si se configura en la cadena vacía (''), no se muestra ninguna ventana emergente.

    • tabId

      número opcional

      Limita el cambio al momento en que se selecciona una pestaña en particular. Se restablece automáticamente cuando se cierra la pestaña.

  • callback

    función opcional

    El parámetro callback se ve de la siguiente manera:

    () => void

Muestra

  • Promise&lt;void&gt;

    Las promesas son compatibles con Manifest V3 y versiones posteriores, pero se proporcionan devoluciones de llamada para retrocompatibilidad. No puedes usar ambos en la misma llamada a función. El se resuelve con el mismo tipo que se pasa a la devolución de llamada.

setTitle()

Promesa
chrome.action.setTitle(
  details: object,
  callback?: function,
)

Establece el título de la acción. Esto aparece en el cuadro de información.

Parámetros

  • detalles

    objeto

    • tabId

      número opcional

      Limita el cambio al momento en que se selecciona una pestaña en particular. Se restablece automáticamente cuando se cierra la pestaña.

    • título

      string

      La cadena que debe mostrar la acción cuando se desplaza el mouse sobre ella.

  • callback

    función opcional

    El parámetro callback se ve de la siguiente manera:

    () => void

Muestra

  • Promise&lt;void&gt;

    Las promesas son compatibles con Manifest V3 y versiones posteriores, pero se proporcionan devoluciones de llamada para retrocompatibilidad. No puedes usar ambos en la misma llamada a función. El se resuelve con el mismo tipo que se pasa a la devolución de llamada.

Eventos

onClicked

chrome.action.onClicked.addListener(
  callback: function,
)

Se activa cuando se hace clic en un ícono de acción. Este evento no se activará si la acción tiene una ventana emergente.

Parámetros

  • callback

    función

    El parámetro callback se ve de la siguiente manera:

    (tab: tabs.Tab) => void