Command bar: add extrude command, nonlinear editing, etc (#1204)
* Tweak toaster look and feel * Add icons, tweak plus icon names * Rename commandBarMeta to commandBarConfig * Refactor command bar, add support for icons * Create a tailwind plugin for aria-pressed button state * Remove overlay from behind command bar * Clean up toolbar * Button and other style tweaks * Icon tweaks follow-up: make old icons work with new sizing * Delete unused static icons * More CSS tweaks * Small CSS tweak to project sidebar * Add command bar E2E test * fumpt * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * fix typo in a comment * Fix icon padding (built version only) * Update onboarding and warning banner icons padding * Misc minor style fixes * Get Extrude opening and canceling from command bar * Iconography tweaks * Get extrude kind of working * Refactor command bar config types and organization * Move command bar configs to be co-located with each other * Start building a state machine for the command bar * Start converting command bar to state machine * Add support for multiple args, confirmation step * Submission behavior, hotkeys, code organization * Add new test for extruding from command bar * Polish step back and selection hotkeys, CSS tweaks * Loading style tweaks * Validate selection inputs, polish UX of args re-editing * Prevent submission with multiple selection on singlular arg * Remove stray console logs * Tweak test, CSS nit, remove extrude "result" argument * Fix linting warnings * Show Ctrl+/ instead of ⌘K on all platforms but Mac * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * Add "Enter sketch" to command bar * fix command bar test * Fix flaky cmd bar extrude test by waiting for engine select response * Cover both button labels '⌘K' and 'Ctrl+/' in test --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
@ -1,46 +1,68 @@
|
||||
import { useEffect } from 'react'
|
||||
import { AnyStateMachine, StateFrom } from 'xstate'
|
||||
import {
|
||||
Command,
|
||||
CommandBarConfig,
|
||||
createMachineCommand,
|
||||
} from '../lib/commands'
|
||||
import { AnyStateMachine, InterpreterFrom, StateFrom } from 'xstate'
|
||||
import { createMachineCommand } from '../lib/createMachineCommand'
|
||||
import { useCommandsContext } from './useCommandsContext'
|
||||
import { modelingMachine } from 'machines/modelingMachine'
|
||||
import { authMachine } from 'machines/authMachine'
|
||||
import { settingsMachine } from 'machines/settingsMachine'
|
||||
import { homeMachine } from 'machines/homeMachine'
|
||||
import { Command, CommandSetConfig, CommandSetSchema } from 'lib/commandTypes'
|
||||
|
||||
interface UseStateMachineCommandsArgs<T extends AnyStateMachine> {
|
||||
// This might not be necessary, AnyStateMachine from xstate is working
|
||||
export type AllMachines =
|
||||
| typeof modelingMachine
|
||||
| typeof settingsMachine
|
||||
| typeof authMachine
|
||||
| typeof homeMachine
|
||||
|
||||
interface UseStateMachineCommandsArgs<
|
||||
T extends AllMachines,
|
||||
S extends CommandSetSchema<T>
|
||||
> {
|
||||
machineId: T['id']
|
||||
state: StateFrom<T>
|
||||
send: Function
|
||||
commandBarConfig?: CommandBarConfig<T>
|
||||
commands: Command[]
|
||||
owner: string
|
||||
actor?: InterpreterFrom<T>
|
||||
commandBarConfig?: CommandSetConfig<T, S>
|
||||
onCancel?: () => void
|
||||
}
|
||||
|
||||
export default function useStateMachineCommands<T extends AnyStateMachine>({
|
||||
export default function useStateMachineCommands<
|
||||
T extends AnyStateMachine,
|
||||
S extends CommandSetSchema<T>
|
||||
>({
|
||||
machineId,
|
||||
state,
|
||||
send,
|
||||
actor,
|
||||
commandBarConfig,
|
||||
owner,
|
||||
}: UseStateMachineCommandsArgs<T>) {
|
||||
const { addCommands, removeCommands } = useCommandsContext()
|
||||
onCancel,
|
||||
}: UseStateMachineCommandsArgs<T, S>) {
|
||||
const { commandBarSend } = useCommandsContext()
|
||||
|
||||
useEffect(() => {
|
||||
const newCommands = state.nextEvents
|
||||
.filter((e) => !['done.', 'error.'].some((n) => e.includes(n)))
|
||||
.map((type) =>
|
||||
createMachineCommand<T>({
|
||||
createMachineCommand<T, S>({
|
||||
ownerMachine: machineId,
|
||||
type,
|
||||
state,
|
||||
send,
|
||||
actor,
|
||||
commandBarConfig,
|
||||
owner,
|
||||
onCancel,
|
||||
})
|
||||
)
|
||||
.filter((c) => c !== null) as Command[] // TS isn't smart enough to know this filter removes nulls
|
||||
|
||||
addCommands(newCommands)
|
||||
commandBarSend({ type: 'Add commands', data: { commands: newCommands } })
|
||||
|
||||
return () => {
|
||||
removeCommands(newCommands)
|
||||
commandBarSend({
|
||||
type: 'Remove commands',
|
||||
data: { commands: newCommands },
|
||||
})
|
||||
}
|
||||
}, [state])
|
||||
}
|
||||
|
Reference in New Issue
Block a user