zulip/web/styles/compose.css

1045 lines
23 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;
}
.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;
align-items: center;
font-size: 15px;
line-height: 18px;
.main-view-banner-elements-wrapper {
display: flex;
align-items: center;
/* 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;
}
& .banner_content {
/* Override Bootstrap when .banner_content is
a paragraph element. */
margin: 0;
/* 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;
& .banner_message {
/* Override Bootstrap when .banner_content
contains an inner .banner_message
paragraph. */
margin: 0;
}
}
.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-action-button {
/* Establish a uniform top and bottom
space around the button, which also
works with the space around the message
text. */
margin-top: 8px;
margin-bottom: 8px;
/* Make as tall as two lines of banner message
text, which have a line-height of 18px, but
no more. */
max-height: 36px;
/* Keep to the top of the box, but stretch
taller based on how the box is flexing. */
min-height: 0;
align-self: stretch;
}
.main-view-banner-close-button {
font-size: 16px;
text-decoration: none;
padding: 0 8px;
/* Let the close button's box stretch,
but no larger than the height of the
banner box when the action button
achieves its full height (margin,
padding, and height), which keeps
the X vertically centered with it. */
align-self: stretch;
max-height: 52px;
/* Display as flexbox to better control
the X icon's position. This creates
an anonymous flexbox item out of the
::before content where the icon sits. */
display: flex;
align-items: center;
}
.banner_content + .main-view-banner-close-button {
/* When there's no action button, set the max
height for the typical height of the box
when it contains only banner message text.
This will keep the action button aligned
with the first or only line of text. */
max-height: 34px;
}
&.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;
}
/* Keep these elements visible above the
.moving_bar element on file uploads. */
.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;
}
}
}