// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package google.apps.card.v1;

import "google/type/color.proto";

option csharp_namespace = "Google.Apps.Card.V1";
option go_package = "google.golang.org/genproto/googleapis/apps/card/v1;card";
option java_multiple_files = true;
option java_outer_classname = "CardProto";
option java_package = "com.google.apps.card.v1";
option php_namespace = "Google\\Apps\\Card\\V1";
option ruby_package = "Google::Apps::Card::V1";

// A card interface displayed in a Google Chat message or Google Workspace
// Add-on.
//
// Cards support a defined layout, interactive UI elements like buttons, and
// rich media like images. Use cards to present detailed information,
// gather information from users, and guide users to take a next step.
//
// [Card builder](https://addons.gsuite.google.com/uikit/builder)
//
// To learn how
// to build cards, see the following documentation:
//
// * For Google Chat apps, see [Design the components of a card or
//   dialog](https://developers.google.com/workspace/chat/design-components-card-dialog).
// * For Google Workspace Add-ons, see [Card-based
// interfaces](https://developers.google.com/apps-script/add-ons/concepts/cards).
//
// **Example: Card message for a Google Chat app**
//
// ![Example contact
// card](https://developers.google.com/workspace/chat/images/card_api_reference.png)
//
// To create the sample card message in Google Chat, use the following JSON:
//
// ```
// {
//   "cardsV2": [
//     {
//       "cardId": "unique-card-id",
//       "card": {
//         "header": {
//            "title": "Sasha",
//            "subtitle": "Software Engineer",
//            "imageUrl":
//            "https://developers.google.com/workspace/chat/images/quickstart-app-avatar.png",
//            "imageType": "CIRCLE",
//            "imageAltText": "Avatar for Sasha"
//          },
//          "sections": [
//            {
//              "header": "Contact Info",
//              "collapsible": true,
//              "uncollapsibleWidgetsCount": 1,
//              "widgets": [
//                {
//                  "decoratedText": {
//                    "startIcon": {
//                      "knownIcon": "EMAIL"
//                    },
//                    "text": "sasha@example.com"
//                  }
//                },
//                {
//                  "decoratedText": {
//                    "startIcon": {
//                      "knownIcon": "PERSON"
//                    },
//                    "text": "<font color=\"#80e27e\">Online</font>"
//                  }
//                },
//                {
//                  "decoratedText": {
//                    "startIcon": {
//                      "knownIcon": "PHONE"
//                    },
//                    "text": "+1 (555) 555-1234"
//                  }
//                },
//                {
//                  "buttonList": {
//                    "buttons": [
//                      {
//                        "text": "Share",
//                        "onClick": {
//                         "openLink": {
//                            "url": "https://example.com/share"
//                          }
//                        }
//                      },
//                      {
//                        "text": "Edit",
//                        "onClick": {
//                          "action": {
//                            "function": "goToView",
//                            "parameters": [
//                              {
//                                "key": "viewType",
//                                "value": "EDIT"
//                              }
//                            ]
//                          }
//                        }
//                      }
//                    ]
//                  }
//                }
//              ]
//            }
//          ]
//        }
//     }
//   ]
// }
// ```
message Card {
  // Represents a card header. For an example in Google Chat apps, see [Add a
  // header](https://developers.google.com/workspace/chat/design-components-card-dialog#add_a_header).
  //
  // [Google Workspace Add-ons and Chat
  // apps](https://developers.google.com/workspace/extend):
  message CardHeader {
    // Required. The title of the card header.
    // The header has a fixed height: if both a
    // title and subtitle are specified, each takes up one line. If only the
    // title is specified, it takes up both lines.
    string title = 1;

    // The subtitle of the card header. If specified, appears on its own line
    // below the `title`.
    string subtitle = 2;

    // The shape used to crop the image.
    //
    // [Google Workspace Add-ons and Chat
    // apps](https://developers.google.com/workspace/extend):
    Widget.ImageType image_type = 3;

    // The HTTPS URL of the image in the card header.
    string image_url = 4;

    // The alternative text of this image that's used for accessibility.
    string image_alt_text = 5;
  }

  // A section contains a collection of widgets that are rendered
  // vertically in the order that they're specified.
  //
  // [Google Workspace Add-ons and Chat
  // apps](https://developers.google.com/workspace/extend):
  message Section {
    // Text that appears at the top of a section.
    // Supports simple HTML formatted text. For more information
    // about formatting text, see
    // [Formatting text in Google Chat
    // apps](https://developers.google.com/workspace/chat/format-messages#card-formatting)
    // and
    // [Formatting
    // text in Google Workspace
    // Add-ons](https://developers.google.com/apps-script/add-ons/concepts/widgets#text_formatting).
    string header = 1;

    // All the widgets in the section.
    // Must contain at least one widget.
    repeated Widget widgets = 2;

    // Indicates whether this section is collapsible.
    //
    // Collapsible sections hide some or all widgets, but users can expand the
    // section to reveal the hidden widgets by clicking **Show more**. Users
    // can hide the widgets again by clicking **Show less**.
    //
    // To determine which widgets are hidden, specify
    // `uncollapsibleWidgetsCount`.
    bool collapsible = 5;

    // The number of uncollapsible widgets which remain visible even when a
    // section is collapsed.
    //
    // For example, when a section
    // contains five widgets and the `uncollapsibleWidgetsCount` is set to `2`,
    // the first two widgets are always shown and the last three are collapsed
    // by default. The `uncollapsibleWidgetsCount` is taken into account only
    // when `collapsible` is `true`.
    int32 uncollapsible_widgets_count = 6;
  }

  // The divider style of a card. Currently only used for dividers betweens card
  // sections.
  //
  // [Google Workspace Add-ons and Chat
  // apps](https://developers.google.com/workspace/extend):
  enum DividerStyle {
    // Don't use. Unspecified.
    DIVIDER_STYLE_UNSPECIFIED = 0;

    // Default option. Render a solid divider between sections.
    SOLID_DIVIDER = 1;

    // If set, no divider is rendered between sections.
    NO_DIVIDER = 2;
  }

  // A card action is the action associated with the card. For example,
  // an invoice card might include actions such as delete invoice, email
  // invoice, or open the invoice in a browser.
  //
  // [Google Workspace
  // Add-ons](https://developers.google.com/workspace/add-ons):
  message CardAction {
    // The label that displays as the action menu item.
    string action_label = 1;

    // The `onClick` action for this action item.
    OnClick on_click = 2;
  }

  // A persistent (sticky) footer that that appears at the bottom of the card.
  //
  // Setting `fixedFooter` without specifying a `primaryButton` or a
  // `secondaryButton` causes an error.
  //
  // For Chat apps, you can use fixed footers in
  // [dialogs](https://developers.google.com/workspace/chat/dialogs), but not
  // [card
  // messages](https://developers.google.com/workspace/chat/create-messages#create).
  // For an example in Google Chat apps, see [Add a persistent
  // footer](https://developers.google.com/workspace/chat/design-components-card-dialog#add_a_persistent_footer).
  //
  // [Google Workspace Add-ons and Chat
  // apps](https://developers.google.com/workspace/extend):
  message CardFixedFooter {
    // The primary button of the fixed footer. The button must be a text button
    // with text and color set.
    Button primary_button = 1;

    // The secondary button of the fixed footer.  The button must be a text
    // button with text and color set.
    // If `secondaryButton` is set, you must also set `primaryButton`.
    Button secondary_button = 2;
  }

  // In Google Workspace Add-ons,
  // determines how a card is displayed.
  //
  // [Google Workspace
  // Add-ons](https://developers.google.com/workspace/add-ons):
  enum DisplayStyle {
    // Don't use. Unspecified.
    DISPLAY_STYLE_UNSPECIFIED = 0;

    // The header of the card appears at the bottom of the
    // sidebar, partially covering the current top card of the stack. Clicking
    // the header pops the card into the card stack. If the card has no header,
    // a generated header is used instead.
    PEEK = 1;

    // Default value. The card is shown by replacing the view of the top card in
    // the card stack.
    REPLACE = 2;
  }

  // The header of the card. A header usually contains a leading image and a
  // title. Headers always appear at the top of a card.
  CardHeader header = 1;

  // Contains a collection of widgets. Each section has its own, optional
  // header. Sections are visually separated by a line divider. For an example
  // in Google Chat apps, see [Define a section of a
  // card](https://developers.google.com/workspace/chat/design-components-card-dialog#define_a_section_of_a_card).
  repeated Section sections = 2;

  // The divider style between sections.
  DividerStyle section_divider_style = 9;

  // The card's actions. Actions are added to the card's toolbar menu.
  //
  // [Google Workspace
  // Add-ons](https://developers.google.com/workspace/add-ons):
  //
  // For example, the following JSON constructs a card action menu with
  // `Settings` and `Send Feedback` options:
  //
  // ```
  // "card_actions": [
  //   {
  //     "actionLabel": "Settings",
  //     "onClick": {
  //       "action": {
  //         "functionName": "goToView",
  //         "parameters": [
  //           {
  //             "key": "viewType",
  //             "value": "SETTING"
  //          }
  //         ],
  //         "loadIndicator": "LoadIndicator.SPINNER"
  //       }
  //     }
  //   },
  //   {
  //     "actionLabel": "Send Feedback",
  //     "onClick": {
  //       "openLink": {
  //         "url": "https://example.com/feedback"
  //       }
  //     }
  //   }
  // ]
  // ```
  repeated CardAction card_actions = 3;

  // Name of the card. Used as a card identifier in card navigation.
  //
  // [Google Workspace
  // Add-ons](https://developers.google.com/workspace/add-ons):
  string name = 4;

  // The fixed footer shown at the bottom of this card.
  //
  // Setting `fixedFooter` without specifying a `primaryButton` or a
  // `secondaryButton` causes an error. For Chat apps, you can use fixed footers
  // in
  // [dialogs](https://developers.google.com/workspace/chat/dialogs), but not
  // [card
  // messages](https://developers.google.com/workspace/chat/create-messages#create).
  //
  // [Google Workspace Add-ons and Chat
  // apps](https://developers.google.com/workspace/extend):
  CardFixedFooter fixed_footer = 5;

  // In Google Workspace Add-ons, sets the display properties of the
  // `peekCardHeader`.
  //
  // [Google Workspace
  // Add-ons](https://developers.google.com/workspace/add-ons):
  DisplayStyle display_style = 6;

  // When displaying contextual content, the peek card header acts as a
  // placeholder so that the user can navigate forward between the homepage
  // cards and the contextual cards.
  //
  // [Google Workspace
  // Add-ons](https://developers.google.com/workspace/add-ons):
  CardHeader peek_card_header = 7;
}

