Some checks failed
Code scanning / CodeQL (push) Failing after 15s
Zulip production suite / Ubuntu 22.04 production build (push) Failing after 26s
Zulip production suite / Debian 12 production install with custom db name and user (push) Has been skipped
Zulip production suite / Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga (push) Has been skipped
Zulip production suite / Ubuntu 24.04 production install (push) Has been skipped
Zulip production suite / Ubuntu 26.04 production install (push) Has been skipped
Zulip production suite / Debian 13 production install (push) Has been skipped
Zulip production suite / 7.0 Version Upgrade (push) Has been skipped
Zulip production suite / 8.0 Version Upgrade (push) Has been skipped
Zulip production suite / 6.0 Version Upgrade (push) Has been skipped
Zulip production suite / 10.0 Version Upgrade (push) Has been skipped
Zulip production suite / 9.0 Version Upgrade (push) Has been skipped
Zulip production suite / 12.0 Version Upgrade (push) Has been skipped
Zulip production suite / 11.0 Version Upgrade (push) Has been skipped
GitHub Actions Security Analysis with zizmor / zizmor (push) Failing after 3s
Zulip CI / Debian 12 (Python 3.11, backend + documentation) (push) Failing after 26s
Zulip CI / Ubuntu 22.04 (Python 3.10, backend + frontend) (push) Failing after 3s
Zulip CI / Ubuntu 24.04 (Python 3.12, backend) (push) Failing after 25s
Zulip CI / Ubuntu 26.04 (Python 3.14, backend) (push) Failing after 25s
Zulip CI / Debian 13 (Python 3.13, backend) (push) Failing after 28s
Zulip production suite / Required jobs (push) Has been cancelled
Zulip CI / Required jobs (push) Has been cancelled
API Documentation Update Check / check-feature-level-updated (push) Has been cancelled
API Documentation Update Check / notify-if-api-docs-changed (push) Has been cancelled
471 lines
13 KiB
CSS
471 lines
13 KiB
CSS
.pill-container {
|
|
display: inline-flex;
|
|
gap: var(--vertical-spacing-input-pill) var(--horizontal-spacing-input-pill);
|
|
flex-wrap: wrap;
|
|
min-width: 0;
|
|
|
|
background-color: var(--color-background-pill-container);
|
|
|
|
padding: var(--outer-spacing-input-pill-container);
|
|
border: 1px solid var(--color-border-pill-container);
|
|
border-radius: 4px;
|
|
align-items: center;
|
|
|
|
cursor: text;
|
|
|
|
.pill {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
max-width: 100%;
|
|
min-width: 0;
|
|
position: relative;
|
|
|
|
height: var(--height-input-pill);
|
|
/* Make sure the `height` property
|
|
is the authoritative source of an
|
|
input pill's height, without being
|
|
affected by borders, etc. */
|
|
box-sizing: border-box;
|
|
margin: 0;
|
|
|
|
color: inherit;
|
|
|
|
border-radius: 4px;
|
|
background-color: var(--color-background-input-pill);
|
|
cursor: pointer;
|
|
|
|
/* Not focus-visible, because we want to support mouse+backpace to
|
|
delete pills */
|
|
&:focus {
|
|
/* Box shadow instead of border, because user pills have avatars
|
|
that extend all the way to the edge of the pill. */
|
|
box-shadow: 0 0 0 1px var(--color-focus-outline-input-pill) inset;
|
|
outline: none;
|
|
|
|
/* For user pills with avatars, the avatar covers up the box
|
|
shadow, so we also have to make a border around the avatar. */
|
|
.pill-image-border {
|
|
border-right: none;
|
|
border-radius: 4px 0 0 4px;
|
|
border-color: var(--color-focus-outline-input-pill);
|
|
}
|
|
}
|
|
|
|
/* Ensure a hover state on pills that can be clicked
|
|
to reveal a user card. */
|
|
&.view_user_profile:hover {
|
|
background-color: var(--color-background-input-pill-hover);
|
|
}
|
|
|
|
.invited-user-name {
|
|
flex: 1;
|
|
min-width: 0;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
margin-right: 3px;
|
|
}
|
|
|
|
.pill-image {
|
|
height: var(--height-input-pill);
|
|
width: var(--height-input-pill);
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.pill-image-border {
|
|
height: var(--height-input-pill);
|
|
width: var(--height-input-pill);
|
|
position: absolute;
|
|
box-sizing: border-box;
|
|
border: 1px solid;
|
|
border-radius: 4px;
|
|
border-color: var(--color-border-input-pill-image);
|
|
}
|
|
|
|
.pill-label {
|
|
/* Treat as flex container to better position status
|
|
emoji and control ellipsis on the pill value. */
|
|
display: flex;
|
|
/* Allow label to collapse for ellipsis effect. */
|
|
min-width: 0;
|
|
align-items: center;
|
|
margin: 0 var(--input-pill-side-padding);
|
|
|
|
.zulip-icon-bot {
|
|
margin-left: 0.4em;
|
|
}
|
|
}
|
|
|
|
.pill-value {
|
|
flex: 0 1 auto;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.pill-close-button,
|
|
.pill-expand-button {
|
|
font-size: 0.7142em; /* 10px at 14px em */
|
|
/* 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;
|
|
color: var(--color-input-pill-close);
|
|
opacity: 0.7;
|
|
}
|
|
|
|
.exit,
|
|
.expand {
|
|
width: var(--length-input-pill-exit);
|
|
height: var(--length-input-pill-exit);
|
|
display: flex;
|
|
justify-content: center;
|
|
margin-right: var(--length-input-pill-exit-margin);
|
|
border-radius: 2px;
|
|
|
|
&:hover {
|
|
background: var(--color-background-input-pill-exit-hover);
|
|
|
|
.pill-close-button,
|
|
.pill-expand-button {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
.group-members-count {
|
|
opacity: 0.65;
|
|
}
|
|
|
|
&.deactivated-pill {
|
|
background-color: var(--color-background-deactivated-user-pill);
|
|
opacity: 0.7;
|
|
|
|
&:focus {
|
|
border-color: var(--color-focus-outline-deactivated-user-pill);
|
|
}
|
|
|
|
.pill-close-button {
|
|
color: var(--color-close-deactivated-user-pill);
|
|
}
|
|
|
|
.exit:hover {
|
|
background: var(
|
|
--color-background-exit-hover-deactivated-user-pill
|
|
);
|
|
}
|
|
|
|
> img {
|
|
opacity: 0.5;
|
|
}
|
|
}
|
|
}
|
|
|
|
.slashed-circle-icon {
|
|
position: absolute;
|
|
background-color: var(--color-background-deactivated-user-pill);
|
|
padding: 0.2em;
|
|
font-size: 0.7em;
|
|
border-radius: 0.625em;
|
|
bottom: -0.0625em;
|
|
left: 1.1em;
|
|
opacity: 1;
|
|
}
|
|
|
|
&.not-editable {
|
|
cursor: not-allowed;
|
|
border: none;
|
|
background-color: transparent;
|
|
padding: 0;
|
|
|
|
.pill {
|
|
padding-right: 4px;
|
|
cursor: not-allowed;
|
|
|
|
&:focus {
|
|
color: inherit;
|
|
border: 1px solid hsl(0deg 0% 0% / 15%);
|
|
background-color: hsl(0deg 0% 0% / 7%);
|
|
}
|
|
|
|
.exit {
|
|
display: none;
|
|
}
|
|
}
|
|
}
|
|
|
|
.input {
|
|
display: inline-block;
|
|
/* This keeps the input sized to
|
|
the same height as pills. */
|
|
line-height: var(--height-input-pill);
|
|
padding: 0 4px;
|
|
|
|
min-width: 2px;
|
|
overflow-wrap: anywhere;
|
|
flex: 1 1 auto;
|
|
|
|
outline: none;
|
|
}
|
|
|
|
&.not-editable-by-user {
|
|
cursor: not-allowed;
|
|
background-color: var(--color-background-pill-container-input-disabled);
|
|
|
|
.pill {
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
.exit {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
&.invalid {
|
|
border-color: var(--color-invalid-input-border);
|
|
box-shadow: var(--invalid-input-box-shadow);
|
|
}
|
|
}
|
|
|
|
.person_picker {
|
|
.pill:hover {
|
|
background-color: var(--color-background-input-pill-hover);
|
|
}
|
|
}
|
|
|
|
#compose-direct-recipient .pill-container {
|
|
border: 1px solid var(--color-compose-recipient-box-border-color);
|
|
|
|
.input:first-child:empty::before {
|
|
content: attr(data-no-recipients-text);
|
|
opacity: 0.5;
|
|
}
|
|
|
|
&:has(.input:focus) {
|
|
border-color: var(--color-compose-recipient-box-has-focus);
|
|
}
|
|
}
|
|
|
|
.low-attention-recipient-row #compose-direct-recipient .pill-container {
|
|
&:has(.pill):not(:focus-within) {
|
|
/* In the low-attention state, prevent this from being
|
|
part of the flex layout on .pill-container when there
|
|
are already user pills (when the "Add user" text is
|
|
never displayed, as specified on the
|
|
.input:first-child:empty::before selector above).
|
|
We avoid doing this when there is focus inside the
|
|
pill container, so that typing in the recipient row
|
|
after narrowing to a DM conversation with `Ctrl + .`
|
|
doesn't create a palimpsest of text over the existing
|
|
user pill. */
|
|
#private_message_recipient {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
#invitee_emails_container .pill-container,
|
|
#integration-url-filter-branches .pill-container {
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
background-color: var(
|
|
--color-background-pill-container-without-placeholder
|
|
);
|
|
}
|
|
|
|
#invitee_emails_container .pill-container.not-editable-by-user {
|
|
height: var(--height-input-pill);
|
|
background-color: var(--color-background-pill-container-input-disabled);
|
|
}
|
|
|
|
.add_subscribers_container .pill-container,
|
|
.add_streams_container .pill-container,
|
|
.add-user-group-container .pill-container,
|
|
.add_members_container .pill-container {
|
|
width: 100%;
|
|
|
|
.input:first-child:empty::before {
|
|
opacity: 0.5;
|
|
content: attr(data-placeholder);
|
|
}
|
|
}
|
|
|
|
.add_streams_container .input,
|
|
.add-user-group-container .input {
|
|
flex-grow: 1;
|
|
}
|
|
|
|
.display_only_pill,
|
|
.display_only_group_pill {
|
|
/* Ensure middle alignment in table contexts. */
|
|
vertical-align: middle;
|
|
/* Resetting these values to prevent unintended inheritance from .pill-container styles. */
|
|
padding: 0;
|
|
border: 0;
|
|
|
|
/* Particularly in light mode, pill colors are almost identical
|
|
to the settings modal background. We place a higher-contrast
|
|
outline on them accordingly. */
|
|
.pill,
|
|
.pill:focus {
|
|
outline: 1px solid var(--color-outline-low-attention-input-pill);
|
|
/* We offset the outline so that pills do not grow in size
|
|
when presented with an outline. */
|
|
outline-offset: -1px;
|
|
|
|
/* Display `(you)` with the same 5px padding to the right
|
|
as ordinary .pill-value text. */
|
|
.my_user_status {
|
|
padding-right: 5px;
|
|
}
|
|
|
|
/* Zero out the margin placed to the left of the bot icon,
|
|
and add in the 5px of padding to the right. Specificity
|
|
necessitates duplicating the .pill-label class here. */
|
|
.pill-label .zulip-icon-bot {
|
|
margin-left: 0;
|
|
padding-right: 5px;
|
|
}
|
|
|
|
.deactivated-user-icon {
|
|
padding-right: 5px;
|
|
}
|
|
}
|
|
|
|
.pill:focus {
|
|
/* We don't want to flash a focus outline
|
|
when clicking on display-only pills. */
|
|
box-shadow: unset;
|
|
/* We also suppress the border on the pill
|
|
image. */
|
|
.pill-image-border {
|
|
border: 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* These pill are similar to .not-editable, but are meant to show
|
|
profile cards when clicked. */
|
|
.user-type-custom-field-pill-container > .display_only_pill,
|
|
.panel_user_list > .pill-container,
|
|
.creator_details > .display_only_pill {
|
|
gap: 2px;
|
|
flex-wrap: nowrap;
|
|
|
|
&.inline_with_text_pill > .pill-deactivated {
|
|
font-size: 0.9em;
|
|
padding-right: 2px;
|
|
}
|
|
|
|
&:hover {
|
|
color: inherit;
|
|
}
|
|
|
|
/* `settings.css` applies a :focus-within box-shadow to `.custom_user_field .pill-container`
|
|
and `.bot_owner_user_field .pill-container`.That effect conflicts with the unified pill
|
|
styling (no shadow), so we override it here. */
|
|
&:focus-within {
|
|
box-shadow: none;
|
|
}
|
|
|
|
> .pill {
|
|
border: none;
|
|
text-decoration: none;
|
|
|
|
&:focus {
|
|
color: inherit;
|
|
}
|
|
|
|
> .pill-label {
|
|
margin: 0;
|
|
|
|
> .pill-value {
|
|
padding: 5px;
|
|
max-width: 165px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#user-profile-modal {
|
|
.user-type-custom-field-pill-container {
|
|
display: inline-flex;
|
|
gap: var(--vertical-spacing-input-pill)
|
|
var(--horizontal-spacing-input-pill);
|
|
max-width: 100%;
|
|
flex-wrap: wrap;
|
|
|
|
/* We override the `.pill-container` style defined in
|
|
`settings.css` to ensure it expands to full width, preventing
|
|
names in the pill from being cut off in the user profile modal. */
|
|
.pill-container {
|
|
max-width: 100%;
|
|
}
|
|
|
|
/* We're overriding the `.pill-value` style defined
|
|
in `settings.css` to ensure that names inside the pill
|
|
render fully and aren't cut off in the user profile modal. */
|
|
.pill-value {
|
|
max-width: 100%;
|
|
}
|
|
}
|
|
}
|
|
|
|
.group_entirely_not_subscribed .display_only_group_pill,
|
|
.creator_details > .display_only_pill {
|
|
/* In places where the pills are not used in tables,
|
|
but instead alongside text, we revert back to the
|
|
baseline vertical alignment. */
|
|
vertical-align: baseline;
|
|
}
|
|
|
|
.creator_details > .display_only_pill.inline_with_text_pill {
|
|
padding: 0;
|
|
|
|
> .pill {
|
|
margin: 0;
|
|
align-items: baseline;
|
|
|
|
> .pill-image {
|
|
/* Add line-height equal to height to mimic baseline alignment. */
|
|
line-height: 20px;
|
|
align-self: center;
|
|
}
|
|
|
|
> .pill-label {
|
|
> .pill-value {
|
|
padding: 0 5px;
|
|
max-width: 200px;
|
|
}
|
|
|
|
> .my_user_status {
|
|
margin-right: 2px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.display_only_group_pill .zulip-icon-user-group {
|
|
/* Reserve the same square box for the user-group
|
|
icon as on pill images. */
|
|
height: var(--height-input-pill);
|
|
width: var(--height-input-pill);
|
|
/* Center the icon in the box using flex. */
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|