Skip to content

Commit 5a15b66

Browse files
committed
refactor(nav-menu): improve usability
1 parent e1498c1 commit 5a15b66

File tree

3 files changed

+29
-18
lines changed

3 files changed

+29
-18
lines changed

examples/next-ts/pages/navigation-menu-viewport.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ export default function Page() {
4848
</button>
4949
</div>
5050

51-
<div {...api.getItemProps({ value: "developers", disabled: true })}>
52-
<button {...api.getTriggerProps({ value: "developers", disabled: true })}>
51+
<div {...api.getItemProps({ value: "developers" })}>
52+
<button {...api.getTriggerProps({ value: "developers" })}>
5353
Developers
5454
<ChevronDown />
5555
</button>

examples/next-ts/pages/navigation-menu.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ export default function Page() {
7171
</Presence>
7272
</div>
7373

74-
<div {...api.getItemProps({ value: "developers", disabled: true })}>
75-
<button {...api.getTriggerProps({ value: "developers", disabled: true })}>
74+
<div {...api.getItemProps({ value: "developers" })}>
75+
<button {...api.getTriggerProps({ value: "developers" })}>
7676
Developers
7777
<ChevronDown />
7878
</button>

packages/machines/navigation-menu/src/navigation-menu.machine.ts

+25-14
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,9 @@ export const machine = createMachine({
9797

9898
exit: ["cleanupObservers", "cleanupAutoResetRef"],
9999

100-
initialState() {
101-
return "closed"
100+
initialState({ prop }) {
101+
const value = prop("value") || prop("defaultValue")
102+
return value ? "open" : "closed"
102103
},
103104

104105
on: {
@@ -113,21 +114,30 @@ export const machine = createMachine({
113114
actions: ["focusTopLevelEl"],
114115
},
115116
"TRIGGER.ENTER": {
116-
actions: ["clearCloseRefs"],
117+
actions: ["clearPreviousValue", "clearCloseRefs"],
117118
},
118119
"TRIGGER.CLICK": [
119120
{
120-
target: "closed",
121121
guard: and("isItemOpen", "isRootMenu"),
122+
target: "closed",
122123
actions: ["setPreviousValue", "clearValue", "setClickCloseRef"],
123124
},
125+
{
126+
guard: and("wasItemOpen", "isRootMenu"),
127+
target: "open",
128+
actions: ["setPreviousValue", "setValueOnNextTick"],
129+
},
124130
{
125131
reenter: true,
126132
target: "open",
127133
actions: ["setPreviousValue", "setValue"],
128134
},
129135
],
130136
"TRIGGER.MOVE": [
137+
{
138+
guard: "isItemOpen",
139+
actions: ["setPreviousValue", "setValue", "setPointerMoveOpenedRef"],
140+
},
131141
{
132142
guard: "isSubmenu",
133143
target: "open",
@@ -145,7 +155,7 @@ export const machine = createMachine({
145155

146156
states: {
147157
closed: {
148-
entry: ["cleanupObservers", "propagateClose", "clearPreviousValue"],
158+
entry: ["cleanupObservers", "propagateClose"],
149159
on: {
150160
"TRIGGER.LEAVE": {
151161
actions: ["clearPointerMoveRef"],
@@ -192,15 +202,11 @@ export const machine = createMachine({
192202
},
193203
"CONTENT.DISMISS": {
194204
target: "closed",
195-
actions: ["focusTriggerIfNeeded", "clearValue", "clearPointerMoveRef"],
205+
actions: ["focusTrigger", "clearValue", "clearPointerMoveRef"],
196206
},
197207
"CONTENT.ENTER": {
198208
actions: ["restoreTabOrder"],
199209
},
200-
"TRIGGER.MOVE": {
201-
guard: "isSubmenu",
202-
actions: ["setValue"],
203-
},
204210
"ROOT.CLOSE": {
205211
// clear the previous value so indicator doesn't animate
206212
actions: ["clearPreviousValue", "cleanupObservers"],
@@ -214,11 +220,11 @@ export const machine = createMachine({
214220
on: {
215221
"CLOSE.DELAY": {
216222
target: "closed",
217-
actions: ["setPreviousValue", "clearValue"],
223+
actions: ["clearValue"],
218224
},
219225
"CONTENT.DISMISS": {
220226
target: "closed",
221-
actions: ["focusTriggerIfNeeded", "clearValue", "clearPointerMoveRef"],
227+
actions: ["focusTrigger", "clearValue", "clearPointerMoveRef"],
222228
},
223229
"CONTENT.ENTER": {
224230
target: "open",
@@ -230,8 +236,8 @@ export const machine = createMachine({
230236

231237
implementations: {
232238
guards: {
233-
isOpen: ({ context }) => context.get("value") !== null,
234239
isItemOpen: ({ context, event }) => context.get("value") === event.value,
240+
wasItemOpen: ({ context, event }) => context.get("previousValue") === event.value,
235241
isRootMenu: ({ context }) => context.get("parent") == null,
236242
isSubmenu: ({ context }) => context.get("parent") != null,
237243
},
@@ -386,6 +392,11 @@ export const machine = createMachine({
386392
setValue({ context, event }) {
387393
context.set("value", event.value)
388394
},
395+
setValueOnNextTick({ context, event }) {
396+
raf(() => {
397+
context.set("value", event.value)
398+
})
399+
},
389400
clearValue({ context }) {
390401
context.set("value", null)
391402
},
@@ -410,7 +421,7 @@ export const machine = createMachine({
410421
tabbableEls[0]?.focus()
411422
})
412423
},
413-
focusTriggerIfNeeded({ context, scope }) {
424+
focusTrigger({ context, scope }) {
414425
if (context.get("value") == null) return
415426
const contentEl = dom.getContentEl(scope, context.get("value")!)
416427
if (!contains(contentEl, scope.getActiveElement())) return

0 commit comments

Comments
 (0)