Skip to content

[Liminal UI] implement new design for Gesturemenu Commands#4205

Open
cindmichelle wants to merge 23 commits into
cybersemics:mainfrom
cindmichelle:gesturemenu/commands
Open

[Liminal UI] implement new design for Gesturemenu Commands#4205
cindmichelle wants to merge 23 commits into
cybersemics:mainfrom
cindmichelle:gesturemenu/commands

Conversation

@cindmichelle
Copy link
Copy Markdown
Collaborator

@cindmichelle cindmichelle commented Apr 29, 2026

Close #3709

Summary

Replace the old CommandItem-based gesture list with a new GestureItem component and redesigns the Gesture Menu command layout.

Changes

New GestureItem component (src/components/GestureItem.tsx)

  • Command row for the Gesture Menu showing a gesture diagram, label, and expandable description when selected
  • Uses solid-color, no-glow GestureDiagram (no gradient, no arrowhead) suited for compact list display

New useGestureHighlight hook (src/hooks/useGestureHighlight.ts)

  • Extracted from CommandItem, drives the highlight prop on GestureDiagram
  • Handles special cases: suffix matching for openMobileCommandUniverse, fixed highlight of 1 for cancel

Gesture Menu layout (src/components/GestureMenu.tsx)

  • Added "Gestures" header with gradient divider
  • Splits commands into two groups: main commands and a visually separated Cancel/Cheatsheet block at the bottom (28px gap)

GestureDiagram enhancements (src/components/GestureDiagram.tsx)

  • New props: arrowhead='none', disableGlow, useGradient, highlightColor
  • Extracted rendering logic into a GesturePath component
  • Solid-color mode uses a single combined <path> per stroke group to eliminate bead artifacts at joints from overlapping round caps
  • arrowhead='none' uses uniform symmetric padding for the viewBox instead of asymmetric arrowhead padding
  • RDLD Bezier segments extracted to a named constant

Results

ios
IMG_3808
IMG_3809

ipad
IMG_0848


Notes

This PR will only focus on redesigning the command list inside the Gesture Menu. Any upcoming layout changes related to splitting the menu into few columns will be handled in a separate ticket

@cindmichelle cindmichelle force-pushed the gesturemenu/commands branch from eb02431 to a6cb891 Compare April 29, 2026 18:21
cindmichelle and others added 4 commits May 5, 2026 03:20
Fixes regression from commit 120a77e where the per-segment rendering refactor split path handling into useGradient-dependent branches, causing two issues:

1. Arrowhead added to help gesture (rdld): The markerEnd condition lost the `path !== 'rdld'` guard, adding an unwanted arrowhead to the ? gesture in the test snapshot.

2. Straight lines instead of Bezier curves: The rdld Bezier path override was only added to the `!useGradient` branch, so callers using useGradient=true (default, e.g. CommandItem) rendered straight line segments instead of the smooth ? shape in the Help modal.

Both fixes restore the original behavior by re-adding the rdld special cases to the per-segment rendering path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
<Overlay />
<Glow />
<GestureMenu commands={commands} />
<div style={{ position: 'relative', zIndex: 1 }}>
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

this one needed in order to make the new header renders above the glow background

@cindmichelle cindmichelle marked this pull request as ready for review May 5, 2026 19:42
@cindmichelle cindmichelle requested a review from BayuAri May 5, 2026 19:43
@BayuAri
Copy link
Copy Markdown
Collaborator

BayuAri commented May 6, 2026

[Mobile] Selected inactive gesture command is blurred when there is no thought available

Step to Reproduce

  1. Open em
  2. Delete all thought if any
  3. Swipe any direction and select any grey gesture command and hold for example: swipe →↑ and hold

Current behavior

The selected menu is blurred, on this step as example: Context View
If user draws a gesture that is greyed out on the gesture menu, the command will be blurred.
This does not happen when there is a thought available.
I think this happens when the greyed out font is highlighted due the active selection on the gesture menu

image
Selected.inactive.gesture.command.is.blurred.when.there.is.no.thought.available.MP4

Expected behavior

The selected inactive gesture menu should not be blurred, refer to when there is thought available.

Copy link
Copy Markdown
Collaborator

