{"version":3,"file":"nav.cjs","names":[],"sources":["../../src/core/nav.ts"],"sourcesContent":["import {\n  createListNavigation,\n  type ListNavigationOptions as FocusListNavigationOptions,\n  type ListKeyAction,\n  type ListNavigation,\n  type ListNavigationAction,\n  type ListNavigationChange,\n  type ListNavigationTypeaheadOptions,\n} from '@vielzeug/focus';\nimport { type Readable, signal } from '@vielzeug/ripple';\n\nexport type ListNavigationOptions<T> = Omit<FocusListNavigationOptions<T>, 'disabled'> & {\n  disabled?: Readable<boolean | undefined>;\n};\n\nexport type ListControl<T> = {\n  [Symbol.dispose](): void;\n  dispose(): void;\n  readonly disposed: boolean;\n  readonly focusedIndex: Readable<number>;\n  getActiveItem(): T | undefined;\n  handleKeydown(event: KeyboardEvent): boolean;\n  navigate(action: ListNavigationAction): number;\n  reset(): void;\n  set(index: number): number;\n};\n\nexport type { ListKeyAction, ListNavigationAction, ListNavigationChange, ListNavigationTypeaheadOptions };\n\nexport const createListControl = <T>(options: ListNavigationOptions<T>): ListControl<T> => {\n  const focusedIndex = signal(-1);\n  let removeAbortListener: (() => void) | undefined;\n  const navigation: ListNavigation<T> = createListNavigation<T>({\n    direction: options.direction,\n    disabled: () => Boolean(options.disabled?.value),\n    getItems: options.getItems,\n    isItemDisabled: options.isItemDisabled,\n    keys: options.keys,\n    loop: options.loop,\n    onNavigate: (change) => {\n      focusedIndex.value = change.index;\n      options.onNavigate?.(change);\n    },\n    orientation: options.orientation,\n    typeahead: options.typeahead,\n  });\n\n  const syncIndex = (): void => {\n    focusedIndex.value = navigation.getIndex();\n  };\n\n  const set = (index: number): number => {\n    const next = navigation.set(index);\n\n    syncIndex();\n\n    return next;\n  };\n\n  const navigate = (action: ListNavigationAction): number => {\n    const next = navigation.navigate(action);\n\n    syncIndex();\n\n    return next;\n  };\n\n  const reset = (): void => {\n    navigation.reset();\n    syncIndex();\n  };\n\n  const handleKeydown = (event: KeyboardEvent): boolean => {\n    const handled = navigation.handleKeydown(event);\n\n    syncIndex();\n\n    return handled;\n  };\n\n  const dispose = (): void => {\n    navigation.dispose();\n    syncIndex();\n    removeAbortListener?.();\n    removeAbortListener = undefined;\n  };\n\n  if (options.signal?.aborted) {\n    dispose();\n  } else if (options.signal) {\n    options.signal?.addEventListener('abort', dispose, { once: true });\n    removeAbortListener = () => options.signal?.removeEventListener('abort', dispose);\n  }\n\n  return {\n    dispose,\n    get disposed() {\n      return navigation.disposed;\n    },\n    focusedIndex,\n    getActiveItem: () => navigation.getActiveItem(),\n    handleKeydown,\n    navigate,\n    reset,\n    set,\n    [Symbol.dispose]: dispose,\n  };\n};\n"],"mappings":"+DA6BA,IAAa,EAAwB,GAAsD,CACzF,IAAM,GAAA,EAAe,EAAA,OAAA,CAAO,EAAE,EAC1B,EACE,GAAA,EAAgC,EAAA,qBAAA,CAAwB,CAC5D,UAAW,EAAQ,UACnB,aAAgB,EAAQ,EAAQ,UAAU,MAC1C,SAAU,EAAQ,SAClB,eAAgB,EAAQ,eACxB,KAAM,EAAQ,KACd,KAAM,EAAQ,KACd,WAAa,GAAW,CACtB,EAAa,MAAQ,EAAO,MAC5B,EAAQ,aAAa,CAAM,CAC7B,EACA,YAAa,EAAQ,YACrB,UAAW,EAAQ,SACrB,CAAC,EAEK,MAAwB,CAC5B,EAAa,MAAQ,EAAW,SAAS,CAC3C,EAEM,EAAO,GAA0B,CACrC,IAAM,EAAO,EAAW,IAAI,CAAK,EAIjC,OAFA,EAAU,EAEH,CACT,EAEM,EAAY,GAAyC,CACzD,IAAM,EAAO,EAAW,SAAS,CAAM,EAIvC,OAFA,EAAU,EAEH,CACT,EAEM,MAAoB,CACxB,EAAW,MAAM,EACjB,EAAU,CACZ,EAEM,EAAiB,GAAkC,CACvD,IAAM,EAAU,EAAW,cAAc,CAAK,EAI9C,OAFA,EAAU,EAEH,CACT,EAEM,MAAsB,CAC1B,EAAW,QAAQ,EACnB,EAAU,EACV,IAAsB,EACtB,EAAsB,IAAA,EACxB,EASA,OAPI,EAAQ,QAAQ,QAClB,EAAQ,EACC,EAAQ,SACjB,EAAQ,QAAQ,iBAAiB,QAAS,EAAS,CAAE,KAAM,EAAK,CAAC,EACjE,MAA4B,EAAQ,QAAQ,oBAAoB,QAAS,CAAO,GAG3E,CACL,UACA,IAAI,UAAW,CACb,OAAO,EAAW,QACpB,EACA,eACA,kBAAqB,EAAW,cAAc,EAC9C,gBACA,WACA,QACA,OACC,OAAO,SAAU,CACpB,CACF"}