index.ts 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. import { computed, getCurrentInstance, inject, unref } from 'vue'
  2. import { isClient } from '@vueuse/core'
  3. import { debugWarn } from '@kankan-components/utils'
  4. import { useGlobalConfig } from '../use-global-config'
  5. import { defaultNamespace } from '../use-namespace'
  6. import type { InjectionKey, Ref } from 'vue'
  7. import type { MaybeRef } from '@vueuse/core'
  8. export type UiIdInjectionContext = {
  9. prefix: number
  10. current: number
  11. }
  12. const defaultIdInjection = {
  13. prefix: Math.floor(Math.random() * 10000),
  14. current: 0,
  15. }
  16. export const ID_INJECTION_KEY: InjectionKey<UiIdInjectionContext> =
  17. Symbol('elIdInjection')
  18. export const useIdInjection = (): UiIdInjectionContext => {
  19. return getCurrentInstance()
  20. ? inject(ID_INJECTION_KEY, defaultIdInjection)
  21. : defaultIdInjection
  22. }
  23. export const useId = (deterministicId?: MaybeRef<string>): Ref<string> => {
  24. const idInjection = useIdInjection()
  25. if (!isClient && idInjection === defaultIdInjection) {
  26. debugWarn(
  27. 'IdInjection',
  28. `Looks like you are using server rendering, you must provide a id provider to ensure the hydration process to be succeed
  29. usage: app.provide(ID_INJECTION_KEY, {
  30. prefix: number,
  31. current: number,
  32. })`
  33. )
  34. }
  35. const namespace = useGlobalConfig('namespace', defaultNamespace)
  36. const idRef = computed(
  37. () =>
  38. unref(deterministicId) ||
  39. `${namespace.value}-id-${idInjection.prefix}-${idInjection.current++}`
  40. )
  41. return idRef
  42. }