| <style include="md-select cr-scrollable"> |
| :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 cr-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" "inputModes" "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" "inputModes"; |
| } |
| |
| /* Set scroll-related styles for the result text container. */ |
| #resultTextContainer { |
| border-color: transparent; |
| border-style: solid; |
| border-width: 1px 0; |
| overflow-y: auto; |
| } |
| |
| #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); |
| } |
| |
| #inputModesContainer { |
| grid-area: inputModes; |
| display: flex; |
| margin-top: 14px; |
| gap: 8px; |
| } |
| |
| #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([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; |
| } |
| |
| #resultTextContainer { |
| max-height: 112px; |
| overflow: auto; |
| /* Incorporates width of righthand scrollbar. */ |
| padding-inline-start: 16px; |
| |
| --scrollbar-width_: 4px; |
| --scrollbar-margin-inline-end_: 4px; |
| padding-inline-end: calc(12px - var(--scrollbar-width_)); |
| margin-inline-end: var(--scrollbar-margin-inline-end_); |
| scrollbar-gutter: stable; |
| } |
| |
| #resultTextContainer .cr-scrollable-top { |
| --cr-scrollable-border-color: var(--color-compose-dialog-divider); |
| /* Since there is a margin-inline-end on #resultsTextContainer, anchor the |
| * border to the end of it so that the border stretches past the scrollbar |
| * and the margin. */ |
| inset-inline-end: calc(anchor(end) - var(--scrollbar-margin-inline-end_)); |
| inset-inline-start: anchor(start); |
| width: unset; |
| } |
| |
| /* Border separating result container text and actions bar. */ |
| #resultOptionsContainer { |
| border-top: 1px solid var(--color-compose-dialog-divider); |
| } |
| |
| #resultOptions { |
| display: flex; |
| align-items: flex-end; |
| gap: 8px; |
| 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); |
| } |
| |
| #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) { |
| #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. */ |
| #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; |
| } |
| |
| .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 cr-icon { |
| width: var(--cr-icon-size); |
| height: var(--cr-icon-size); |
| } |
| |
| .icon-buttons-row |
| .button-container:last-child { |
| padding-left: 10px; |
| position: relative |
| } |
| |
| /* Vertical divider between undo and redo buttons. */ |
| .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], |
| #inputModesContainer[hidden] { |
| display: none; |
| } |
| </style> |
| |
| <div id="firstRunDialog" class="dialog" hidden="[[!showFirstRunDialog_]]"> |
| <div id="firstRunHeading"> |
| <div id="firstRunIconContainer"> |
| <cr-icon icon="compose:compose"></cr-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" hidden="[[enterprise_]]"> |
| $i18nRaw{firstRunMainMid}</div> |
| <div id="firstRunMidTextEnterprise" hidden="[[!enterprise_]]"> |
| $i18nRaw{firstRunMainMidEnterprise}</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="inputModesContainer" hidden$="[[!showInputModes_]]"> |
| <cr-chip id="polishChip" selected on-click="onPolishChipClick_"> |
| <cr-icon icon="[[polishChipIcon_]]"></cr-icon> |
| $i18n{inputModeChipPolish} |
| </cr-chip> |
| <cr-chip id="elaborateChip" on-click="onElaborateChipClick_"> |
| <cr-icon icon="[[elaborateChipIcon_]]"></cr-icon> |
| $i18n{inputModeChipElaborate} |
| </cr-chip> |
| <cr-chip id="formalizeChip" on-click="onFormalizeChipClick_"> |
| <cr-icon icon="[[formalizeChipIcon_]]"></cr-icon> |
| $i18n{inputModeChipFormalize} |
| </cr-chip> |
| </div> |
| <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" class="cr-scrollable"> |
| <div class="cr-scrollable-top"></div> |
| <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="modifierMenu" |
| value="[[selectedModifier_]]" |
| aria-label="$i18n{modifierMenuLabel}" |
| on-change="onModifierChanged_" |
| on-keydown="openModifierMenuOnKeyDown_"> |
| <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"> |
| <div class="button-container"> |
| <cr-button id="undoButton" title="$i18n{undo}" |
| disabled="[[!undoEnabled_]]" on-click="onUndoClick_"> |
| <div aria-hidden="true"> $i18n{undoButtonText} </div> |
| <cr-icon aria-hidden="true" slot="suffix-icon" |
| icon="compose:undo"> |
| </cr-icon> |
| </cr-button> |
| </div> |
| <div class="button-container"> |
| <cr-button id="redoButton" title="$i18n{redo}" |
| disabled="[[!redoEnabled_]]" on-click="onRedoClick_"> |
| <div aria-hidden="true"> $i18n{redoButtonText} </div> |
| <cr-icon aria-hidden="true" slot="suffix-icon" |
| icon="compose:redo"> |
| </cr-icon> |
| </cr-button> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| |
| <div id="submitFooter" class="footer" hidden$="[[submitted_]]"> |
| <div class="footer-text"> |
| <div on-click="onFooterClick_" hidden="[[enterprise_]]"> |
| $i18nRaw{inputFooter}</div> |
| <div on-click="onFooterClick_" hidden="[[!enterprise_]]"> |
| $i18nRaw{inputFooterEnterprise}</div> |
| </div> |
| <cr-button id="submitButton" class="action-button" on-click="onSubmit_" |
| disabled="[[!isSubmitEnabled_]]"> |
| <cr-icon slot="prefix-icon" icon="compose:compose"></cr-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="[[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_)]]"> |
| <cr-icon aria-hidden="true" slot="prefix-icon" icon="compose:undo"> |
| </cr-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> |