uiStateStore.ts 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import { create } from "zustand"
  2. import type { AutocompletePickerState } from "../components/autocomplete/types.js"
  3. /**
  4. * UI-specific state that doesn't need to persist across task switches.
  5. * This separates UI state from task/message state in the main CLI store.
  6. */
  7. interface UIState {
  8. // Exit handling state
  9. showExitHint: boolean
  10. pendingExit: boolean
  11. // Countdown timer for auto-accepting followup questions
  12. countdownSeconds: number | null
  13. // Custom input mode for followup questions
  14. showCustomInput: boolean
  15. isTransitioningToCustomInput: boolean
  16. // Focus management for scroll area vs input
  17. manualFocus: "scroll" | "input" | null
  18. // TODO viewer overlay
  19. showTodoViewer: boolean
  20. // Autocomplete picker state
  21. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  22. pickerState: AutocompletePickerState<any>
  23. }
  24. interface UIActions {
  25. // Exit handling actions
  26. setShowExitHint: (show: boolean) => void
  27. setPendingExit: (pending: boolean) => void
  28. // Countdown timer actions
  29. setCountdownSeconds: (seconds: number | null) => void
  30. // Custom input mode actions
  31. setShowCustomInput: (show: boolean) => void
  32. setIsTransitioningToCustomInput: (transitioning: boolean) => void
  33. // Focus management actions
  34. setManualFocus: (focus: "scroll" | "input" | null) => void
  35. // TODO viewer actions
  36. setShowTodoViewer: (show: boolean) => void
  37. // Picker state actions
  38. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  39. setPickerState: (state: AutocompletePickerState<any>) => void
  40. // Reset all UI state to defaults
  41. resetUIState: () => void
  42. }
  43. const initialState: UIState = {
  44. showExitHint: false,
  45. pendingExit: false,
  46. countdownSeconds: null,
  47. showCustomInput: false,
  48. isTransitioningToCustomInput: false,
  49. manualFocus: null,
  50. showTodoViewer: false,
  51. pickerState: {
  52. activeTrigger: null,
  53. results: [],
  54. selectedIndex: 0,
  55. isOpen: false,
  56. isLoading: false,
  57. triggerInfo: null,
  58. },
  59. }
  60. export const useUIStateStore = create<UIState & UIActions>((set) => ({
  61. ...initialState,
  62. setShowExitHint: (show) => set({ showExitHint: show }),
  63. setPendingExit: (pending) => set({ pendingExit: pending }),
  64. setCountdownSeconds: (seconds) => set({ countdownSeconds: seconds }),
  65. setShowCustomInput: (show) => set({ showCustomInput: show }),
  66. setIsTransitioningToCustomInput: (transitioning) => set({ isTransitioningToCustomInput: transitioning }),
  67. setManualFocus: (focus) => set({ manualFocus: focus }),
  68. setShowTodoViewer: (show) => set({ showTodoViewer: show }),
  69. setPickerState: (state) => set({ pickerState: state }),
  70. resetUIState: () => set(initialState),
  71. }))