2024-04-12 10:22:57 +00:00
|
|
|
@use 'sass:color';
|
|
|
|
@use "sass:map";
|
2023-10-20 16:05:57 +00:00
|
|
|
//
|
|
|
|
// Mixins
|
|
|
|
// --------------------------------------------------
|
|
|
|
|
|
|
|
@mixin compact {
|
|
|
|
$selector: &;
|
|
|
|
@at-root [zoteroUIDensity="compact"] {
|
|
|
|
@if $selector {
|
|
|
|
#{$selector} {
|
|
|
|
@content;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@else {
|
|
|
|
@content;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@mixin comfortable {
|
|
|
|
$selector: &;
|
|
|
|
@at-root [zoteroUIDensity="comfortable"] {
|
|
|
|
@if $selector {
|
|
|
|
#{$selector} {
|
|
|
|
@content;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@else {
|
|
|
|
@content;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-10-24 06:36:56 +00:00
|
|
|
|
|
|
|
// @NOTE: this mixin uses `state` mixin, therefore must be used in a selector nested
|
|
|
|
// underneath selectors listed in arguments, e.g., .virtualized-table .row
|
|
|
|
// by default. See `state` mixin for more details.
|
|
|
|
@mixin focus-states(
|
2023-11-15 09:07:54 +00:00
|
|
|
$selectedState: '.row.selected',
|
|
|
|
$focused: '.virtualized-table:focus-within'
|
|
|
|
) {
|
|
|
|
@media (prefers-color-scheme: light) {
|
|
|
|
@content("light");
|
|
|
|
|
|
|
|
@include state($selectedState) {
|
|
|
|
@include state($focused) {
|
|
|
|
@content("white");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@media (prefers-color-scheme: dark) {
|
|
|
|
@content("dark");
|
|
|
|
|
|
|
|
@include state($selectedState) {
|
|
|
|
@include state($focused) {
|
|
|
|
@content("white");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-10-24 06:36:56 +00:00
|
|
|
|
2023-11-15 09:07:54 +00:00
|
|
|
// An implementation of Firefox light-dark() CSS mixin, which is not supported in 102
|
|
|
|
@mixin light-dark($prop, $light-color, $dark-color) {
|
|
|
|
@media (prefers-color-scheme: light) {
|
|
|
|
#{$prop}: $light-color;
|
|
|
|
}
|
|
|
|
@media (prefers-color-scheme: dark) {
|
|
|
|
#{$prop}: $dark-color;
|
|
|
|
}
|
2023-10-24 06:36:56 +00:00
|
|
|
}
|
2023-10-27 13:00:21 +00:00
|
|
|
|
|
|
|
@mixin color-scheme {
|
|
|
|
@media (prefers-color-scheme: light) {
|
|
|
|
@content("light");
|
|
|
|
}
|
|
|
|
|
|
|
|
@media (prefers-color-scheme: dark) {
|
|
|
|
@content("dark");
|
|
|
|
}
|
2023-11-28 10:58:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@mixin clicky-item {
|
|
|
|
display: flex;
|
|
|
|
align-items: flex-start;
|
|
|
|
gap: 4px;
|
|
|
|
padding-inline-start: 4px;
|
|
|
|
overflow: hidden;
|
2023-12-24 06:26:30 +00:00
|
|
|
border-radius: 5px;
|
2023-11-28 10:58:59 +00:00
|
|
|
|
2023-12-24 06:26:30 +00:00
|
|
|
&:not([disabled]):hover {
|
2023-11-28 10:58:59 +00:00
|
|
|
background-color: var(--fill-quinary);
|
|
|
|
}
|
2023-12-24 06:26:30 +00:00
|
|
|
|
|
|
|
&:not([disabled]):active {
|
|
|
|
background-color: var(--fill-quarternary);
|
|
|
|
}
|
2023-11-28 10:58:59 +00:00
|
|
|
|
2024-01-17 20:04:29 +00:00
|
|
|
.icon {
|
|
|
|
height: calc(1.3333333333 * var(--zotero-font-size));
|
|
|
|
}
|
|
|
|
|
2023-11-28 10:58:59 +00:00
|
|
|
.label {
|
|
|
|
display: -webkit-box;
|
|
|
|
-webkit-box-orient: vertical;
|
|
|
|
-webkit-line-clamp: 10;
|
|
|
|
width: 0; // Needed to allow the label to shrink for some reason
|
|
|
|
flex: 1;
|
|
|
|
overflow: hidden;
|
|
|
|
}
|
|
|
|
|
2023-12-01 16:11:02 +00:00
|
|
|
.icon, .label {
|
|
|
|
padding-block: 2px;
|
2023-11-28 10:58:59 +00:00
|
|
|
}
|
|
|
|
}
|
2023-12-01 07:43:43 +00:00
|
|
|
|
2024-01-13 02:16:08 +00:00
|
|
|
@mixin meta-table {
|
|
|
|
display: grid;
|
|
|
|
grid-template-columns: max-content 1fr;
|
2024-01-13 02:31:54 +00:00
|
|
|
column-gap: 8px;
|
2024-01-13 02:16:08 +00:00
|
|
|
row-gap: 2px;
|
|
|
|
width: inherit;
|
|
|
|
|
|
|
|
.meta-row {
|
|
|
|
display: grid;
|
|
|
|
grid-template-columns: subgrid;
|
|
|
|
grid-column: span 2;
|
|
|
|
|
2024-01-13 13:50:24 +00:00
|
|
|
&[hidden] {
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
|
itembox focus edits and refactoring (#4096)
- removed ztabindex logic from itemBox. It is no longer needed, adds
unnecessary complexity and is likely at the root of multiple glitches
if a plugin inserts an arbitrary row that does not have ztabindex set.
- if a creator row is deleted when the focus is inside of the row, focus
another creator row to not loose the focus.
- more centralized button handling in `_ensureButtonsFocusable` and
`_updateCreatorButtonsStatus`
- refactoring of hidden toolbarbuttons css so that the icons are still
hidden and don't occupy space (if desired) but are still visible for
screen readers, so they are focusable without JS changing their
visibility (this with ztabindex removal fixes vpat 24)
- removed `escape_enter` event from `editable-text`. It was a workaround
to know when itemBox should move focus back to itemTree. Unhandled
Enter on an input or Escape should focus itemTree (or reader) from
anywhere in the itemPane/contextPane (not just itemBox), so that logic
is moved to itemDetails.js. To avoid conflicts with Shift-Enter, do
not propagate that event outside of multiline editable-text. Fixes:
#3896
- removed not necessary keyboard nav handling from itemDetails.js. It
was only needed for mac, and is redundant if "Keyboard navigation"
setting is on
- using `keydown` instead of `keypress` for itemDetails keyboard nav
handling because `Enter` `keypress` does not seem to get out of
`editable-text` but `keydown` does.
- old handleKeyPress from itemBox is no longer relevant for most
elements, so it is removed and substituted with a dedicated handler
just for creator row.
- moved the creator's paste handler into its own dedicated function
from the autocomplete handler (which was confusing)
- special handling for `enter` and `escape` events on `editable-text`
with autocomplete to not stop event propagation, so that the events
can bubble and be handled in `itemDetails`. It avoids some cases of
the focus being lost and returned to the `window`. It was unnecessary
earlier due to `escape_enter` workaround but only within itemBox and
only within itemPane.
- removed explicit tab navigation handling from `collapsible-section`
header. Currently, it may get stuck when buttons are hidden (e.g. in
the trash mode). It was only added to enable keyboard navigation on
mac before special "Keyboard navigation" setting was discovered (it
was never an issue on windows), so now it's easier to just let mozilla
handle it.
- always use `getTitleField` to find and focus the proper title field in
itemBox
- on shift-tab from the focused tab, just move focus to the first
focusable element before the splitter without any special handling for
attachments, notes and duplicates pane as before. It ensures a more
consistent and predictable keyboard navigation, especially now that
itemPane is fairly keyboard accessible.
Fixes: #4076
2024-05-07 14:42:20 +00:00
|
|
|
&:not(:hover):not(:focus-within) .show-on-hover,
|
|
|
|
&.noHover .show-on-hover {
|
|
|
|
clip-path: inset(50%);
|
|
|
|
&.no-display {
|
|
|
|
width: 0;
|
|
|
|
height: 0;
|
|
|
|
padding: 0;
|
|
|
|
}
|
2024-01-13 02:16:08 +00:00
|
|
|
}
|
|
|
|
.meta-data {
|
|
|
|
width: 0;
|
|
|
|
min-width: 100%;
|
|
|
|
display: flex;
|
|
|
|
toolbarbutton {
|
|
|
|
margin-inline-start: 4px;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
editable-text {
|
|
|
|
flex: 1; // stretch value field as much as possible
|
|
|
|
max-width: 100%; // stay within .meta-data when the itemBox is narrow
|
|
|
|
.input {
|
|
|
|
// allow input to be shrunk by other elements when the itemBox is narrow
|
|
|
|
min-width: 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.meta-label {
|
|
|
|
display: flex;
|
|
|
|
font-weight: normal;
|
|
|
|
text-align: end;
|
|
|
|
color: var(--fill-secondary);
|
|
|
|
|
|
|
|
&[fieldname^="creator"] {
|
|
|
|
justify-content: space-between;
|
|
|
|
align-items: center;
|
|
|
|
}
|
|
|
|
> label {
|
|
|
|
margin-top: 2px;
|
|
|
|
@include comfortable {
|
|
|
|
margin-top: 3px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.key {
|
|
|
|
width: 100%;
|
|
|
|
}
|
|
|
|
|
|
|
|
toolbarbutton {
|
|
|
|
@include focus-ring;
|
|
|
|
|
|
|
|
// needed to have the outline appear on all platforms
|
|
|
|
appearance: none;
|
|
|
|
-moz-appearance: none;
|
|
|
|
align-self: center;
|
|
|
|
// Make all buttons tigher to not stretch the rows
|
|
|
|
height: auto;
|
|
|
|
width: auto;
|
|
|
|
padding: 1px;
|
|
|
|
border-radius: 2px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-12-01 07:43:43 +00:00
|
|
|
|
|
|
|
/* Hide icons on macOS. We use :is() to work around weird behavior in Fx101 where a regular child
|
|
|
|
selector doesn't match the first time the menu is opened. */
|
|
|
|
@mixin macOS-hide-menu-icons {
|
|
|
|
$selector: &;
|
|
|
|
@at-root {
|
|
|
|
@media (-moz-platform: macos) {
|
|
|
|
// Yes, every single one of these :is-es is necessary!
|
|
|
|
:is(:is(#{$selector}) .menuitem-iconic, :is(#{$selector}) .menu-iconic) {
|
|
|
|
list-style-image: none !important;
|
|
|
|
|
|
|
|
.menu-iconic-left {
|
|
|
|
display: none !important;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-12-20 11:29:28 +00:00
|
|
|
|
|
|
|
@mixin macOS-inactive-opacity {
|
|
|
|
$selector: &;
|
|
|
|
@at-root {
|
|
|
|
@media (-moz-platform: macos) {
|
|
|
|
#{$selector} {
|
|
|
|
&:-moz-window-inactive {
|
|
|
|
opacity: 0.6;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-12-21 14:15:48 +00:00
|
|
|
/*
|
|
|
|
This mixin replaces the default focus-rings - those are platform-specific, do not show up on some
|
|
|
|
components (e.g. toolbarbutton) and sometimes are too wide (e.g. around textfield on macOS).
|
|
|
|
Box-shadow is used to be able to set the radius.
|
|
|
|
*/
|
2024-03-02 07:51:55 +00:00
|
|
|
@mixin focus-ring($thin: false, $selector: focus-visible) {
|
|
|
|
&:#{$selector} {
|
|
|
|
@media (-moz-platform: windows) {
|
|
|
|
outline: var(--color-focus-outer-border) solid var(--width-focus-outer-border);
|
|
|
|
outline-offset: var(--width-focus-border);
|
|
|
|
box-shadow: 0 0 0 var(--width-focus-border) var(--color-focus-border);
|
|
|
|
}
|
|
|
|
|
|
|
|
@media not (-moz-platform: windows) {
|
2024-04-17 09:30:05 +00:00
|
|
|
// fx115: Necessary to hide default focus ring
|
|
|
|
outline: none;
|
2024-03-02 07:51:55 +00:00
|
|
|
box-shadow: 0 0 0 var(--width-focus-border) var(--color-focus-border);
|
|
|
|
|
|
|
|
@if $thin {
|
|
|
|
--width-focus-border: 1px;
|
|
|
|
--color-focus-border: var(--color-accent);
|
|
|
|
}
|
|
|
|
}
|
2023-12-21 14:15:48 +00:00
|
|
|
}
|
2024-03-02 07:51:55 +00:00
|
|
|
}
|
2024-04-12 10:22:57 +00:00
|
|
|
|
|
|
|
@mixin derive-colors($colors) {
|
|
|
|
@each $name, $color in $colors {
|
|
|
|
--#{$name}: #{$color};
|
|
|
|
}
|
|
|
|
|
|
|
|
// composite (opaque) colors
|
|
|
|
--color-quinary-on-background: #{color.mix(
|
|
|
|
map.get($colors, "color-background"), color.change(map.get($colors, "fill-quinary"), $alpha: 1), 100% * (1 - color.alpha(map.get($colors, "fill-quinary")))
|
|
|
|
)};
|
|
|
|
--color-quarternary-on-background: #{color.mix(
|
|
|
|
map.get($colors, "color-background"), color.change(map.get($colors, "fill-quarternary"), $alpha: 1), 100% * (1 - color.alpha(map.get($colors, "fill-quarternary")))
|
|
|
|
)};
|
|
|
|
--color-quinary-on-sidepane: #{color.mix(
|
|
|
|
map.get($colors, "color-sidepane"), color.change(map.get($colors, "fill-quinary"), $alpha: 1), 100% * (1 - color.alpha(map.get($colors, "fill-quinary")))
|
|
|
|
)};
|
|
|
|
--color-quarternary-on-sidepane: #{color.mix(
|
|
|
|
map.get($colors, "color-sidepane"), color.change(map.get($colors, "fill-quarternary"), $alpha: 1), 100% * (1 - color.alpha(map.get($colors, "fill-quarternary")))
|
|
|
|
)};
|
|
|
|
--color-stripe-on-background: #{color.mix(
|
|
|
|
map.get($colors, "color-background"), color.change(map.get($colors, "color-stripe"), $alpha: 1), 100% * (1 - color.alpha(map.get($colors, "color-stripe")))
|
|
|
|
)};
|
|
|
|
--color-menu-opaque: rgb(
|
|
|
|
#{color.alpha(map.get($colors, "color-menu")) * color.red(map.get($colors, "color-menu"))},
|
|
|
|
#{color.alpha(map.get($colors, "color-menu")) * color.green(map.get($colors, "color-menu"))},
|
|
|
|
#{color.alpha(map.get($colors, "color-menu")) * color.blue(map.get($colors, "color-menu"))}
|
|
|
|
);
|
|
|
|
|
|
|
|
// background materials
|
|
|
|
--material-background: var(--color-background);
|
|
|
|
--material-background50: var(--color-background50);
|
|
|
|
--material-background70: var(--color-background70);
|
|
|
|
--material-button: var(--color-button);
|
|
|
|
--material-control: var(--color-control);
|
|
|
|
--material-menu: var(--color-menu);
|
|
|
|
--material-sidepane: var(--color-sidepane);
|
|
|
|
--material-tabbar: var(--color-tabbar);
|
|
|
|
--material-toolbar: var(--color-toolbar);
|
|
|
|
--material-mix-quinary: var(--color-quinary-on-background);
|
|
|
|
--material-mix-quarternary: var(--color-quarternary-on-background);
|
|
|
|
--material-stripe: var(--color-stripe-on-background);
|
|
|
|
|
|
|
|
// border materials
|
|
|
|
--material-border-transparent: 1px solid transparent;
|
|
|
|
--material-border: 1px solid var(--color-border);
|
|
|
|
--material-border50: 1px solid var(--color-border50);
|
|
|
|
--material-panedivider: 1px solid var(--color-panedivider);
|
|
|
|
--material-border-quinary: 1px solid var(--fill-quinary);
|
|
|
|
--material-border-quarternary: 1px solid var(--fill-quarternary);
|
2024-04-22 19:02:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@mixin contain-richlistbox {
|
|
|
|
// richlistbox elements are crazy and will expand beyond the window size
|
|
|
|
// unless all/most elements in the hierarchy that contain that
|
|
|
|
// richlistbox have a min-height: 0 set
|
|
|
|
vbox, hbox {
|
|
|
|
min-height: 0;
|
|
|
|
}
|
|
|
|
}
|