Widgets

A widget is a UI element that provides one or more of the following:

  • Structure for other widgetssuch as cards and sections,
  • Information to the usersuch as text and images, or
  • Affordances for actionsuch as buttons, text input fields, or checkboxes.

Sets of widgets added to card sections define the overall add-on UI. The widgets have the same appearance and function on both web and mobile devices. The reference documentation describes several methods for building widget sets.

Widget types

Add-on widgets are generally categorized into three groups: structural widgets, informational widgets, and user interaction widgets.

Structural widgets

Structural widgets provide containers and organization for the other widgets used in the UI.

  • Button set —A collection of one or more text or image buttons, grouped together in a horizontal row.
  • Card —A single context card that contains one or more card sections. You define how users can move between cards by configuring card navigation .
  • Card header —The header for a given card. Card headers can have titles, subtitles, and an image. Card actions and universal actions appear in the card header if the add-on uses them.
  • Card section —A collected group of widgets, divided from the other card sections by a horizontal rule and optionally having a section header. Each card must have at least one card section. You cannot add cards or card headers to a card section.

Structural widgets

In addition to these basic structural widgets, in a Google Workspace Add-on you can use the Card service to create structures that overlap the current card: fixed footers and peek cards :

You can add a fixed row of buttons to the bottom of your card. This row doesn't move or scroll with the rest of the card content.

Fixed footer widget example

The following code excerpt shows how to define an example fixed footer and add it to a 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 
 (); 
 

Peek card

Peek card example

When new contextual content is triggered by a user action, such as opening a Gmail message, you can either display the new contextual content immediately (default behavior) or display a peek card notification at the bottom of the sidebar. If a user clicks Back to return to your homepage while a contextual trigger is active, a peek card appears to help users find the contextual content again.

To display a peek card when new contextual content is available, instead of immediately displaying the new contextual content, add .setDisplayStyle(CardService.DisplayStyle.PEEK) to your CardBuilder class. A peek card only appears if a single card object is returned with your contextual trigger; otherwise, the returned cards immediately replace the current card.

To customize the peek card’s header, add the .setPeekCardHeader() method with a standard CardHeader object when building your contextual card. By default, a Peek card header contains only the name of your add-on.

Customized peek card example