@BayuAri BayuAri left a comment

Choose a reason for hiding this comment

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

List of issue:

There is no other issue found from my end.

@cindmichelle
Copy link
Copy Markdown
Collaborator Author

cindmichelle commented May 10, 2026

Hi @BayuAri , good catch! ive made a fix for the issue above. I also attached how the fix looks like now. and since this is the only issue atm, im going to ask @fbmcipher to review the work as well

gesture-ru.mp4

@cindmichelle cindmichelle requested a review from fbmcipher May 10, 2026 18:44
@BayuAri
Copy link
Copy Markdown
Collaborator

BayuAri commented May 10, 2026

@cindmichelle
Confirmed fixed.
Inactive (unavailable) command is displayed as grey font without glow.

image

Copy link
Copy Markdown
Collaborator

@fbmcipher fbmcipher left a comment

Choose a reason for hiding this comment

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

All in all this is really solid – the new useGestureHighlight abstraction is a meaningful improvement, the code is strong, and the implementation is really close to the mockup. Great work!

That said, I want to push this a little further and get it as close to 1:1 with the design as we can. That's the level of quality we're aiming for, and I think we can get there.

A couple of process suggestions:

  • Keep the reference mockup open beside the running implementation while you develop. Side by side, the differences are much easier to spot.
  • Try xScope. I use it constantly when I implement UIs from mockups and it's been a major help. Two tools in particular:
    • Guides for measuring spacing between elements. For example, this is how we can clearly see the GestureDiagram is slightly larger than it should be. The numeric values aren't 1:1 pixel measurements (the mockup is at 200% scale in Photoshop and the iOS simulator is sized by eye to match), but the relative differences still help quantify the disparity.
    • Loupe for color comparison.
Image

In all the notes below, left is the reference design, right is the current implementation. The majority of issues are font weight, sizing, and spacing — these are hard to translate 1:1 even with the raw Figma values, which is exactly why a measurement tool helps.


1. Font mismatch

Note: We haven't added the new UI font (Radio Canada Big) into main yet, so this isn't really a fault of your implementation per se. That said, since we're pushing for 1:1, I should flag it now.

  • Reference: UI font is Radio Canada Big.
  • Implementation: Helvetica on iOS, Roboto on Android.
  • Fix: Include Radio Canada Big in the app and use it for all Gesture Menu UI. (We'll migrate the rest of the app's UI in follow-up PRs.)

2. "Gestures" header is too thin

Image
  • Reference: Semibold.
  • Implementation: Light.
  • Fix: Increase the font weight.

3. Command subtitle is too thin

Image
  • Reference: Regular.
  • Implementation: Thin.
  • Fix: Increase the font weight.

4. Gesture diagram is too large

Image
  • Reference: Smaller diagram, leaving more breathing room next to the label.
  • Implementation: Slightly oversized.
  • Fix: Reduce the gesture diagram size to match.

5. Too much space between the "Gestures" header and its divider

Image
  • Reference: Header sits closer to the underline.
  • Implementation: ~2–3px more space than the mockup.
  • Fix: Tighten the gap between the "Gestures" header and the line beneath it.

6. Not enough space between the highlighted command and the next command

Image

Measure the gap between the end of the highlighted command and the start of the next command.

  • Reference: Larger gap below the highlighted row.
  • Implementation: Slightly smaller.
  • Fix: Increase that gap.

7. Too much space between non-highlighted commands

Image

Measure the gap between consecutive non-highlighted commands.

  • Reference: Tighter row spacing.
  • Implementation: Slightly larger.
  • Fix: Reduce the vertical gap between non-highlighted command rows.

8. Gap to the "Cancel / Command Universe" block is too large

Image
  • Reference: Smaller separator gap.
  • Implementation: Larger.
  • Fix: Reduce the spacing between the main command list and the Cancel / Command Universe block.

9. Empty space above "Cancel / Command Universe" when there are no other commands

Image
  • Reference: When the main command list is empty, the Cancel / Command Universe block sits flush at the top.
  • Implementation: There's still empty space above it.
  • Fix: When the main command list is empty, suppress the top margin / separator gap above the Cancel block.

