How can I make a sticky, pill-shaped button that expands on click to show more navigation links?

Found Nav while searching for inspiration and thought to attempt to recreate it. Turned out to be more complicated than I thought. Is there someone on here that knows how to achieve this? This is how far I got πŸ˜“ https://codesandbox.io/s/dynamic-button-tmft35?file=/src/styles.scss This is where I found the sticky button: https://studiorotate.com
Headless Commerce Agency - RotateΒ° - eCommerce Agency
Headless eCommerce leaders, without compromise. Beautiful, bespoke & built-to-last experiences. All grounded in strategy, geared for high growth.
6 Replies
theoriginalandrew
theoriginalandrewβ€’12mo ago
I'll take a look at it for ya. Seems like a fun little pattern Firstly - I recommend looking at the code which has been written on the site (they don't show you business logic like interactions, so its nice to at least know their structure). One thing that points out is that its an unordered list with a button in each list item surrounded in a div. This helps you understand that the menu is essentially just an inline list. For handling the visibility of the nav items, you can use the useState hook you brought in and do a simple toggle ->
const [visible, setVisible] = useState(false);

const handleVisible = () => setVisible(prevState => !prevState);
const [visible, setVisible] = useState(false);

const handleVisible = () => setVisible(prevState => !prevState);
and then wrap visible around the items you want. Remember that variables can only be wrapped around a single wrapped element, so you may need to also wrap a fragment around the menu values ->
{visible && <><button>test</button><button>test 2</button></>}
{visible && <><button>test</button><button>test 2</button></>}
If you need to force something to specific state rather than toggling, you can always pass in () => setVisible(true|false) . From there, you should have the general logic down and it seems like you have most of the styling already done. I would recommend not putting the anchor tags inside of your button, thats not good semantically. perhaps a pattern such as this would work ->
<div>
<button onClick={handleVisibility}>Menu</button>
{visible && (
<ul>
<li><button>Item 1</button></li>
<li><button>Menu 2</button></li>
<li><button onclick={() => setVisible(false)}>Close</button></li>
</ul>
)}
</div>
<div>
<button onClick={handleVisibility}>Menu</button>
{visible && (
<ul>
<li><button>Item 1</button></li>
<li><button>Menu 2</button></li>
<li><button onclick={() => setVisible(false)}>Close</button></li>
</ul>
)}
</div>
capt_uhu
capt_uhuβ€’12mo ago
for the pill shape i'd recommend something like border-radius: 9999px; it seems like over kill but gets clamped by the browser for each element it's on. This will keep the pill shape no matter what your width or height.
marvxkiyi
marvxkiyiβ€’12mo ago
@Andrew i did analyze the og website. And kind of came to same conclusion as you. I also found that the width of the pill button changes evey time one clicks on a different item. Tho still no idea how to recreate this πŸ₯² @jsnkuhn πŸ‘†
MarkBoots
MarkBootsβ€’12mo ago
i was playing with this a bit (fun practice) This is what I have so far (Vanilla JS) https://codepen.io/MarkBoots/pen/MWLEQar Still have to figure out how to thransition the width on open and close
marvxkiyi
marvxkiyiβ€’12mo ago
@marYou you are a genius! Going to spend my weekend understanding all of it πŸ™πŸΏ
MarkBoots
MarkBootsβ€’12mo ago
no problem, good luck!
Want results from more Discord servers?
Add your server