// Each card is made up of widgets.
//
// A widget is a composite object that can represent one of text, images,
// buttons, and other object types.
message Widget {
  // The shape used to crop the image.
  //
  // [Google Workspace Add-ons and Chat
  // apps](https://developers.google.com/workspace/extend):
  enum ImageType {
    // Default value. Applies a square mask to the image. For example, a 4x3
    // image becomes 3x3.
    SQUARE = 0;

    // Applies a circular mask to the image. For example, a 4x3 image becomes a
    // circle with a diameter of 3.
    CIRCLE = 1;
  }

  // Specifies whether widgets align to the left, right, or center of a column.
  //
  // [Google Chat apps](https://developers.google.com/workspace/chat):
  enum HorizontalAlignment {
    // Don't use. Unspecified.
    HORIZONTAL_ALIGNMENT_UNSPECIFIED = 0;

    // Default value. Aligns widgets to the start position of the column. For
    // left-to-right layouts, aligns to the left. For right-to-left layouts,
    // aligns to the right.
    START = 1;

    // Aligns widgets to the center of the column.
    CENTER = 2;

    // Aligns widgets to the end position of the column. For left-to-right
    // layouts, aligns widgets to the right. For right-to-left layouts, aligns
    // widgets to the left.
    END = 3;
  }

  // A widget can only have one of the following items. You can use multiple
  // widget fields to display more items.
  oneof data {
    // Displays a text paragraph. Supports simple HTML formatted text. For more
    // information about formatting text, see
    // [Formatting text in Google Chat
    // apps](https://developers.google.com/workspace/chat/format-messages#card-formatting)
    // and
    // [Formatting
    // text in Google Workspace
    // Add-ons](https://developers.google.com/apps-script/add-ons/concepts/widgets#text_formatting).
    //
    // For example, the following JSON creates a bolded text:
    // ```
    // "textParagraph": {
    //   "text": "  <b>bold text</b>"
    // }
    // ```
    TextParagraph text_paragraph = 1;

    // Displays an image.
    //
    // For example, the following JSON creates an image with alternative text:
    // ```
    // "image": {
    //   "imageUrl":
    //   "https://developers.google.com/workspace/chat/images/quickstart-app-avatar.png",
    //   "altText": "Chat app avatar"
    // }
    // ```
    Image image = 2;

    // Displays a decorated text item.
    //
    // For example, the following JSON creates a decorated text widget showing
    // email address:
    //
    // ```
    // "decoratedText": {
    //   "icon": {
    //     "knownIcon": "EMAIL"
    //   },
    //   "topLabel": "Email Address",
    //   "text": "sasha@example.com",
    //   "bottomLabel": "This is a new Email address!",
    //   "switchControl": {
    //     "name": "has_send_welcome_email_to_sasha",
    //     "selected": false,
    //     "controlType": "CHECKBOX"
    //   }
    // }
    // ```
    DecoratedText decorated_text = 3;

    // A list of buttons.
    //
    // For example, the following JSON creates two buttons. The first
    // is a blue text button and the second is an image button that opens a
    // link:
    // ```
    // "buttonList": {
    //   "buttons": [
    //     {
    //       "text": "Edit",
    //       "color": {
    //         "red": 0,
    //         "green": 0,
    //         "blue": 1,
    //         "alpha": 1
    //       },
    //       "disabled": true,
    //     },
    //     {
    //       "icon": {
    //         "knownIcon": "INVITE",
    //         "altText": "check calendar"
    //       },
    //       "onClick": {
    //         "openLink": {
    //           "url": "https://example.com/calendar"
    //         }
    //       }
    //     }
    //   ]
    // }
    // ```
    ButtonList button_list = 4;

    // Displays a text box that users can type into.
    //
    // For example, the following JSON creates a text input for an email
    // address:
    //
    // ```
    // "textInput": {
    //   "name": "mailing_address",
    //   "label": "Mailing Address"
    // }
    // ```
    //
    // As another example, the following JSON creates a text input for a
    // programming language with static suggestions:
    // ```
    // "textInput": {
    //   "name": "preferred_programing_language",
    //   "label": "Preferred Language",
    //   "initialSuggestions": {
    //     "items": [
    //       {
    //         "text": "C++"
    //       },
    //       {
    //         "text": "Java"
    //       },
    //       {
    //         "text": "JavaScript"
    //       },
    //       {
    //         "text": "Python"
    //       }
    //     ]
    //   }
    // }
    // ```
    TextInput text_input = 5;

    // Displays a selection control that lets users select items. Selection
    // controls can be checkboxes, radio buttons, switches, or dropdown menus.
    //
    // For example, the following JSON creates a dropdown menu that lets users
    // choose a size:
    //
    // ```
    // "selectionInput": {
    //   "name": "size",
    //   "label": "Size"
    //   "type": "DROPDOWN",
    //   "items": [
    //     {
    //       "text": "S",
    //       "value": "small",
    //       "selected": false
    //     },
    //     {
    //       "text": "M",
    //       "value": "medium",
    //       "selected": true
    //     },
    //     {
    //       "text": "L",
    //       "value": "large",
    //       "selected": false
    //     },
    //     {
    //       "text": "XL",
    //       "value": "extra_large",
    //       "selected": false
    //     }
    //   ]
    // }
    // ```
    SelectionInput selection_input = 6;

    // Displays a widget that lets users input a date, time, or date and time.
    //
    // For example, the following JSON creates a date time picker to schedule an
    // appointment:
    //
    //
    // ```
    // "dateTimePicker": {
    //   "name": "appointment_time",
    //   "label": "Book your appointment at:",
    //   "type": "DATE_AND_TIME",
    //   "valueMsEpoch": "796435200000"
    // }
    // ```
    DateTimePicker date_time_picker = 7;

    // Displays a horizontal line divider between widgets.
    //
    // For example, the following JSON creates a divider:
    // ```
    // "divider": {
    // }
    // ```
    Divider divider = 9;

    // Displays a grid with a collection of items.
    //
    // A grid supports any number of columns and items. The number of rows is
    // determined by the upper bounds of the number items divided by the number
    // of columns. A grid with 10 items and 2 columns has 5 rows. A grid with 11
    // items and 2 columns has 6 rows.
    //
    // [Google Workspace Add-ons and
    // Chat apps](https://developers.google.com/workspace/extend):
    //
    // For example, the following JSON creates a 2 column grid with a single
    // item:
    //
    // ```
    // "grid": {
    //   "title": "A fine collection of items",
    //   "columnCount": 2,
    //   "borderStyle": {
    //     "type": "STROKE",
    //     "cornerRadius": 4
    //   },
    //   "items": [
    //     {
    //       "image": {
    //         "imageUri": "https://www.example.com/image.png",
    //         "cropStyle": {
    //           "type": "SQUARE"
    //         },
    //         "borderStyle": {
    //           "type": "STROKE"
    //         }
    //       },
    //       "title": "An item",
    //       "textAlignment": "CENTER"
    //     }
    //   ],
    //   "onClick": {
    //     "openLink": {
    //       "url": "https://www.example.com"
    //     }
    //   }
    // }
    // ```
    Grid grid = 10;

    // Displays up to 2 columns.
    //
    // To include more than 2 columns, or to use rows, use the `Grid` widget.
    //
    // For example, the following JSON creates 2 columns that each contain
    // text paragraphs:
    //
    // ```
    // "columns": {
    //   "columnItems": [
    //     {
    //       "horizontalSizeStyle": "FILL_AVAILABLE_SPACE",
    //       "horizontalAlignment": "CENTER",
    //       "verticalAlignment": "CENTER",
    //       "widgets": [
    //         {
    //           "textParagraph": {
    //             "text": "First column text paragraph"
    //           }
    //         }
    //       ]
    //     },
    //     {
    //       "horizontalSizeStyle": "FILL_AVAILABLE_SPACE",
    //       "horizontalAlignment": "CENTER",
    //       "verticalAlignment": "CENTER",
    //       "widgets": [
    //         {
    //           "textParagraph": {
    //             "text": "Second column text paragraph"
    //           }
    //         }
    //       ]
    //     }
    //   ]
    // }
    // ```
    Columns columns = 11;
  }

  // Specifies whether widgets align to the left, right, or center of a column.
  HorizontalAlignment horizontal_alignment = 8;
}

