chromium/chrome/browser/resources/compose/app.html

<style include="md-select">
  :host {
    --compose-loading-body-and-footer-height: 136px;
    --gap-between-sections_: 16px;
    --padding_: 20px;
    display: grid;
    grid-template-areas: "dialog";
    grid-auto-columns: 100%;
    align-items: start;
    user-select: none;
  }

  a {
    color: var(--color-compose-dialog-link);
  }

  .dialog {
    width: 448px;
    display: flex;
    flex-direction: column;
    gap: var(--gap-between-sections_);
    grid-area: dialog;
    padding: var(--padding_) 0;
  }

  .close-button {
    position: fixed;
    --close-button-distance-from-edge: calc(20px -
        ((var(--cr-icon-button-size) - var(--cr-icon-button-icon-size)) / 2));
    inset-block-start: var(--close-button-distance-from-edge);
    inset-inline-end: var(--close-button-distance-from-edge);
  }

  #firstRunHeading {
    display: flex;
    height: 48px;
    align-items: start;
    padding: 0 var(--padding_);
  }

  #freMsbbHeading {
    display: flex;
    height: 48px;
    align-items: start;
    padding: 0 var(--padding_);
  }

  #firstRunIconContainer {
    margin-inline-end: var(--gap-between-sections_);
    min-width: 48px;
    height: 48px;
    border-radius: 12px;
    background: linear-gradient(136deg,
        var(--color-sys-gradient-primary) 1.59%,
        var(--color-sys-gradient-tertiary) 100%);
    color: var(--color-compose-dialog-logo);
    display: flex;
    justify-content: center;
    align-items: center;
    transform-origin: top left;
  }

  #firstRunHeading iron-icon {
    --iron-icon-width: 20px;
    --iron-icon-height: 20px;
  }

  #firstRunContainer {
    color: var(--cr-secondary-text-color);
    font: inherit;
    font-size: 13px;
    line-height: 20px;
    display: flex;
    flex-direction: column;
    gap: 7px;
    padding: 0 20px;
  }

  #freMsbbContainer {
    color: var(--cr-secondary-text-color);
    font: inherit;
    font-size: 13px;
    line-height: 20px;
    display: flex;
    flex-direction: column;
    padding: 0 20px;
  }

  #heading {
    display: flex;
    height: 24px;
    align-items: center;
    padding: 0 var(--padding_);
  }

  h1 {
    color: var(--color-compose-dialog-title);
    font-size: 16px;
    font-weight: 500;
    line-height: 24px;
    margin: 0;
    margin-inline-end: auto;
    padding-inline-end: 32px; /* From --cr-icon-button-size. */
  }

  cr-icon-button {
    --cr-icon-button-fill-color: var(--color-compose-dialog-foreground-subtle);
    margin: 0;
  }

  #bodyAndFooter {
    display: grid;
    grid-template-areas: "body" "footer";
    grid-auto-columns: 100%;
    gap: var(--gap-between-sections_);
    position: relative;
  }

  #body {
    --results-background_: var(--color-compose-dialog-result-background);
    box-sizing: border-box;
    grid-area: body;
    display: grid;
    grid-template-areas: "textarea" "bodyContent";
    grid-auto-columns: 100%;
    max-height: 220px;
    padding: 0 20px;
  }

  :host(:not([submitted_])) #body {
    /* Non-submitted dialog has no bodyContent. */
    grid-template-areas: "textarea";
  }

  /* Set scroll-related styles if UI refinements are not enabled. */
  :host(:not([enable-ui-refinements])) #body {
    --scrollbar-width_: 4px;
    border-color: transparent;
    border-style: solid;
    border-width: 1px 0;
    overflow: auto;
    padding-inline-end: calc(20px - var(--scrollbar-width_));
    scrollbar-gutter: stable;
  }

  :host(:not([enable-ui-refinements]))
      #body.can-scroll:not(.scrolled-to-top) {
    border-top: solid 1px var(--color-compose-dialog-divider);
  }

  :host(:not([enable-ui-refinements]))
      #body.can-scroll:not(.scrolled-to-bottom) {
    border-bottom: solid 1px var(--color-compose-dialog-divider);
  }

  :host(:not([enable-ui-refinements])[loading-indicator-shown_]) #body {
    /* When loading, the heights of contents within #body are in flux due to
    * animations. Force the entire #body to be visible to prevent scrollbars
    * from flickering, and remove scrollbar width from padding. */
    overflow: visible;
    padding-inline-end: 20px;
  }

  /* Set scroll-related styles if UI refinements are enabled */
  :host([enable-ui-refinements]) #resultTextContainer {
    border-color: transparent;
    border-style: solid;
    border-width: 1px 0;
    overflow-y: auto;
  }

  :host([enable-ui-refinements])
       #resultTextContainer.can-scroll:not(.scrolled-to-top) {
    border-top-color: var(--scrollable-border-color);
  }

  /* Different elements are made scrollable depending on whether UI refinements
   * are enabled. */
  #body::-webkit-scrollbar, #resultTextContainer::-webkit-scrollbar {
    background: transparent;
    width: var(--scrollbar-width_);
  }

  #body::-webkit-scrollbar-thumb {
    background: var(--color-compose-dialog-scrollbar-thumb);
  }

  #resultTextContainer::-webkit-scrollbar-thumb {
    border-radius: 10px;
    background: var(--color-compose-dialog-result-container-scrollbar-thumb);
  }

  :host([loading-indicator-shown_]) #bodyAndFooter {
    /* There is no footer in the loading screen. */
    grid-template-areas: "body";
    height: var(--compose-loading-body-and-footer-height);
  }

  #textarea {
    grid-area: textarea;
  }

  #loading,
  .result-container {
    grid-area: bodyContent;
    margin-top: 8px;
  }

  #loading {
    display: flex;
    border: solid 1px var(--results-background_);
    border-radius: 8px;
    padding: 15px;
    box-sizing: border-box;
    height: 80px;
  }

  .result-container {
    --compose-result-text-color-while-loading: var(
        --color-compose-dialog-result-foreground-while-loading);
    --compose-result-text-color: var(--color-compose-dialog-result-foreground);
    border-radius: 8px;
    display: flex;
    box-sizing: border-box;
    background: var(--results-background_);
    color: var(--cr-primary-text-color);
    font-size: 12px;
    line-height: 16px;
  }

  :host([enable-ui-refinements][is-editing-result-text_]) .result-container {
    outline: solid 2px var(--cr-focus-outline-color);
  }

  #resultContainerInner {
    display: flex;
    flex-direction: column;
    width: 100%;
    box-sizing: border-box;
    padding-top: 16px;
  }

  :host(:not([enable-ui-refinements])) #resultContainerInner {
    padding: 16px;
  }

  /* #resultTextContainer is only styled if UI refinements are applied. */
  :host([enable-ui-refinements]) #resultTextContainer {
    max-height: 112px;
    overflow: auto;
    /* Incorporates width of righthand scrollbar. */
    padding-inline-start: 16px;
    margin-inline-end: 4px;

    --scrollbar-width_: 4px;
    padding-inline-end: calc(12px - var(--scrollbar-width_));
    scrollbar-gutter: stable;
  }

  /* Border separating result container text and actions bar. */
  :host([enable-ui-refinements]) #resultOptionsContainer {
    border-top: 1px solid var(--color-compose-dialog-divider);
  }

  #resultOptions {
    display: flex;
    align-items: flex-end;
    gap: 8px;
  }

  /* Adjust padding and margins based on whether UI refinements is enabled. */
  :host(:not([enable-ui-refinements])) #resultOptions {
    margin-block-start: 16px;
  }
  :host([enable-ui-refinements]) #resultOptions {
    padding: 8px 12px;
  }

  #resultFooter[inert], #resultOptions[inert] {
    opacity: 0;
  }

  #resultOptions .md-select {
    --md-select-bg-color: transparent;
    min-height: 36px;
    min-width: 96px;
    height: auto;
    width: auto;
  }

  select option {
    --md-select-option-bg-color: var(--results-background_);
    color: var(--compose-result-text-color);
  }

  select option:disabled {
    color: var(--color-compose-dialog-select-option-disabled);
  }

  :host([enable-ui-refinements]) #resultOptions .md-select {
    min-height: 24px;
    min-width: 60px;
    line-height: 16px;
    border: 0;
    border-radius: 100px;
    font-family: Roboto, "Noto Sans", Arial, sans-serif;
    font-weight: 500;
    color: var(--cr-secondary-text-color);

    /* Custom drop-down arrow. */
    background: url(//resources/images/chevron_down.svg)
      calc(100% - var(--md-select-side-padding) + var(--md-arrow-width))
      center no-repeat;
  }

  @media (prefers-color-scheme: dark) {
    :host([enable-ui-refinements]) #resultOptions .md-select {
      /* Separate svg required for dark mode as color is hard-coded into
      * file. */
      background-image: url(//resources/images/dark/chevron_down.svg)
    }
  }

  /* Re-define hover style for md-select, as replacing the background overwrites
  the default style. */
  :host([enable-ui-refinements]) #resultOptions .md-select:hover {
    background-color: var(--color-comboxbox-ink-drop-hovered,
      var(--cr-hover-on-subtle-background-color));
  }

  .icon-buttons-row {
    display: grid;
    grid-auto-columns: var(--cr-icon-size);
    grid-auto-rows: var(--cr-icon-size);
    grid-auto-flow: column;
    gap: 12px;
    align-items: center;
    justify-items: center;
    margin-inline-start: auto;
  }

  :host([enable-ui-refinements]) .icon-buttons-row {
    grid-auto-columns: auto;
    grid-auto-rows: auto;
    gap: 10px;
  }

  .icon-buttons-row cr-icon-button {
    --cr-icon-button-fill-color: var(--color-compose-dialog-result-icon);
    --cr-icon-button-icon-size: var(--cr-icon-size);
    margin: 0;
  }

  /* cr-button is only used when UI refinements is enabled. */
  .icon-buttons-row cr-button {
    --cr-button-text-color: var(--color-compose-dialog-result-icon);
    --cr-icon-size: 16px;
    margin: 0;
    padding-inline-start: 8px;
    padding-inline-end: 4px;
    padding-top: 4px;
    padding-bottom: 4px;
    min-height: 24px;
    height: auto;
    border: 0;
    gap: 4px;
  }

  .icon-buttons-row cr-button div {
    margin-top: 2px;
    line-height: 14px;
    font-size: 11px;
  }

  .icon-buttons-row cr-button iron-icon {
    width: var(--cr-icon-size);
    height: var(--cr-icon-size);
  }

  :host([enable-ui-refinements]) .icon-buttons-row
      .button-container:last-child {
    padding-left: 10px;
    position: relative
  }

  /* Vertical divider between undo and redo buttons. */
  :host([enable-ui-refinements]) .icon-buttons-row > div:last-child:before {
    content: "";
    background: var(--color-compose-dialog-divider);
    position: absolute;
    top: 25%;
    left: 0px;
    height: 50%;
    width: 1px;
  }

  .footer {
    grid-area: footer;
    align-items: center;
    display: flex;
    padding: 0 var(--padding_);
    justify-content: flex-end;
  }

  #submitFooter {
    gap:35px;
  }

  #resultFooter {
    gap:45px;
  }

  .footer-text {
    display: flex;
    align-items: start;
    gap: 8px;
    margin-inline-end: auto;
    color: var(--color-compose-dialog-foreground-subtle);
    font-size: 11px;
    line-height: 16px;
  }

  .footer-text .icon-buttons-row {
    --cr-icon-size: 16px;
    margin-inline-end: 8px;
  }

  .footer cr-button {
    margin-inline-start: 8px;
  }

  #errorFooter {
    flex-direction: column;
    user-select: text;
  }

  #errorGoBackButton {
    margin-top: 20px;
    align-self: end;
  }

  :host-context([is-editing-submitted-input_]) #body,
  :host-context([is-editing-submitted-input_]) .footer {
    visibility: hidden;
  }

  :host-context([is-editing-submitted-input_]) #bodyAndFooter {
    /* Ensure there's always enough height to show the edit flow. The edit flow
    * overlays over the existing content, and sometimes, the existing content
    * is not tall enough to show the textarea and buttons (eg. the error
    * state). */
    min-height: 153px;
  }

  :host-context([is-editing-submitted-input_]) #bodyAndFooter {
    min-height: 141px;
  }

  #editContainer {
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    position: absolute;
    gap: var(--gap-between-sections_);
    inset: 0;
    padding: 0 var(--padding_);
  }

  #editContainer compose-textarea {
    --compose-textarea-input-height: 100%;
    flex: 1;
  }

  #editContainer .footer {
    padding: 0;
    visibility: visible;
  }

  /**
   * cr-hidden-style stamps an !important on [hidden] elements, which prevents
   * any animations/transitions from applying. Instead of using cr-hidden-style,
   * list all the [hidden] elements below. Not all elements need this, just
   * the ones that override the default 'display' property.
   */
  .dialog[hidden],
  .footer[hidden],
  .result-container[hidden],
  .md-select[hidden],
  .icon-buttons-row cr-icon-button[hidden],
  #loading[hidden],
  #editContainer[hidden] {
    display: none;
  }
