{"version":3,"sources":["../../../src/components/BreadcrumbMenu/useBreadcrumbBuilder.ts","../../../src/components/BreadcrumbMenu/breadcrumbStore.ts"],"sourcesContent":["import { useEffect } from 'react';\nimport { useBreadcrumb, type BreadcrumbItem } from './breadcrumbStore';\n\n/**\n * Interface para configuração de um nível de breadcrumb dinâmico (com dados)\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface BreadcrumbLevelWithData<T = any> {\n  /** Dados do nível atual */\n  data: T | null;\n  /** ID extraído da URL para comparação */\n  urlId?: string;\n  /** Função para obter o ID dos dados */\n  getId: (data: T) => string;\n  /** Função para obter o nome dos dados */\n  getName: (data: T) => string;\n  /** Função para construir a URL do breadcrumb */\n  getUrl: (data: T, previousIds: string[]) => string;\n}\n\n/**\n * Interface para configuração de um nível de breadcrumb estático (sem dados)\n */\nexport interface BreadcrumbLevelStatic {\n  /** Breadcrumb estático */\n  breadcrumb: BreadcrumbItem;\n  /** ID extraído da URL para validação (se não estiver na URL, não mostra) */\n  urlId?: string;\n}\n\n/**\n * Union type para aceitar ambos os tipos de breadcrumb\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type BreadcrumbLevel<T = any> =\n  | BreadcrumbLevelWithData<T>\n  | BreadcrumbLevelStatic;\n\n/**\n * Configuração do builder de breadcrumbs\n */\nexport interface BreadcrumbBuilderConfig {\n  /** Namespace único para este breadcrumb */\n  namespace: string;\n  /** Breadcrumb inicial (raiz) */\n  root: BreadcrumbItem;\n  /** Níveis hierárquicos de breadcrumbs (cada um pode ter tipo diferente) */\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  levels: BreadcrumbLevel<any>[];\n}\n\n/**\n * Hook para construir breadcrumbs hierárquicos automaticamente\n *\n * Suporta dois tipos de breadcrumbs:\n * 1. Dinâmico (com dados): Requer dados carregados do backend\n * 2. Estático: Breadcrumb fixo que aparece baseado na URL\n *\n * @param config - Configuração do builder\n * @returns Breadcrumbs e métodos para manipulá-los\n *\n * @example\n * // Breadcrumb dinâmico (com dados do backend)\n * ```tsx\n * const { breadcrumbs } = useBreadcrumbBuilder({\n *   namespace: 'performance',\n *   root: { id: 'home', name: 'Home', url: '/' },\n *   levels: [\n *     {\n *       data: subjectData,\n *       urlId: subjectId,\n *       getId: (data) => data.subjectId,\n *       getName: (data) => data.subjectName,\n *       getUrl: (data) => `/subjects/${data.subjectId}`,\n *     },\n *   ],\n * });\n * ```\n *\n * @example\n * // Breadcrumb estático (sem dados)\n * ```tsx\n * const { breadcrumbs } = useBreadcrumbBuilder({\n *   namespace: 'settings',\n *   root: { id: 'home', name: 'Home', url: '/' },\n *   levels: [\n *     {\n *       breadcrumb: { id: 'settings', name: 'Configurações', url: '/settings' },\n *       urlId: 'settings', // Mostra apenas se 'settings' estiver na URL\n *     },\n *     {\n *       breadcrumb: { id: 'profile', name: 'Perfil', url: '/settings/profile' },\n *       urlId: 'profile',\n *     },\n *   ],\n * });\n * ```\n *\n * @example\n * // Misturar estático e dinâmico\n * ```tsx\n * const { breadcrumbs } = useBreadcrumbBuilder({\n *   namespace: 'mixed',\n *   root: { id: 'home', name: 'Home', url: '/' },\n *   levels: [\n *     // Estático\n *     {\n *       breadcrumb: { id: 'products', name: 'Produtos', url: '/products' },\n *       urlId: 'products',\n *     },\n *     // Dinâmico\n *     {\n *       data: categoryData,\n *       urlId: categoryId,\n *       getId: (data) => data.id,\n *       getName: (data) => data.name,\n *       getUrl: (data) => `/products/${data.id}`,\n *     },\n *   ],\n * });\n * ```\n */\n/**\n * Type guard para verificar se é um breadcrumb com dados\n */\nconst isBreadcrumbWithData = (\n  level: BreadcrumbLevel\n): level is BreadcrumbLevelWithData => {\n  return 'data' in level;\n};\n\nexport const useBreadcrumbBuilder = (config: BreadcrumbBuilderConfig) => {\n  const { namespace, root, levels } = config;\n  const { breadcrumbs, setBreadcrumbs, sliceBreadcrumbs } =\n    useBreadcrumb(namespace);\n\n  // Extrair apenas os dados dos levels que são as verdadeiras dependências\n  const levelDependencies = levels.map((level) =>\n    isBreadcrumbWithData(level) ? level.data : null\n  );\n  const levelUrlIds = levels.map((level) => level.urlId);\n\n  useEffect(() => {\n    const newBreadcrumbs: BreadcrumbItem[] = [root];\n    const previousIds: string[] = [];\n\n    // Construir breadcrumbs hierarquicamente\n    for (const level of levels) {\n      const { urlId } = level;\n\n      // Verificar se é breadcrumb com dados ou estático\n      if (isBreadcrumbWithData(level)) {\n        // Breadcrumb dinâmico (com dados)\n        const { data, getId, getName, getUrl } = level;\n\n        // Parar se não temos dados\n        if (!data) break;\n\n        const dataId = getId(data);\n\n        // Se urlId está definido, deve corresponder ao dataId\n        // Se urlId é undefined, significa que estamos em nível superior, então parar\n        if (urlId === undefined || dataId !== urlId) break;\n\n        // Adicionar breadcrumb\n        newBreadcrumbs.push({\n          id: dataId,\n          name: getName(data),\n          url: getUrl(data, previousIds),\n        });\n\n        previousIds.push(dataId);\n      } else {\n        // Breadcrumb estático\n        const { breadcrumb } = level;\n\n        // Se urlId é undefined, parar (não estamos neste nível)\n        if (urlId === undefined) break;\n\n        // Adicionar breadcrumb estático\n        newBreadcrumbs.push(breadcrumb);\n        previousIds.push(breadcrumb.id);\n      }\n    }\n\n    setBreadcrumbs(newBreadcrumbs);\n  }, [namespace, ...levelDependencies, ...levelUrlIds, root.id]);\n\n  return {\n    breadcrumbs,\n    sliceBreadcrumbs,\n  };\n};\n","import { create } from 'zustand';\n\n/**\n * Interface para um item de breadcrumb\n */\nexport interface BreadcrumbItem {\n  id: string;\n  name: string;\n  url: string;\n}\n\n/**\n * Interface para o estado do store de breadcrumbs\n */\ninterface BreadcrumbStore {\n  // Múltiplas instâncias de breadcrumbs identificadas por namespace\n  breadcrumbs: Record<string, BreadcrumbItem[]>;\n\n  // Define todos os breadcrumbs de uma instância\n  setBreadcrumbs: (namespace: string, items: BreadcrumbItem[]) => void;\n\n  // Adiciona um breadcrumb ao final da lista\n  addBreadcrumb: (namespace: string, item: BreadcrumbItem) => void;\n\n  // Atualiza um breadcrumb existente\n  updateBreadcrumb: (\n    namespace: string,\n    itemId: string,\n    updates: Partial<BreadcrumbItem>\n  ) => void;\n\n  // Remove um breadcrumb e todos os seguintes\n  removeBreadcrumbFrom: (namespace: string, itemId: string) => void;\n\n  // Mantém apenas os breadcrumbs até o índice especificado\n  sliceBreadcrumbs: (namespace: string, index: number) => void;\n\n  // Limpa todos os breadcrumbs de uma instância\n  clearBreadcrumbs: (namespace: string) => void;\n\n  // Obtém os breadcrumbs de uma instância\n  getBreadcrumbs: (namespace: string) => BreadcrumbItem[];\n}\n\n/**\n * Store Zustand para gerenciar breadcrumbs\n * Suporta múltiplas instâncias através de namespaces\n */\nexport const useBreadcrumbStore = create<BreadcrumbStore>((set, get) => ({\n  breadcrumbs: {},\n\n  setBreadcrumbs: (namespace: string, items: BreadcrumbItem[]) => {\n    set((state) => ({\n      breadcrumbs: {\n        ...state.breadcrumbs,\n        [namespace]: items,\n      },\n    }));\n  },\n\n  addBreadcrumb: (namespace: string, item: BreadcrumbItem) => {\n    set((state) => {\n      const current = state.breadcrumbs[namespace] || [];\n      return {\n        breadcrumbs: {\n          ...state.breadcrumbs,\n          [namespace]: [...current, item],\n        },\n      };\n    });\n  },\n\n  updateBreadcrumb: (\n    namespace: string,\n    itemId: string,\n    updates: Partial<BreadcrumbItem>\n  ) => {\n    set((state) => {\n      const current = state.breadcrumbs[namespace] || [];\n      return {\n        breadcrumbs: {\n          ...state.breadcrumbs,\n          [namespace]: current.map((item) =>\n            item.id === itemId ? { ...item, ...updates } : item\n          ),\n        },\n      };\n    });\n  },\n\n  removeBreadcrumbFrom: (namespace: string, itemId: string) => {\n    set((state) => {\n      const current = state.breadcrumbs[namespace] || [];\n      const index = current.findIndex((item) => item.id === itemId);\n      if (index === -1) return state;\n\n      return {\n        breadcrumbs: {\n          ...state.breadcrumbs,\n          [namespace]: current.slice(0, index),\n        },\n      };\n    });\n  },\n\n  sliceBreadcrumbs: (namespace: string, index: number) => {\n    set((state) => {\n      const current = state.breadcrumbs[namespace] || [];\n      return {\n        breadcrumbs: {\n          ...state.breadcrumbs,\n          [namespace]: current.slice(0, index + 1),\n        },\n      };\n    });\n  },\n\n  clearBreadcrumbs: (namespace: string) => {\n    set((state) => {\n      const { [namespace]: _, ...rest } = state.breadcrumbs;\n      return {\n        breadcrumbs: rest,\n      };\n    });\n  },\n\n  getBreadcrumbs: (namespace: string) => {\n    return get().breadcrumbs[namespace] || [];\n  },\n}));\n\n/**\n * Hook customizado para facilitar o uso de breadcrumbs\n *\n * @param namespace - Identificador único para esta instância de breadcrumbs\n * @returns Objeto com breadcrumbs e métodos para manipulá-los\n *\n * @example\n * ```tsx\n * const { breadcrumbs, setBreadcrumbs, addBreadcrumb } = useBreadcrumb('performance');\n *\n * // Definir breadcrumbs iniciais\n * setBreadcrumbs([\n *   { id: 'home', name: 'Home', url: '/' },\n *   { id: 'page', name: 'Page', url: '/page' }\n * ]);\n *\n * // Adicionar novo breadcrumb\n * addBreadcrumb({ id: 'detail', name: 'Detail', url: '/page/detail' });\n * ```\n */\nexport const useBreadcrumb = (namespace: string) => {\n  const store = useBreadcrumbStore();\n  const breadcrumbs = store.breadcrumbs[namespace] || [];\n\n  return {\n    breadcrumbs,\n\n    /**\n     * Define todos os breadcrumbs de uma vez\n     */\n    setBreadcrumbs: (items: BreadcrumbItem[]) => {\n      store.setBreadcrumbs(namespace, items);\n    },\n\n    /**\n     * Adiciona um novo breadcrumb ao final\n     */\n    addBreadcrumb: (item: BreadcrumbItem) => {\n      store.addBreadcrumb(namespace, item);\n    },\n\n    /**\n     * Atualiza um breadcrumb existente\n     */\n    updateBreadcrumb: (itemId: string, updates: Partial<BreadcrumbItem>) => {\n      store.updateBreadcrumb(namespace, itemId, updates);\n    },\n\n    /**\n     * Remove um breadcrumb e todos os seguintes\n     */\n    removeBreadcrumbFrom: (itemId: string) => {\n      store.removeBreadcrumbFrom(namespace, itemId);\n    },\n\n    /**\n     * Mantém apenas os breadcrumbs até o índice especificado (inclusivo)\n     */\n    sliceBreadcrumbs: (index: number) => {\n      store.sliceBreadcrumbs(namespace, index);\n    },\n\n    /**\n     * Limpa todos os breadcrumbs\n     */\n    clearBreadcrumbs: () => {\n      store.clearBreadcrumbs(namespace);\n    },\n  };\n};\n"],"mappings":"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","names":[]}