// A paragraph of text that supports formatting. For an example in
// Google Chat apps, see [Add a paragraph of formatted
// text](https://developers.google.com/workspace/chat/add-text-image-card-dialog#add_a_paragraph_of_formatted_text).
// For more information
// about formatting text, see
// [Formatting text in Google Chat
// apps](https://developers.google.com/workspace/chat/format-messages#card-formatting)
// and
// [Formatting
// text in Google Workspace
// Add-ons](https://developers.google.com/apps-script/add-ons/concepts/widgets#text_formatting).
//
// [Google Workspace Add-ons and
// Chat apps](https://developers.google.com/workspace/extend):
message TextParagraph {
  // The text that's shown in the widget.
  string text = 1;
}

// An image that is specified by a URL and can have an `onClick` action. For an
// example, see [Add an
// image](https://developers.google.com/workspace/chat/add-text-image-card-dialog#add_an_image).
//
// [Google Workspace Add-ons and Chat
// apps](https://developers.google.com/workspace/extend):
message Image {
  // The HTTPS URL that hosts the image.
  //
  // For example:
  //
  // ```
  // https://developers.google.com/workspace/chat/images/quickstart-app-avatar.png
  // ```
  string image_url = 1;

  // When a user clicks the image, the click triggers this action.
  OnClick on_click = 2;

  // The alternative text of this image that's used for accessibility.
  string alt_text = 3;
}

// Displays a divider between widgets as a horizontal line. For an example in
// Google Chat apps, see
// [Add a horizontal divider between
// widgets](https://developers.google.com/workspace/chat/format-structure-card-dialog#add_a_horizontal_divider_between_widgets).
//
// [Google Workspace Add-ons and Chat
// apps](https://developers.google.com/workspace/extend):
//
// For example, the following JSON creates a divider:
//
// ```
// "divider": {}
// ```
message Divider {}

// A widget that displays text with optional decorations such as a label above
// or below the text, an icon in front of the text, a selection widget, or a
// button after the text. For an example in
// Google Chat apps, see [Display text with decorative
// text](https://developers.google.com/workspace/chat/add-text-image-card-dialog#display_text_with_decorative_elements).
//
// [Google Workspace Add-ons and Chat
// apps](https://developers.google.com/workspace/extend):
message DecoratedText {
  // Either a toggle-style switch or a checkbox inside a `decoratedText` widget.
  //
  // [Google Workspace Add-ons and Chat
  // apps](https://developers.google.com/workspace/extend):
  //
  // Only supported in the `decoratedText` widget.
  message SwitchControl {
    // How the switch appears in the user interface.
    //
    // [Google Workspace Add-ons
    // and Chat apps](https://developers.google.com/workspace/extend):
    enum ControlType {
      // A toggle-style switch.
      SWITCH = 0;

      // Deprecated in favor of `CHECK_BOX`.
      CHECKBOX = 1;

      // A checkbox.
      CHECK_BOX = 2;
    }

    // The name by which the switch widget is identified in a form input event.
    //
    // For details about working with form inputs, see [Receive form
    // data](https://developers.google.com/workspace/chat/read-form-data).
    string name = 1;

    // The value entered by a user, returned as part of a form input event.
    //
    // For details about working with form inputs, see [Receive form
    // data](https://developers.google.com/workspace/chat/read-form-data).
    string value = 2;

    // When `true`, the switch is selected.
    bool selected = 3;

    // The action to perform when the switch state is changed, such as what
    //  function to run.
    Action on_change_action = 4;

    // How the switch appears in the user interface.
    //
    // [Google Workspace Add-ons
    // and Chat apps](https://developers.google.com/workspace/extend):
    ControlType control_type = 5;
  }

  // Deprecated in favor of `startIcon`.
  Icon icon = 1 [deprecated = true];

  // The icon displayed in front of the text.
  Icon start_icon = 12;

  // The text that appears above `text`. Always truncates.
  string top_label = 3;

  // Required. The primary text.
  //
  // Supports simple formatting. For more information
  // about formatting text, see
  // [Formatting text in Google Chat
  // apps](https://developers.google.com/workspace/chat/format-messages#card-formatting)
  // and
  // [Formatting
  // text in Google Workspace
  // Add-ons](https://developers.google.com/apps-script/add-ons/concepts/widgets#text_formatting).
  string text = 4;

  // The wrap text setting. If `true`, the text wraps and displays on
  // multiple lines. Otherwise, the text is truncated.
  //
  // Only applies to `text`, not `topLabel` and `bottomLabel`.
  bool wrap_text = 5;

  // The text that appears below `text`. Always wraps.
  string bottom_label = 6;

  // This action is triggered when users click `topLabel` or `bottomLabel`.
  OnClick on_click = 7;

  // A button, switch, checkbox, or image that appears to the right-hand side
  // of text in the `decoratedText` widget.
  oneof control {
    // A button that a user can click to trigger an action.
    Button button = 8;

    // A switch widget that a user can click to change its state and trigger an
    // action.
    SwitchControl switch_control = 9;

    // An icon displayed after the text.
    //
    // Supports
    // [built-in](https://developers.google.com/workspace/chat/format-messages#builtinicons)
    // and
    // [custom](https://developers.google.com/workspace/chat/format-messages#customicons)
    // icons.
    Icon end_icon = 11;
  }
}

