Files
wekan/client/components/cards/checklists.css
T
Lauri Ojansivu 2536861b79 - Full right-to-left (RTL) UI for every page when an RTL language is selected
(Arabic and its variants, Persian/Farsi, Hebrew, Uyghur, Uzbek-Arabic and
  Yiddish — the languages flagged `rtl: true` in `imports/i18n/languages.js`).
  Previously only some pages flipped. The root `<html>` element now gets a
  reactive `dir="rtl"`/`dir="ltr"` attribute that follows the chosen language, so
  the whole UI mirrors at once. To make this work on every page rather than a
  handful, all directional component CSS was converted to CSS logical properties
  (`margin-left`→`margin-inline-start`, `left:`→`inset-inline-start:`,
  `text-align: left`→`text-align: start`, `float: left`→`float: inline-start`,
  and the mirror-image right/end variants) across 48 stylesheets, which flip
  automatically with `dir`. Horizontal-centering rules using
  `left: 50%` + `transform: translate(-50%, …)` were intentionally kept physical,
  since those already center correctly in both directions. The calendar view also
  renders RTL. Thanks to xet7 and Claude.
- Tests for the RTL UI. A fast, server-less `tests/rtl.test.js` (run with
  `node tests/rtl.test.js`) checks that exactly the expected languages are
  flagged `rtl: true`, that the direction helper maps each language to the right
  `dir` value, that the root `<html>` and the client keep `dir` in sync, and —
  as a regression guard — that component CSS keeps using logical properties
  (no physical `margin-left`/`float: left`/bare `left:` offsets sneak back in).
  A Playwright browser spec `tests/playwright/specs/18-rtl-layout.e2e.js` drives
  the app in both English (LTR) and Arabic (RTL) and asserts, on the boards list,
  board view, card details, my-cards / due-cards / global-search, the admin
  settings page and the login page, that the direction is correct, the
  translated text is visible, and leading-edge content (the boards menu, the
  first board list) sits on the correct side. Thanks to xet7 and Claude.
- Fixed the "Meteor unit tests" CI job hanging until its 45-minute timeout. The
  workflow set `TEST_WATCH: '0'`, but meteortesting:mocha computes
  `testWatch: TEST_WATCH || …` and the string `'0'` is truthy in JavaScript, so
  it turned on watch mode and the process never exited. Removing the env var lets
  `meteor test --once` finish and exit with the correct status.

Thanks to xet7 and Claude !

Fixes #6136,
fixes #3376,
fixes #884
2026-06-14 08:59:58 +03:00

194 lines
4.1 KiB
CSS

.js-add-checklist {
color: #8c8c8c;
}
textarea.js-add-checklist-item,
textarea.js-edit-checklist-item {
overflow: hidden;
word-wrap: break-word;
resize: none;
height: 34px;
}
.delete-text,
.js-delete-checklist-item,
.js-convert-checklist-item-to-card {
color: #8c8c8c;
text-decoration: underline;
word-wrap: break-word;
float: inline-end;
padding-top: 6px;
}
.delete-text:hover,
.js-delete-checklist-item:hover,
.js-convert-checklist-item-to-card:hover {
color: inherit;
}
.checklists-title {
display: flex;
justify-content: space-between;
}
.checklist-progress-bar-container {
display: flex;
flex-direction: row;
align-items: center;
}
.checklist-progress-bar-container .checklist-progress-text {
margin-inline-end: 10px;
}
.checklist-progress-bar-container .checklist-progress-bar {
width: 80%;
height: 10px;
background-color: #e0e0e0;
border-radius: 16px;
}
.checklist-progress-bar-container .checklist-progress-bar .checklist-progress {
color: #fff;
background-color: #666;
padding: 0.01em 16px;
border-radius: 16px;
height: 100%;
}
.checklist-title {
padding: 10px;
}
.checklist-title .checkbox {
float: inline-start;
width: 30px;
height: 30px;
font-size: 18px;
line-height: 30px;
}
.checklist-title .title {
font-size: 18px;
line-height: 25px;
}
.checklist-title .checklist-stat {
margin: 0 0.5em;
float: inline-end;
padding-top: 6px;
}
.checklist-title .checklist-stat.is-finished {
color: #3cb500;
}
.checklist-title span.fa.checklist-handle {
padding-inline-end: 20px;
padding-top: 3px;
float: inline-start;
}
#card-details-overlay {
top: 0;
bottom: -600px;
inset-inline-end: 0;
}
.checklist {
background: #f7f7f7;
}
.checklist.placeholder {
background: #ccc;
border-radius: 2px;
}
.checklist.ui-sortable-helper {
box-shadow: -2px 2px 8px rgba(0,0,0,0.3), 0 0 1px rgba(0,0,0,0.5);
transform: rotate(4deg);
cursor: grabbing;
}
.checklist-item {
margin: 0 0 0 0.1em;
line-height: 18px;
font-size: 1.1em;
margin-top: 3px;
display: flex;
background: #f7f7f7;
opacity: 1;
transition: height 0ms 400ms, opacity 400ms 0ms;
height: auto;
overflow: hidden;
}
.checklist-item.is-checked.invisible {
opacity: 0;
height: 0;
transition: height 0ms 0ms, opacity 600ms 0ms;
margin-top: 0;
margin-bottom: 0;
}
.checklist-item.placeholder {
background: #ccc;
border-radius: 2px;
}
.checklist-item.ui-sortable-helper {
box-shadow: -2px 2px 8px rgba(0,0,0,0.3), 0 0 1px rgba(0,0,0,0.5);
transform: rotate(4deg);
cursor: grabbing;
}
.checklist-item:hover {
background-color: #ebebeb;
}
.checklist-item .check-box-container {
padding-inline-end: 10px;
}
.checklist-item .check-box {
margin: 0.1em 0 0 0;
}
.checklist-item .check-box.is-checked {
border-bottom: 2px solid #3cb500;
border-inline-end: 2px solid #3cb500;
}
.checklist-item .item-title {
flex: 1;
}
.checklist-item .item-title.is-checked {
color: #8c8c8c;
font-style: italic;
text-decoration: line-through;
}
.checklist-item .item-title .viewer p {
margin-bottom: 2px;
display: block;
word-wrap: break-word;
max-width: 420px;
}
.checklist-item span.fa.checklistitem-handle {
padding-top: 2px;
padding-inline-end: 10px;
}
.js-delete-checklist-item,
.js-convert-checklist-item-to-card {
margin: 0 0 0.5em 1.33em;
padding: 12px 0 0 0;
}
.add-checklist-item {
margin: 0.2em 0 0.5em 1.33em;
}
.add-checklist-item.js-open-inlined-form,
.add-checklist.js-open-inlined-form {
display: block;
width: 50%;
}
.add-checklist-item.js-open-inlined-form:hover,
.add-checklist.js-open-inlined-form:hover {
background: #dbdbdb;
color: #222;
box-shadow: 0 1px 2px rgba(0,0,0,0.2);
}
.add-checklist-top {
/* more space to checklists title */
padding-inline-start: 20px;
/* + is easier clickable */
padding-inline-end: 20px;
}
.add-checklist-top.js-open-inlined-form:hover {
background: #dbdbdb;
color: #222;
box-shadow: 0 1px 2px rgba(0,0,0,.2);
}
.card-details-item-title {
/* max width for adding checklist at top */
width: 100%;
}
.checklist-details-menu {
float: inline-end;
padding: 6px 10px 6px 10px;
}
.edit-controls label.toggle-label {
margin-inline-start: 2px;
}