Um widget é um elemento de interface que oferece um ou mais dos seguintes recursos:
- Estrutura para outros widgets, como cards e seções.
 - Informações para o usuário, como texto e imagens, ou
 - Affordances para ação, como botões, campos de entrada de texto ou caixas de seleção.
 
Os conjuntos de widgets adicionados às seções de cards definem a interface geral do complemento. Os widgets têm a mesma aparência e função na Web e em dispositivos móveis. A documentação de referência descreve vários métodos para criar conjuntos de widgets.
Tipos de widget
Os widgets de complemento geralmente são categorizados em três grupos: estruturais, informativos e de interação do usuário.
Widgets estruturais
Os widgets estruturais fornecem contêineres e organização para os outros widgets usados na interface.
- Conjunto de botões: uma coleção de um ou mais botões de texto ou imagem, agrupados em uma linha horizontal.
 - Card: um único card de contexto que contém uma ou mais seções. Você define como os usuários podem se mover entre cards configurando a navegação por cards.
 - Cabeçalho do card: o cabeçalho de um card específico. Os cabeçalhos dos cards podem ter títulos, subtítulos e uma imagem. As ações do card e as ações universais aparecem no cabeçalho do card se o complemento as usar.
 - Seção de cards: um grupo coletado de widgets, dividido das outras seções de cards por uma regra horizontal e, opcionalmente, com um cabeçalho de seção. Cada card precisa ter pelo menos uma seção. Não é possível adicionar cards ou cabeçalhos de card a uma seção de card.
 
Além desses widgets estruturais básicos, em um complemento do Google Workspace, você pode usar o serviço de card para criar estruturas que se sobrepõem ao card atual: rodapés fixos e cards de visualização:
Rodapé fixo
Você pode adicionar uma linha fixa de botões à parte de baixo do card. Essa linha não se move nem rola com o restante do conteúdo do card.

O trecho de código a seguir mostra como definir um exemplo de rodapé fixo e adicioná-lo a um card:
var fixedFooter = CardService.newFixedFooter()
    .setPrimaryButton(
        CardService.newTextButton()
            .setText("Primary")
            .setOpenLink(CardService.newOpenLink()
                .setUrl("https://www.google.com")))
    .setSecondaryButton(
        CardService.newTextButton()
            .setText("Secondary")
            .setOnClickAction(
                CardService.newAction()
                    .setFunctionName(
                        "secondaryCallback")));
var card = CardService.newCardBuilder()
    // (...)
    .setFixedFooter(fixedFooter)
    .build();
Exibir card

Quando um novo conteúdo contextual é acionado por uma ação do usuário, como abrir uma mensagem do Gmail, você pode mostrar o novo conteúdo imediatamente (comportamento padrão) ou exibir uma notificação de card de visualização na parte de baixo da barra lateral. Se um usuário clicar em Voltar para retornar à sua página inicial enquanto um gatilho contextual está ativo, um card de prévia vai aparecer para ajudar os usuários a encontrar o conteúdo contextual novamente.
Para mostrar um card de visualização quando um novo conteúdo contextual estiver disponível, em vez de
mostrar imediatamente o novo conteúdo contextual, adicione
.setDisplayStyle(CardService.DisplayStyle.PEEK) à sua classe
CardBuilder. Um card de prévia só aparece se um único objeto de card for retornado com seu
gatilho contextual. Caso contrário, os cards retornados substituem imediatamente o
card atual.
Para personalizar o cabeçalho do card de prévia, adicione o método .setPeekCardHeader() com um objeto CardHeader padrão ao criar o card contextual. Por padrão, um cabeçalho de card de visualização
contém apenas o nome do seu complemento.