// A field in which users can enter text. Supports suggestions and on-change
// actions. For an example in Google Chat apps, see [Add a field in which a user
// can enter
// text](https://developers.google.com/workspace/chat/design-interactive-card-dialog#add_a_field_in_which_a_user_can_enter_text).
//
// Chat apps receive and can process the value of entered text during form input
// events. For details about working with form inputs, see [Receive form
// data](https://developers.google.com/workspace/chat/read-form-data).
//
// When you need to collect undefined or abstract data from users,
// use a text input. To collect defined or enumerated data from users, use the
// [SelectionInput][google.apps.card.v1.SelectionInput] widget.
//
// [Google Workspace Add-ons and Chat
// apps](https://developers.google.com/workspace/extend):
message TextInput {
  // How a text input field appears in the user interface. For example,
  // whether it's a single line input field, or a multi-line input. If
  // `initialSuggestions` is specified, `type` is always `SINGLE_LINE`,
  // even if it's set to `MULTIPLE_LINE`.
  //
  // [Google Workspace Add-ons and Chat
  // apps](https://developers.google.com/workspace/extend):
  enum Type {
    // The text input field has a fixed height of one line.
    SINGLE_LINE = 0;

    // The text input field has a fixed height of multiple lines.
    MULTIPLE_LINE = 1;
  }

  // The name by which the text input is identified in a form input event.
  //
  // For details about working with form inputs, see [Receive form
  // data](https://developers.google.com/workspace/chat/read-form-data).
  string name = 1;

  // The text that appears above the text input field in the user interface.
  //
  // Specify text that helps the user enter the information your app needs.
  // For example, if you are asking someone's name, but specifically need their
  // surname, write `surname` instead of `name`.
  //
  // Required if `hintText` is unspecified. Otherwise, optional.
  string label = 2;

  // Text that appears below the text input field meant to assist users by
  // prompting them to enter a certain value. This text is always visible.
  //
  // Required if `label` is unspecified. Otherwise, optional.
  string hint_text = 3;

  // The value entered by a user, returned as part of a form input event.
  //
  // For details about working with form inputs, see [Receive form
  // data](https://developers.google.com/workspace/chat/read-form-data).
  string value = 4;

  // How a text input field appears in the user interface.
  // For example, whether the field is single or multi-line.
  Type type = 5;

  // What to do when a change occurs in the text input field. For example, a
  // user adding to the field or deleting text.
  //
  // Examples of actions to take include running a custom function or opening
  // a [dialog](https://developers.google.com/workspace/chat/dialogs)
  // in Google Chat.
  Action on_change_action = 6;

  // Suggested values that users can enter. These values appear when users click
  // inside the text input field. As users type, the suggested values
  // dynamically filter to match what the users have typed.
  //
  // For example, a text input field for programming language might suggest
  // Java, JavaScript, Python, and C++. When users start typing `Jav`, the list
  // of suggestions filters to show just `Java` and `JavaScript`.
  //
  // Suggested values help guide users to enter values that your app can make
  // sense of. When referring to JavaScript, some users might enter `javascript`
  // and others `java script`. Suggesting `JavaScript` can standardize how users
  // interact with your app.
  //
  // When specified, `TextInput.type` is always `SINGLE_LINE`, even if it's set
  // to `MULTIPLE_LINE`.
  //
  // [Google Workspace
  // Add-ons and Chat apps](https://developers.google.com/workspace/extend):
  Suggestions initial_suggestions = 7;

  // Optional. Specify what action to take when the text input field provides
  // suggestions to users who interact with it.
  //
  // If unspecified, the suggestions are set by `initialSuggestions` and
  // are processed by the client.
  //
  // If specified, the app takes the action specified here, such as running
  // a custom function.
  //
  // [Google Workspace
  // Add-ons](https://developers.google.com/workspace/add-ons):
  Action auto_complete_action = 8;

  // Text that appears in the text input field when the field is empty.
  // Use this text to prompt users to enter a value. For example, `Enter a
  // number from 0 to 100`.
  //
  // [Google Chat apps](https://developers.google.com/workspace/chat):
  string placeholder_text = 12;
}

// Suggested values that users can enter. These values appear when users click
// inside the text input field. As users type, the suggested values
// dynamically filter to match what the users have typed.
//
// For example, a text input field for programming language might suggest
// Java, JavaScript, Python, and C++. When users start typing `Jav`, the list
// of suggestions filters to show `Java` and `JavaScript`.
//
// Suggested values help guide users to enter values that your app can make
// sense of. When referring to JavaScript, some users might enter `javascript`
// and others `java script`. Suggesting `JavaScript` can standardize how users
// interact with your app.
//
// When specified, `TextInput.type` is always `SINGLE_LINE`, even if it's set
// to `MULTIPLE_LINE`.
//
// [Google Workspace
// Add-ons and Chat apps](https://developers.google.com/workspace/extend):
message Suggestions {
  // One suggested value that users can enter in a text input field.
  //
  // [Google Workspace Add-ons and Chat
  // apps](https://developers.google.com/workspace/extend):
  message SuggestionItem {
    oneof content {
      // The value of a suggested input to a text input field. This is
      // equivalent to what users enter themselves.
      string text = 1;
    }
  }

  // A list of suggestions used for autocomplete recommendations in text input
  // fields.
  repeated SuggestionItem items = 1;
}

// A list of buttons layed out horizontally. For an example in
// Google Chat apps, see
// [Add a
// button](https://developers.google.com/workspace/chat/design-interactive-card-dialog#add_a_button).
//
// [Google Workspace Add-ons and Chat
// apps](https://developers.google.com/workspace/extend):
message ButtonList {
  // An array of buttons.
  repeated Button buttons = 1;
}

