Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Varios sistemas operativos tienen widgets, paneles que permiten a los usuarios leer contenido y realizar tareas. Algunos ejemplos son los widgets de la pantalla principal de Android, los widgets del panel de control y hoy de macOS, la barra táctil de Apple, las tarjetas diarias de Samsung, los widgets de miniaplicaciones y los compañeros de aplicaciones de relojes inteligentes.
En Windows 11, los widgets aparecen en el panel de widgets, que se abre desde el lado izquierdo de la barra de tareas:
En Windows 11, las Web Apps progresivas (PWA) pueden definir widgets, actualizarlos y controlar las interacciones del usuario dentro de ellos.
Requiere la creación de un widget personalizado para la PWA
Una PWA existente no se puede colocar simplemente en el panel de widgets tal cual, como puede hacer con la barra lateral de Microsoft Edge. En su lugar, debes crear una experiencia de widget personalizada que sea adecuada para el host del widget, que actualmente es el panel de widgets de Windows 11. (Puede haber otros hosts de widgets en el futuro). El panel de widgets de Windows 11 requiere que los widgets se generen mediante plantillas de tarjeta adaptable en lugar de HTML y JavaScript, por lo que el widget debe diseñarse por separado del resto de la interfaz de usuario de la aplicación.
Vea también:
Para crear un widget controlado por PWA y entregarlo a través de la Microsoft Store, no se requiere código C++/C#. Una vez que haya creado el widget y pueda instalar y ejecutar correctamente el widget desde un punto de conexión público, puede empaquetar la aplicación mediante PWABuilder.com y enviarla a Microsoft Store sin necesidad de ningún código adicional. La PWA que respalda el widget debe poder instalarse desde un punto de conexión público, ya que PWABuilder no admite empaquetar aplicaciones desde localhost.
Vea también:
Instalación de WinAppSDK y habilitación del modo de desarrollador
Para habilitar el desarrollo y la prueba de widgets en el equipo local:
Instale WinAppSDK 1.2.
Habilitar el modo de desarrollador en Windows 11:
Abrir configuración.
En el cuadro de texto Buscar una configuración , escriba
developery, a continuación, haga clic en Usar funciones para desarrolladores.Habilitar el modo de desarrollador:
Definir widgets
Los widgets se definen en el archivo de manifiesto de PWA, mediante el miembro de widgets manifiesto. Este miembro de manifiesto es una matriz que puede contener varias definiciones de widgets.
{
"name": "PWAmp",
"description": "A music player app",
"icons": [
{ "src": "img/icon-96.png", "sizes": "96x96" },
{ "src": "img/icon-128.png", "sizes": "128x128" },
{ "src": "img/icon-256.png", "sizes": "256x256" },
{ "src": "img/icon-512.png", "sizes": "512x512" }
],
"widgets": [
/* widget definitions go here */
]
}
Cada entrada de la widgets matriz contiene varios campos, como se muestra a continuación:
{
...
"widgets": [
{
"name": "PWAmp mini player",
"description": "widget to control the PWAmp music player",
"tag": "pwamp",
"template": "pwamp-template",
"ms_ac_template": "widgets/mini-player-template.json",
"data": "widgets/mini-player-data.json",
"type": "application/json",
"screenshots": [
{
"src": "./screenshot-widget.png",
"sizes": "600x400",
"label": "The PWAmp mini-player widget"
}
],
"icons": [
{
"src": "./favicon-16.png",
"sizes": "16x16"
}
],
"auth": false,
"update": 86400
}
]
}
En el ejemplo anterior, una aplicación de reproductor de música define un widget de mini reproductor. Una definición de widget en el manifiesto de la aplicación web tiene los siguientes campos obligatorios y opcionales:
| Campo | Description | ¿Necesario? |
|---|---|---|
name |
El título del widget, presentado a los usuarios. | Sí |
short_name |
Una versión corta alternativa del nombre. | No |
description |
Una descripción de lo que hace el widget. | Sí |
icons |
Una matriz de iconos que se usarán para el widget. Si falta, se usa en su lugar el miembro del icons manifiesto. Se omiten los iconos mayores de 1024 x 1024. |
No |
screenshots |
Una serie de capturas de pantalla que muestran el aspecto del widget. Análogo al screenshot miembro manifiesto. El platform campo de un elemento de captura de pantalla admite los Windows valores y any Se ignoran las imágenes de más de 1024 x 1024 píxeles. Para conocer los requisitos de captura de pantalla específicos del panel de widgets de Windows 11, consulte Requisitos de imagen de captura de pantalla en Integración con el selector de widgets. |
Sí |
tag |
Cadena que se usa para hacer referencia al widget en el trabajo de servicio de PWA. | Sí |
template |
La plantilla que se va a usar para mostrar el widget en el panel de widgets del sistema operativo. Nota: actualmente, esta propiedad solo es informativa y no se usa. Consulte ms_ac_template a continuación. |
No |
ms_ac_template |
La dirección URL de la plantilla personalizada de tarjetas adaptables que se usará para mostrar el widget en el panel de widgets del sistema operativo. Consulte Definición de una plantilla de widget más abajo. | Sí |
data |
La dirección URL donde se pueden encontrar los datos con los que rellenar la plantilla. Si está presente, esta dirección URL es necesaria para devolver un JSON válido. | No |
type |
El tipo MIME de los datos del widget. | No |
auth |
Un valor booleano que indica si el widget requiere autenticación. | No |
update |
La frecuencia, en segundos, con la que se actualizará el widget. El código del trabajo de servicio debe realizar la actualización; El widget no se actualiza automáticamente. Consulte Acceder a instancias de widgets en tiempo de ejecución. | No |
multiple |
Un valor booleano que indica si se permiten varias instancias del widget. Valores predeterminados de true. |
No |
Definir una plantilla de widget
Para que los widgets sean fáciles de crear y adaptar a varios paneles de widgets del sistema operativo, se muestran mediante plantillas. Existen dos tipos de plantillas:
- Plantillas genéricas, definidas por sus nombres mediante el
templatecampo. - Plantillas personalizadas, definidas por sus direcciones URL mediante un campo de plantilla personalizado.
Por el momento, solo se admiten plantillas de tarjetas adaptables personalizadas. Las tarjetas adaptables son un formato de intercambio de tarjetas abierto que se puede usar para intercambiar contenido de la interfaz de usuario de una manera común y coherente. Consulta Información general sobre tarjetas adaptables.
Para definir una plantilla personalizada de tarjetas adaptables en Windows 11, usa el campo de la definición del widget que se encuentra en el manifiesto de la ms_ac_template aplicación web. Aunque template no se usa actualmente, es un campo obligatorio.
{
...
"template": "pwamp-template",
"ms_ac_template": "widgets/mini-player.json",
...
}
El ms_ac_template valor del campo debe ser una dirección URL válida de un archivo de plantilla.
Este es un ejemplo de una plantilla de tarjetas adaptables:
{
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"size": "Medium",
"text": "Now playing...",
"horizontalAlignment": "Center"
},
{
"type": "TextBlock",
"spacing": "Large",
"weight": "Bolder",
"horizontalAlignment": "Center",
"text": "${song}, by ${artist}",
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.5"
}
Para obtener más información, consulte Plantillas de tarjetas adaptables.
A continuación, debe enlazar los datos a la plantilla.
Enlazar datos a la plantilla
La plantilla declara la interfaz de usuario de un widget. A continuación, los datos rellenan esta interfaz de usuario.
Para enlazar datos a la plantilla, use el campo en la definición del data widget. Este campo debe establecerse en una dirección URL que devuelva datos JSON válidos.
La plantilla definida en la sección anterior contiene dos variables: song y artist, que se incluyen en la sintaxis de la expresión de enlace: ${}. Los datos devueltos por la URL en la data definición del widget deben contener valores para estas variables.
Este es un ejemplo de lo que podría devolver la data dirección URL:
{
"song": "I Will Always Love You",
"artist": "Whitney Houston"
}
Definir acciones de widget
Si desea que el widget permita que los usuarios realicen tareas, defina una plantilla que admita acciones.
Este es un ejemplo de una acción definida en una plantilla personalizada de tarjetas adaptables:
{
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"size": "Medium",
"text": "Now playing...",
"horizontalAlignment": "Center"
},
{
"type": "TextBlock",
"spacing": "Large",
"weight": "Bolder",
"horizontalAlignment": "Center",
"text": "${song}, by ${artist}",
}
],
"actions": [
{
"type": "Action.Execute",
"title": "Previous",
"verb": "previous-song"
},
{
"type": "Action.Execute",
"title": "Next",
"verb": "next-song"
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.5"
}
Anote el verb campo de la plantilla JSON anterior. Se usará al gestionar las acciones del widget en el código del trabajo de servicio. Consulte Gestionar acciones de widgets.
Acceder a instancias de widgets en tiempo de ejecución
Puede acceder a los widgets y actualizarlos desde el código de trabajo de servicio de PWA. El acceso a widgets en tiempo de ejecución es útil en casos como:
- Representación de widgets durante la instalación.
- Actualizando widgets en actualizaciones de trabajos de servicio.
- Control de las acciones del usuario en los widgets.
- Actualizar widgets cuando cambia la aplicación.
Un trabajo de servicio tiene acceso al objeto y a varios eventos de self.widgets widget que, en conjunto, constituyen una API que se usa para reaccionar a los cambios y acceder a los widgets en tiempo de ejecución.
En las secciones siguientes se proporcionan ejemplos de código. Para obtener una referencia de la API, consulte la referencia de la API del trabajo de servicio.
Representar widgets en la instalación
Cuando se instala una PWA, los widgets que la aplicación define en su manifiesto se agregan al panel de widgets, pero aún no están instalados. Un widget solo se instala cuando el usuario elige agregar el widget desde el panel.
Cuando se instala un widget, no se representa automáticamente utilizando los ms_ac_template campos and data de la definición del widget.
Para representar el widget, escucha el evento en el trabajo de widgetinstall servicio y actualiza el widget mediante la widgets.updateByTag función:
// Listen to the widgetinstall event.
self.addEventListener("widgetinstall", event => {
// The widget just got installed, render it using renderWidget.
// Pass the event.widget object to the function.
event.waitUntil(renderWidget(event.widget));
});
async function renderWidget(widget) {
// Get the template and data URLs from the widget definition.
const templateUrl = widget.definition.msAcTemplate;
const dataUrl = widget.definition.data;
// Fetch the template text and data.
const template = await (await fetch(templateUrl)).text();
const data = await (await fetch(dataUrl)).text();
// Render the widget with the template and data.
await self.widgets.updateByTag(widget.definition.tag, {template, data});
}
Actualizar widgets en actualizaciones de trabajos de servicio
Cuando el código del trabajo de servicio cambia en una PWA, el explorador detecta ese cambio, instala el nuevo trabajo de servicio y, posteriormente, activa el trabajo de servicio.
Cuando esto ocurre, es importante actualizar las instancias de widget que ya puedan estar ejecutándose. Es posible que los widgets se hayan instalado antes de que se emita el evento de trabajo activate de servicio. Para evitar que se muestren widgets vacíos, actualiza los widgets cuando se produzca el activate evento
// Update the widgets to their initial states
// when the service worker is activated.
self.addEventListener("activate", event => {
event.waitUntil(updateWidgets());
});
async function updateWidgets() {
// Get the widget that match the tag defined in the web app manifest.
const widget = await self.widgets.getByTag("pwamp");
if (!widget) {
return;
}
// Using the widget definition, get the template and data.
const template = await (await fetch(widget.definition.msAcTemplate)).text();
const data = await (await fetch(widget.definition.data)).text();
// Render the widget with the template and data.
await self.widgets.updateByTag(widget.definition.tag, {template, data});
}
Gestionar acciones de widget
Si la plantilla de widget contiene acciones, los usuarios pueden ejecutar esas acciones haciendo clic en los botones del widget representado. Para obtener información sobre cómo definir acciones en una plantilla, consulte Definir acciones de widget.
Cuando un usuario ejecuta una acción de widget, se desencadena un widgetclick evento en el trabajo de servicio de PWA. Para controlar la acción del usuario, escucha el evento:
self.addEventListener('widgetclick', (event) => {
switch (event.action) {
case 'previous-song':
// Application logic to play the previous song...
break;
case 'next-song':
// Application logic to play the next song...
break;
}
});
Para abreviar, el código de aplicación real no se muestra en el fragmento de código anterior. Cuando se reciben las previous-song acciones o next-song , es probable que sea necesario enviar un mensaje a la aplicación mediante Client.postMessage para informar a la aplicación de que debe empezar a reproducir las canciones anteriores o siguientes.
Tenga en cuenta que la action propiedad del widgetEvent objeto pasado al detector de eventos anterior coincide con la cadena definida en el action.verb campo de la plantilla de widget.
Para obtener más información sobre el widgetclick evento y a qué información puede acceder desde él, consulte Referencia de la API del trabajo de servicio a continuación.
Actualizar widgets en cambios de aplicación
En secciones anteriores, aprendió cómo actualizar widgets cuando se producían eventos específicos de widget, acciones de widget y actualizaciones de trabajos de servicio. También puede ser útil para actualizar widgets cuando sucede algo en la aplicación, o cuando ocurre una notificación push, o periódicamente.
En esta sección, aprenderá a usar la API de sincronización periódica en segundo plano para actualizar widgets periódicamente. Para obtener más información sobre la API de sincronización periódica en segundo plano, consulte Uso de la API de sincronización periódica en segundo plano para obtener contenido actualizado de forma periódica.
En el siguiente fragmento de código, se utiliza un detector de eventos para reaccionar a varios eventos del ciclo de vida del widget de aplicación. Cuando se detecta una instalación de widget, se registra una sincronización periódica y cuando se detecta la eliminación de un widget, la sincronización periódica no se registra.
Cuando se producen eventos de sincronización periódicos, las instancias de widget se actualizan con la widgets.updateByTag función.
self.addEventListener("widgetinstall", event => {
event.waitUntil(onWidgetInstall(event.widget));
});
self.addEventListener("widgetuninstall", event => {
event.waitUntil(onWidgetUninstall(event.widget));
});
async function onWidgetInstall(widget) {
// Register a periodic sync, if this wasn't done already.
// We use the same tag for the sync registration and the widget to
// avoid registering several periodic syncs for the same widget.
const tags = await self.registration.periodicSync.getTags();
if (!tags.includes(widget.definition.tag)) {
await self.registration.periodicSync.register(widget.definition.tag, {
minInterval: widget.definition.update
});
}
// And also update the instance.
await updateWidget(widget);
}
async function onWidgetUninstall(widget) {
// On uninstall, unregister the periodic sync.
// If this was the last widget instance, then unregister the periodic sync.
if (widget.instances.length === 1 && "update" in widget.definition) {
await self.registration.periodicSync.unregister(widget.definition.tag);
}
}
// Listen to periodicsync events to update all widget instances
// periodically.
self.addEventListener("periodicsync", async event => {
const widget = await self.widgets.getByTag(event.tag);
if (widget && "update" in widget.definition) {
event.waitUntil(updateWidget(widget));
}
});
async function updateWidget(widget) {
// Get the template and data URLs from the widget definition.
const templateUrl = widget.definition.msAcTemplate;
const dataUrl = widget.definition.data;
// Fetch the template text and data.
const template = await (await fetch(templateUrl)).text();
const data = await (await fetch(dataUrl)).text();
// Render the widget with the template and data.
await self.widgets.updateByTag(widget.definition.tag, {template, data});
}
Aplicación de demostración
PWAmp es un reproductor de música PWA demo aplicación que define un widget. El widget PWAmp permite a los usuarios visualizar la canción actual y reproducir las canciones anteriores o siguientes.
Si aún no lo ha hecho, instale WinAppSDK 1.2 y habilite el modo de desarrollador en Windows 11.
Vaya a PWAmp e instale la aplicación en Windows 11.
Abra el panel de widgets de Windows 11 presionando la tecla del logotipo de Windows + W.
Haga clic en Agregar widgets para abrir la pantalla de configuración de widgets , desplácese hasta el widget del mini reproductor de PWAmp y agréguelo.
Cierre la pantalla de configuración de widgets . El mini reproductor de PWAmp ahora se muestra en el panel de widgets.
El widget PWAmp muestra la canción actual y los botones para reproducir la canción anterior o siguiente.
Referencia de API del trabajo de servicio
El objeto global de trabajo de servicio (o ServiceWorkerGlobalScope) contiene un widgets atributo que expone los siguientes métodos basados en promesas:
| Método | Descripción | Parameters | Valor devuelto |
|---|---|---|---|
getByTag(tag) |
Obtiene un widget por etiqueta. | La etiqueta de widget | Una promesa que se resuelve en el objeto widget que coincide con la etiqueta, o undefined. |
getByInstanceId(id) |
Obtiene un widget por identificador de instancia. | El identificador de instancia del widget | Una promesa que se resuelve en el objeto widget correspondiente, o undefined. |
getByHostId(id) |
Obtiene widgets por identificador de host. | El id. del host | Una matriz de objetos widget encontrados en ese host. |
matchAll(options) |
Obtiene widgets por opciones coincidentes. | Un objeto widgetOptions | Una promesa que se resuelve en una matriz de objetos de widget que coinciden con los options criterios. |
updateByInstanceId(id, payload) |
Novedades un widget por identificador de instancia. | El identificador de instancia y un objeto widgetPayload | Una promesa que resuelve en undefined o Error. |
updateByTag(tag, payload) |
Novedades un widget por etiqueta. | La etiqueta widget y un objeto widgetPayload | Una promesa que resuelve en undefined o Error. |
El objeto global del trabajo de servicio también define los siguientes eventos:
-
widgetinstall: se desencadena cuando el host del widget está instalando un widget. -
widgetuninstall: se desencadena cuando el host del widget está desinstalando un widget. -
widgetresume: se desencadena cuando el host del widget reanuda la representación de los widgets instalados, lo que puede ocurrir después de que el host suspendiera la representación de los widgets para conservar los recursos. -
widgetclick: se desencadena cuando el usuario ejecuta una de las acciones del widget.
Para obtener más información sobre los objetos que se proporcionan con estos eventos, vea widgetEvent object y widgetClickEvent object, a continuación.
objeto widget
Cada widget se representa como un widget objeto que contiene las siguientes propiedades:
-
installable: un valor booleano que indica si el widget se puede instalar. -
definition: un objeto widgetDefinition. -
instances: una matriz de objetos widgetInstance que representan el estado actual de cada instancia del widget.
Objeto widgetOptions
Cuando se usa matchAll(options) para obtener varios widgets, es necesario un widgetOptions objeto para filtrar qué widgets devolver. El widgetOptions objeto contiene las siguientes propiedades, todas las cuales son opcionales:
-
installable: un valor booleano que indica si los widgets devueltos se deben instalar. -
installed: un valor booleano que indica si los widgets devueltos están instalados en el host del widget. -
tag: una cadena que se usa para filtrar los widgets devueltos por etiqueta. -
instanceId: una cadena que se usa para filtrar los widgets devueltos por identificador de instancia. -
hostId: una cadena que se usa para filtrar los widgets devueltos por ID de host del widget.
Objeto widgetPayload
Al crear o actualizar una instancia de widget, el trabajo de servicio debe enviar la plantilla y los datos necesarios para rellenar el widget. La plantilla y los datos se denominan carga útil. El widgetPayload objeto contiene las siguientes propiedades:
-
template: la plantilla, como una cadena, que se usará para representar el widget. Este será el JSON stringified de una plantilla de tarjeta adaptable. -
data: los datos, como una cadena, que se van a usar con la plantilla de widget. Estos datos pueden ser datos JSON stringified.
Objeto widgetInstance
Este objeto representa una instancia determinada de un widget en un host de widget y contiene las siguientes propiedades:
-
id: la cadena GUID interna usada para hacer referencia a la instancia. -
host: puntero interno al host del widget que ha instalado esta instancia. -
updated: unDateobjeto que representa la última vez que se enviaron datos a la instancia. -
payload: un objeto widgetPayload que representa la última carga que se envió a esta instancia.
Objeto widgetDefinition
Este objeto representa la definición original del widget, que se encuentra en el archivo de manifiesto de PWA. Las propiedades de este objeto coinciden con las propiedades que se enumeran en Definir widgets, arriba.
Objeto widgetEvent
Este objeto se pasa como argumento a los oyentes de eventos de widget de trabajo de servicio de tipo widgetinstall, widgetuninstall, y widgetresume.
Para los tipos , widgetinstallwidgetuninstall, y widgetresume event, el widgetEvent objeto tiene las siguientes propiedades:
| Propiedad | Descripción | Tipo |
|---|---|---|
widget |
La instancia del widget que desencadenó el evento. | widget |
instanceId |
El identificador de instancia del widget. | String |
hostId |
El ID de host del widget. | String |
Objeto widgetClickEvent
Este objeto se pasa como argumento a los oyentes de eventos de widget de trabajo de servicio de tipo widgetclick. Puedes abrir la ventana de la widgetclick aplicación en respuesta al evento mediante .clients.openWindow()
El widgetClickEvent objeto tiene las siguientes propiedades:
| Propiedad | Descripción | Tipo |
|---|---|---|
action |
La acción que desencadenó el evento, tal como se define en los actions.verb campos de la plantilla de widget. Consulte Definir acciones de widget. |
String |
widget |
La instancia del widget que desencadenó el evento. | widgetInstance |
hostId |
El ID de host del widget. | String |
instanceId |
El identificador de instancia del widget. | String |