zulip/web/styles/compose.css

1010 lines
22 KiB
CSS

#compose_buttons {
text-align: right;
display: flex;
flex-direction: row;
align-items: center;
.new_message_button {
margin-left: 4px;
.button.small {
font-size: 1em;
padding: 3px 10px;
vertical-align: middle;
}
.compose_mobile_button {
& span {
font-size: 1.2em !important;
font-weight: 400;
line-height: 1em;
}
}
}
.reply_button_container {
flex: 1;
min-width: 0;
margin-left: 0;
.compose_reply_button {
width: 100%;
text-align: left;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
.mobile_button_container {
@media (width >= $sm_min) {
display: none;
}
}
.stream_button_container,
.private_button_container {
@media (width < $sm_min) {
display: none;
}
}
}
/* Main geometry for this element is in zulip.css */
#compose-content {
background-color: hsl(232deg 30% 92%);
transition: background-color 200ms linear;
padding: 4px 4px 8px;
border: 1px solid hsl(0deg 0% 0% / 10%);
border-radius: 9px 9px 0 0;
box-shadow: 0 0 0 hsl(236deg 11% 28%);
height: 100%;
display: flex;
flex-flow: column;
box-sizing: border-box;
}
.message_comp {
display: none;
padding: 5px 10px 0 5px;
#compose_banners {
max-height: min(25vh, 240px);
overflow-y: auto;
}
}
.autocomplete_secondary {
opacity: 0.8;
font-size: 85%;
}
.active .autocomplete_secondary {
opacity: 1;
}
.narrow_to_compose_recipient_current_view_help {
margin: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.compose_table {
height: 100%;
display: flex;
flex-flow: column;
.stream-selection-header-colorblock {
box-shadow: none;
border: 1px solid hsl(0deg 0% 80%);
border-right: none;
&.message_header_private_message {
border-radius: 3px 0 0 3px;
border-bottom: 0;
background-color: hsl(0deg 0% 27%);
}
}
#compose-recipient {
&.compose-recipient-direct-selected {
#compose_select_recipient_widget {
border-radius: 4px !important;
}
.stream_header_colorblock {
display: none;
}
}
.topic-marker-container {
/* Ensure the marker ( < ) stays centered vertically
with the dropdown, even when adjacent stacking pills
in, e.g., a group DM. */
display: flex;
align-items: center;
height: var(--compose-recipient-box-min-height);
.fa-angle-right {
font-size: 0.9em;
-webkit-text-stroke: 0.05em;
align-self: center;
margin: 0 5px;
}
}
& a.narrow_to_compose_recipients {
background: transparent;
font-size: 18px;
padding: 0 1px;
align-self: center;
line-height: 20px;
opacity: 0.7;
border: 0;
margin-left: 3px;
text-decoration: none;
color: inherit;
&:hover {
opacity: 1;
}
}
}
#compose-direct-recipient {
flex-grow: 1;
}
.message_header {
background: none;
background-color: hsl(0deg 0% 92%);
border: none;
border-radius: 0;
box-shadow: none !important;
}
.messagebox {
box-shadow: none !important;
}
}
#send_message_form {
margin: 0;
height: 100%;
.messagebox-wrapper {
flex: 1;
}
.messagebox {
/* normally 5px 14px; pull in the right and bottom a bit */
cursor: default;
padding: 0;
background: none;
box-shadow: none;
border: none;
height: 100%;
display: flex;
flex-flow: column;
}
.message_content {
margin-right: 0;
}
}
#below-compose-content {
display: flex;
flex-direction: column;
width: 100%;
margin-top: 6px;
margin-bottom: -2px;
.compose_bottom_top_container {
display: flex;
}
.compose_bottom_bottom_container {
display: flex;
justify-content: space-between;
}
}
#compose_limit_indicator {
margin-right: 8px;
font-size: 12px;
color: hsl(39deg 100% 50%);
align-self: center;
&.over_limit {
color: hsl(0deg 76% 65%);
font-weight: bold;
}
}
#compose {
position: fixed;
bottom: 0;
left: 0;
z-index: 4;
}
#compose-container {
display: flex;
flex-direction: column;
width: 100%;
margin: auto;
}
#compose_top {
display: flex;
justify-content: space-between;
align-items: flex-start;
padding-bottom: 5px;
}
#compose_top_right {
display: flex;
align-items: center;
height: var(--compose-recipient-box-min-height);
& button {
background: transparent;
color: inherit;
font-size: 15px;
font-weight: normal;
line-height: 20px;
opacity: 0.7;
border: 0;
padding: 0;
margin-left: 4px;
vertical-align: unset;
text-shadow: none;
&:hover {
opacity: 1;
}
}
}
.collapse_composebox_button,
#compose_close {
display: none;
}
.main-view-banner {
margin-bottom: 20px;
border-radius: 5px;
border: 1px solid;
display: flex;
/* Baseline alignment ensures the closing X
appears centered with the banner text. */
align-items: baseline;
font-size: 15px;
line-height: 18px;
.main-view-banner-elements-wrapper {
display: flex;
/* Baseline alignment ensures the banner
and button text appear centered with
each other. */
align-items: baseline;
/* Allow this flex container to grow or
shrink to fit the outer container. */
flex: 1 1 auto;
/* Allow items to wrap; this supports an
intrinsic layout for banner text and
buttons, which will always occupy the
space available, without our having
to fiddle with tons of media queries. */
flex-wrap: wrap;
}
& p {
margin: 0; /* override bootstrap */
/* 5px right padding + 10px left-margin of the neighbouring button will match the left padding */
padding: 8px 5px 8px 15px;
/* The banner text uses a flex-basis of 150px,
which is roughly the width at which banner
text lines are still comfortably readable.
Still, it can grow and shrink as needed. */
flex: 1 1 150px;
}
.main-view-banner-action-button,
.upload_banner_cancel_button {
border: none;
border-radius: 4px;
padding: 5px 10px;
font-weight: 600;
margin-top: 4.5px;
margin-bottom: 4.5px;
/* Buttons take a minimum height for
when their text fits on a single
line. */
min-height: 32px;
/* When we're larger than large mobile
scales ($ml_min), flex the button to
its max-content, i.e., all its text
on a single line. But do not grow in
order to avoid awkward, oversized
buttons within the flex group. */
flex: 0 1 max-content;
/* Use this margin-left hack to keep
the button to the righthand side of
the banner. */
margin-left: auto;
@media (width < $ml_min) {
/* When we're smaller than large mobile
scales, we allow the button to grow,
so that it can span the full width of
narrow, mobile-scale banners as it
wraps onto a second line.
We also allow the button to shrink,
so that, for example, the text can
wrap on the schedule-message button
that appears when undoing a scheduled
message. */
flex: 1 1 max-content;
/* Use a 10px left margin to keep the
button away from the edge of the
banner box to match the banner text;
we need this only at small scales,
when the button grows to the full
width of the flex container. */
margin-left: 10px;
}
/* Extra margin to ensure the layout is identical when there is no
close button. */
&.right_edge {
margin-right: 10px;
}
}
.main-view-banner-close-button {
font-size: 16px;
text-decoration: none;
padding: 9px 8px;
}
&.success {
background-color: hsl(147deg 43% 92%);
border: 1px solid hsl(147deg 57% 25% / 40%);
color: hsl(147deg 57% 25%);
.main-view-banner-close-button {
color: hsl(147deg 57% 25% / 50%);
&:hover {
color: hsl(147deg 57% 25%);
}
&:active {
color: hsl(147deg 57% 25% / 75%);
}
}
.main-view-banner-action-button {
background-color: hsl(147deg 57% 25% / 10%);
color: inherit;
&:hover {
background-color: hsl(147deg 57% 25% / 12%);
}
&:active {
background-color: hsl(147deg 57% 25% / 15%);
}
}
}
/* warning and warning-style classes have the same CSS; this is since
the warning class has some associated javascript which we do not want
for some of the banners, for which we use the warning-style class. */
&.warning,
&.warning-style {
background-color: hsl(50deg 75% 92%);
border-color: hsl(38deg 44% 27% / 40%);
color: hsl(38deg 44% 27%);
.main-view-banner-close-button {
color: hsl(38deg 44% 27% / 50%);
&:hover {
color: hsl(38deg 44% 27%);
}
&:active {
color: hsl(38deg 44% 27% / 75%);
}
}
.main-view-banner-action-button {
background-color: hsl(38deg 44% 27% / 10%);
color: inherit;
&:hover {
background-color: hsl(38deg 44% 27% / 12%);
}
&:active {
background-color: hsl(38deg 44% 27% / 15%);
}
}
}
&.error {
background-color: hsl(4deg 35% 90%);
border-color: hsl(3deg 57% 33% / 40%);
color: hsl(4deg 58% 33%);
.main-view-banner-close-button {
color: hsl(4deg 58% 33% / 50%);
&:hover {
color: hsl(4deg 58% 33%);
}
&:active {
color: hsl(4deg 58% 33% / 75%);
}
}
.main-view-banner-action-button {
background-color: hsl(3deg 57% 33% / 10%);
color: inherit;
&:hover {
background-color: hsl(3deg 57% 33% / 12%);
}
&:active {
background-color: hsl(3deg 57% 33% / 15%);
}
}
}
&.info {
background-color: hsl(204deg 58% 92%);
border-color: hsl(204deg 49% 29% / 40%);
position: relative;
color: hsl(204deg 49% 29%);
.main-view-banner-close-button {
color: hsl(204deg 49% 29% / 50%);
&:hover {
color: hsl(204deg 49% 29%);
}
&:active {
color: hsl(204deg 49% 29% / 75%);
}
}
.main-view-banner-action-button,
.upload_banner_cancel_button {
background-color: hsl(204deg 49% 29% / 10%);
color: inherit;
&:hover {
background-color: hsl(204deg 49% 29% / 12%);
}
&:active {
background-color: hsl(204deg 49% 29% / 15%);
}
}
}
}
.upload_banner {
overflow: hidden;
&.hidden {
display: none;
}
.moving_bar {
position: absolute;
width: 0;
/* The progress updates seem to come every second or so,
so this is the smoothest it can probably get. */
transition: width 1s ease-in-out;
background: hsl(204deg 63% 85%);
top: 0;
bottom: 0;
}
.upload_msg {
flex-grow: 1;
}
.upload_msg,
.main-view-banner-close-button,
.upload_banner_cancel_button {
z-index: 1;
position: relative;
}
}
.composition-area {
position: relative;
flex: 1;
}
@keyframes message-limit-flash {
0% {
box-shadow: none;
}
100% {
box-shadow: 0 0 0 1pt hsl(0deg 76% 65%);
}
}
textarea.new_message_textarea {
display: table-cell;
width: calc(100% - 12px);
padding: 5px;
height: 1.5em;
max-height: 22em;
margin-bottom: 0;
resize: vertical !important;
margin-top: 5px;
border-radius: 4px;
color: hsl(0deg 0% 33%);
background-color: hsl(0deg 0% 100%);
&.over_limit,
&.over_limit:focus {
box-shadow: 0 0 0 1pt hsl(0deg 76% 65%);
&.flash {
animation: message-limit-flash 0.5s ease-in-out infinite;
}
}
&:read-only,
&:disabled {
cursor: not-allowed;
background-color: hsl(0deg 0% 93%);
}
&.invalid,
&.invalid:focus {
border: 1px solid hsl(3deg 57% 33%);
box-shadow: 0 0 2px hsl(3deg 57% 33%);
}
}
textarea.new_message_textarea,
.compose_table .recipient_box {
border: 1px solid hsl(0deg 0% 0% / 20%);
box-shadow: none;
transition: border 0.2s ease;
color: var(--color-text-default);
&:focus {
outline: 0;
border: 1px solid hsl(0deg 0% 67%);
box-shadow: none;
}
}
input.recipient_box {
margin: 0;
padding: 0 6px;
height: auto;
border-radius: 3px;
}
#compose_select_recipient_widget {
border-radius: 0 4px 4px 0;
width: auto;
outline: none;
&.dropdown-widget-button {
padding: 0 6px;
}
}
#stream_message_recipient_topic.recipient_box {
width: 100%;
/* This width roughly corresponds to how long of a topic can appear in
the left sidebar with a single digit unread count without being
cut off. */
max-width: 175px;
}
#private_message_recipient.recipient_box {
width: 100%;
}
#compose-send-button {
padding: 3px 12px;
margin-bottom: 0;
font-weight: 600;
font-size: 0.9em;
border-radius: 4px 0 0 4px;
.loader {
display: none;
position: relative;
top: -6px;
}
}
.enter_sends_choices {
.enter_sends_choice {
display: flex;
gap: 8px;
padding-top: 4px;
& input[type="radio"] {
position: relative;
top: 5px;
width: auto;
cursor: pointer;
margin: 4px 0 0;
&:focus {
outline: 1px dotted hsl(0deg 0% 20%);
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
}
&:first-child {
padding: 0 0 4px;
border-bottom: 1px solid hsl(0deg 0% 0% / 20%);
}
}
.enter_sends_choice_text {
display: flex;
flex-direction: column;
}
.enter_sends_minor,
.enter_sends_minor kbd {
opacity: 0.9;
font-size: 11px;
color: hsl(0deg 0% 50%);
}
}
.open_enter_sends_dialog {
font-size: 12px;
height: 14px;
padding-left: 4px;
opacity: 0.7;
margin-bottom: 5px;
position: relative;
top: -2px;
cursor: pointer;
@media (width < $mm_min) {
font-size: 11px;
}
& kbd {
padding: 0 4px;
}
&:hover {
opacity: 1;
}
.enter_sends_true,
.enter_sends_false {
display: none;
}
& i {
padding-left: 3px;
font-size: 12px;
font-weight: 600;
}
}
#compose-recipient {
display: flex;
width: 100%;
/* Use this containing flex element to
establish the minimum height of all its
children; the default `align-items: stretch`
(which is set on any flexbox without specifying
it) ensures that the child flex items will
always stretch to fit the height set here;
larger heights, such as on group-DM pills,
will allow this to grow as needed.
Child flex items like chevrons take
`align-self: center` to center only
themselves, where necessary. */
min-height: var(--compose-recipient-box-min-height);
}
.compose_control_buttons_container {
margin-right: auto;
display: flex;
gap: 4px;
align-items: center;
/* We use the selector in this manner to maintain specificity. */
.compose_control_button_container .compose_gif_icon {
font-size: 22px;
/* Remove top and bottom padding. This is necessary
* because `compose_gif_icon` is no longer a flex item. */
padding: 0 5px;
}
.compose_control_button {
padding: 5px;
opacity: 0.7;
color: inherit;
text-decoration: none;
font-size: 17px;
text-align: center;
&:hover {
opacity: 1;
}
}
.fa-eye {
position: relative;
top: -0.7px;
}
.compose_control_menu {
padding: 0 1px;
font-size: 18px;
}
.compose_control_menu_wrapper {
opacity: 0.7;
padding: 0;
margin: 0;
&:hover {
opacity: 1;
}
.compose_control_menu {
opacity: 1;
}
}
.hide-sm,
.hide-lg {
display: flex;
align-items: center;
gap: 4px;
padding: 0;
margin: 0;
}
.divider {
color: hsl(0deg 0% 75%);
font-size: 20px;
margin: 0 3px;
}
.compose_draft_button {
font-size: 15px;
font-weight: 600;
font-family: "Source Sans 3 VF", sans-serif;
padding: 0 5px;
position: relative;
top: 0.7px;
}
.compose_help_button {
font-size: 20px;
line-height: 17px;
}
}
.compose_right_float_container {
display: flex;
flex-direction: row;
white-space: nowrap;
margin-top: 2px;
height: 24px;
&.disabled-compose-send-button-container {
cursor: not-allowed;
& button {
pointer-events: none;
background-color: hsl(0deg 0% 65%);
}
}
}
.drag {
display: none;
height: 18px;
width: 100%;
top: 23px;
position: relative;
cursor: ns-resize;
}
.preview_message_area {
/* minus 5px padding. */
width: calc(100% - 12px);
padding: 5px;
margin-top: 5px;
/* the maximum height the textarea gets to. */
max-height: 308px;
/* the minimum height the textarea collapses to. */
min-height: 42px;
overflow: auto;
border: 1px solid hsl(0deg 0% 67%);
border-radius: 4px;
background-color: hsl(0deg 0% 98%);
cursor: not-allowed;
}
.markdown_preview_spinner {
margin: auto;
}
#compose_select_recipient_widget_wrapper {
display: flex;
justify-content: flex-start;
height: var(--compose-recipient-box-min-height);
.stream_header_colorblock {
margin: 0;
}
.dropdown_widget_value {
flex-grow: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: var(--color-text-default);
.stream-privacy-type-icon {
font-size: 13px;
width: 13px;
height: 13px;
position: relative;
top: 2px;
}
}
.fa-chevron-down {
padding-left: 5px;
color: hsl(0deg 0% 58%);
font-weight: lighter;
}
/* This is the "Select a stream" default message */
.text-warning {
color: inherit;
}
}
.dropdown-menu {
& ul {
list-style: none;
margin: 0;
background: hsl(0deg 0% 100%);
}
.typeahead-header {
margin: 0;
padding-left: 20px;
padding-right: 20px;
padding-top: 4px;
border-top: 1px solid hsl(0deg 0% 0% / 20%);
display: flex;
align-items: center;
}
#typeahead-header-text {
font-size: 12px;
}
&.typeahead {
background: hsl(0deg 0% 100%);
}
}
.compose_mobile_stream_button i,
.compose_mobile_private_button i {
margin-right: 4px;
}
/* `^` icon located next to `Send` / `Scheduled` button which shows
options to schedule the message. */
#send_later {
display: flex;
align-items: center;
float: right;
color: hsl(0deg 0% 100%);
border-radius: 0 4px 4px 0;
padding: 0;
margin: 0;
.zulip-icon {
padding: 5px 3px;
font-size: 17px;
}
.separator-line {
background-color: hsl(0deg 0% 100% / 65%);
height: 70%;
width: 1px;
}
&:hover,
&:focus {
box-shadow: none;
}
}
@media (width < $xl_min) {
#compose-content {
margin-right: 7px;
}
}
@media (width < $md_min) {
#compose-content {
margin-right: 7px;
margin-left: 7px;
}
}
@media (width < $mm_min) {
#compose-content {
margin-right: 5px;
margin-left: 5px;
}
}
#compose.compose-fullscreen {
z-index: 99;
#compose-container {
height: 100%;
}
.message_comp {
flex: 1;
display: flex !important;
flex-flow: column;
}
#compose-textarea,
#preview_message_area {
/* Setting height to 0 is necessary to make the flex+Simplebar
combination work correctly, without pushing the compose
controls offscreen when previewing a very tall message. */
max-height: none !important;
height: 0;
flex: 1;
}
}
.preview_mode {
.preview_mode_disabled {
cursor: not-allowed;
opacity: 0.3;
.compose_control_button {
pointer-events: none;
}
}
}