The following code, based on the Cats Google Workspace Add-on quickstart , notifies users about new contextual content with a Peek card and customizes the Peek card's header to display the selected Gmail message thread's subject.

  var 
  
 peekHeader 
  
 = 
  
 CardService 
 . 
 newCardHeader 
 () 
  
 . 
 setTitle 
 ( 
' Contextual 
  
 Cat 
' ) 
  
 . 
 setImageUrl 
 ( 
' https 
 : 
 // 
 www 
 . 
 gstatic 
 . 
 com 
 / 
 images 
 / 
  
 icons 
 / 
 material 
 / 
 system 
 / 
 1 
 x 
 / 
 pets_black_48dp 
 . 
 png 
' ) 
  
 . 
 setSubtitle 
 ( 
 text 
 ); 
 . 
  
 . 
  
 . 
 var 
  
 card 
  
 = 
  
 CardService 
 . 
 newCardBuilder 
 () 
  
 . 
 setDisplayStyle 
 ( 
 CardService 
 . 
 DisplayStyle 
 . 
 PEEK 
 ) 
  
 . 
 setPeekCardHeader 
 ( 
 peekHeader 
 ); 
 

Informational widgets

Informational widgets present information to the user.

  • Image —An image indicated by a hosted and publicly accessbile URL you provide.
  • DecoratedText —A text content string that you can pair with other elements such as top and bottom text labels, and an image or icon. DecoratedText widgets can also include a Button or Switch widget. Added switches can be toggles or checkboxes . The content text of the DecoratedText widget can use HTML formatting ; the top and bottom labels must use plain text.
  • Text paragraph —A text paragraph, which can include HTML formatted elements.

Informational widgets

User interaction widgets

User interaction widgets allow the add-on to respond to actions taken by the users. You can configure these widgets with action responses to display different cards, open URLs, show notifications, compose draft emails, or run other Apps Script functions. See the Building Interactive Cards guide for details.

  • Card action —A menu item placed in the add-on header bar menu. The header bar menu can also contain items defined as universal actions , which appear on every card the add-on defines.
  • DateTime pickers —widgets that allow users to select a date, time, or both. See Date and time pickers below for more information.
  • Image button —A button that uses an image instead of text. You can use one of several predefined icons or a publicly-hosted image indicated by its URL.
  • Selection input —An input field that represents a collection of options. Selection input widgets present as checkboxes, radio buttons or drop-down selection boxes.
  • Switch —A toggle widget. You can only use switches in conjunction with a DecoratedText widget. By default these display as a toggle switch, but you can cause them to display as a checkbox instead.
  • Text button —A button with a text label. You can specify a background color fill for text buttons (the default is transparent). You can also disable the button as needed.
  • Text input —A text input field. The widget can have title text, hint text and multiline text. The widget can trigger actions when the text value changes.
  • Grid —A multi-column layout that represents a collection of items. You can represent items with an image, title, subtitle, and a range of customization options such as border and crop styles.
Card action widgetUser interaction widgets

DecoratedText checkboxes

You can define a DecoratedText widget that has a checkbox attached, instead of a button or binary toggle switch. Like with switches, the value of the checkbox is included in the action event object that is passed to the Action attached to this DecoratedText by the setOnClickAction(action) method.

Decorated-text checkbox widget example

The following code excerpt shows how to define a checkbox DecoratedText widget, which you can then add to a card:

  var 
  
 decoratedText 
  
 = 
  
 CardService 
 . 
 newDecoratedText 
 () 
  
 // 
  
 ( 
 ... 
 ) 
  
 . 
 setSwitch 
 ( 
 CardService 
 . 
 newSwitch 
 () 
  
 . 
 setFieldName 
 ( 
' form_input_switch_key 
' ) 
  
 . 
 setValue 
 ( 
' switch_is_on 
' ) 
  
 . 
 setControlType 
 ( 
  
 CardService 
 . 
 SwitchControlType 
 . 
 CHECK_BOX 
 )); 
 

Date and time pickers

You can define widgets that allow users to select a time, a date, or both. You can use setOnChangeAction() to assign a widget handler function to execute when the value of the picker changes.

Customized peek card example

The following code excerpt shows how to define a date-only picker, a time-only picker, and a date-time picker, which you can then add to a 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 
" )); 
 

The following is an example of a date-time picker widget handler function. This handler formats and logs a string representing the date-time chosen by the user in a date-time picker widget with the 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 
 ); 
  
 } 
 } 
 

The following table shows examples of the picker selection UIs on desktop and mobile devices. When selected, the date picker opens a month-based calendar UI to allow the user to quickly select a new date.

When the user selects the time picker on desktop devices, a drop-down menu opens with a list of times separated in 30 minute increments that the user can select from. The user can also type in a specific time. On mobile devices selecting a time picker opens the built-in mobile "clock" time picker.

Desktop Mobile
date picker selection example mobile date picker selection example
time picker selection example mobile time picker selection example

Grid

Display items in a multi-column layout with the grid widget. Each item can display an image, title, and subtitle. Use additional configuration options to set the positioning of text relative to the image in a grid item.

You can configure a grid item with an identifier that's returned as a parameter to the action defined on the grid.

Grid widget example

  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 
" )); 
 

Text formatting

Some text-based widgets can support simple text HTML formatting. When setting the text content of these widgets, just include the corresponding HTML tags.

The supported tags and their purpose are shown in the following table:

Format Example Rendered result
Bold
"This is <b>bold</b>." This is bold .
Italics
"This is <i>italics</i>." This is italics .
Underline
"This is <u>underline</u>." This is underline .
Strikethrough
"This is <s>strikethrough</s>." This is strikethrough .
Font color
"This is <font color=\"#FF0000\">red font</font>." This is red font .
Hyperlink
"This is a <a href=\"https://www.google.com\">hyperlink</a>." This is a hyperlink .
Time
"This is a time format: <time>2023-02-16 15:00</time>." This is a time format: .
Newline
"This is the first line. <br> This is a new line. " This is the first line.
This is a new line.