// A widget that creates one or more UI items that users can select.
// For example, a dropdown menu or checkboxes. You can use this widget to
// collect data that can be predicted or enumerated. For an example in Google
// Chat apps, see [Add selectable UI
// elements](/workspace/chat/design-interactive-card-dialog#add_selectable_ui_elements).
//
// Chat apps can process the value of items that users select or input. For
// details about working with form inputs, see [Receive form
// data](https://developers.google.com/workspace/chat/read-form-data).
//
// To collect undefined or abstract data from users, use
// the [TextInput][google.apps.card.v1.TextInput] widget.
//
// [Google Workspace Add-ons
// and Chat apps](https://developers.google.com/workspace/extend):
message SelectionInput {
  // The format for the items that users can select. Different options support
  // different types of interactions. For example, users can select multiple
  // checkboxes, but can only select one item from a dropdown menu.
  //
  // Each selection input supports one type of selection. Mixing checkboxes
  // and switches, for example, isn't supported.
  //
  // [Google Workspace Add-ons and Chat
  // apps](https://developers.google.com/workspace/extend):
  enum SelectionType {
    // A set of checkboxes. Users can select one or more checkboxes.
    CHECK_BOX = 0;

    // A set of radio buttons. Users can select one radio button.
    RADIO_BUTTON = 1;

    // A set of switches. Users can turn on one or more switches.
    SWITCH = 2;

    // A dropdown menu. Users can select one item from the menu.
    DROPDOWN = 3;

    // A multiselect menu for static or dynamic data. From the menu bar,
    // users select one or more items. Users can also input values to populate
    // dynamic data. For example, users can start typing the name of a Google
    // Chat space and the widget autosuggests the space.
    //
    // To populate items for a multiselect menu, you can use one of the
    // following types of data sources:
    //
    //  * Static data: Items are specified as `SelectionItem` objects in the
    //    widget. Up to 100 items.
    //  * Google Workspace data: Items are populated using data from Google
    //    Workspace, such as Google Workspace users or Google Chat spaces.
    //  * External data: Items are populated from an external data
    //    source outside of Google Workspace.
    //
    // For examples of how to implement multiselect menus, see
    // [Add a multiselect
    // menu](https://developers.google.com/workspace/chat/design-interactive-card-dialog#multiselect-menu).
    //
    // [Google Workspace Add-ons and Chat
    // apps](https://developers.google.com/workspace/extend):
    // Multiselect for Google Workspace Add-ons are in
    // Developer Preview.
    MULTI_SELECT = 4;
  }

  // An item that users can select in a selection input, such as a checkbox
  // or switch.
  //
  // [Google Workspace Add-ons and Chat
  // apps](https://developers.google.com/workspace/extend):
  message SelectionItem {
    // The text that identifies or describes the item to users.
    string text = 1;

    // The value associated with this item. The client should use this as a form
    // input value.
    //
    // For details about working with form inputs, see [Receive form
    // data](https://developers.google.com/workspace/chat/read-form-data).
    string value = 2;

    // Whether the item is selected by default. If the selection input only
    // accepts one value (such as for radio buttons or a dropdown menu), only
    // set this field for one item.
    bool selected = 3;

    // For multiselect menus, the URL for the icon displayed next to
    // the item's `text` field. Supports PNG and JPEG files. Must be an `HTTPS`
    // URL. For example,
    // `https://developers.google.com/workspace/chat/images/quickstart-app-avatar.png`.
    string start_icon_uri = 4;

    // For multiselect menus, a text description or label that's
    // displayed below the item's `text` field.
    string bottom_text = 5;
  }

  // For a
  // [`SelectionInput`][google.apps.card.v1.SelectionInput] widget that uses a
  // multiselect menu, a data source from Google Workspace. Used to populate
  // items in a multiselect menu.
  //
  // [Google Chat apps](https://developers.google.com/workspace/chat):
  message PlatformDataSource {
    // A data source shared by all [Google Workspace
    // applications]
    // (https://developers.google.com/workspace/chat/api/reference/rest/v1/HostApp).
    //
    // [Google Chat apps](https://developers.google.com/workspace/chat):
    enum CommonDataSource {
      // Default value. Don't use.
      UNKNOWN = 0;

      // Google Workspace users. The user can only view and select users from
      // their Google Workspace organization.
      USER = 1;
    }

    // The data source.
    oneof data_source {
      // A data source shared by all Google Workspace applications, such as
      // users in a Google Workspace organization.
      CommonDataSource common_data_source = 1;
    }
  }

  // The name that identifies the selection input in a form input event.
  //
  // For details about working with form inputs, see [Receive form
  // data](https://developers.google.com/workspace/chat/read-form-data).
  string name = 1;

  // The text that appears above the selection input field in the user
  // interface.
  //
  // Specify text that helps the user enter the information your app needs.
  // For example, if users are selecting the urgency of a work ticket from a
  // drop-down menu, the label might be "Urgency" or "Select urgency".
  string label = 2;

  // The type of items that are displayed to users in a `SelectionInput` widget.
  // Selection types support different types of interactions. For example, users
  // can select one or more checkboxes, but they can only select one value from
  // a dropdown menu.
  SelectionType type = 3;

  // An array of selectable items. For example, an array of radio buttons or
  // checkboxes. Supports up to 100 items.
  repeated SelectionItem items = 4;

  // If specified, the form is submitted when the selection changes. If not
  // specified, you must specify a separate button that submits the form.
  //
  // For details about working with form inputs, see [Receive form
  // data](https://developers.google.com/workspace/chat/read-form-data).
  Action on_change_action = 5;

  // For multiselect menus, the maximum number of items that a user can select.
  // Minimum value is 1 item. If unspecified, defaults to 3 items.
  int32 multi_select_max_selected_items = 6;

  // For multiselect menus, the number of text characters that a user inputs
  // before the app queries autocomplete and displays suggested items
  // in the menu.
  //
  // If unspecified, defaults to 0 characters for static data sources and 3
  // characters for external data sources.
  int32 multi_select_min_query_length = 7;

  // For a multiselect menu, the data source that populates
  // selection items.
  //
  // [Google Chat apps](https://developers.google.com/workspace/chat):
  oneof multi_select_data_source {
    // An external data source, such as a relational data base.
    Action external_data_source = 8;

    // A data source from Google Workspace.
    PlatformDataSource platform_data_source = 9;
  }
}

// Lets users input a date, a time, or both a date and a time. For an example in
// Google Chat apps, see [Let a user pick a date and
// time](https://developers.google.com/workspace/chat/design-interactive-card-dialog#let_a_user_pick_a_date_and_time).
//
// Users can input text or use the picker to select dates and times. If users
// input an invalid date or time, the picker shows an error that prompts users
// to input the information correctly.
//
// [Google Workspace
// Add-ons and Chat apps](https://developers.google.com/workspace/extend):
message DateTimePicker {
  // The format for the date and time in the `DateTimePicker` widget.
  // Determines whether users can input a date, a time, or both a date and time.
  //
  // [Google Workspace Add-ons and Chat
  // apps](https://developers.google.com/workspace/extend):
  enum DateTimePickerType {
    // Users input a date and time.
    DATE_AND_TIME = 0;

    // Users input a date.
    DATE_ONLY = 1;

    // Users input a time.
    TIME_ONLY = 2;
  }

  // The name by which the `DateTimePicker` is identified in a form input event.
  //
  // For details about working with form inputs, see [Receive form
  // data](https://developers.google.com/workspace/chat/read-form-data).
  string name = 1;

  // The text that prompts users to input a date, a time, or a date and time.
  // For example, if users are scheduling an appointment, use a label such as
  // `Appointment date` or `Appointment date and time`.
  string label = 2;

  // Whether the widget supports inputting a date, a time, or the date and time.
  DateTimePickerType type = 3;

  // The default value displayed in the widget, in milliseconds since [Unix
  // epoch time](https://en.wikipedia.org/wiki/Unix_time).
  //
  // Specify the value based on the type of picker (`DateTimePickerType`):
  //
  // * `DATE_AND_TIME`: a calendar date and time in UTC. For example, to
  //   represent January 1, 2023 at 12:00 PM UTC, use `1672574400000`.
  // * `DATE_ONLY`: a calendar date at 00:00:00 UTC. For example, to represent
  //   January 1, 2023, use `1672531200000`.
  // * `TIME_ONLY`: a time in UTC. For example, to represent 12:00 PM, use
  //   `43200000` (or `12 * 60 * 60 * 1000`).
  int64 value_ms_epoch = 4;

  // The number representing the time zone offset from UTC, in minutes.
  // If set, the `value_ms_epoch` is displayed in the specified time zone.
  // If unset, the value defaults to the user's time zone setting.
  int32 timezone_offset_date = 5;

  // Triggered when the user clicks **Save** or **Clear** from the
  // `DateTimePicker` interface.
  Action on_change_action = 6;
}