* the universe-opener sequence appears at the end of a longer in-progress gesture.
* - `cancel`: has no gesture path; shows a fixed highlight of 1 only when selected.
*
* @param command - The command whose gesture diagram to highlight.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Documentation looks good! Just a minor style note to prefer specifying parameter comments inline wtih the type for better IntelliSense – rather than the older JSDoc style.

const useGestureHighlight = (
     /** Comment. **/
    command: Command,
    /** Comment. **/
    gestureInProgress: string | undefined,
// ...

@cindmichelle
Copy link
Copy Markdown
Collaborator Author

@fbmcipher Thanks for the feedback! Initially I kept using Helvetica and Roboto font because I noticed the Command Center implementation was still using the default font, so I assumed the difference between the design and the application fonts might have been intentional 😅

Looks like I can download the font assets from Google Fonts. But do we need to import the font with specific file extension? By default, it will be downloaded as .ttf file from Google Fonts

cindmichelle added a commit to cindmichelle/em that referenced this pull request May 11, 2026
…review)

Addresses review items cybersemics#2cybersemics#9:
- Bump "Gestures" header to semibold (cybersemics#2)
- Set command subtitle to regular weight (cybersemics#3)
- Reduce gesture diagram from 32 to 26 (cybersemics#4)
- Tighten header→divider gap (cybersemics#5)
- Tighter non-highlighted row spacing, larger gap below highlighted row (cybersemics#6, cybersemics#7)
- Shrink Cancel-block gap; flush to top when main list is empty (cybersemics#8, cybersemics#9)
@fbmcipher
Copy link
Copy Markdown
Collaborator

@cindmichelle The way you've got it with .woff2 looks perfect!

@cindmichelle cindmichelle force-pushed the gesturemenu/commands branch from 898affa to 9d69f2b Compare May 18, 2026 16:34
@cindmichelle
Copy link
Copy Markdown
Collaborator Author

cindmichelle commented May 18, 2026

Hi @fbmcipher , thanks for the xScope recommendation, it’s really helps me to compare the mockup sizing against the simulator!

I also noticed that you already enabled the spacing indicators in Figma. It’s been really helpful for implementing the spacing based on that, because earlier I was having a bit of difficulty implementing the spacing since I couldn’t inspect the distances properly. I hope we can also have this indicator for all components!
image


I’ve also updated the PR again to make the font-family and spacing closer to 1:1 with the mockup. One thing worth mentioning though is the GestureDiagram behaviour, as I’m still struggling to make the sizing and display match the mockup exactly due to the SVG aspect ratio being preserved.

As a result, gesture paths with a width/height ratio 1:2 (e.g Select Between) and 2:1 (e.g New Subthought) are ended up being displayed smaller compared to other gesture diagrams with a 1:1 ratio. Do you think this behaviour is acceptable?

image

@cindmichelle
Copy link
Copy Markdown
Collaborator Author

@fbmcipher in my last commit, i also tried to reduce the padding around the gesture path so we could have more space to render the gesture path. but could you advice which one do you prefer?

image

@cindmichelle cindmichelle requested a review from fbmcipher May 18, 2026 17:46
@fbmcipher
Copy link
Copy Markdown
Collaborator

Thanks @cindmichelle! This is shaping up to look really close to the design. I'm impressed with the progress in the last iteration!

I did still spot some minor spacing inconsistencies though. Take a look at the screenshot below. I annotated all of the spacing issues I could find. The mockup is on the left, and the current implementation on the right. Matching colours pair up measurements that should be equal between the two sides (e.g. green = space between command title and description; red = top of screen to "Gestures" header). These inconsistencies are at the level of a few pixels off here and there, but it does add up.

Alignment guides

To share a bit more about my general process with xScope:

My general process is to open the Simulator (iPhone 17) on one side of the screen, and the mockup (in Preview, Figma, etc.) on the other. Then, I line up the top and bottom of the image with the Simulator so they're at equal size.

Compare my alignment in the image above (Simulator and Preview window are exactly the same size) to yours (Figma smaller than the Simulator) – that zoom mismatch propagates into every measurement you take. xScope's guide tool helps here: draw a horizontal guide at the top and the bottom of the Simulator, then scale the mockup to match.

One thing to note: the numbers on my images are only for relative comparison – both Preview and Simulator are zoomed past 100%, so they can't be plugged into code directly. Use them as signals (this gap's too big, that margin's too small), then on your own setup: tweak the code, adjust your measurements, and repeat until your implementation's numbers match the mockup's at the same zoom.

Just those issues, and I think we're ready to send to Raine for review. Thanks for your persistence – I don't want to be too picky, but 1:1 is worth aiming for.

As always, let me know if I can help clarify anything at all!

@fbmcipher
Copy link
Copy Markdown
Collaborator

@fbmcipher in my last commit, i also tried to reduce the padding around the gesture path so we could have more space to render the gesture path. but could you advice which one do you prefer?

I think 9d69f2b is better, because the width of the gesture diagram feels more consistent than in 865320c.

@fbmcipher
Copy link
Copy Markdown
Collaborator

I also noticed that you already enabled the spacing indicators in Figma. It’s been really helpful for implementing the spacing based on that, because earlier I was having a bit of difficulty implementing the spacing since I couldn’t inspect the distances properly. I hope we can also have this indicator for all components!

Interesting, I didn't change anything! I'll try and figure out what changed, so that you always have access to these measurement tools going forward.

@fbmcipher
Copy link
Copy Markdown
Collaborator

One thing worth mentioning though is the GestureDiagram behaviour, as I’m still struggling to make the sizing and display match the mockup exactly due to the SVG aspect ratio being preserved.

As a result, gesture paths with a width/height ratio 1:2 (e.g Select Between) and 2:1 (e.g New Subthought) are ended up being displayed smaller compared to other gesture diagrams with a 1:1 ratio. Do you think this behaviour is acceptable?

Yes, that's acceptable for now. We should tackle that in a separate PR to manage complexity.

Copy link
Copy Markdown
Collaborator

@fbmcipher fbmcipher left a comment

Choose a reason for hiding this comment

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

In addition to my comments above, a couple other notes:

All gesture titles should line up

The title for "Command Universe" is slightly misaligned with the rest of the gesture titles. This might be because its GestureDiagram is slightly narrower. The simplest way to solve this problem, without touching GestureDiagram, would be to enforce a fixed width for the first column of each gesture.

Extraneous space between top of screen and Gestures header in Capacitor (red line in my image)

Look at the comparison image I posted today – the red line is a lot longer in the Simulator than in the mockup. I think this might be something to do with the status bar area. Capacitor lets us render underneath the status bar area (the viewport fills the entire screen, even the portion occupied by the status bar), and there might be some conditional padding/height displacement somewhere that avoids that status bar area.

style={{
color: 'rgb(255, 255, 255, 0.7)',
marginBottom: '0.75em',
marginBottom: '8px',
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I know there is a conversion effort to rem underway, so to save us some work later we should probably use rem units instead of px.

(If you're using AI, you could use a quick prompt to save some time!)

Copy link
Copy Markdown
Collaborator Author

@cindmichelle cindmichelle May 27, 2026

Choose a reason for hiding this comment

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

@fbmcipher sounds good. But I want to confirm again whether the font sizes in the design are already finalized, so I can convert them to rem based on the current design?

e.g. Gestures text with font-size: 16px0.89rem (since 1rem is 18px by default), and the Gesture command title font-size: 17px0.94rem.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@cindmichelle Yes, the font sizes look good to me.

@cindmichelle
Copy link
Copy Markdown
Collaborator Author

All gesture titles should line up

The title for "Command Universe" is slightly misaligned with the rest of the gesture titles. This might be because its GestureDiagram is slightly narrower. The simplest way to solve this problem, without touching GestureDiagram, would be to enforce a fixed width for the first column of each gesture.

@fbmcipher do you mean the Cancel gesture? I don’t see any misalignment in the Command Universe title, but I can see a slight one in the Cancel gesture

image

@fbmcipher
Copy link
Copy Markdown
Collaborator

Hi, it's been a while but yes, I think so.

But I would focus on the general issue, not any specific command – in general, it's important that all command titles line up all of the time.

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.

New design for the commands in the Gesture Menu

3 participants