monkeytype/frontend
Nad Alaba 5ca47e116b
impr(tape mode): support RTL languages (@NadAlaba) (#5748)
### Description

1. Support RTL in tape mode:
- In `scrollTape()`: flip the sign of `#words.margin-left` and add
`.word.margin-right` to center first letter in RTL.
- In `Caret.getTargetPositionLeft()`: flip the direction of tapeMargin
in RTL.
   - Remove restriction on RTL tape mode from test-logic.ts.

2. Support zero-width characters in tape mode:
- Subtract the width of the last letter that has a positive width if the
current letter has a zero width (e.g, diacritics). This is needed when
calculation is based on letter widths instead of letter position, which
is done in caret.ts when tape=word, and in `scrollTape()` when
tape=letter.

3. Remove the width change of `#words` in tape mode to 200vw because
it's not needed anymore now that we're using `white-space: nowrap`:
- Also adjust the limit of `.afterNewline.margin-left` to be 3 times the
new width of `#words` which is now equal to `#wordsWrapper.width` by
default.

4. Make `.word.height` in `.withLigature` langs similar to their height
in english:
- Imitate the appearance and behavior of `inline-block` `<letter>`s in
`.withLigatures` lanuages. These languages make the display of
`<letter>` elements `inline` in order to allow the joining of letters.
However, this causes `<letter>`'s `border-bottom` to be ignored, which
changes `.word` height, so we add a `padding-bottom` to the `.word` in
that case.
- Also, `inline` `<letter>`s overflow the `#wordWrapper` without
wrapping (e.g, when `maxLineWidth` = 20ch and we type 30 letters), so we
add the property `overflow-wrap: anywhere`, but we don't allow `.hints`
to inherit this property.
- P.S, it is necessary that all `.word`s have the same height (with and
without ligatures), because we now set the height of `.beforeNewline`s
in css, and we depend on these elements to have the same height as
`.word`s so that the user won't feel a vertical shift in lines in tape
mode.

5. Animate turning off tape mode in `updateWordsMargin()` if
`SmoothLineScroller` is on.

6. Block removing words at the first call of `scrollTape()`:
- Because the inline style of `#words.margin-left` may be negative when
restarting the test, making `scrollTape()` start when the first word is
overflown to the left, which makes `scrollTape()` remove that word (this
bug affects LTR and RTL langs).

closes #3923

---------

Co-authored-by: Jack <jack@monkeytype.com>
2025-06-18 12:02:43 +02:00
..
__tests__ perf: use cache in local-storage-with-schema (@fehmer) (#6596) 2025-05-27 17:12:05 +02:00
docker fix: local development using docker not working with pnpm (@fehmer) (#6401) 2025-03-26 13:11:02 +01:00
scripts refactor: move languages to contracts (@fehmer) (#6497) 2025-05-07 14:02:27 +02:00
src impr(tape mode): support RTL languages (@NadAlaba) (#5748) 2025-06-18 12:02:43 +02:00
static fix(quotes): gladiator quote (@acdpsn) (#6626) 2025-06-16 14:45:13 +02:00
.eslintrc.cjs chore: add eslint compat plugin (@fehmer) (#6542) 2025-05-12 16:52:01 +02:00
.firebaserc_example
.oxlintrc.json chore: update plugins overrides 2025-06-14 15:33:52 +02:00
firebase.json
gulpfile.js chore: add oxlint (@miodec) (#6455) 2025-04-16 17:18:50 +02:00
knip.json
package.json chore: bump oxlint version 2025-06-14 14:43:05 +02:00
tsconfig.json refactor: remove global type namespaces (@miodec) (#5907) 2024-09-23 15:34:16 +02:00
vite.config.dev.js chore: add oxlint (@miodec) (#6455) 2025-04-16 17:18:50 +02:00
vite.config.js chore: add sentry 2025-04-29 17:36:23 +02:00
vite.config.prod.js chore: try to use auto commit detection again 2025-05-03 12:02:51 +02:00
vitest.config.js refactor: move funboxes to a shared package (@miodec) (#6063) 2024-12-04 16:11:07 +01:00