// A text, icon, or text and icon button that users can click. For an example in
// Google Chat apps, see
// [Add a
// button](https://developers.google.com/workspace/chat/design-interactive-card-dialog#add_a_button).
//
// To make an image a clickable button, specify an
// [`Image`][google.apps.card.v1.Image] (not an
// [`ImageComponent`][google.apps.card.v1.ImageComponent]) and set an
// `onClick` action.
//
// [Google Workspace
// Add-ons and Chat apps](https://developers.google.com/workspace/extend):
message Button {
  // The text displayed inside the button.
  string text = 1;

  // The icon image. If both `icon` and `text` are set, then the icon appears
  // before the text.
  Icon icon = 2;

  // If set, the button is filled with a solid background color and the font
  // color changes to maintain contrast with the background color. For example,
  // setting a blue background likely results in white text.
  //
  // If unset, the image background is white and the font color is blue.
  //
  // For red, green, and blue, the value of each field is a `float` number that
  // you can express in either of two ways: as a number between 0 and 255
  // divided by 255 (153/255), or as a value between 0 and 1 (0.6). 0 represents
  // the absence of a color and 1 or 255/255 represent the full presence of that
  // color on the RGB scale.
  //
  // Optionally set `alpha`, which sets a level of transparency using this
  // equation:
  //
  // ```
  // pixel color = alpha * (this color) + (1.0 - alpha) * (background color)
  // ```
  //
  // For `alpha`, a value of `1` corresponds with a solid color, and a value of
  // `0` corresponds with a completely transparent color.
  //
  // For example, the following color represents a half transparent red:
  //
  // ```
  // "color": {
  //    "red": 1,
  //    "green": 0,
  //    "blue": 0,
  //    "alpha": 0.5
  // }
  // ```
  google.type.Color color = 3;

  // Required. The action to perform when a user clicks the button, such as
  // opening a hyperlink or running a custom function.
  OnClick on_click = 4;

  // If `true`, the button is displayed in an inactive state and doesn't respond
  // to user actions.
  bool disabled = 5;

  // The alternative text that's used for accessibility.
  //
  // Set descriptive text that lets users know what the button does. For
  // example, if a button opens a hyperlink, you might write: "Opens a new
  // browser tab and navigates to the Google Chat developer documentation at
  // https://developers.google.com/workspace/chat".
  string alt_text = 6;
}

// An icon displayed in a widget on a card. For an example in Google Chat apps,
// see [Add an
// icon](https://developers.google.com/workspace/chat/add-text-image-card-dialog#add_an_icon).
//
// Supports
// [built-in](https://developers.google.com/workspace/chat/format-messages#builtinicons)
// and
// [custom](https://developers.google.com/workspace/chat/format-messages#customicons)
// icons.
//
// [Google Workspace Add-ons and Chat
// apps](https://developers.google.com/workspace/extend):
message Icon {
  // The icon displayed in the widget on the card.
  oneof icons {
    // Display one of the built-in icons provided by Google Workspace.
    //
    // For example, to display an airplane icon, specify `AIRPLANE`.
    // For a bus, specify `BUS`.
    //
    // For a full list of supported icons, see [built-in
    // icons](https://developers.google.com/workspace/chat/format-messages#builtinicons).
    string known_icon = 1;

    // Display a custom icon hosted at an HTTPS URL.
    //
    // For example:
    //
    // ```
    // "iconUrl":
    // "https://developers.google.com/workspace/chat/images/quickstart-app-avatar.png"
    // ```
    //
    // Supported file types include `.png` and `.jpg`.
    string icon_url = 2;

    // Display one of the [Google Material
    // Icons](https://fonts.google.com/icons).
    //
    // For example, to display a [checkbox
    // icon](https://fonts.google.com/icons?selected=Material%20Symbols%20Outlined%3Acheck_box%3AFILL%400%3Bwght%40400%3BGRAD%400%3Bopsz%4048),
    // use
    // ```
    // "material_icon": {
    //   "name": "check_box"
    // }
    // ```
    //
    // [Google Chat apps](https://developers.google.com/workspace/chat):
    MaterialIcon material_icon = 5;
  }

  // Optional. A description of the icon used for accessibility.
  // If unspecified, the default value `Button` is provided. As a best practice,
  // you should set a helpful description for what the icon displays, and if
  // applicable, what it does. For example, `A user's account portrait`, or
  // `Opens a new browser tab and navigates to the Google Chat developer
  // documentation at https://developers.google.com/workspace/chat`.
  //
  // If the icon is set in a [`Button`][google.apps.card.v1.Button], the
  // `altText` appears as helper text when the user hovers over the button.
  // However, if the button also sets `text`, the icon's `altText` is ignored.
  string alt_text = 3;

  // The crop style applied to the image. In some cases, applying a
  // `CIRCLE` crop causes the image to be drawn larger than a built-in
  // icon.
  Widget.ImageType image_type = 4;
}

// A [Google Material Icon](https://fonts.google.com/icons), which includes over
// 2500+ options.
//
// For example, to display a [checkbox
// icon](https://fonts.google.com/icons?selected=Material%20Symbols%20Outlined%3Acheck_box%3AFILL%400%3Bwght%40400%3BGRAD%400%3Bopsz%4048)
// with customized weight and grade, write the following:
//
// ```
// {
//   "name": "check_box",
//   "fill": true,
//   "weight": 300,
//   "grade": -25
// }
// ```
//
// [Google Chat apps](https://developers.google.com/workspace/chat):
message MaterialIcon {
  // The icon name defined in the [Google Material
  // Icon](https://fonts.google.com/icons), for example, `check_box`. Any
  // invalid names are abandoned and replaced with empty string and
  // results in the icon failing to render.
  string name = 1;

  // Whether the icon renders as filled. Default value is false.
  //
  // To preview different icon settings, go to
  // [Google Font Icons](https://fonts.google.com/icons) and adjust the
  // settings under **Customize**.
  bool fill = 2;

  // The stroke weight of the icon. Choose from {100, 200, 300, 400,
  // 500, 600, 700}. If absent, default value is 400. If any other value is
  // specified, the default value is used.
  //
  // To preview different icon settings, go to
  // [Google Font Icons](https://fonts.google.com/icons) and adjust the
  // settings under **Customize**.
  int32 weight = 3;

  // Weight and grade affect a symbol’s thickness. Adjustments to grade are more
  // granular than adjustments to weight and have a small impact on the size of
  // the symbol. Choose from {-25, 0, 200}. If absent, default value is 0. If
  // any other value is specified, the default value is used.
  //
  // To preview different icon settings, go to
  // [Google Font Icons](https://fonts.google.com/icons) and adjust the
  // settings under **Customize**.
  int32 grade = 4;
}

// Represents the crop style applied to an image.
//
// [Google Workspace Add-ons and
// Chat apps](https://developers.google.com/workspace/extend):
//
// For example, here's how to apply a 16:9 aspect ratio:
//
// ```
// cropStyle {
//  "type": "RECTANGLE_CUSTOM",
//  "aspectRatio": 16/9
// }
// ```
message ImageCropStyle {
  // Represents the crop style applied to an image.
  //
  // [Google Workspace Add-ons
  // and Chat apps](https://developers.google.com/workspace/extend):
  enum ImageCropType {
    // Don't use. Unspecified.
    IMAGE_CROP_TYPE_UNSPECIFIED = 0;

    // Default value. Applies a square crop.
    SQUARE = 1;

    // Applies a circular crop.
    CIRCLE = 2;

    // Applies a rectangular crop with a custom aspect ratio. Set the custom
    // aspect ratio with `aspectRatio`.
    RECTANGLE_CUSTOM = 3;

    // Applies a rectangular crop with a 4:3 aspect ratio.
    RECTANGLE_4_3 = 4;
  }

  // The crop type.
  ImageCropType type = 1;

  // The aspect ratio to use if the crop type is `RECTANGLE_CUSTOM`.
  //
  // For example, here's how to apply a 16:9 aspect ratio:
  //
  // ```
  // cropStyle {
  //  "type": "RECTANGLE_CUSTOM",
  //  "aspectRatio": 16/9
  // }
  // ```
  double aspect_ratio = 2;
}

// The style options for the border of a card or widget, including the border
// type and color.
//
// [Google Workspace Add-ons and Chat
// apps](https://developers.google.com/workspace/extend):
message BorderStyle {
  // Represents the border types applied to widgets.
  //
  // [Google Workspace Add-ons
  // and Chat apps](https://developers.google.com/workspace/extend):
  enum BorderType {
    // Don't use. Unspecified.
    BORDER_TYPE_UNSPECIFIED = 0;

    // Default value. No border.
    NO_BORDER = 1;

    // Outline.
    STROKE = 2;
  }

  // The border type.
  BorderType type = 1;

  // The colors to use when the type is `BORDER_TYPE_STROKE`.
  google.type.Color stroke_color = 2;

  // The corner radius for the border.
  int32 corner_radius = 3;
}