</style>

<div id="firstRunDialog" class="dialog" hidden="[[!showFirstRunDialog_]]">
  <div id="firstRunHeading">
    <div id="firstRunIconContainer">
      <iron-icon icon="compose:compose"></iron-icon>
    </div>
    <h1>$i18n{firstRunTitle}</h1>
    <cr-icon-button id="firstRunCloseButton" class="close-button"
      iron-icon="cr:close" on-click="onClose_" aria-label="$i18n{close}">
    </cr-icon-button>
  </div>

  <div id="firstRunContainer">
    <div id="firstRunTopText">$i18n{firstRunMainTop}</div>
    <div id="firstRunMidText">$i18n{firstRunMainMid}</div>
    <div id="firstRunBottomText" on-click="onFirstRunBottomTextClick_">
      $i18nRaw{firstRunMainBottom}
    </div>
  </div>

  <div id="firstRunFooter" class="footer">
    <cr-button id="firstRunOkButton" class="action-button"
      on-click="onFirstRunOkButtonClick_">
      $i18n{firstRunOkButton}
    </cr-button>
  </div>
</div>


<div id="freMsbbDialog" class="dialog" hidden="[[!showMSBBDialog_]]">
  <div id="freMsbbHeading">
    <h1>$i18n{freMsbbTitle}</h1>
    <cr-icon-button id="closeButtonMSBB" class="close-button"
      iron-icon="cr:close" on-click="onClose_">
    </cr-icon-button>
  </div>

  <div id="freMsbbContainer">
    <div id="freMsbbText">
      $i18nRaw{freMsbbMain}
    </div>
  </div>

  <div id="freMsbbFooter" class="footer">
    <cr-button id="SettingsButton" class="action-button"
      on-click="onMsbbSettingsClick_">
      $i18n{freMsbbSettingsButton}
    </cr-button>
  </div>
