{"version":3,"file":"spotlight.store.cjs","names":[],"sources":["../src/spotlight.store.ts"],"sourcesContent":["import { clamp } from '@mantine/hooks';\nimport { createStore, MantineStore, useStore } from '@mantine/store';\n\nexport interface SpotlightState {\n  opened: boolean;\n  selected: number;\n  listId: string;\n  query: string;\n  empty: boolean;\n  registeredActions: Set<string>;\n}\n\nexport type SpotlightStore = MantineStore<SpotlightState>;\n\nexport const createSpotlightStore = () =>\n  createStore<SpotlightState>({\n    opened: false,\n    empty: false,\n    selected: -1,\n    listId: '',\n    query: '',\n    registeredActions: new Set(),\n  });\n\nexport const useSpotlight = (store: SpotlightStore) => useStore(store);\n\nexport function updateSpotlightStateAction(\n  update: (state: SpotlightState) => Partial<SpotlightState>,\n  store: SpotlightStore\n) {\n  const state = store.getState();\n  store.setState({ ...state, ...update(store.getState()) });\n}\n\nexport function openSpotlightAction(store: SpotlightStore) {\n  updateSpotlightStateAction(() => ({ opened: true, selected: -1 }), store);\n}\n\nexport function closeSpotlightAction(store: SpotlightStore) {\n  updateSpotlightStateAction(() => ({ opened: false }), store);\n}\n\nexport function toggleSpotlightAction(store: SpotlightStore) {\n  updateSpotlightStateAction(\n    (state) => ({ opened: !state.opened, selected: state.opened ? state.selected : -1 }),\n    store\n  );\n}\n\nexport function setSelectedAction(index: number, store: SpotlightStore) {\n  store.updateState((state) => ({ ...state, selected: index }));\n}\n\nexport function setListId(id: string, store: SpotlightStore) {\n  store.updateState((state) => ({ ...state, listId: id }));\n}\n\nfunction findElementByQuerySelector<T extends HTMLElement>(\n  selector: string,\n  root: Document | Element | ShadowRoot = document\n): T | null {\n  // Directly try to find the element in the current root.\n  const element = root.querySelector<T>(selector);\n  if (element) {\n    return element;\n  }\n\n  // Iterate through all children of the current root.\n  const children = root instanceof ShadowRoot ? root.host.children : root.children;\n  for (let i = 0; i < children.length; i += 1) {\n    const child = children[i];\n\n    // Recursively search in the child's shadow root if it exists.\n    if (child.shadowRoot) {\n      const shadowElement = findElementByQuerySelector<T>(selector, child.shadowRoot);\n      if (shadowElement) {\n        return shadowElement;\n      }\n    }\n\n    // Also, search recursively in the child itself if it does not have a shadow root or the element wasn't found in its shadow root.\n    const nestedElement = findElementByQuerySelector<T>(selector, child);\n    if (nestedElement) {\n      return nestedElement;\n    }\n  }\n\n  // Return null if the element isn't found in the current root or any of its shadow DOMs.\n  return null;\n}\n\nexport function selectAction(index: number, store: SpotlightStore): number {\n  const state = store.getState();\n  const actionsList = state.listId ? findElementByQuerySelector(`#${state.listId}`) : null;\n  const selected = actionsList?.querySelector<HTMLButtonElement>('[data-selected]');\n  const actions = actionsList?.querySelectorAll<HTMLButtonElement>('[data-action]') ?? [];\n  const nextIndex = index === -1 ? actions.length - 1 : index === actions.length ? 0 : index;\n\n  const selectedIndex = clamp(nextIndex, 0, actions.length - 1);\n  selected?.removeAttribute('data-selected');\n  actions[selectedIndex]?.scrollIntoView({ block: 'nearest' });\n  actions[selectedIndex]?.setAttribute('data-selected', 'true');\n  setSelectedAction(selectedIndex, store);\n\n  return selectedIndex;\n}\n\nexport function selectNextAction(store: SpotlightStore) {\n  return selectAction(store.getState().selected + 1, store);\n}\n\nexport function selectPreviousAction(store: SpotlightStore) {\n  return selectAction(store.getState().selected - 1, store);\n}\n\nexport function triggerSelectedAction(store: SpotlightStore) {\n  const state = store.getState();\n  const selected = state.listId\n    ? findElementByQuerySelector<HTMLButtonElement>(`#${state.listId} [data-selected]`)\n    : null;\n  selected?.click();\n}\n\nexport function registerAction(id: string, store: SpotlightStore) {\n  const state = store.getState();\n  state.registeredActions.add(id);\n  return () => {\n    state.registeredActions.delete(id);\n  };\n}\n\nexport function setQuery(query: string, store: SpotlightStore) {\n  updateSpotlightStateAction(() => ({ query }), store);\n  Promise.resolve().then(() => {\n    selectAction(0, store);\n    updateSpotlightStateAction(\n      (state) => ({\n        empty: (state.query.trim().length > 0 && state.registeredActions.size === 0) || false,\n      }),\n      store\n    );\n  });\n}\n\nexport function clearSpotlightState(\n  { clearQuery }: { clearQuery: boolean | undefined },\n  store: SpotlightStore\n) {\n  store.updateState((state) => ({\n    ...state,\n    selected: -1,\n    query: clearQuery ? '' : state.query,\n    empty: clearQuery ? false : state.empty,\n  }));\n}\n\nexport const spotlightActions = {\n  open: openSpotlightAction,\n  close: closeSpotlightAction,\n  toggle: toggleSpotlightAction,\n  updateState: updateSpotlightStateAction,\n  setSelectedAction,\n  setListId,\n  selectAction,\n  selectNextAction,\n  selectPreviousAction,\n  triggerSelectedAction,\n  registerAction,\n  setQuery,\n  clearSpotlightState,\n};\n\nexport function createSpotlight() {\n  const store = createSpotlightStore();\n  const actions = {\n    open: () => openSpotlightAction(store),\n    close: () => closeSpotlightAction(store),\n    toggle: () => toggleSpotlightAction(store),\n  };\n\n  return [store, actions] as const;\n}\n\nexport const [spotlightStore, spotlight] = createSpotlight();\nexport const { open: openSpotlight, close: closeSpotlight, toggle: toggleSpotlight } = spotlight;\n"],"mappings":"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"}