useParams.ts 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. /*
  2. * next/compat/router is used so that this doesn't cause an error on App
  3. * Router builds. However, no replacement for the functionality is provided if
  4. * the router is missing (it just silently fails).
  5. *
  6. * This is fine because docs (the only site moving to App Router right now)
  7. * doesn't use this hook. Skipping it silently is less troublesome than trying
  8. * to make it work across both routers -- making search params work seamlessly
  9. * is a giant pain, and too much critical studio functionality depends on this
  10. * to mess with it lightly.
  11. */
  12. import { useRouter } from 'next/compat/router'
  13. import { useMemo } from 'react'
  14. /**
  15. * Helper to convert kebab case to camel case
  16. */
  17. function convertToCamelCase(key: string): string {
  18. if (!key.includes('-')) {
  19. return key
  20. }
  21. const parts = key.split('-')
  22. const capitalizedParts = parts.map((part, index) => {
  23. if (index === 0) {
  24. return part
  25. }
  26. return part.charAt(0).toUpperCase() + part.slice(1)
  27. })
  28. return capitalizedParts.join('')
  29. }
  30. export function useParams(): {
  31. [k: string]: string | undefined
  32. } {
  33. const router = useRouter()
  34. const query = router?.query
  35. const modifiedQuery = {
  36. ...query,
  37. }
  38. // Convert kebab case keys to camel case
  39. Object.keys(modifiedQuery).forEach((key) => {
  40. const modifiedKey = convertToCamelCase(key)
  41. if (modifiedKey !== key) {
  42. modifiedQuery[modifiedKey] = modifiedQuery[key]
  43. delete modifiedQuery[key]
  44. }
  45. })
  46. return useMemo(
  47. () =>
  48. Object.fromEntries(
  49. Object.entries(modifiedQuery).map(([key, value]) => {
  50. if (Array.isArray(value)) {
  51. return [key, value[0]]
  52. } else {
  53. return [key, value]
  54. }
  55. })
  56. ),
  57. [query]
  58. )
  59. }