O código a seguir, com base no início rápido do complemento Gatos do Google Workspace, notifica os usuários sobre novos conteúdos contextuais com um cartão de espiada e personaliza o cabeçalho do cartão de espiada para mostrar o assunto da conversa selecionada do Gmail.
var peekHeader = CardService.newCardHeader()
    .setTitle('Contextual Cat')
    .setImageUrl('https://www.gstatic.com/images/
        icons/material/system/1x/pets_black_48dp.png')
    .setSubtitle(text);
. . .
var card = CardService.newCardBuilder()
    .setDisplayStyle(CardService.DisplayStyle.PEEK)
    .setPeekCardHeader(peekHeader);
Widgets informativos
Os widgets informativos apresentam informações ao usuário.
- Imagem: uma imagem indicada por um URL hospedado e acessível publicamente que você fornece.
 - DecoratedText: uma string de conteúdo de texto que pode ser combinada com outros elementos, como rótulos de texto na parte superior e inferior, além de uma imagem ou um ícone. Os widgets DecoratedText também podem incluir um widget Button ou Switch. Os switches adicionados podem ser alternâncias ou caixas de seleção. O texto de conteúdo do widget DecoratedText pode usar formatação HTML. Já os rótulos superior e inferior precisam usar texto simples.
 - Parágrafo de texto: um parágrafo de texto que pode incluir elementos formatados em HTML.
 
Widgets de interação do usuário
Os widgets de interação do usuário permitem que o complemento responda às ações realizadas pelos usuários. É possível configurar esses widgets com respostas de ação para mostrar diferentes cards, abrir URLs, mostrar notificações, criar rascunhos de e-mails ou executar outras funções do Apps Script. Consulte o guia Como criar cards interativos para mais detalhes.
- Ação do card: um item de menu colocado no menu da barra de cabeçalho do complemento. O menu da barra de cabeçalho também pode conter itens definidos como ações universais, que aparecem em todos os cards definidos pelo complemento.
 - Seletores de data e hora: widgets que permitem aos usuários selecionar uma data, um horário ou ambos. Consulte Seletores de data e hora abaixo para mais informações.
 - Botão de imagem: um botão que usa uma imagem em vez de texto. Você pode usar um dos vários ícones predefinidos ou uma imagem hospedada publicamente indicada pelo URL.
 - Entrada de seleção: um campo de entrada que representa uma coleção de opções. Os widgets de entrada de seleção aparecem como caixas de seleção, botões de opção ou caixas de seleção suspensas.
 - Switch: um widget de alternância. Só é possível usar chaves em conjunto com um widget DecoratedText. Por padrão, eles aparecem como um botão de alternância, mas é possível fazer com que sejam exibidos como uma caixa de seleção.
 - Botão de texto: um botão com um rótulo de texto. É possível especificar um preenchimento de cor de fundo para botões de texto (o padrão é transparente). Você também pode desativar o botão conforme necessário.
 - Entrada de texto: um campo de entrada de texto. O widget pode ter texto de título, texto de dica e texto de várias linhas. O widget pode acionar ações quando o valor do texto muda.
 - Grade: um layout de várias colunas que representa uma coleção de itens. É possível representar itens com uma imagem, um título, um subtítulo e várias opções de personalização, como estilos de borda e corte.
 
Caixas de seleção DecoratedText
É possível definir um widget DecoratedText
com uma caixa de seleção anexada, em vez de um botão ou uma chave
binária. Assim como nos botões de alternância, o valor da caixa de seleção é incluído no
objeto de evento de ação
transmitido ao Action
anexado a esse DecoratedText
pelo método
setOnClickAction(action).

O trecho de código a seguir mostra como definir um widget de caixa de seleção DecoratedText
que pode ser adicionado a um card:
var decoratedText = CardService.newDecoratedText()
    // (...)
    .setSwitch(CardService.newSwitch()
        .setFieldName('form_input_switch_key')
        .setValue('switch_is_on')
        .setControlType(
            CardService.SwitchControlType.CHECK_BOX));
Seletores de data e hora
Você pode definir widgets que permitem aos usuários selecionar um horário, uma data ou ambos.
É possível usar setOnChangeAction() para atribuir uma função de manipulador de widget a
ser executada quando o valor do seletor mudar.

O trecho de código a seguir mostra como definir um seletor somente de data, um seletor somente de hora e um seletor de data e hora, que podem ser adicionados a um card:
var dateOnlyPicker = CardService.newDatePicker()
    .setTitle("Enter a date")
    .setFieldName("date_field")
    // Set default value as May 24 2019. Either a
    // number or string is acceptable.
    .setValueInMsSinceEpoch(1558668600000)
    .setOnChangeAction(CardService.newAction()
        .setFunctionName("handleDateChange"));
var timeOnlyPicker = CardService.newTimePicker()
    .setTitle("Enter a time")
    .setFieldName("time_field")
    // Set default value as 23:30.
    .setHours(23)
    .setMinutes(30)
    .setOnChangeAction(CardService.newAction()
        .setFunctionName("handleTimeChange"));
var dateTimePicker = CardService.newDateTimePicker()
    .setTitle("Enter a date and time")
    .setFieldName("date_time_field")
    // Set default value as May 24 2019 03:30 AM UTC.
    // Either a number or string is acceptable.
    .setValueInMsSinceEpoch(1558668600000)
    // EDT time is 4 hours behind UTC.
    .setTimeZoneOffsetInMins(-4 * 60)
    .setOnChangeAction(CardService.newAction()
        .setFunctionName("handleDateTimeChange"));
Confira abaixo um exemplo de função de manipulador de widget de seleção de data e hora. Este manipulador formata e registra uma string que representa a data e hora escolhidas pelo usuário em um widget seletor de data e hora com o ID "myDateTimePickerWidgetID":
function handleDateTimeChange(event) {
  var dateTimeInput =
    event.commonEventObject.formInputs["myDateTimePickerWidgetID"];
  var msSinceEpoch = dateTimeInput.msSinceEpoch;
  var hasDate = dateTimeInput.hasDate;
  var hasTime = dateTimeInput.hadTime;
  // The following requires you to configure the add-on to read user locale
  // and timezone.
  // See https://developers.google.com/workspace/add-ons/how-tos/access-user-locale
  var userTimezoneId = event.userTimezone.id;
  // Format and log the date-time selected using the user's timezone.
  var formattedDateTime;
  if (hasDate && hasTime) {
    formattedDateTime = Utilities.formatDate(
      new Date(msSinceEpoch), userTimezoneId, "yyy/MM/dd hh:mm:ss");
  } else if (hasDate) {
    formattedDateTime = Utilities.formatDate(
      new Date(msSinceEpoch), userTimezoneId, "yyy/MM/dd")
      + ", Time unspecified";
  } else if (hasTime) {
    formattedDateTime = "Date unspecified, "
      + Utilities.formatDate(
          new Date(msSinceEpoch), userTimezoneId, "hh:mm a");
  }
  if (formattedDateTime) {
    console.log(formattedDateTime);
  }
}
A tabela a seguir mostra exemplos das interfaces de seleção do seletor em computadores e dispositivos móveis. Quando selecionado, o seletor de data abre uma interface do usuário de calendário baseada em meses para permitir que o usuário selecione rapidamente uma nova data.
Quando o usuário seleciona o seletor de horário em dispositivos desktop, um menu suspenso é aberto com uma lista de horários separados em incrementos de 30 minutos que o usuário pode selecionar em. O usuário também pode digitar um horário específico. Em dispositivos móveis, selecionar um seletor de tempo abre o seletor de tempo "relógio" integrado.
| Computador | Dispositivo móvel | 
|---|---|
 
     | 
     
     | 
  
 
     | 
     
     | 
  
Grade
Mostre itens em um layout de várias colunas com o widget de grade. Cada item pode mostrar uma imagem, um título e um subtítulo. Use outras opções de configuração para definir o posicionamento do texto em relação à imagem em um item de grade.
É possível configurar um item de grade com um identificador que é retornado como um parâmetro para a ação definida na grade.

var gridItem = CardService.newGridItem()
  .setIdentifier("item_001")
  .setTitle("Lucian R.")
  .setSubtitle("Chief Information Officer")
  .setImage(imageComponent);
var cropStyle = CardService.newImageCropStyle()
  .setImageCropType(CardService.ImageCropType.RECTANGLE_4_3);
var imageComponent = CardService.newImageComponent()
  .setImageUrl("https://developers.google.com/workspace/
      images/cymbal/people/person1.jpeg")
  .setCropStyle(cropStyle)
var grid = CardService.newGrid()
  .setTitle("Recently viewed")
  .addItem(gridItem)
  .setNumColumns(2)
  .setOnClickAction(CardService.newAction()
    .setFunctionName("handleGridItemClick"));
Formatação do texto
Alguns widgets baseados em texto podem oferecer suporte à formatação HTML de texto simples. Ao definir o conteúdo de texto desses widgets, inclua apenas as tags HTML correspondentes.
As tags aceitas e a finalidade delas são mostradas na tabela a seguir:
| Formato | Exemplo | Resultado renderizado | 
|---|---|---|
| Negrito | "This is <b>bold</b>." | 
  Este texto está em negrito. | 
| Itálico | "This is <i>italics</i>." | 
  Isso está em itálico. | 
| Sublinhado | "This is <u>underline</u>." | 
  Isso é sublinhado. | 
| Tachado | "This is <s>strikethrough</s>." | 
  Isso é  | 
| Cor da fonte | "This is <font color=\"#FF0000\">red font</font>." | 
  Esta é uma fonte vermelha. | 
| Hiperlink | "This is a <a href=\"https://www.google.com\">hyperlink</a>." | 
  Este é um hiperlink. | 
| Tempo | "This is a time format: <time>2023-02-16 15:00</time>." | 
  Este é um formato de hora: . | 
| Nova linha | "This is the first line. <br> This is a new line." | 
  Esta é a primeira linha.  Esta é uma nova linha.  |