Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement lettercase feature #2461

Open
wants to merge 15 commits into
base: main
Choose a base branch
from

Conversation

RED-ROSE515
Copy link
Contributor

@RED-ROSE515 RED-ROSE515 commented Oct 17, 2024

Closes #2424

I implemented lettercase features( LowerCase, UpperCase, SentenceCase, TitleCase) to the ToolBar.

These are the screenshots.
image
image
image
image

Copy link
Contributor

@raineorshine raineorshine left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! This is a great stat. Thanks for adding a unit test as well.

Please always reference the associated issue number in the PR description. That way GitHub will link the PR to the issue. I've added it above.

It looks like the Linter, Tests, and Puppeteer tests are all failing in the CI. Once these are all passing I can do a proper review.

I will note that useWindowOverlay has been duplicated in the ColorPicker and LetterCasePicker component. As mentioned in the issue, and following the DRY principle, we want to avoid code duplication. Code duplication doubles the amount of code to maintain and leads to subtle discrepancies over time. Instead, factor out the common code and use the appropriate level of abstraction to share common functionality.

Copy link
Contributor

@raineorshine raineorshine left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! Looks very good. I've offered some tips below to clean up the code a bit.

There are just a couple behavioral issues I am seeing:

  1. Let's prevent both the ColorPicker dropdown and the LetterCase dropdown from being open at the same time. If one is clicked, the other one should close.
  2. The browser selection (i.e. text cursor) is not being preserved when it starts at the end of the thought. I'm guessing that selection.restore does not work in this case because savedSelection.node is not the same after the thought re-renders.

.prettierrc.json Outdated Show resolved Hide resolved
src/@types/State.ts Outdated Show resolved Hide resolved
src/shortcuts/lettercase.ts Outdated Show resolved Hide resolved
src/actions/formatLetterCase.ts Outdated Show resolved Hide resolved
src/actions/formatLetterCase.ts Outdated Show resolved Hide resolved
src/shortcuts/lettercase.ts Outdated Show resolved Hide resolved
src/components/__tests__/LetterCasePicker.ts Outdated Show resolved Hide resolved
src/components/LetterCasePicker.tsx Outdated Show resolved Hide resolved
<div style={{ userSelect: 'none' }}>
<div
ref={ref}
style={{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This project uses PandaCSS for styling. The style attribute should only be used for styles with dynamic runtime values. Otherwise you should use Panda's css function. See other components for usage, or check out https://panda-css.com/docs/concepts/writing-styles.

src/actions/formatLetterCase.ts Outdated Show resolved Hide resolved
@raineorshine
Copy link
Contributor

When you rebase on main, note the signature for isDropdownOpen has changed: 9b340a2

Copy link
Contributor

@raineorshine raineorshine left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, thanks for the update. The changes that you made look good.

  1. Let's prevent both the ColorPicker dropdown and the LetterCase dropdown from being open at the same time. If one is clicked, the other one should close.

The LetterCasePicker is closed when the ColorPicker is selected, but not the other way around. You also need to close the ColorPicker when the LetterCasePicker is opened.

2. The browser selection (i.e. text cursor) is not being preserved when it starts at the end of the thought. I'm guessing that selection.restore does not work in this case because savedSelection.node is not the same after the thought re-renders.

This is still not working for me. When the caret is at the end of the thought and I apply a letter case, the caret incorrectly moves to the beginning of the thought.

This project uses PandaCSS for styling. The style attribute should only be used for styles with dynamic runtime values. Otherwise you should use Panda's css function. See other components for usage, or check out panda-css.com/docs/concepts/writing-styles.

Do you need any help with this? The style attributes need to be replaced with calls to PandaCSS's css function.

src/actions/toggleLetterCase.ts Outdated Show resolved Hide resolved
src/actions/toggleLetterCase.ts Outdated Show resolved Hide resolved
Comment on lines 12 to 15
multicursor: {
enabled: false,
error: () => 'Cannot change text color with multiple thoughts.',
},
Copy link
Contributor

@raineorshine raineorshine Oct 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll want to set this to multicursor: ignore and then implement each option as a separate shortcut to enable multicursor support.

I considered the possibility of implementing multicursor support inline to the reducer, but that would miss out on the existing cursor handling that happens automatically with execShortcutWithMulticursor. Plus, we need each letter case option to be a separate shortcut anyway so that they show up in the Command Palette. Separate shortcuts are a bit verbose, but it provides the necessary functionality.

Let me know if anything about the multicursor functionality needs clarification.

@RED-ROSE515
Copy link
Contributor Author

@raineorshine . I will check and fix the feedbacks.
In my opinion, there is no need to save the caret offset.
Lettercase feature changes the letter case of the current thought. I mean the full thought.
For example, Bold applies to the selected text but Letter case applies to the current full thought.
So I think there is no need to preserve the selection.
I tried to implement PandaCSS on my side, it doesn't work.

@raineorshine
Copy link
Contributor

In my opinion, there is no need to save the caret offset.

From the developer's perspective, preserving the caret offset can feel like extra work, and maybe it's not that important so it could be ignored. However from the user's perspective, having the caret move to the beginning of the thought is the extra work. The default to them is that the caret stays in the same place. To move the caret to the beginning of the thought, we would need evidence that this provides additional affordance to the user.

Maybe the user is typing a thought, decides halfway through that they need to make the thought title case, then they resume writing. In this case, the caret should definitely be where they left it after they activate title case. It is less likely that the user's intention is to edit the beginning of a thought when their caret was at the end.

I tried to implement PandaCSS on my side, it doesn't work.

No problem, let's troubleshoot. Where did it stop working? What was the actual and expected behavior?

Copy link
Contributor

@raineorshine raineorshine left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. The browser selection (i.e. text cursor) is not being preserved when it starts at the end of the thought. I'm guessing that selection.restore does not work in this case because savedSelection.node is not the same after the thought re-renders.

This is still not working for me. When the caret is at the end of the thought and I apply a letter case, the caret incorrectly moves to the beginning of the thought.

Better. Try activating a few different letter case options in a row. The caret is preserved the first time, but then moves on subsequent activations.

You'll want to set this to multicursor: ignore and then implement each option as a separate shortcut to enable multicursor support.

I considered the possibility of implementing multicursor support inline to the reducer, but that would miss out on the existing cursor handling that happens automatically with execShortcutWithMulticursor. Plus, we need each letter case option to be a separate shortcut anyway so that they show up in the Command Palette. Separate shortcuts are a bit verbose, but it provides the necessary functionality.

Let me know if anything about the multicursor functionality needs clarification.

The letter case options still need to be split into separate shortcuts and given multicursor support, but for simplicity we can do that in a separate PR. The current functionality is adequate for an initial implementation.

src/components/LetterCasePicker.tsx Show resolved Hide resolved
fill={colors.fgOverlay90}
size={fontSize}
style={{
position: 'absolute',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

position and width can be done with className={css(...)}. We usually just reserve style={...} for dynamic runtime values.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Command: Lettercase
2 participants