// Represents an image.
//
// [Google Workspace Add-ons and Chat
// apps](https://developers.google.com/workspace/extend):
message ImageComponent {
  // The image URL.
  string image_uri = 1;

  // The accessibility label for the image.
  string alt_text = 2;

  // The crop style to apply to the image.
  ImageCropStyle crop_style = 3;

  // The border style to apply to the image.
  BorderStyle border_style = 4;
}

// Displays a grid with a collection of items. Items can only include text or
// images. For responsive columns, or to include more than text or images, use
// [`Columns`][google.apps.card.v1.Columns]. For an example in Google Chat apps,
// see [Display a Grid with a collection of
// items](https://developers.google.com/workspace/chat/format-structure-card-dialog#display_a_grid_with_a_collection_of_items).
//
// A grid supports any number of columns and items. The number of rows is
// determined by items divided by columns. A grid with
// 10 items and 2 columns has 5 rows. A grid with 11 items and 2 columns
// has 6 rows.
//
// [Google Workspace Add-ons and Chat
// apps](https://developers.google.com/workspace/extend):
//
// For example, the following JSON creates a 2 column grid with a single
// item:
//
// ```
// "grid": {
//   "title": "A fine collection of items",
//   "columnCount": 2,
//   "borderStyle": {
//     "type": "STROKE",
//     "cornerRadius": 4
//   },
//   "items": [
//     {
//       "image": {
//         "imageUri": "https://www.example.com/image.png",
//         "cropStyle": {
//           "type": "SQUARE"
//         },
//         "borderStyle": {
//           "type": "STROKE"
//         }
//       },
//       "title": "An item",
//       "textAlignment": "CENTER"
//     }
//   ],
//   "onClick": {
//     "openLink": {
//       "url": "https://www.example.com"
//     }
//   }
// }
// ```
message Grid {
  // Represents an item in a grid layout. Items can contain text, an image, or
  // both text and an image.
  //
  // [Google Workspace Add-ons and Chat
  // apps](https://developers.google.com/workspace/extend):
  message GridItem {
    // Represents the various layout options available for a grid item.
    //
    // [Google Workspace Add-ons and Chat
    // apps](https://developers.google.com/workspace/extend):
    enum GridItemLayout {
      // Don't use. Unspecified.
      GRID_ITEM_LAYOUT_UNSPECIFIED = 0;

      // The title and subtitle are shown below the grid item's image.
      TEXT_BELOW = 1;

      // The title and subtitle are shown above the grid item's image.
      TEXT_ABOVE = 2;
    }

    // A user-specified identifier for this grid item. This identifier is
    // returned in the parent grid's `onClick` callback parameters.
    string id = 1;

    // The image that displays in the grid item.
    ImageComponent image = 2;

    // The grid item's title.
    string title = 3;

    // The grid item's subtitle.
    string subtitle = 4;

    // The layout to use for the grid item.
    GridItemLayout layout = 9;
  }

  // The text that displays in the grid header.
  string title = 1;

  // The items to display in the grid.
  repeated GridItem items = 2;

  // The border style to apply to each grid item.
  BorderStyle border_style = 3;

  // The number of columns to display in the grid. A default value
  // is used if this field isn't specified, and that default value is
  // different depending on where the grid is shown (dialog versus companion).
  int32 column_count = 4;

  // This callback is reused by each individual grid item, but with the
  // item's identifier and index in the items list added to the callback's
  // parameters.
  OnClick on_click = 5;
}

// The `Columns` widget displays up to 2 columns in a card or dialog. You can
// add widgets to each column; the widgets appear in the order that they are
// specified. For an example in Google Chat apps, see
// [Display cards and dialogs in
// columns](https://developers.google.com/workspace/chat/format-structure-card-dialog#display_cards_and_dialogs_in_columns).
//
// The height of each column is determined by the taller column. For example, if
// the first column is taller than the second column, both columns have the
// height of the first column. Because each column can contain a different
// number of widgets, you can't define rows or align widgets between the
// columns.
//
// Columns are displayed side-by-side. You can customize the width of each
// column using the `HorizontalSizeStyle` field. If the user's
// screen width is too narrow, the second column wraps below the first:
//
// * On web, the second column wraps if the screen width is less than or equal
//   to 480 pixels.
// * On iOS devices, the second column wraps if the screen width is
//   less than or equal to 300 pt.
// * On Android devices, the second column wraps if the screen width is
//   less than or equal to 320 dp.
//
// To include more than 2 columns, or to use rows, use the
// [`Grid`][google.apps.card.v1.Grid] widget.
//
// [Google Workspace Add-ons and Chat
// apps](https://developers.google.com/workspace/extend):
// Columns for Google Workspace Add-ons are in
// Developer Preview.
message Columns {
  // A column.
  //
  // [Google Workspace Add-ons and Chat
  // apps](https://developers.google.com/workspace/extend):
  // Columns for Google Workspace Add-ons are in
  // Developer Preview.
  message Column {
    // Specifies how a column fills the width of the card. The width of each
    // column depends on both the `HorizontalSizeStyle` and the width of the
    // widgets within the column.
    //
    // [Google Workspace Add-ons and Chat
    // apps](https://developers.google.com/workspace/extend):
    // Columns for Google Workspace Add-ons are in
    // Developer Preview.
    enum HorizontalSizeStyle {
      // Don't use. Unspecified.
      HORIZONTAL_SIZE_STYLE_UNSPECIFIED = 0;

      // Default value. Column fills the available space, up to 70% of the
      // card's width. If both columns are set to `FILL_AVAILABLE_SPACE`, each
      // column fills 50% of the space.
      FILL_AVAILABLE_SPACE = 1;

      // Column fills the least amount of space possible and no more than 30% of
      // the card's width.
      FILL_MINIMUM_SPACE = 2;
    }

    // Specifies whether widgets align to the top, bottom, or center of a
    // column.
    //
    // [Google Workspace Add-ons and Chat
    // apps](https://developers.google.com/workspace/extend):
    // Columns for Google Workspace Add-ons are in
    // Developer Preview.
    enum VerticalAlignment {
      // Don't use. Unspecified.
      VERTICAL_ALIGNMENT_UNSPECIFIED = 0;

      // Default value. Aligns widgets to the center of a column.
      CENTER = 1;

      // Aligns widgets to the top of a column.
      TOP = 2;

      // Aligns widgets to the bottom of a column.
      BOTTOM = 3;
    }

    // The supported widgets that you can include in a column.
    //
    // [Google Workspace Add-ons and Chat
    // apps](https://developers.google.com/workspace/extend):
    // Columns for Google Workspace Add-ons are in
    // Developer Preview.
    message Widgets {
      oneof data {
        // [TextParagraph][google.apps.card.v1.TextParagraph] widget.
        TextParagraph text_paragraph = 1;

        // [Image][google.apps.card.v1.Image] widget.
        Image image = 2;

        // [DecoratedText][google.apps.card.v1.DecoratedText] widget.
        DecoratedText decorated_text = 3;

        // [ButtonList][google.apps.card.v1.ButtonList] widget.
        ButtonList button_list = 4;

        // [TextInput][google.apps.card.v1.TextInput] widget.
        TextInput text_input = 5;

        // [SelectionInput][google.apps.card.v1.SelectionInput] widget.
        SelectionInput selection_input = 6;

        // [DateTimePicker][google.apps.card.v1.DateTimePicker] widget.
        DateTimePicker date_time_picker = 7;
      }
    }

    // Specifies how a column fills the width of the card.
    HorizontalSizeStyle horizontal_size_style = 1;

    // Specifies whether widgets align to the left, right, or center of a
    // column.
    Widget.HorizontalAlignment horizontal_alignment = 2;

    // Specifies whether widgets align to the top, bottom, or center of a
    // column.
    VerticalAlignment vertical_alignment = 3;

    // An array of widgets included in a column. Widgets appear in the order
    // that they are specified.
    repeated Widgets widgets = 4;
  }

  // An array of columns. You can include up to 2 columns in a card or dialog.
  repeated Column column_items = 2;
}