</div>


<div id="appDialog" class="dialog" hidden="[[!showMainAppDialog_]]">
  <div id="heading">
    <h1>$i18n{dialogTitle}</h1>
    <cr-icon-button id="closeButton" class="close-button" iron-icon="cr:close"
      on-click="onClose_" aria-label="$i18n{close}">
    </cr-icon-button>
  </div>

  <div id="bodyAndFooter">
    <div id="body">
      <compose-textarea id="textarea" value="{{input_}}"
        readonly="[[submitted_]]" allow-exiting-readonly-mode="[[!loading_]]"
        on-edit-click="onEditClick_" input-params="[[inputParams_]]">
      </compose-textarea>

      <div id="loading"
          hidden="[[!loadingIndicatorShown_]]">
        <cr-loading-gradient>
          <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="51">
            <clipPath>
              <rect x="0" y="0" width="100%" height="11" rx="4"></rect>
              <rect x="0" y="20" width="100%" height="10.8333" rx="4"></rect>
              <rect x="0" y="40" width="75%" height="11" rx="4"></rect>
            </clipPath>
          </svg>
        </cr-loading-gradient>
      </div>
      <div id="resultContainer" class="result-container"
          hidden="[[hideResults_(hasOutput_, feedbackEnabled_)]]">
        <div id="resultContainerInner">
          <div id="resultTextContainer">
            <compose-result-text id="resultText" text-input="[[responseText_]]"
              is-output-complete="{{outputComplete_}}"
              has-output="{{hasOutput_}}"
              has-partial-output="{{hasPartialOutput_}}"
              on-result-edit="onResultEdit_"
              on-set-result-focus="onSetResultFocus_">
            </compose-result-text>
          </div>
          <div id="resultOptionsContainer">
            <div id="resultOptions"
                inert$="[[hideResults_(hasOutput_, feedbackEnabled_)]]">
              <select class="md-select" id="lengthMenu"
                value="[[selectedLength_]]" aria-label="$i18n{lengthMenuTitle}"
                on-change="onLengthChanged_" hidden="[[enableUiRefinements]]">
                <template is="dom-repeat" items="[[lengthOptions_]]">
                  <option value="[[item.value]]" disabled$="[[item.isDefault]]"
                      selected$="[[item.isDefault]]">
                    [[item.label]]
                  </option>
                </template>
              </select>
              <select class="md-select" id="toneMenu" value="[[selectedTone_]]"
                  aria-label="$i18n{toneMenuTitle}" on-change="onToneChanged_"
                  hidden="[[enableUiRefinements]]">
                <template is="dom-repeat" items="[[toneOptions_]]">
                  <option value="[[item.value]]" disabled$="[[item.isDefault]]"
                      selected$="[[item.isDefault]]">
                    [[item.label]]
                  </option>
                </template>
              </select>
              <select class="md-select" id="modifierMenu"
                  value="[[selectedModifier_]]"
                  aria-label="$i18n{modifierMenuLabel}"
                  on-change="onModifierChanged_"
                  on-keydown="openModifierMenuOnKeyDown_"
                  hidden="[[!enableUiRefinements]]">
                <template is="dom-repeat" items="[[modifierOptions_]]">
                  <option value="[[item.value]]" disabled$="[[item.isDefault]]"
                      selected$="[[item.isDefault]]">
                    [[item.label]]
                  </option>
                </template>
              </select>
              <div class="icon-buttons-row">
                <cr-icon-button id="undoButton" iron-icon="compose:undo"
                  title="$i18n{undo}" disabled="[[!undoEnabled_]]"
                  on-click="onUndoClick_" hidden="[[enableUiRefinements]]">
                </cr-icon-button>
                <cr-icon-button id="refreshButton" iron-icon="compose:refresh"
                  title="$i18n{resubmit}" on-click="onRefresh_"
                  hidden="[[enableUiRefinements]]">
                </cr-icon-button>
                <div class="button-container" hidden="[[!enableUiRefinements]]">
                  <cr-button id="undoButtonRefined" title="$i18n{undo}"
                    disabled="[[!undoEnabled_]]" on-click="onUndoClick_">
                    <div aria-hidden="true"> $i18n{undoButtonText} </div>
                    <iron-icon aria-hidden="true" slot="suffix-icon"
                      icon="compose:undo">
                    </iron-icon>
                  </cr-button>
                </div>
                <div class="button-container" hidden="[[!enableUiRefinements]]">
                  <cr-button id="redoButton" title="$i18n{redo}"
                    disabled="[[!redoEnabled_]]" on-click="onRedoClick_">
                    <div aria-hidden="true"> $i18n{redoButtonText} </div>
                    <iron-icon aria-hidden="true" slot="suffix-icon"
                      icon="compose:redo">
                    </iron-icon>
                  </cr-icon-button>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <div id="submitFooter" class="footer" hidden$="[[submitted_]]">
      <div class="footer-text">
        <div on-click="onFooterClick_">
          $i18nRaw{inputFooter}
        </div>
      </div>
      <cr-button id="submitButton" class="action-button" on-click="onSubmit_"
        disabled="[[!isSubmitEnabled_]]">
        <iron-icon slot="prefix-icon" icon="compose:compose"></iron-icon>
        $i18n{submitButton}
      </cr-button>
    </div>

    <div id="resultFooter" class="footer"
        hidden$="[[hideResults_(hasOutput_, feedbackEnabled_)]]"
        inert$="[[hasPartialOutput_]]">
      <div class="footer-text">
        <div on-click="onFooterClick_">
          <b id="onDeviceUsedFooter"
              hidden$="[[!showOnDeviceDogfoodFooter_(response_)]]"
              >$i18nRaw{onDeviceUsedFooter}
          </b>
          <!-- <span hidden="[[!showOnDeviceDogfoodFooter_(response_)]]"
              >$i18nRaw{dogfoodFooter}</span>
          <span hidden="[[!showDefaultResultFooter_(response_, enableUiRefinements)]]"
              >$i18nRaw{resultFooter}</span>
          <span
            hidden="[[!showRefinementsResultFooter_(response_, enableUiRefinements)]]"
            >$i18nRaw{refinementsResultFooter}</span> -->
          <span hidden="[[!showOnDeviceDogfoodFooter_(response_)]]"
              >$i18nRaw{dogfoodFooter}</span>
          <span hidden="[[showOnDeviceDogfoodFooter_(response_)]]"
              >$i18nRaw{resultFooter}</span>
        </div>
        <cr-feedback-buttons id="feedbackButtons"
            on-selected-option-changed="onFeedbackSelectedOptionChanged_"
            selected-option="[[feedbackState_]]"
            disabled$="[[!feedbackEnabled_]]">
        </cr-feedback-buttons>
      </div>
      <cr-button id="acceptButton" class="action-button" on-click="onAccept_">
        [[acceptButtonText_(textSelected_)]]
      </cr-button>
    </div>

    <div id="errorFooter" class="footer"
        hidden="[[!hasFailedResponse_(response_)]]">
      <div on-click="onFooterClick_" class="footer-text">
        <span hidden="[[hasErrorWithLink_(response_)]]"
          >[[failedResponseErrorText_(response_)]]</span>
        <span hidden="[[!hasUnsupportedLanguageResponse_(response_)]]"
          >$i18nRaw{errorUnsupportedLanguage}</span>
        <span hidden="[[!hasPermissionDeniedResponse_(response_)]]"
          >$i18nRaw{errorPermissionDenied}</span>
      </div>
      <cr-button id="errorGoBackButton" class="action-button"
        on-click="onErrorGoBackButton_"
        hidden="[[!isBackFromErrorAvailable_(response_)]]">
        <iron-icon aria-hidden="true" slot="prefix-icon" icon="compose:undo">
        </iron-icon>
        <div aria-hidden="true">
          $i18nRaw{errorFilteredGoBackButton}
        </div>
      </cr-button>
    </div>

    <div id="editContainer" hidden$="[[!isEditingSubmittedInput_]]">
      <compose-textarea id="editTextarea" value="{{editedInput_}}"
        input-params="[[inputParams_]]">
      </compose-textarea>
      <div class="footer">
        <if expr="not(is_win)">
          <cr-button id="cancelEditButton" class="tonal-button"
            on-click="onCancelEditClick_">
            $i18n{editCancelButton}
          </cr-button>
        </if>
        <cr-button id="submitEditButton" class="action-button"
          on-click="onSubmitEdit_"
          disabled$="[[!isEditSubmitEnabled_]]">
          $i18n{editUpdateButton}
        </cr-button>
        <if expr="is_win">
          <cr-button id="cancelEditButton" class="tonal-button"
            on-click="onCancelEditClick_">
            $i18n{editCancelButton}
          </cr-button>
        </if>
      </div>
    </div>
  </div>
</div>