widget 是一个简单的界面元素,可提供以下一项或多项:
- 其他微件(例如卡片和版块)的结构
- 向用户显示的信息,例如文字和图片,或者
- 操作方式,例如按钮、文本输入字段或复选框。
添加到卡片部分的微件集定义了完整的插件界面。这些 widget 在网页和移动设备上具有相同的外观和功能。参考文档介绍了几种构建 widget 集的方法。
使用 Google Workspace 插件设计套件
为了节省设计插件 widget 的时间,设计人员可以使用 Figma 中提供的 Google Workspace 插件界面设计套件。您可以创建 Figma 帐号,或向组织管理员申请许可。
浏览组件并使用内置模板来创建和直观呈现 widget。
微件类型
插件 widget 通常分为三类:结构微件、信息微件和用户互动微件。
结构化 widget
结构微件可为 AI 中使用的其他微件提供容器和组织。
- 按钮集 - 包含一个或多个文本按钮或图片按钮的集合,按水平行分组。
- 卡片 - 包含一个或多个卡片部分的单个上下文卡片。您可以通过配置卡片导航来定义用户如何在卡片之间移动。
- 卡片标题 - 给定卡片的标题。卡片标题可以包含标题、字幕和图片。如果该插件使用卡片操作和通用操作,它们会在卡片标头中显示。
- 卡片部分 - 一组微件的集合,按水平规则与其他卡片部分划分,并可选择具有部分标题。每张卡片必须至少具有一个卡片部分。您不能向卡片部分添加卡片或卡片标头。
除了这些基本结构 widget 之外,在 Google Workspace 插件中,您还可以使用 Card 服务创建与当前卡片重叠的结构:固定页脚和提示卡:
固定页脚
您现在可以在卡片底部添加一行固定的按钮。此行不会与卡片内容的其余部分一起移动或滚动。以下代码摘录显示了如何定义示例固定页脚并将其添加到卡片中:
var fixedFooter = CardService.newFixedFooter() .setPrimaryButton( CardService.newTextButton() .setText("help") .setOpenLink(CardService.newOpenLink() .setUrl("https://www.google.com"))) .setSecondaryButton( CardService.newTextButton() .setText("submit") .setOnClickAction( CardService.newAction() .setFunctionName( "submitCallback"))); var card = CardService.newCardBuilder() // (...) .setFixedFooter(fixedFooter) .build();
|
![]() |
提示卡片
当新的上下文内容被用户操作触发(例如打开 Gmail 邮件)时,您可以立即显示新的上下文内容(默认行为),也可以在边栏底部显示提示卡片通知。如果用户在内容相关触发器处于启用状态时点击“返回” 以返回首页,系统将显示提示卡片,以帮助用户再次找到相关内容。
如需在有新的上下文内容时显示提示卡片,请将 .setDisplayStyle(CardService.DisplayStyle.PEEK)
添加到 CardBuilder
类,而不是立即显示新的上下文内容。提示卡片仅在通过内容触发器返回时有一个卡片对象才会显示;否则,返回的卡片会立即取代当前卡片。
如需自定义提示卡片的标头,请在构建内容卡片时添加带有标准 CardHeader
对象的 .setPeekCardHeader()
方法。默认情况下,Peek 卡片标题仅包含插件的名称。
以下代码基于 Cats Google Workspace 插件快速入门,通过 Peek 卡片向用户告知了新的上下文内容,并自定义了 Peek 卡片的标题,以显示所选的 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);
|
![]() |
信息微件
信息 widget 可向用户显示信息。
- 映像 - 这种映像由您提供的可公开访问的托管网址表示。
- DecoratedText - 可与其他元素(如顶部和底部文本标签)以及图片或图标配对的文本内容字符串。DecoratedText widget 还可以包含 Button 或 Switch widget。添加的开关可以是简单的切换开关或复选框。DecoratedText 微件的内容文本可以使用 HTML 格式;顶部和底部标签必须使用纯文本。
- 文本段落 - 一个简单的文本段落,可包含 HTML 格式元素。
用户互动微件
用户互动微件允许插件响应用户执行的操作。您可以使用操作响应配置这些 widget,以显示不同的卡片、打开网址、显示通知、撰写草稿电子邮件或运行其他 Apps 脚本函数。如需了解详情,请参阅构建交互式卡片指南。
- 卡片操作 - 放置在插件标题栏菜单中的菜单项。标题栏菜单中还可以包含定义为通用操作的项目,这些项目会显示在插件定义的每张卡片上。
- 时间轴选择器 - 允许用户选择日期和/或时间的微件。如需了解详情,请参阅下文的日期和时间选择器。
- 图片按钮 - 使用图片而非文字的按钮。您可以使用多个预定义图标,也可以用其网址指示的公开托管图片。
- 选择输入 - 表示一系列选项的输入字段。选择输入微件以复选框、单选按钮或下拉选择框的形式显示。
- 开关 - 一个切换微件。您只能将开关与 DecoratedText 微件结合使用。默认情况下,这些按钮显示为切换开关,但您可以改为将其显示为复选框。
- 文本按钮 - 带有文本标签的按钮。您可以为文本按钮指定背景颜色填充(默认值为透明)。您还可以根据需要停用该按钮。
- 文本输入 - 文本输入字段。微件可以包含标题文本、提示文本和多行文本。当文本值发生更改时,微件可以触发操作。
- 网格 - 多列布局,表示一系列项。您可以使用图片、标题、副标题以及一系列自定义选项(例如边框和剪裁样式)表示项。
DecoratedText 复选框
您可以定义一个带有复选框(而不是按钮或二进制切换开关)的 DecoratedText
widget。与开关一样,复选框的值会包含在通过 setOnClickAction(action)
方法附加到此 DecoratedText
的 Action
的操作事件对象中。
以下代码摘录展示了如何定义复选框 DecoratedText
微件,然后您可以将其添加到卡片:
var decoratedText = CardService.newDecoratedText() // (...) .setSwitch(CardService.newSwitch() .setFieldName('form_input_switch_key') .setValue('switch_is_on') .setControlType( CardService.SwitchControlType.CHECK_BOX));
|
![]() |
日期和时间选择器
您可以定义 widget,以便用户选择时间和/或日期。
您可以使用 setOnChangeAction()
来分配选择器选择器的值发生更改时要执行的处理程序函数。
以下代码片段展示了如何定义仅限日期的选择器、仅限时间的选择器和日期时间选择器,然后将其添加到卡片:
var dateOnlyPicker = CardService.newDatePicker() .setTitle("Enter the 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 the 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 the date and time in EDT 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"));
|
![]() |
以下是日期时间选择器 widget 处理程序函数的示例。该处理程序会简单地记录并记录一个字符串,该字符串表示用户在日期时间选择器 widget 中 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/apps-script/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);
}
}
下表显示了桌面设备和移动设备上的选择器选择界面示例。选择此选项后,日期选择器会打开一个基于月份的日历界面,以便用户快速选择新日期。
用户在桌面设备上选择时间选择器后,系统会打开一个下拉菜单,其中每个列表按 30 分钟为增量显示,可供用户选择时间。用户还可以输入特定时间。在移动设备上,选择时间选择器会打开内置的移动“时钟”时间选择器。
桌面设备 | 移动设备 |
---|---|
![]() |
![]() |
![]() |
![]() |
网格
使用网格微件以多列布局显示内容。每个项目可以显示图片、标题和副标题。您可以使用其他配置选项来设置文本相对于图片在网格项中的位置。
您可以使用标识符(以参数形式返回给网格上定义的操作)网格项。
var gridItem = CardService.newGridItem() .setIdentifier("item_001") .setTitle("A grid item") .setSubtitle("with a subtitle") .setImage(imageComponent); var cropStyle = CardService.newImageCropStyle() .setImageCropType(CardService.ImageCropType.SQUARE); var borderStyle = CardService.newBorderStyle() .setType(CardService.BorderType.STROKE) .setCornerRadius(8) .setStrokeColor("#00FF00FF"); var imageComponent = CardService.newImageComponent() .setImageUrl("https://cataas.com/cat?0.001") .setCropStyle(cropStyle) .setBorderStyle(borderStyle); var grid = CardService.newGrid() .setTitle("My first grid") .addItem(gridItem) .setNumColumns(2) .setOnClickAction(CardService.newAction() .setFunctionName("handleGridItemClick"));
|
![]() |
文本格式
某些基于文本的微件可支持简单的文本 HTML 格式。设置这些 widget 的文本内容时,只需添加相应的 HTML 标记即可。
受支持的标记及其用途如下表所示:
形式 | 示例 | 呈现结果 |
---|---|---|
粗体 | "This is <b>bold</b>." |
这是粗体。 |
斜体 | "This is <i>italics</i>." |
这种语言显示为斜体。 |
下划线 | "This is <u>underline</u>." |
即下划线。 |
删除线 | "This is <s>strikethrough</s>." |
这是 |
字体颜色 | "This is <font color=\"#FF0000\">red font</text>." |
这是红色字体。 |
超链接 | "This is a <a href=\"https://www.google.com\">hyperlink</a>." |
这是一个超链接。 |
时间 | "This is a time format: <time>2023-02-16 15:00</time>." |
请使用以下时间格式:。 |
换行符 | "This is the first line. <br> This is a new line. 英寸 |
这是第一行。 这是新行。 |