// Represents how to respond when users click an interactive element on
// a card, such as a button.
//
// [Google Workspace Add-ons and Chat
// apps](https://developers.google.com/workspace/extend):
message OnClick {
  oneof data {
    // If specified, an action is triggered by this `onClick`.
    Action action = 1;

    // If specified, this `onClick` triggers an open link action.
    OpenLink open_link = 2;

    // An add-on triggers this action when the action needs to open a
    // link. This differs from the `open_link` above in that this needs to talk
    // to server to get the link. Thus some preparation work is required for
    // web client to do before the open link action response comes back.
    //
    // [Google Workspace
    // Add-ons](https://developers.google.com/workspace/add-ons):
    Action open_dynamic_link_action = 3;

    // A new card is pushed to the card stack after clicking if specified.
    //
    // [Google Workspace
    // Add-ons](https://developers.google.com/workspace/add-ons):
    Card card = 4;
  }
}

// Represents an `onClick` event that opens a hyperlink.
//
// [Google Workspace Add-ons and Chat
// apps](https://developers.google.com/workspace/extend):
message OpenLink {
  // When an `OnClick` action opens a link, then the client can either open it
  // as a full-size window (if that's the frame used by the client), or an
  // overlay (such as a pop-up). The implementation depends on the client
  // platform capabilities, and the value selected might be ignored if the
  // client doesn't support it. `FULL_SIZE` is supported by all clients.
  //
  // [Google Workspace
  // Add-ons](https://developers.google.com/workspace/add-ons):
  enum OpenAs {
    // The link opens as a full-size window (if that's the frame used by the
    // client).
    FULL_SIZE = 0;

    // The link opens as an overlay, such as a pop-up.
    OVERLAY = 1;
  }

  // What the client does when a link opened by an `OnClick` action is closed.
  //
  // Implementation depends on client platform capabilities. For example, a web
  // browser might open a link in a pop-up window with an `OnClose` handler.
  //
  // If both `OnOpen` and `OnClose` handlers are set, and the client platform
  // can't support both values, `OnClose` takes precedence.
  //
  // [Google Workspace
  // Add-ons](https://developers.google.com/workspace/add-ons):
  enum OnClose {
    // Default value. The card doesn't reload; nothing happens.
    NOTHING = 0;

    // Reloads the card after the child window closes.
    //
    // If used in conjunction with
    // [`OpenAs.OVERLAY`](https://developers.google.com/workspace/add-ons/reference/rpc/google.apps.card.v1#openas),
    // the child window acts as a modal dialog and the parent card is blocked
    // until the child window closes.
    RELOAD = 1;
  }

  // The URL to open.
  string url = 1;

  // How to open a link.
  //
  // [Google Workspace
  // Add-ons](https://developers.google.com/workspace/add-ons):
  OpenAs open_as = 2;

  // Whether the client forgets about a link after opening it, or observes it
  // until the window closes.
  //
  // [Google Workspace
  // Add-ons](https://developers.google.com/workspace/add-ons):
  OnClose on_close = 3;
}

// An action that describes the behavior when the form is submitted.
// For example, you can invoke an Apps Script script to handle the form.
// If the action is triggered, the form values are sent to the server.
//
// [Google Workspace Add-ons and Chat
// apps](https://developers.google.com/workspace/extend):
message Action {
  // List of string parameters to supply when the action method is invoked.
  // For example, consider three snooze buttons: snooze now, snooze one day,
  // or snooze next week. You might use `action method = snooze()`, passing the
  // snooze type and snooze time in the list of string parameters.
  //
  // To learn more, see
  // [`CommonEventObject`](https://developers.google.com/workspace/chat/api/reference/rest/v1/Event#commoneventobject).
  //
  // [Google Workspace Add-ons and Chat
  // apps](https://developers.google.com/workspace/extend):
  message ActionParameter {
    // The name of the parameter for the action script.
    string key = 1;

    // The value of the parameter.
    string value = 2;
  }

  // Specifies the loading indicator that the action displays while
  // making the call to the action.
  //
  // [Google Workspace Add-ons and Chat
  // apps](https://developers.google.com/workspace/extend):
  enum LoadIndicator {
    // Displays a spinner to indicate that content is loading.
    SPINNER = 0;

    // Nothing is displayed.
    NONE = 1;
  }

  // Optional. Required when opening a
  // [dialog](https://developers.google.com/workspace/chat/dialogs).
  //
  // What to do in response to an interaction with a user, such as a user
  // clicking a button in a card message.
  //
  // If unspecified, the app responds by executing an `action`—like opening a
  // link or running a function—as normal.
  //
  // By specifying an `interaction`, the app can respond in special interactive
  // ways. For example, by setting `interaction` to `OPEN_DIALOG`, the app can
  // open a [dialog](https://developers.google.com/workspace/chat/dialogs).
  //
  // When specified, a loading indicator isn't shown. If specified for
  // an add-on, the entire card is stripped and nothing is shown in the client.
  //
  // [Google Chat apps](https://developers.google.com/workspace/chat):
  enum Interaction {
    // Default value. The `action` executes as normal.
    INTERACTION_UNSPECIFIED = 0;

    // Opens a [dialog](https://developers.google.com/workspace/chat/dialogs), a
    // windowed, card-based interface that Chat apps use to interact with users.
    //
    // Only supported by Chat apps in response to button-clicks on card
    // messages. If specified for
    // an add-on, the entire card is stripped and nothing is shown in the
    // client.
    //
    // [Google Chat apps](https://developers.google.com/workspace/chat):
    OPEN_DIALOG = 1;
  }

  // A custom function to invoke when the containing element is
  // clicked or othrwise activated.
  //
  // For example usage, see [Read form
  // data](https://developers.google.com/workspace/chat/read-form-data).
  string function = 1;

  // List of action parameters.
  repeated ActionParameter parameters = 2;

  // Specifies the loading indicator that the action displays while
  // making the call to the action.
  LoadIndicator load_indicator = 3;

  // Indicates whether form values persist after the action. The default value
  // is `false`.
  //
  // If `true`, form values remain after the action is triggered. To let the
  // user make changes while the action is being processed, set
  // [`LoadIndicator`](https://developers.google.com/workspace/add-ons/reference/rpc/google.apps.card.v1#loadindicator)
  // to `NONE`. For [card
  // messages](https://developers.google.com/workspace/chat/api/guides/v1/messages/create#create)
  // in Chat apps, you must also set the action's
  // [`ResponseType`](https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces.messages#responsetype)
  // to `UPDATE_MESSAGE` and use the same
  // [`card_id`](https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces.messages#CardWithId)
  // from the card that contained the action.
  //
  // If `false`, the form values are cleared when the action is triggered.
  // To prevent the user from making changes while the action is being
  // processed, set
  // [`LoadIndicator`](https://developers.google.com/workspace/add-ons/reference/rpc/google.apps.card.v1#loadindicator)
  // to `SPINNER`.
  bool persist_values = 4;

  // Optional. Required when opening a
  // [dialog](https://developers.google.com/workspace/chat/dialogs).
  //
  // What to do in response to an interaction with a user, such as a user
  // clicking a button in a card message.
  //
  // If unspecified, the app responds by executing an `action`—like opening a
  // link or running a function—as normal.
  //
  // By specifying an `interaction`, the app can respond in special interactive
  // ways. For example, by setting `interaction` to `OPEN_DIALOG`, the app can
  // open a [dialog](https://developers.google.com/workspace/chat/dialogs). When
  // specified, a loading indicator isn't shown. If specified for
  // an add-on, the entire card is stripped and nothing is shown in the client.
  //
  // [Google Chat apps](https://developers.google.com/workspace/chat):
  Interaction interaction = 5;
}
