@iclips/ui 2.0.2 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/MIGRATION-v3.md +244 -0
  2. package/README.md +1 -1
  3. package/dist/alert-theme.css +20 -79
  4. package/dist/components/ui/charts/donut-chart.cjs +1 -1
  5. package/dist/components/ui/charts/donut-chart.cjs.map +1 -1
  6. package/dist/components/ui/charts/donut-chart.js +39 -60
  7. package/dist/components/ui/charts/donut-chart.js.map +1 -1
  8. package/dist/components/ui/charts/kpi-card.cjs +1 -1
  9. package/dist/components/ui/charts/kpi-card.cjs.map +1 -1
  10. package/dist/components/ui/charts/kpi-card.js +19 -19
  11. package/dist/components/ui/charts/kpi-card.js.map +1 -1
  12. package/dist/components/ui/data/comment-system.cjs +1 -1
  13. package/dist/components/ui/data/comment-system.cjs.map +1 -1
  14. package/dist/components/ui/data/comment-system.js +67 -67
  15. package/dist/components/ui/data/comment-system.js.map +1 -1
  16. package/dist/components/ui/data/data-table.cjs +1 -1
  17. package/dist/components/ui/data/data-table.cjs.map +1 -1
  18. package/dist/components/ui/data/data-table.js +112 -101
  19. package/dist/components/ui/data/data-table.js.map +1 -1
  20. package/dist/components/ui/data/editorial-calendar.cjs +1 -1
  21. package/dist/components/ui/data/editorial-calendar.cjs.map +1 -1
  22. package/dist/components/ui/data/editorial-calendar.js +291 -291
  23. package/dist/components/ui/data/editorial-calendar.js.map +1 -1
  24. package/dist/components/ui/data/filter-builder.cjs +1 -1
  25. package/dist/components/ui/data/filter-builder.cjs.map +1 -1
  26. package/dist/components/ui/data/filter-builder.js +1 -1
  27. package/dist/components/ui/data/filter-builder.js.map +1 -1
  28. package/dist/components/ui/feedback/empty-state.cjs +1 -1
  29. package/dist/components/ui/feedback/empty-state.cjs.map +1 -1
  30. package/dist/components/ui/feedback/empty-state.js +14 -14
  31. package/dist/components/ui/feedback/empty-state.js.map +1 -1
  32. package/dist/components/ui/feedback/toast.cjs +1 -1
  33. package/dist/components/ui/feedback/toast.cjs.map +1 -1
  34. package/dist/components/ui/feedback/toast.js +53 -22
  35. package/dist/components/ui/feedback/toast.js.map +1 -1
  36. package/dist/components/ui/forms/calendar.cjs +1 -1
  37. package/dist/components/ui/forms/calendar.cjs.map +1 -1
  38. package/dist/components/ui/forms/calendar.js +16 -16
  39. package/dist/components/ui/forms/calendar.js.map +1 -1
  40. package/dist/components/ui/forms/combobox.cjs +1 -1
  41. package/dist/components/ui/forms/combobox.cjs.map +1 -1
  42. package/dist/components/ui/forms/combobox.js +78 -76
  43. package/dist/components/ui/forms/combobox.js.map +1 -1
  44. package/dist/components/ui/forms/file-attachment-list.cjs +1 -1
  45. package/dist/components/ui/forms/file-attachment-list.cjs.map +1 -1
  46. package/dist/components/ui/forms/file-attachment-list.js +4 -4
  47. package/dist/components/ui/forms/file-attachment-list.js.map +1 -1
  48. package/dist/components/ui/forms/file-upload-zone.cjs +2 -2
  49. package/dist/components/ui/forms/file-upload-zone.cjs.map +1 -1
  50. package/dist/components/ui/forms/file-upload-zone.js +55 -49
  51. package/dist/components/ui/forms/file-upload-zone.js.map +1 -1
  52. package/dist/components/ui/forms/form.cjs +1 -1
  53. package/dist/components/ui/forms/form.cjs.map +1 -1
  54. package/dist/components/ui/forms/form.js +11 -11
  55. package/dist/components/ui/forms/form.js.map +1 -1
  56. package/dist/components/ui/forms/input-validation.cjs +1 -1
  57. package/dist/components/ui/forms/input-validation.cjs.map +1 -1
  58. package/dist/components/ui/forms/input-validation.js +20 -20
  59. package/dist/components/ui/forms/input-validation.js.map +1 -1
  60. package/dist/components/ui/forms/multi-select.cjs +1 -1
  61. package/dist/components/ui/forms/multi-select.cjs.map +1 -1
  62. package/dist/components/ui/forms/multi-select.js +69 -67
  63. package/dist/components/ui/forms/multi-select.js.map +1 -1
  64. package/dist/components/ui/forms/radio-group.cjs +1 -1
  65. package/dist/components/ui/forms/radio-group.cjs.map +1 -1
  66. package/dist/components/ui/forms/radio-group.js +19 -19
  67. package/dist/components/ui/forms/radio-group.js.map +1 -1
  68. package/dist/components/ui/forms/social-button.cjs +1 -1
  69. package/dist/components/ui/forms/social-button.cjs.map +1 -1
  70. package/dist/components/ui/forms/social-button.js +6 -6
  71. package/dist/components/ui/forms/social-button.js.map +1 -1
  72. package/dist/components/ui/forms/toggle.cjs +1 -1
  73. package/dist/components/ui/forms/toggle.cjs.map +1 -1
  74. package/dist/components/ui/forms/toggle.js +7 -7
  75. package/dist/components/ui/forms/toggle.js.map +1 -1
  76. package/dist/components/ui/navigation/navigation-menu.cjs +1 -1
  77. package/dist/components/ui/navigation/navigation-menu.cjs.map +1 -1
  78. package/dist/components/ui/navigation/navigation-menu.js +14 -14
  79. package/dist/components/ui/navigation/navigation-menu.js.map +1 -1
  80. package/dist/components/ui/navigation/sidebar.cjs +1 -1
  81. package/dist/components/ui/navigation/sidebar.cjs.map +1 -1
  82. package/dist/components/ui/navigation/sidebar.js +44 -44
  83. package/dist/components/ui/navigation/sidebar.js.map +1 -1
  84. package/dist/components/ui/overlays/context-menu.cjs +1 -1
  85. package/dist/components/ui/overlays/context-menu.cjs.map +1 -1
  86. package/dist/components/ui/overlays/context-menu.js +1 -1
  87. package/dist/components/ui/overlays/context-menu.js.map +1 -1
  88. package/dist/components/ui/overlays/dropdown-menu.cjs +1 -1
  89. package/dist/components/ui/overlays/dropdown-menu.cjs.map +1 -1
  90. package/dist/components/ui/overlays/dropdown-menu.js +5 -5
  91. package/dist/components/ui/overlays/dropdown-menu.js.map +1 -1
  92. package/dist/components/ui/overlays/menubar.cjs +1 -1
  93. package/dist/components/ui/overlays/menubar.cjs.map +1 -1
  94. package/dist/components/ui/overlays/menubar.js +29 -29
  95. package/dist/components/ui/overlays/menubar.js.map +1 -1
  96. package/dist/components/ui/overlays/tooltip.cjs +1 -1
  97. package/dist/components/ui/overlays/tooltip.cjs.map +1 -1
  98. package/dist/components/ui/overlays/tooltip.js +12 -12
  99. package/dist/components/ui/overlays/tooltip.js.map +1 -1
  100. package/dist/components/ui/primitives/avatar.cjs +1 -1
  101. package/dist/components/ui/primitives/avatar.cjs.map +1 -1
  102. package/dist/components/ui/primitives/avatar.js +20 -27
  103. package/dist/components/ui/primitives/avatar.js.map +1 -1
  104. package/dist/components/ui/primitives/badge.cjs +1 -1
  105. package/dist/components/ui/primitives/badge.cjs.map +1 -1
  106. package/dist/components/ui/primitives/badge.js +13 -13
  107. package/dist/components/ui/primitives/badge.js.map +1 -1
  108. package/dist/components/ui/primitives/button.cjs +1 -1
  109. package/dist/components/ui/primitives/button.cjs.map +1 -1
  110. package/dist/components/ui/primitives/button.js +11 -8
  111. package/dist/components/ui/primitives/button.js.map +1 -1
  112. package/dist/index.cjs +1 -1
  113. package/dist/index.css +1 -1
  114. package/dist/index.d.cts +3 -3
  115. package/dist/index.d.ts +3 -3
  116. package/dist/index.js +34 -35
  117. package/dist/index.js.map +1 -1
  118. package/dist/preset.css +1 -2
  119. package/dist/toast-theme.css +100 -64
  120. package/dist/tokens.css +59 -159
  121. package/package.json +5 -3
  122. package/scripts/check-colors.mjs +208 -0
@@ -1 +1 @@
1
- {"version":3,"file":"combobox.js","sources":["../../../../src/components/ui/forms/combobox.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { Check, ChevronsUpDown, Search } from \"lucide-react\";\nimport { cn, mergeRefs } from \"../utils\";\nimport { Button } from \"../primitives/button\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../overlays/popover\";\nimport { Input } from \"./input\";\n\nexport interface ComboboxOption {\n value: string;\n label: string;\n disabled?: boolean;\n}\n\nexport interface ComboboxGroup {\n /**\n * Rótulo do grupo — renderizado em negrito e caixa alta\n */\n label: string;\n\n /**\n * Quando presente, o cabeçalho do grupo é selecionável e representa o próprio grupo.\n * Sem `value`, o cabeçalho é apenas um rótulo visual não clicável.\n */\n value?: string;\n\n /**\n * Opções pertencentes ao grupo — renderizadas indentadas, em peso normal\n */\n options: ComboboxOption[];\n}\n\nexport interface ComboboxProps {\n /** Rótulo acessível do gatilho quando não há `<Label>` associado */\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n\n /**\n * Valor selecionado atual\n */\n value?: string;\n\n /**\n * Callback quando o valor muda\n */\n onValueChange?: (value: string) => void;\n\n /**\n * Lista de opções disponíveis.\n * Use `options` OU `groups` — nunca os dois ao mesmo tempo.\n */\n options?: ComboboxOption[];\n\n /**\n * Opções agrupadas hierarquicamente.\n * Use `options` OU `groups` — nunca os dois ao mesmo tempo.\n */\n groups?: ComboboxGroup[];\n\n /**\n * Placeholder quando nenhum valor está selecionado\n */\n placeholder?: string;\n \n /**\n * Placeholder do campo de busca\n */\n searchPlaceholder?: string;\n \n /**\n * Mensagem quando não há resultados\n */\n emptyMessage?: string;\n \n /**\n * Se o campo está desabilitado\n */\n disabled?: boolean;\n \n /**\n * Se está carregando opções\n */\n loading?: boolean;\n \n /**\n * Classes adicionais para o trigger\n */\n className?: string;\n \n /**\n * Largura do popover (padrão: mesma largura do trigger)\n */\n popoverWidth?: string | number;\n \n /**\n * Altura máxima da lista de opções\n */\n maxHeight?: string;\n \n /**\n * Alinhamento do popover\n */\n align?: \"start\" | \"center\" | \"end\";\n \n /**\n * Se deve permitir limpar seleção\n */\n clearable?: boolean;\n\n /**\n * Função customizada de filtro\n */\n filterFn?: (option: ComboboxOption, searchTerm: string) => boolean;\n}\n\n/**\n * ComboBox - Componente de seleção com busca\n * \n * Combina um Select tradicional com capacidade de pesquisa.\n * Ideal para listas grandes onde o usuário precisa buscar valores.\n *\n * @example\n * ```tsx\n * // Lista plana\n * <Combobox\n * value={clienteId}\n * onValueChange={setClienteId}\n * options={clientes}\n * placeholder=\"Selecione o cliente\"\n * searchPlaceholder=\"Buscar cliente...\"\n * />\n *\n * // Lista hierárquica — grupos selecionáveis com seus clientes indentados\n * <Combobox\n * value={selecao}\n * onValueChange={setSelecao}\n * groups={grupos.map(g => ({\n * label: g.nomeGrupo,\n * value: `g-${g.grupoClienteId}`,\n * options: g.clientes.map(c => ({ value: String(c.id), label: c.nome })),\n * }))}\n * />\n * ```\n */\nexport const Combobox = React.forwardRef<\n React.ElementRef<typeof Button>,\n ComboboxProps\n>(({\n value,\n onValueChange,\n options,\n groups,\n placeholder = \"Selecionar...\",\n searchPlaceholder = \"Buscar...\",\n emptyMessage = \"Nenhum resultado encontrado\",\n disabled = false,\n loading = false,\n className,\n popoverWidth,\n maxHeight = \"300px\",\n align = \"start\",\n clearable = false,\n filterFn,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledby,\n}, ref) => {\n const [open, setOpen] = React.useState(false);\n const [searchTerm, setSearchTerm] = React.useState(\"\");\n const triggerRef = React.useRef<HTMLButtonElement>(null);\n const mergedTriggerRef = React.useMemo(() => mergeRefs(triggerRef, ref), [ref]);\n\n // Função de filtro padrão\n const defaultFilterFn = (option: ComboboxOption, term: string) => {\n const searchLower = term.toLowerCase();\n return (\n option.label.toLowerCase().includes(searchLower) ||\n option.value.toLowerCase().includes(searchLower)\n );\n };\n\n const filter = filterFn || defaultFilterFn;\n\n // Filtrar opções baseado no termo de busca\n const filteredOptions = React.useMemo(() => {\n if (!options) return [];\n if (!searchTerm) return options;\n return options.filter((option) => filter(option, searchTerm));\n }, [options, searchTerm, filter]);\n\n // Filtrar grupos preservando a hierarquia: um grupo permanece visível quando o próprio\n // rótulo casa com a busca (com todas as suas opções) ou quando alguma opção casa.\n const filteredGroups = React.useMemo(() => {\n if (!groups) return undefined;\n if (!searchTerm) return groups;\n\n const termLower = searchTerm.toLowerCase();\n\n return groups\n .map((group) => {\n if (group.label.toLowerCase().includes(termLower)) return group;\n return { ...group, options: group.options.filter((o) => filter(o, searchTerm)) };\n })\n .filter(\n (group) =>\n group.options.length > 0 || group.label.toLowerCase().includes(termLower)\n );\n }, [groups, searchTerm, filter]);\n\n // Todas as opções selecionáveis — inclui os cabeçalhos de grupo que têm `value`,\n // para que o trigger consiga exibir o rótulo de um grupo selecionado.\n const allOptions = React.useMemo<ComboboxOption[]>(() => {\n if (groups) {\n return groups.flatMap((group) => [\n ...(group.value ? [{ value: group.value, label: group.label }] : []),\n ...group.options,\n ]);\n }\n return options ?? [];\n }, [options, groups]);\n\n // Encontrar a opção selecionada\n const selectedOption = allOptions.find((option) => option.value === value);\n\n const hasResults = groups\n ? (filteredGroups?.length ?? 0) > 0\n : filteredOptions.length > 0;\n\n // Resetar busca ao fechar\n const handleOpenChange = (newOpen: boolean) => {\n setOpen(newOpen);\n if (!newOpen) {\n setSearchTerm(\"\");\n }\n };\n\n // Selecionar opção\n const handleSelect = (selectedValue: string) => {\n if (value === selectedValue && clearable) {\n onValueChange?.(\"\");\n } else {\n onValueChange?.(selectedValue);\n }\n setOpen(false);\n };\n\n return (\n <Popover open={open} onOpenChange={handleOpenChange}>\n <PopoverTrigger asChild>\n <Button\n ref={mergedTriggerRef}\n variant=\"outline\"\n role=\"combobox\"\n aria-expanded={open}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledby}\n className={cn(\n \"w-full justify-between font-normal\",\n !value && \"text-muted-foreground\",\n className\n )}\n disabled={disabled || loading}\n >\n <span className=\"truncate\">\n {loading\n ? \"Carregando...\"\n : selectedOption\n ? selectedOption.label\n : placeholder}\n </span>\n <ChevronsUpDown className=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent\n className=\"overflow-hidden p-0\"\n style={{\n width: popoverWidth || triggerRef.current?.offsetWidth || 'auto',\n }}\n align={align}\n >\n <div className=\"flex flex-col overflow-hidden\">\n {/* Search Input */}\n <div className=\"flex items-center border-b px-3\">\n <Search className=\"mr-2 h-4 w-4 shrink-0 opacity-50\" />\n <Input\n placeholder={searchPlaceholder}\n value={searchTerm}\n onChange={(e) => setSearchTerm(e.target.value)}\n className=\"h-11 border-0 focus-visible:ring-0 focus-visible:ring-offset-0\"\n autoFocus\n />\n </div>\n\n {/* Options List */}\n <div\n className=\"overflow-y-auto overflow-x-hidden overscroll-contain [&::-webkit-scrollbar]:w-2.5 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-primary/30 [&::-webkit-scrollbar-thumb:hover]:bg-primary/50\"\n style={{ maxHeight }}\n onWheel={(e) => e.stopPropagation()}\n onTouchMove={(e) => e.stopPropagation()}\n >\n <div className=\"p-1\">\n {!hasResults ? (\n <div className=\"py-6 text-center text-sm text-muted-foreground\">\n {emptyMessage}\n </div>\n ) : groups ? (\n // Itens de grupo usam <button> nativo, não o componente Button: a variante\n // `has-[>svg]:px-3` do Button entra em conflito com o recuo dos filhos e\n // anula a indentação. Mesmo padrão adotado no MultiSelect.\n filteredGroups?.map((group, groupIndex) => (\n <div\n key={group.value ?? group.label}\n className={cn(\n // Separador entre blocos de grupo\n groupIndex > 0 && \"mt-1.5 border-t border-border pt-1.5\"\n )}\n >\n {group.value ? (\n // Cabeçalho selecionável — representa o próprio grupo\n <button\n type=\"button\"\n onClick={() => handleSelect(group.value!)}\n className={cn(\n \"flex w-full items-center justify-between gap-2 rounded-sm px-2 py-1.5 text-sm\",\n \"font-semibold uppercase tracking-wide\",\n \"transition-colors duration-100 hover:bg-accent hover:text-accent-foreground\",\n value === group.value && \"bg-accent\"\n )}\n >\n <span className=\"truncate\">{group.label}</span>\n <Check\n className={cn(\n \"h-4 w-4 shrink-0\",\n value === group.value ? \"opacity-100\" : \"opacity-0\"\n )}\n />\n </button>\n ) : (\n // Cabeçalho apenas visual\n <div className=\"px-2 py-1.5 text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n {group.label}\n </div>\n )}\n {group.options.map((option) => (\n <button\n key={option.value}\n type=\"button\"\n onClick={() => handleSelect(option.value)}\n disabled={option.disabled}\n className={cn(\n \"flex w-full items-center justify-between gap-2 rounded-sm py-1.5 pl-6 pr-2 text-sm\",\n \"transition-colors duration-100 hover:bg-accent hover:text-accent-foreground\",\n \"disabled:pointer-events-none disabled:opacity-50\",\n value === option.value && \"bg-accent\"\n )}\n >\n <span className=\"truncate\">{option.label}</span>\n <Check\n className={cn(\n \"h-4 w-4 shrink-0\",\n value === option.value ? \"opacity-100\" : \"opacity-0\"\n )}\n />\n </button>\n ))}\n </div>\n ))\n ) : (\n filteredOptions.map((option) => (\n <Button\n key={option.value}\n variant=\"ghost\"\n className={cn(\n \"w-full justify-start font-normal\",\n value === option.value && \"bg-accent\"\n )}\n onClick={() => handleSelect(option.value)}\n disabled={option.disabled}\n >\n <Check\n className={cn(\n \"mr-2 h-4 w-4\",\n value === option.value ? \"opacity-100\" : \"opacity-0\"\n )}\n />\n <span className=\"truncate\">{option.label}</span>\n </Button>\n ))\n )}\n </div>\n </div>\n </div>\n </PopoverContent>\n </Popover>\n );\n});\nCombobox.displayName = \"Combobox\";\n"],"names":["Combobox","React","value","onValueChange","options","groups","placeholder","searchPlaceholder","emptyMessage","disabled","loading","className","popoverWidth","maxHeight","align","clearable","filterFn","ariaLabel","ariaLabelledby","ref","open","setOpen","searchTerm","setSearchTerm","triggerRef","mergedTriggerRef","mergeRefs","filter","option","term","searchLower","filteredOptions","filteredGroups","termLower","group","o","selectedOption","hasResults","handleOpenChange","newOpen","handleSelect","selectedValue","jsxs","Popover","jsx","PopoverTrigger","Button","cn","ChevronsUpDown","PopoverContent","_a","Search","Input","groupIndex","Check"],"mappings":";;;;;;;;AAiJO,MAAMA,IAAWC,EAAM,WAG5B,CAAC;AAAA,EACD,OAAAC;AAAA,EACA,eAAAC;AAAA,EACA,SAAAC;AAAA,EACA,QAAAC;AAAA,EACA,aAAAC,IAAc;AAAA,EACd,mBAAAC,IAAoB;AAAA,EACpB,cAAAC,IAAe;AAAA,EACf,UAAAC,IAAW;AAAA,EACX,SAAAC,IAAU;AAAA,EACV,WAAAC;AAAA,EACA,cAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,OAAAC,IAAQ;AAAA,EACR,WAAAC,IAAY;AAAA,EACZ,UAAAC;AAAA,EACA,cAAcC;AAAA,EACd,mBAAmBC;AACrB,GAAGC,MAAQ;;AACT,QAAM,CAACC,GAAMC,CAAO,IAAIpB,EAAM,SAAS,EAAK,GACtC,CAACqB,GAAYC,CAAa,IAAItB,EAAM,SAAS,EAAE,GAC/CuB,IAAavB,EAAM,OAA0B,IAAI,GACjDwB,IAAmBxB,EAAM,QAAQ,MAAMyB,EAAUF,GAAYL,CAAG,GAAG,CAACA,CAAG,CAAC,GAWxEQ,IAASX,MARS,CAACY,GAAwBC,MAAiB;AAChE,UAAMC,IAAcD,EAAK,YAAA;AACzB,WACED,EAAO,MAAM,YAAA,EAAc,SAASE,CAAW,KAC/CF,EAAO,MAAM,cAAc,SAASE,CAAW;AAAA,EAEnD,IAKMC,IAAkB9B,EAAM,QAAQ,MAC/BG,IACAkB,IACElB,EAAQ,OAAO,CAACwB,MAAWD,EAAOC,GAAQN,CAAU,CAAC,IADpClB,IADH,CAAA,GAGpB,CAACA,GAASkB,GAAYK,CAAM,CAAC,GAI1BK,IAAiB/B,EAAM,QAAQ,MAAM;AACzC,QAAI,CAACI,EAAQ;AACb,QAAI,CAACiB,EAAY,QAAOjB;AAExB,UAAM4B,IAAYX,EAAW,YAAA;AAE7B,WAAOjB,EACJ,IAAI,CAAC6B,MACAA,EAAM,MAAM,YAAA,EAAc,SAASD,CAAS,IAAUC,IACnD,EAAE,GAAGA,GAAO,SAASA,EAAM,QAAQ,OAAO,CAACC,MAAMR,EAAOQ,GAAGb,CAAU,CAAC,EAAA,CAC9E,EACA;AAAA,MACC,CAACY,MACCA,EAAM,QAAQ,SAAS,KAAKA,EAAM,MAAM,cAAc,SAASD,CAAS;AAAA,IAAA;AAAA,EAEhF,GAAG,CAAC5B,GAAQiB,GAAYK,CAAM,CAAC,GAezBS,IAXanC,EAAM,QAA0B,MAC7CI,IACKA,EAAO,QAAQ,CAAC6B,MAAU;AAAA,IAC/B,GAAIA,EAAM,QAAQ,CAAC,EAAE,OAAOA,EAAM,OAAO,OAAOA,EAAM,MAAA,CAAO,IAAI,CAAA;AAAA,IACjE,GAAGA,EAAM;AAAA,EAAA,CACV,IAEI9B,KAAW,CAAA,GACjB,CAACA,GAASC,CAAM,CAAC,EAGc,KAAK,CAACuB,MAAWA,EAAO,UAAU1B,CAAK,GAEnEmC,IAAahC,MACd2B,KAAA,gBAAAA,EAAgB,WAAU,KAAK,IAChCD,EAAgB,SAAS,GAGvBO,IAAmB,CAACC,MAAqB;AAC7C,IAAAlB,EAAQkB,CAAO,GACVA,KACHhB,EAAc,EAAE;AAAA,EAEpB,GAGMiB,IAAe,CAACC,MAA0B;AAC9C,IAAIvC,MAAUuC,KAAiB1B,IAC7BZ,KAAA,QAAAA,EAAgB,MAEhBA,KAAA,QAAAA,EAAgBsC,IAElBpB,EAAQ,EAAK;AAAA,EACf;AAEA,SACE,gBAAAqB,EAACC,GAAA,EAAQ,MAAAvB,GAAY,cAAckB,GACjC,UAAA;AAAA,IAAA,gBAAAM,EAACC,GAAA,EAAe,SAAO,IACrB,UAAA,gBAAAH;AAAA,MAACI;AAAA,MAAA;AAAA,QACC,KAAKrB;AAAA,QACL,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,iBAAeL;AAAA,QACf,cAAYH;AAAA,QACZ,mBAAiBC;AAAA,QACjB,WAAW6B;AAAA,UACT;AAAA,UACA,CAAC7C,KAAS;AAAA,UACVS;AAAA,QAAA;AAAA,QAEF,UAAUF,KAAYC;AAAA,QAEtB,UAAA;AAAA,UAAA,gBAAAkC,EAAC,QAAA,EAAK,WAAU,YACb,UAAAlC,IACG,kBACA0B,IACAA,EAAe,QACf9B,EAAA,CACN;AAAA,UACA,gBAAAsC,EAACI,GAAA,EAAe,WAAU,mCAAA,CAAmC;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA,GAEjE;AAAA,IACA,gBAAAJ;AAAA,MAACK;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO;AAAA,UACL,OAAOrC,OAAgBsC,IAAA1B,EAAW,YAAX,gBAAA0B,EAAoB,gBAAe;AAAA,QAAA;AAAA,QAE5D,OAAApC;AAAA,QAEA,UAAA,gBAAA4B,EAAC,OAAA,EAAI,WAAU,iCAEb,UAAA;AAAA,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,mCACb,UAAA;AAAA,YAAA,gBAAAE,EAACO,GAAA,EAAO,WAAU,mCAAA,CAAmC;AAAA,YACrD,gBAAAP;AAAA,cAACQ;AAAA,cAAA;AAAA,gBACC,aAAa7C;AAAA,gBACb,OAAOe;AAAA,gBACP,UAAU,CAAC,MAAMC,EAAc,EAAE,OAAO,KAAK;AAAA,gBAC7C,WAAU;AAAA,gBACV,WAAS;AAAA,cAAA;AAAA,YAAA;AAAA,UACX,GACF;AAAA,UAGA,gBAAAqB;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO,EAAE,WAAA/B,EAAA;AAAA,cACT,SAAS,CAAC,MAAM,EAAE,gBAAA;AAAA,cAClB,aAAa,CAAC,MAAM,EAAE,gBAAA;AAAA,cAEtB,UAAA,gBAAA+B,EAAC,OAAA,EAAI,WAAU,OACZ,UAACP,IAIEhC;AAAA;AAAA;AAAA;AAAA,gBAIF2B,KAAA,gBAAAA,EAAgB,IAAI,CAACE,GAAOmB,MAC1B,gBAAAX;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBAEC,WAAWK;AAAA;AAAA,sBAETM,IAAa,KAAK;AAAA,oBAAA;AAAA,oBAGnB,UAAA;AAAA,sBAAAnB,EAAM;AAAA;AAAA,wBAEL,gBAAAQ;AAAA,0BAAC;AAAA,0BAAA;AAAA,4BACC,MAAK;AAAA,4BACL,SAAS,MAAMF,EAAaN,EAAM,KAAM;AAAA,4BACxC,WAAWa;AAAA,8BACT;AAAA,8BACA;AAAA,8BACA;AAAA,8BACA7C,MAAUgC,EAAM,SAAS;AAAA,4BAAA;AAAA,4BAG3B,UAAA;AAAA,8BAAA,gBAAAU,EAAC,QAAA,EAAK,WAAU,YAAY,UAAAV,EAAM,OAAM;AAAA,8BACxC,gBAAAU;AAAA,gCAACU;AAAA,gCAAA;AAAA,kCACC,WAAWP;AAAA,oCACT;AAAA,oCACA7C,MAAUgC,EAAM,QAAQ,gBAAgB;AAAA,kCAAA;AAAA,gCAC1C;AAAA,8BAAA;AAAA,4BACF;AAAA,0BAAA;AAAA,wBAAA;AAAA;AAAA;AAAA,wBAIF,gBAAAU,EAAC,OAAA,EAAI,WAAU,mFACZ,YAAM,MAAA,CACT;AAAA;AAAA,sBAEDV,EAAM,QAAQ,IAAI,CAACN,MAClB,gBAAAc;AAAA,wBAAC;AAAA,wBAAA;AAAA,0BAEC,MAAK;AAAA,0BACL,SAAS,MAAMF,EAAaZ,EAAO,KAAK;AAAA,0BACxC,UAAUA,EAAO;AAAA,0BACjB,WAAWmB;AAAA,4BACT;AAAA,4BACA;AAAA,4BACA;AAAA,4BACA7C,MAAU0B,EAAO,SAAS;AAAA,0BAAA;AAAA,0BAG5B,UAAA;AAAA,4BAAA,gBAAAgB,EAAC,QAAA,EAAK,WAAU,YAAY,UAAAhB,EAAO,OAAM;AAAA,4BACzC,gBAAAgB;AAAA,8BAACU;AAAA,8BAAA;AAAA,gCACC,WAAWP;AAAA,kCACT;AAAA,kCACA7C,MAAU0B,EAAO,QAAQ,gBAAgB;AAAA,gCAAA;AAAA,8BAC3C;AAAA,4BAAA;AAAA,0BACF;AAAA,wBAAA;AAAA,wBAjBKA,EAAO;AAAA,sBAAA,CAmBf;AAAA,oBAAA;AAAA,kBAAA;AAAA,kBArDIM,EAAM,SAASA,EAAM;AAAA,gBAAA;AAAA,kBAyD9BH,EAAgB,IAAI,CAACH,MACnB,gBAAAc;AAAA,gBAACI;AAAA,gBAAA;AAAA,kBAEC,SAAQ;AAAA,kBACR,WAAWC;AAAA,oBACT;AAAA,oBACA7C,MAAU0B,EAAO,SAAS;AAAA,kBAAA;AAAA,kBAE5B,SAAS,MAAMY,EAAaZ,EAAO,KAAK;AAAA,kBACxC,UAAUA,EAAO;AAAA,kBAEjB,UAAA;AAAA,oBAAA,gBAAAgB;AAAA,sBAACU;AAAA,sBAAA;AAAA,wBACC,WAAWP;AAAA,0BACT;AAAA,0BACA7C,MAAU0B,EAAO,QAAQ,gBAAgB;AAAA,wBAAA;AAAA,sBAC3C;AAAA,oBAAA;AAAA,oBAEF,gBAAAgB,EAAC,QAAA,EAAK,WAAU,YAAY,YAAO,MAAA,CAAM;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAfpChB,EAAO;AAAA,cAAA,CAiBf,IArFD,gBAAAgB,EAAC,OAAA,EAAI,WAAU,kDACZ,UAAApC,EAAA,CACH,EAmFC,CAEL;AAAA,YAAA;AAAA,UAAA;AAAA,QACF,EAAA,CACF;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GACF;AAEJ,CAAC;AACDR,EAAS,cAAc;"}
1
+ {"version":3,"file":"combobox.js","sources":["../../../../src/components/ui/forms/combobox.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { Check, ChevronsUpDown, Search } from \"lucide-react\";\nimport { cn, mergeRefs } from \"../utils\";\nimport { Button } from \"../primitives/button\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../overlays/popover\";\nimport { Input } from \"./input\";\n\nexport interface ComboboxOption {\n value: string;\n label: string;\n disabled?: boolean;\n}\n\nexport interface ComboboxGroup {\n /**\n * Rótulo do grupo — renderizado em negrito e caixa alta\n */\n label: string;\n\n /**\n * Quando presente, o cabeçalho do grupo é selecionável e representa o próprio grupo.\n * Sem `value`, o cabeçalho é apenas um rótulo visual não clicável.\n */\n value?: string;\n\n /**\n * Opções pertencentes ao grupo — renderizadas indentadas, em peso normal\n */\n options: ComboboxOption[];\n}\n\nexport interface ComboboxProps {\n /** Rótulo acessível do gatilho quando não há `<Label>` associado */\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n\n /**\n * Valor selecionado atual\n */\n value?: string;\n\n /**\n * Callback quando o valor muda\n */\n onValueChange?: (value: string) => void;\n\n /**\n * Lista de opções disponíveis.\n * Use `options` OU `groups` — nunca os dois ao mesmo tempo.\n */\n options?: ComboboxOption[];\n\n /**\n * Opções agrupadas hierarquicamente.\n * Use `options` OU `groups` — nunca os dois ao mesmo tempo.\n */\n groups?: ComboboxGroup[];\n\n /**\n * Placeholder quando nenhum valor está selecionado\n */\n placeholder?: string;\n \n /**\n * Placeholder do campo de busca\n */\n searchPlaceholder?: string;\n \n /**\n * Mensagem quando não há resultados\n */\n emptyMessage?: string;\n \n /**\n * Se o campo está desabilitado\n */\n disabled?: boolean;\n \n /**\n * Se está carregando opções\n */\n loading?: boolean;\n \n /**\n * Classes adicionais para o trigger\n */\n className?: string;\n \n /**\n * Largura do popover (padrão: mesma largura do trigger)\n */\n popoverWidth?: string | number;\n \n /**\n * Altura máxima da lista de opções\n */\n maxHeight?: string;\n \n /**\n * Alinhamento do popover\n */\n align?: \"start\" | \"center\" | \"end\";\n \n /**\n * Se deve permitir limpar seleção\n */\n clearable?: boolean;\n\n /**\n * Função customizada de filtro\n */\n filterFn?: (option: ComboboxOption, searchTerm: string) => boolean;\n}\n\n/**\n * ComboBox - Componente de seleção com busca\n * \n * Combina um Select tradicional com capacidade de pesquisa.\n * Ideal para listas grandes onde o usuário precisa buscar valores.\n *\n * @example\n * ```tsx\n * // Lista plana\n * <Combobox\n * value={clienteId}\n * onValueChange={setClienteId}\n * options={clientes}\n * placeholder=\"Selecione o cliente\"\n * searchPlaceholder=\"Buscar cliente...\"\n * />\n *\n * // Lista hierárquica — grupos selecionáveis com seus clientes indentados\n * <Combobox\n * value={selecao}\n * onValueChange={setSelecao}\n * groups={grupos.map(g => ({\n * label: g.nomeGrupo,\n * value: `g-${g.grupoClienteId}`,\n * options: g.clientes.map(c => ({ value: String(c.id), label: c.nome })),\n * }))}\n * />\n * ```\n */\nexport const Combobox = React.forwardRef<\n React.ElementRef<typeof Button>,\n ComboboxProps\n>(({\n value,\n onValueChange,\n options,\n groups,\n placeholder = \"Selecionar...\",\n searchPlaceholder = \"Buscar...\",\n emptyMessage = \"Nenhum resultado encontrado\",\n disabled = false,\n loading = false,\n className,\n popoverWidth,\n maxHeight = \"300px\",\n align = \"start\",\n clearable = false,\n filterFn,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledby,\n}, ref) => {\n const [open, setOpen] = React.useState(false);\n const [searchTerm, setSearchTerm] = React.useState(\"\");\n const triggerRef = React.useRef<HTMLButtonElement>(null);\n const mergedTriggerRef = React.useMemo(() => mergeRefs(triggerRef, ref), [ref]);\n\n // Função de filtro padrão\n const defaultFilterFn = (option: ComboboxOption, term: string) => {\n const searchLower = term.toLowerCase();\n return (\n option.label.toLowerCase().includes(searchLower) ||\n option.value.toLowerCase().includes(searchLower)\n );\n };\n\n const filter = filterFn || defaultFilterFn;\n\n // Filtrar opções baseado no termo de busca\n const filteredOptions = React.useMemo(() => {\n if (!options) return [];\n if (!searchTerm) return options;\n return options.filter((option) => filter(option, searchTerm));\n }, [options, searchTerm, filter]);\n\n // Filtrar grupos preservando a hierarquia: um grupo permanece visível quando o próprio\n // rótulo casa com a busca (com todas as suas opções) ou quando alguma opção casa.\n const filteredGroups = React.useMemo(() => {\n if (!groups) return undefined;\n if (!searchTerm) return groups;\n\n const termLower = searchTerm.toLowerCase();\n\n return groups\n .map((group) => {\n if (group.label.toLowerCase().includes(termLower)) return group;\n return { ...group, options: group.options.filter((o) => filter(o, searchTerm)) };\n })\n .filter(\n (group) =>\n group.options.length > 0 || group.label.toLowerCase().includes(termLower)\n );\n }, [groups, searchTerm, filter]);\n\n // Todas as opções selecionáveis — inclui os cabeçalhos de grupo que têm `value`,\n // para que o trigger consiga exibir o rótulo de um grupo selecionado.\n const allOptions = React.useMemo<ComboboxOption[]>(() => {\n if (groups) {\n return groups.flatMap((group) => [\n ...(group.value ? [{ value: group.value, label: group.label }] : []),\n ...group.options,\n ]);\n }\n return options ?? [];\n }, [options, groups]);\n\n // Encontrar a opção selecionada\n const selectedOption = allOptions.find((option) => option.value === value);\n\n const hasResults = groups\n ? (filteredGroups?.length ?? 0) > 0\n : filteredOptions.length > 0;\n\n // Resetar busca ao fechar\n const handleOpenChange = (newOpen: boolean) => {\n setOpen(newOpen);\n if (!newOpen) {\n setSearchTerm(\"\");\n }\n };\n\n // Selecionar opção\n const handleSelect = (selectedValue: string) => {\n if (value === selectedValue && clearable) {\n onValueChange?.(\"\");\n } else {\n onValueChange?.(selectedValue);\n }\n setOpen(false);\n };\n\n return (\n <Popover open={open} onOpenChange={handleOpenChange}>\n <PopoverTrigger asChild>\n <Button\n ref={mergedTriggerRef}\n variant=\"outline\"\n role=\"combobox\"\n aria-expanded={open}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledby}\n className={cn(\n \"w-full justify-between font-normal\",\n !value && \"text-muted-foreground\",\n className\n )}\n disabled={disabled || loading}\n >\n <span className=\"truncate\">\n {loading\n ? \"Carregando...\"\n : selectedOption\n ? selectedOption.label\n : placeholder}\n </span>\n <ChevronsUpDown className=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent\n className=\"overflow-hidden p-0\"\n style={{\n width: popoverWidth || triggerRef.current?.offsetWidth || 'auto',\n }}\n align={align}\n >\n <div className=\"flex flex-col overflow-hidden\">\n {/* Search Input */}\n <div className=\"flex items-center border-b px-3\">\n <Search className=\"mr-2 h-4 w-4 shrink-0 opacity-50\" />\n <Input\n placeholder={searchPlaceholder}\n value={searchTerm}\n onChange={(e) => setSearchTerm(e.target.value)}\n className=\"h-11 border-0 focus-visible:ring-0 focus-visible:ring-offset-0\"\n autoFocus\n />\n </div>\n\n {/* Options List */}\n <div\n className=\"overflow-y-auto overflow-x-hidden overscroll-contain [&::-webkit-scrollbar]:w-2.5 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-primary/30 [&::-webkit-scrollbar-thumb:hover]:bg-primary/50\"\n style={{ maxHeight }}\n onWheel={(e) => e.stopPropagation()}\n onTouchMove={(e) => e.stopPropagation()}\n >\n <div className=\"p-1\">\n {!hasResults ? (\n <div className=\"py-6 text-center text-sm text-muted-foreground\">\n {emptyMessage}\n </div>\n ) : groups ? (\n // Itens de grupo usam <button> nativo, não o componente Button: a variante\n // `has-[>svg]:px-3` do Button entra em conflito com o recuo dos filhos e\n // anula a indentação. Mesmo padrão adotado no MultiSelect.\n filteredGroups?.map((group, groupIndex) => (\n <div\n key={group.value ?? group.label}\n className={cn(\n // Separador entre blocos de grupo\n groupIndex > 0 && \"mt-1.5 border-t border-border pt-1.5\"\n )}\n >\n {group.value ? (\n // Cabeçalho selecionável — representa o próprio grupo\n <button\n type=\"button\"\n onClick={() => handleSelect(group.value!)}\n className={cn(\n \"flex w-full items-center justify-between gap-2 rounded-sm px-2 py-1.5 text-sm\",\n \"font-semibold uppercase tracking-wide\",\n \"transition-colors duration-100 hover:bg-accent hover:text-accent-foreground\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset\",\n value === group.value && \"bg-secondary text-secondary-foreground hover:bg-secondary hover:text-secondary-foreground\"\n )}\n >\n <span className=\"truncate\">{group.label}</span>\n <Check\n className={cn(\n \"h-4 w-4 shrink-0\",\n value === group.value ? \"opacity-100\" : \"opacity-0\"\n )}\n />\n </button>\n ) : (\n // Cabeçalho apenas visual\n <div className=\"px-2 py-1.5 text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n {group.label}\n </div>\n )}\n {group.options.map((option) => (\n <button\n key={option.value}\n type=\"button\"\n onClick={() => handleSelect(option.value)}\n disabled={option.disabled}\n className={cn(\n \"flex w-full items-center justify-between gap-2 rounded-sm py-1.5 pl-6 pr-2 text-sm\",\n \"transition-colors duration-100 hover:bg-accent hover:text-accent-foreground\",\n \"disabled:pointer-events-none disabled:opacity-50\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset\",\n value === option.value && \"bg-secondary text-secondary-foreground font-medium hover:bg-secondary hover:text-secondary-foreground\"\n )}\n >\n <span className=\"truncate\">{option.label}</span>\n <Check\n className={cn(\n \"h-4 w-4 shrink-0\",\n value === option.value ? \"opacity-100\" : \"opacity-0\"\n )}\n />\n </button>\n ))}\n </div>\n ))\n ) : (\n filteredOptions.map((option) => (\n <Button\n key={option.value}\n variant=\"ghost\"\n className={cn(\n \"w-full justify-start font-normal\",\n value === option.value && \"bg-secondary text-secondary-foreground font-medium hover:bg-secondary hover:text-secondary-foreground dark:hover:bg-secondary\"\n )}\n onClick={() => handleSelect(option.value)}\n disabled={option.disabled}\n >\n <Check\n className={cn(\n \"mr-2 h-4 w-4\",\n value === option.value ? \"opacity-100\" : \"opacity-0\"\n )}\n />\n <span className=\"truncate\">{option.label}</span>\n </Button>\n ))\n )}\n </div>\n </div>\n </div>\n </PopoverContent>\n </Popover>\n );\n});\nCombobox.displayName = \"Combobox\";\n"],"names":["Combobox","React","value","onValueChange","options","groups","placeholder","searchPlaceholder","emptyMessage","disabled","loading","className","popoverWidth","maxHeight","align","clearable","filterFn","ariaLabel","ariaLabelledby","ref","open","setOpen","searchTerm","setSearchTerm","triggerRef","mergedTriggerRef","mergeRefs","filter","option","term","searchLower","filteredOptions","filteredGroups","termLower","group","o","selectedOption","hasResults","handleOpenChange","newOpen","handleSelect","selectedValue","jsxs","Popover","jsx","PopoverTrigger","Button","cn","ChevronsUpDown","PopoverContent","_a","Search","Input","groupIndex","Check"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),l=require("lucide-react"),P=require("react"),g=require("../primitives/badge.cjs"),d=require("../primitives/button.cjs"),k=require("../primitives/progress.cjs"),r=require("../overlays/tooltip.cjs"),h=require("../utils.cjs");function $(t){return t?t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1)} KB`:t<1024*1024*1024?`${(t/(1024*1024)).toFixed(1)} MB`:`${(t/(1024*1024*1024)).toFixed(1)} GB`:""}function z(t){if(!t)return"";try{const i=new Date(t);return isNaN(i.getTime())?t:i.toLocaleDateString("pt-BR",{day:"2-digit",month:"2-digit",year:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return t}}function E(t,i){if(t.length<=i)return t;const a=t.lastIndexOf(".");if(a===-1)return t.substring(0,i-3)+"...";const n=t.substring(a);return t.substring(0,a).substring(0,i-n.length-3)+"..."+n}function F({attachments:t,onDownload:i,onRemove:a,onView:n,showDownload:x=!0,showRemove:p=!1,showView:v=!1,maxFilenameLength:C=40,variant:w="compact",emptyMessage:B="Nenhum anexo",isLoading:O=!1,className:j}){const[y,T]=P.useState({}),m=async(s,f,o)=>{if(!o)return;const u=s.chave||s.nomeOriginal;T(c=>({...c,[u]:f}));try{await o(s)}finally{T(c=>({...c,[u]:null}))}};return O?e.jsx("div",{className:h.cn("space-y-2",j),children:[1,2,3].map(s=>e.jsxs("div",{className:"flex items-center gap-2 p-3 border rounded bg-muted/30 animate-pulse",children:[e.jsx("div",{className:"h-4 w-4 bg-muted-foreground/20 rounded"}),e.jsx("div",{className:"h-4 flex-1 bg-muted-foreground/20 rounded"})]},s))}):t.length===0?e.jsx("div",{className:h.cn("text-center py-6 text-sm text-muted-foreground border rounded-lg bg-muted/20",j),children:B}):e.jsx("div",{className:h.cn("space-y-2",j),children:t.map((s,f)=>{const o=s.chave||s.id||`${s.nomeOriginal}-${f}`,u=y[s.chave||s.nomeOriginal],c=u==="download",N=u==="view",b=(()=>{switch(s.status){case"completed":return e.jsx(g.Badge,{variant:"outline",className:"bg-success/10 text-success-emphasis border-success/20 hover:bg-success/10",children:"✓ Enviado"});case"uploading":return e.jsx(g.Badge,{variant:"outline",className:"bg-info/10 text-info-emphasis border-info/20 hover:bg-info/10",children:"Enviando..."});case"failed":return e.jsx(g.Badge,{variant:"outline",className:"bg-destructive/10 text-destructive-emphasis border-destructive/20 hover:bg-destructive/10",children:"✗ Erro"});case"retrying":return e.jsx(g.Badge,{variant:"outline",className:"bg-warning/10 text-warning-emphasis border-warning/20 hover:bg-warning/10",children:"Tentando..."});default:return null}})();return w==="detailed"?e.jsx("div",{className:h.cn("p-4 border rounded-lg bg-card transition-colors",s.status==="failed"&&"border-destructive/30 bg-destructive/5"),children:e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"flex items-start gap-3 flex-1 min-w-0",children:[e.jsx(l.Paperclip,{className:"h-5 w-5 text-muted-foreground mt-0.5 flex-shrink-0"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx(r.TooltipProvider,{children:e.jsxs(r.Tooltip,{children:[e.jsx(r.TooltipTrigger,{asChild:!0,children:e.jsx("p",{className:"text-sm font-medium truncate",children:s.nomeOriginal})}),e.jsx(r.TooltipContent,{children:e.jsx("p",{className:"text-xs",children:s.nomeOriginal})})]})}),e.jsxs("div",{className:"flex items-center gap-2 mt-1 text-xs text-muted-foreground",children:[s.tamanhoBytes&&e.jsx("span",{children:$(s.tamanhoBytes)}),s.tamanhoBytes&&s.dataUpload&&e.jsx("span",{children:"•"}),s.dataUpload&&e.jsx("span",{children:z(s.dataUpload)})]}),s.status==="uploading"&&typeof s.progress=="number"&&e.jsx(k.Progress,{value:s.progress,className:"h-1 mt-2"}),s.status==="failed"&&s.erro&&e.jsxs("div",{className:"flex items-center gap-1 mt-2 text-xs text-destructive",children:[e.jsx(l.AlertCircle,{className:"h-3 w-3"}),e.jsx("span",{children:s.erro})]})]})]}),e.jsxs("div",{className:"flex items-center gap-2 flex-shrink-0",children:[b,s.status==="completed"&&e.jsxs(e.Fragment,{children:[v&&n&&e.jsx(r.TooltipProvider,{children:e.jsxs(r.Tooltip,{children:[e.jsx(r.TooltipTrigger,{asChild:!0,children:e.jsx(d.Button,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:()=>m(s,"view",n),disabled:N,"aria-label":`Visualizar ${s.nomeOriginal}`,children:e.jsx(l.Eye,{className:"h-4 w-4"})})}),e.jsx(r.TooltipContent,{children:"Visualizar"})]})}),x&&i&&e.jsx(r.TooltipProvider,{children:e.jsxs(r.Tooltip,{children:[e.jsx(r.TooltipTrigger,{asChild:!0,children:e.jsx(d.Button,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:()=>m(s,"download",i),disabled:c,"aria-label":`Baixar ${s.nomeOriginal}`,children:e.jsx(l.Download,{className:"h-4 w-4"})})}),e.jsx(r.TooltipContent,{children:"Baixar"})]})}),p&&a&&e.jsx(r.TooltipProvider,{children:e.jsxs(r.Tooltip,{children:[e.jsx(r.TooltipTrigger,{asChild:!0,children:e.jsx(d.Button,{variant:"ghost",size:"icon",className:"h-8 w-8 text-destructive hover:text-destructive",onClick:()=>a(s),"aria-label":`Remover ${s.nomeOriginal}`,children:e.jsx(l.Trash2,{className:"h-4 w-4"})})}),e.jsx(r.TooltipContent,{children:"Remover"})]})})]})]})]})},o):e.jsxs("div",{className:h.cn("flex items-center justify-between gap-2 p-3 border rounded-lg bg-muted/30 transition-colors",s.status==="failed"&&"border-destructive/30 bg-destructive/5"),children:[e.jsxs("div",{className:"flex items-center gap-2 flex-1 min-w-0",children:[e.jsx(l.Paperclip,{className:"h-4 w-4 text-muted-foreground flex-shrink-0"}),e.jsx(r.TooltipProvider,{children:e.jsxs(r.Tooltip,{children:[e.jsx(r.TooltipTrigger,{asChild:!0,children:e.jsx("span",{className:"text-sm truncate",children:E(s.nomeOriginal,C)})}),e.jsx(r.TooltipContent,{children:e.jsx("p",{className:"max-w-xs break-all",children:s.nomeOriginal})})]})}),s.status==="uploading"&&typeof s.progress=="number"&&e.jsxs("span",{className:"text-xs text-muted-foreground flex-shrink-0",children:[s.progress,"%"]}),b]}),s.status==="completed"&&e.jsxs("div",{className:"flex items-center gap-1 flex-shrink-0",children:[v&&n&&e.jsx(r.TooltipProvider,{children:e.jsxs(r.Tooltip,{children:[e.jsx(r.TooltipTrigger,{asChild:!0,children:e.jsx(d.Button,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:()=>m(s,"view",n),disabled:N,"aria-label":`Visualizar ${s.nomeOriginal}`,children:e.jsx(l.Eye,{className:"h-4 w-4"})})}),e.jsx(r.TooltipContent,{children:"Visualizar"})]})}),x&&i&&e.jsx(r.TooltipProvider,{children:e.jsxs(r.Tooltip,{children:[e.jsx(r.TooltipTrigger,{asChild:!0,children:e.jsx(d.Button,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:()=>m(s,"download",i),disabled:c,"aria-label":`Baixar ${s.nomeOriginal}`,children:e.jsx(l.Download,{className:"h-4 w-4"})})}),e.jsx(r.TooltipContent,{children:"Baixar"})]})}),p&&a&&e.jsx(r.TooltipProvider,{children:e.jsxs(r.Tooltip,{children:[e.jsx(r.TooltipTrigger,{asChild:!0,children:e.jsx(d.Button,{variant:"ghost",size:"icon",className:"h-8 w-8 text-destructive hover:text-destructive",onClick:()=>a(s),"aria-label":`Remover ${s.nomeOriginal}`,children:e.jsx(l.Trash2,{className:"h-4 w-4"})})}),e.jsx(r.TooltipContent,{children:"Remover"})]})})]}),s.status==="failed"&&s.erro&&e.jsx(r.TooltipProvider,{children:e.jsxs(r.Tooltip,{children:[e.jsx(r.TooltipTrigger,{asChild:!0,children:e.jsx(l.AlertCircle,{className:"h-4 w-4 text-destructive flex-shrink-0"})}),e.jsx(r.TooltipContent,{children:e.jsx("p",{className:"text-xs",children:s.erro})})]})})]},o)})})}exports.FileAttachmentList=F;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),l=require("lucide-react"),P=require("react"),g=require("../primitives/badge.cjs"),d=require("../primitives/button.cjs"),k=require("../primitives/progress.cjs"),r=require("../overlays/tooltip.cjs"),u=require("../utils.cjs");function $(t){return t?t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1)} KB`:t<1024*1024*1024?`${(t/(1024*1024)).toFixed(1)} MB`:`${(t/(1024*1024*1024)).toFixed(1)} GB`:""}function z(t){if(!t)return"";try{const i=new Date(t);return isNaN(i.getTime())?t:i.toLocaleDateString("pt-BR",{day:"2-digit",month:"2-digit",year:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return t}}function E(t,i){if(t.length<=i)return t;const a=t.lastIndexOf(".");if(a===-1)return t.substring(0,i-3)+"...";const n=t.substring(a);return t.substring(0,a).substring(0,i-n.length-3)+"..."+n}function F({attachments:t,onDownload:i,onRemove:a,onView:n,showDownload:x=!0,showRemove:p=!1,showView:v=!1,maxFilenameLength:C=40,variant:w="compact",emptyMessage:B="Nenhum anexo",isLoading:O=!1,className:j}){const[y,T]=P.useState({}),m=async(s,f,o)=>{if(!o)return;const h=s.chave||s.nomeOriginal;T(c=>({...c,[h]:f}));try{await o(s)}finally{T(c=>({...c,[h]:null}))}};return O?e.jsx("div",{className:u.cn("space-y-2",j),children:[1,2,3].map(s=>e.jsxs("div",{className:"flex items-center gap-2 p-3 border rounded bg-muted/30 animate-pulse",children:[e.jsx("div",{className:"h-4 w-4 bg-muted-foreground/20 rounded"}),e.jsx("div",{className:"h-4 flex-1 bg-muted-foreground/20 rounded"})]},s))}):t.length===0?e.jsx("div",{className:u.cn("text-center py-6 text-sm text-muted-foreground border rounded-lg bg-muted/20",j),children:B}):e.jsx("div",{className:u.cn("space-y-2",j),children:t.map((s,f)=>{const o=s.chave||s.id||`${s.nomeOriginal}-${f}`,h=y[s.chave||s.nomeOriginal],c=h==="download",N=h==="view",b=(()=>{switch(s.status){case"completed":return e.jsx(g.Badge,{variant:"outline",className:"bg-success/10 text-success-emphasis border-success/20 hover:bg-success/10",children:"✓ Enviado"});case"uploading":return e.jsx(g.Badge,{variant:"outline",className:"bg-info/10 text-info-emphasis border-info/20 hover:bg-info/10",children:"Enviando..."});case"failed":return e.jsx(g.Badge,{variant:"outline",className:"bg-destructive/10 text-destructive-emphasis border-destructive/20 hover:bg-destructive/10",children:"✗ Erro"});case"retrying":return e.jsx(g.Badge,{variant:"outline",className:"bg-warning/10 text-warning-emphasis border-warning/20 hover:bg-warning/10",children:"Tentando..."});default:return null}})();return w==="detailed"?e.jsx("div",{className:u.cn("p-4 border rounded-lg bg-card transition-colors",s.status==="failed"&&"border-destructive/30 bg-destructive/5"),children:e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"flex items-start gap-3 flex-1 min-w-0",children:[e.jsx(l.Paperclip,{className:"h-5 w-5 text-muted-foreground mt-0.5 flex-shrink-0"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx(r.TooltipProvider,{children:e.jsxs(r.Tooltip,{children:[e.jsx(r.TooltipTrigger,{asChild:!0,children:e.jsx("p",{className:"text-sm font-medium truncate",children:s.nomeOriginal})}),e.jsx(r.TooltipContent,{children:e.jsx("p",{className:"text-xs",children:s.nomeOriginal})})]})}),e.jsxs("div",{className:"flex items-center gap-2 mt-1 text-xs text-muted-foreground",children:[s.tamanhoBytes&&e.jsx("span",{children:$(s.tamanhoBytes)}),s.tamanhoBytes&&s.dataUpload&&e.jsx("span",{children:"•"}),s.dataUpload&&e.jsx("span",{children:z(s.dataUpload)})]}),s.status==="uploading"&&typeof s.progress=="number"&&e.jsx(k.Progress,{value:s.progress,className:"h-1 mt-2"}),s.status==="failed"&&s.erro&&e.jsxs("div",{className:"flex items-center gap-1 mt-2 text-xs text-destructive-emphasis",children:[e.jsx(l.AlertCircle,{className:"h-3 w-3"}),e.jsx("span",{children:s.erro})]})]})]}),e.jsxs("div",{className:"flex items-center gap-2 flex-shrink-0",children:[b,s.status==="completed"&&e.jsxs(e.Fragment,{children:[v&&n&&e.jsx(r.TooltipProvider,{children:e.jsxs(r.Tooltip,{children:[e.jsx(r.TooltipTrigger,{asChild:!0,children:e.jsx(d.Button,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:()=>m(s,"view",n),disabled:N,"aria-label":`Visualizar ${s.nomeOriginal}`,children:e.jsx(l.Eye,{className:"h-4 w-4"})})}),e.jsx(r.TooltipContent,{children:"Visualizar"})]})}),x&&i&&e.jsx(r.TooltipProvider,{children:e.jsxs(r.Tooltip,{children:[e.jsx(r.TooltipTrigger,{asChild:!0,children:e.jsx(d.Button,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:()=>m(s,"download",i),disabled:c,"aria-label":`Baixar ${s.nomeOriginal}`,children:e.jsx(l.Download,{className:"h-4 w-4"})})}),e.jsx(r.TooltipContent,{children:"Baixar"})]})}),p&&a&&e.jsx(r.TooltipProvider,{children:e.jsxs(r.Tooltip,{children:[e.jsx(r.TooltipTrigger,{asChild:!0,children:e.jsx(d.Button,{variant:"ghost",size:"icon",className:"h-8 w-8 text-destructive-emphasis hover:text-destructive-emphasis",onClick:()=>a(s),"aria-label":`Remover ${s.nomeOriginal}`,children:e.jsx(l.Trash2,{className:"h-4 w-4"})})}),e.jsx(r.TooltipContent,{children:"Remover"})]})})]})]})]})},o):e.jsxs("div",{className:u.cn("flex items-center justify-between gap-2 p-3 border rounded-lg bg-muted/30 transition-colors",s.status==="failed"&&"border-destructive/30 bg-destructive/5"),children:[e.jsxs("div",{className:"flex items-center gap-2 flex-1 min-w-0",children:[e.jsx(l.Paperclip,{className:"h-4 w-4 text-muted-foreground flex-shrink-0"}),e.jsx(r.TooltipProvider,{children:e.jsxs(r.Tooltip,{children:[e.jsx(r.TooltipTrigger,{asChild:!0,children:e.jsx("span",{className:"text-sm truncate",children:E(s.nomeOriginal,C)})}),e.jsx(r.TooltipContent,{children:e.jsx("p",{className:"max-w-xs break-all",children:s.nomeOriginal})})]})}),s.status==="uploading"&&typeof s.progress=="number"&&e.jsxs("span",{className:"text-xs text-muted-foreground flex-shrink-0",children:[s.progress,"%"]}),b]}),s.status==="completed"&&e.jsxs("div",{className:"flex items-center gap-1 flex-shrink-0",children:[v&&n&&e.jsx(r.TooltipProvider,{children:e.jsxs(r.Tooltip,{children:[e.jsx(r.TooltipTrigger,{asChild:!0,children:e.jsx(d.Button,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:()=>m(s,"view",n),disabled:N,"aria-label":`Visualizar ${s.nomeOriginal}`,children:e.jsx(l.Eye,{className:"h-4 w-4"})})}),e.jsx(r.TooltipContent,{children:"Visualizar"})]})}),x&&i&&e.jsx(r.TooltipProvider,{children:e.jsxs(r.Tooltip,{children:[e.jsx(r.TooltipTrigger,{asChild:!0,children:e.jsx(d.Button,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:()=>m(s,"download",i),disabled:c,"aria-label":`Baixar ${s.nomeOriginal}`,children:e.jsx(l.Download,{className:"h-4 w-4"})})}),e.jsx(r.TooltipContent,{children:"Baixar"})]})}),p&&a&&e.jsx(r.TooltipProvider,{children:e.jsxs(r.Tooltip,{children:[e.jsx(r.TooltipTrigger,{asChild:!0,children:e.jsx(d.Button,{variant:"ghost",size:"icon",className:"h-8 w-8 text-destructive-emphasis hover:text-destructive-emphasis",onClick:()=>a(s),"aria-label":`Remover ${s.nomeOriginal}`,children:e.jsx(l.Trash2,{className:"h-4 w-4"})})}),e.jsx(r.TooltipContent,{children:"Remover"})]})})]}),s.status==="failed"&&s.erro&&e.jsx(r.TooltipProvider,{children:e.jsxs(r.Tooltip,{children:[e.jsx(r.TooltipTrigger,{asChild:!0,children:e.jsx(l.AlertCircle,{className:"h-4 w-4 text-destructive-emphasis flex-shrink-0"})}),e.jsx(r.TooltipContent,{children:e.jsx("p",{className:"text-xs",children:s.erro})})]})})]},o)})})}exports.FileAttachmentList=F;
2
2
  //# sourceMappingURL=file-attachment-list.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-attachment-list.cjs","sources":["../../../../src/components/ui/forms/file-attachment-list.tsx"],"sourcesContent":["import { AlertCircle, Download, Eye, Paperclip, Trash2 } from 'lucide-react';\nimport { useState } from 'react';\n\nimport { Badge } from '../primitives/badge';\nimport { Button } from '../primitives/button';\nimport { Progress } from '../primitives/progress';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../overlays/tooltip';\nimport { cn } from '../utils';\n\n/**\n * Interface para um anexo de arquivo\n */\nexport interface FileAttachment {\n id?: string;\n nomeOriginal: string;\n chave?: string;\n tamanhoBytes?: number;\n dataUpload?: string;\n status?: 'completed' | 'uploading' | 'failed' | 'retrying';\n progress?: number;\n erro?: string;\n}\n\n/**\n * Props do componente FileAttachmentList\n */\nexport interface FileAttachmentListProps {\n /** Lista de anexos a serem exibidos */\n attachments: FileAttachment[];\n\n /** Callback quando usuário clica em download */\n onDownload?: (attachment: FileAttachment) => void | Promise<void>;\n\n /** Callback quando usuário clica em remover */\n onRemove?: (attachment: FileAttachment) => void;\n\n /** Callback quando usuário clica em visualizar */\n onView?: (attachment: FileAttachment) => void | Promise<void>;\n\n /** Mostrar botão de download */\n showDownload?: boolean;\n\n /** Mostrar botão de remover */\n showRemove?: boolean;\n\n /** Mostrar botão de visualizar */\n showView?: boolean;\n\n /** Comprimento máximo do nome do arquivo antes de truncar */\n maxFilenameLength?: number;\n\n /** Variante de exibição */\n variant?: 'compact' | 'detailed';\n\n /** Mensagem quando lista está vazia */\n emptyMessage?: string;\n\n /** Estado de loading geral */\n isLoading?: boolean;\n\n /** Classe CSS adicional */\n className?: string;\n}\n\n/**\n * Formata o tamanho do arquivo em formato legível\n */\nfunction formatarTamanhoArquivo(bytes?: number): string {\n if (!bytes) return '';\n\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;\n}\n\n/**\n * Formata a data em formato brasileiro\n */\nfunction formatarData(stringData?: string): string {\n if (!stringData) return '';\n\n try {\n const data = new Date(stringData);\n if (isNaN(data.getTime())) return stringData;\n return data.toLocaleDateString('pt-BR', {\n day: '2-digit',\n month: '2-digit',\n year: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n } catch {\n return stringData;\n }\n}\n\n/**\n * Trunca o nome do arquivo mantendo a extensão\n */\nfunction truncarNomeArquivo(nomeArquivo: string, comprimentoMaximo: number): string {\n if (nomeArquivo.length <= comprimentoMaximo) return nomeArquivo;\n\n const ultimoIndicePonto = nomeArquivo.lastIndexOf('.');\n if (ultimoIndicePonto === -1) {\n return nomeArquivo.substring(0, comprimentoMaximo - 3) + '...';\n }\n\n const extensao = nomeArquivo.substring(ultimoIndicePonto);\n const nome = nomeArquivo.substring(0, ultimoIndicePonto);\n const nomeTruncado = nome.substring(0, comprimentoMaximo - extensao.length - 3) + '...';\n\n return nomeTruncado + extensao;\n}\n\n/**\n * Componente para exibir lista de anexos com ações (download, view, remove)\n */\nexport function FileAttachmentList({\n attachments,\n onDownload,\n onRemove,\n onView,\n showDownload = true,\n showRemove = false,\n showView = false,\n maxFilenameLength = 40,\n variant = 'compact',\n emptyMessage = 'Nenhum anexo',\n isLoading = false,\n className,\n}: FileAttachmentListProps) {\n const [estadosCarregamento, setEstadosCarregamento] = useState<Record<string, 'download' | 'view' | null>>({});\n\n const gerenciarAcao = async (\n anexo: FileAttachment,\n acao: 'download' | 'view',\n callback?: (attachment: FileAttachment) => void | Promise<void>,\n ) => {\n if (!callback) return;\n\n const chave = anexo.chave || anexo.nomeOriginal;\n setEstadosCarregamento(anterior => ({ ...anterior, [chave]: acao }));\n\n try {\n await callback(anexo);\n } finally {\n setEstadosCarregamento(anterior => ({ ...anterior, [chave]: null }));\n }\n };\n\n if (isLoading) {\n return (\n <div className={cn('space-y-2', className)}>\n {[1, 2, 3].map(i => (\n <div key={i} className=\"flex items-center gap-2 p-3 border rounded bg-muted/30 animate-pulse\">\n <div className=\"h-4 w-4 bg-muted-foreground/20 rounded\" />\n <div className=\"h-4 flex-1 bg-muted-foreground/20 rounded\" />\n </div>\n ))}\n </div>\n );\n }\n\n if (attachments.length === 0) {\n return (\n <div className={cn('text-center py-6 text-sm text-muted-foreground border rounded-lg bg-muted/20', className)}>\n {emptyMessage}\n </div>\n );\n }\n\n return (\n <div className={cn('space-y-2', className)}>\n {attachments.map((anexo, indice) => {\n const chave = anexo.chave || anexo.id || `${anexo.nomeOriginal}-${indice}`;\n const estadoCarregamentoAtual = estadosCarregamento[anexo.chave || anexo.nomeOriginal];\n const estaBaixando = estadoCarregamentoAtual === 'download';\n const estaVisualizando = estadoCarregamentoAtual === 'view';\n\n // Badge de status\n const badgeStatus = (() => {\n switch (anexo.status) {\n case 'completed':\n return (\n <Badge variant=\"outline\" className=\"bg-success/10 text-success-emphasis border-success/20 hover:bg-success/10\">\n ✓ Enviado\n </Badge>\n );\n case 'uploading':\n return (\n <Badge variant=\"outline\" className=\"bg-info/10 text-info-emphasis border-info/20 hover:bg-info/10\">\n Enviando...\n </Badge>\n );\n case 'failed':\n return (\n <Badge variant=\"outline\" className=\"bg-destructive/10 text-destructive-emphasis border-destructive/20 hover:bg-destructive/10\">\n ✗ Erro\n </Badge>\n );\n case 'retrying':\n return (\n <Badge variant=\"outline\" className=\"bg-warning/10 text-warning-emphasis border-warning/20 hover:bg-warning/10\">\n Tentando...\n </Badge>\n );\n default:\n return null;\n }\n })();\n\n if (variant === 'detailed') {\n return (\n <div\n key={chave}\n className={cn(\n 'p-4 border rounded-lg bg-card transition-colors',\n anexo.status === 'failed' && 'border-destructive/30 bg-destructive/5',\n )}\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex items-start gap-3 flex-1 min-w-0\">\n <Paperclip className=\"h-5 w-5 text-muted-foreground mt-0.5 flex-shrink-0\" />\n\n <div className=\"flex-1 min-w-0\">\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <p className=\"text-sm font-medium truncate\">\n {anexo.nomeOriginal}\n </p>\n </TooltipTrigger>\n <TooltipContent>\n <p className=\"text-xs\">{anexo.nomeOriginal}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n\n <div className=\"flex items-center gap-2 mt-1 text-xs text-muted-foreground\">\n {anexo.tamanhoBytes && (\n <span>{formatarTamanhoArquivo(anexo.tamanhoBytes)}</span>\n )}\n {anexo.tamanhoBytes && anexo.dataUpload && (\n <span>•</span>\n )}\n {anexo.dataUpload && (\n <span>{formatarData(anexo.dataUpload)}</span>\n )}\n </div>\n\n {anexo.status === 'uploading' && typeof anexo.progress === 'number' && (\n <Progress value={anexo.progress} className=\"h-1 mt-2\" />\n )}\n\n {anexo.status === 'failed' && anexo.erro && (\n <div className=\"flex items-center gap-1 mt-2 text-xs text-destructive\">\n <AlertCircle className=\"h-3 w-3\" />\n <span>{anexo.erro}</span>\n </div>\n )}\n </div>\n </div>\n\n <div className=\"flex items-center gap-2 flex-shrink-0\">\n {badgeStatus}\n\n {anexo.status === 'completed' && (\n <>\n {showView && onView && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => gerenciarAcao(anexo, 'view', onView)}\n disabled={estaVisualizando}\n aria-label={`Visualizar ${anexo.nomeOriginal}`}\n >\n <Eye className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Visualizar</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n\n {showDownload && onDownload && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => gerenciarAcao(anexo, 'download', onDownload)}\n disabled={estaBaixando}\n aria-label={`Baixar ${anexo.nomeOriginal}`}\n >\n <Download className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Baixar</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n\n {showRemove && onRemove && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 text-destructive hover:text-destructive\"\n onClick={() => onRemove(anexo)}\n aria-label={`Remover ${anexo.nomeOriginal}`}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Remover</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </>\n )}\n </div>\n </div>\n </div>\n );\n }\n\n // Variante: compact\n return (\n <div\n key={chave}\n className={cn(\n 'flex items-center justify-between gap-2 p-3 border rounded-lg bg-muted/30 transition-colors',\n anexo.status === 'failed' && 'border-destructive/30 bg-destructive/5',\n )}\n >\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <Paperclip className=\"h-4 w-4 text-muted-foreground flex-shrink-0\" />\n\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <span className=\"text-sm truncate\">\n {truncarNomeArquivo(anexo.nomeOriginal, maxFilenameLength)}\n </span>\n </TooltipTrigger>\n <TooltipContent>\n <p className=\"max-w-xs break-all\">{anexo.nomeOriginal}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n\n {anexo.status === 'uploading' && typeof anexo.progress === 'number' && (\n <span className=\"text-xs text-muted-foreground flex-shrink-0\">\n {anexo.progress}%\n </span>\n )}\n\n {badgeStatus}\n </div>\n\n {anexo.status === 'completed' && (\n <div className=\"flex items-center gap-1 flex-shrink-0\">\n {showView && onView && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => gerenciarAcao(anexo, 'view', onView)}\n disabled={estaVisualizando}\n aria-label={`Visualizar ${anexo.nomeOriginal}`}\n >\n <Eye className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Visualizar</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n\n {showDownload && onDownload && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => gerenciarAcao(anexo, 'download', onDownload)}\n disabled={estaBaixando}\n aria-label={`Baixar ${anexo.nomeOriginal}`}\n >\n <Download className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Baixar</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n\n {showRemove && onRemove && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 text-destructive hover:text-destructive\"\n onClick={() => onRemove(anexo)}\n aria-label={`Remover ${anexo.nomeOriginal}`}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Remover</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </div>\n )}\n\n {anexo.status === 'failed' && anexo.erro && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <AlertCircle className=\"h-4 w-4 text-destructive flex-shrink-0\" />\n </TooltipTrigger>\n <TooltipContent>\n <p className=\"text-xs\">{anexo.erro}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </div>\n );\n })}\n </div>\n );\n}\n"],"names":["formatarTamanhoArquivo","bytes","formatarData","stringData","data","truncarNomeArquivo","nomeArquivo","comprimentoMaximo","ultimoIndicePonto","extensao","FileAttachmentList","attachments","onDownload","onRemove","onView","showDownload","showRemove","showView","maxFilenameLength","variant","emptyMessage","isLoading","className","estadosCarregamento","setEstadosCarregamento","useState","gerenciarAcao","anexo","acao","callback","chave","anterior","cn","jsxs","jsx","i","indice","estadoCarregamentoAtual","estaBaixando","estaVisualizando","badgeStatus","Badge","Paperclip","TooltipProvider","Tooltip","TooltipTrigger","TooltipContent","Progress","AlertCircle","Fragment","Button","Eye","Download","Trash2"],"mappings":"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"}
1
+ {"version":3,"file":"file-attachment-list.cjs","sources":["../../../../src/components/ui/forms/file-attachment-list.tsx"],"sourcesContent":["import { AlertCircle, Download, Eye, Paperclip, Trash2 } from 'lucide-react';\nimport { useState } from 'react';\n\nimport { Badge } from '../primitives/badge';\nimport { Button } from '../primitives/button';\nimport { Progress } from '../primitives/progress';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../overlays/tooltip';\nimport { cn } from '../utils';\n\n/**\n * Interface para um anexo de arquivo\n */\nexport interface FileAttachment {\n id?: string;\n nomeOriginal: string;\n chave?: string;\n tamanhoBytes?: number;\n dataUpload?: string;\n status?: 'completed' | 'uploading' | 'failed' | 'retrying';\n progress?: number;\n erro?: string;\n}\n\n/**\n * Props do componente FileAttachmentList\n */\nexport interface FileAttachmentListProps {\n /** Lista de anexos a serem exibidos */\n attachments: FileAttachment[];\n\n /** Callback quando usuário clica em download */\n onDownload?: (attachment: FileAttachment) => void | Promise<void>;\n\n /** Callback quando usuário clica em remover */\n onRemove?: (attachment: FileAttachment) => void;\n\n /** Callback quando usuário clica em visualizar */\n onView?: (attachment: FileAttachment) => void | Promise<void>;\n\n /** Mostrar botão de download */\n showDownload?: boolean;\n\n /** Mostrar botão de remover */\n showRemove?: boolean;\n\n /** Mostrar botão de visualizar */\n showView?: boolean;\n\n /** Comprimento máximo do nome do arquivo antes de truncar */\n maxFilenameLength?: number;\n\n /** Variante de exibição */\n variant?: 'compact' | 'detailed';\n\n /** Mensagem quando lista está vazia */\n emptyMessage?: string;\n\n /** Estado de loading geral */\n isLoading?: boolean;\n\n /** Classe CSS adicional */\n className?: string;\n}\n\n/**\n * Formata o tamanho do arquivo em formato legível\n */\nfunction formatarTamanhoArquivo(bytes?: number): string {\n if (!bytes) return '';\n\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;\n}\n\n/**\n * Formata a data em formato brasileiro\n */\nfunction formatarData(stringData?: string): string {\n if (!stringData) return '';\n\n try {\n const data = new Date(stringData);\n if (isNaN(data.getTime())) return stringData;\n return data.toLocaleDateString('pt-BR', {\n day: '2-digit',\n month: '2-digit',\n year: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n } catch {\n return stringData;\n }\n}\n\n/**\n * Trunca o nome do arquivo mantendo a extensão\n */\nfunction truncarNomeArquivo(nomeArquivo: string, comprimentoMaximo: number): string {\n if (nomeArquivo.length <= comprimentoMaximo) return nomeArquivo;\n\n const ultimoIndicePonto = nomeArquivo.lastIndexOf('.');\n if (ultimoIndicePonto === -1) {\n return nomeArquivo.substring(0, comprimentoMaximo - 3) + '...';\n }\n\n const extensao = nomeArquivo.substring(ultimoIndicePonto);\n const nome = nomeArquivo.substring(0, ultimoIndicePonto);\n const nomeTruncado = nome.substring(0, comprimentoMaximo - extensao.length - 3) + '...';\n\n return nomeTruncado + extensao;\n}\n\n/**\n * Componente para exibir lista de anexos com ações (download, view, remove)\n */\nexport function FileAttachmentList({\n attachments,\n onDownload,\n onRemove,\n onView,\n showDownload = true,\n showRemove = false,\n showView = false,\n maxFilenameLength = 40,\n variant = 'compact',\n emptyMessage = 'Nenhum anexo',\n isLoading = false,\n className,\n}: FileAttachmentListProps) {\n const [estadosCarregamento, setEstadosCarregamento] = useState<Record<string, 'download' | 'view' | null>>({});\n\n const gerenciarAcao = async (\n anexo: FileAttachment,\n acao: 'download' | 'view',\n callback?: (attachment: FileAttachment) => void | Promise<void>,\n ) => {\n if (!callback) return;\n\n const chave = anexo.chave || anexo.nomeOriginal;\n setEstadosCarregamento(anterior => ({ ...anterior, [chave]: acao }));\n\n try {\n await callback(anexo);\n } finally {\n setEstadosCarregamento(anterior => ({ ...anterior, [chave]: null }));\n }\n };\n\n if (isLoading) {\n return (\n <div className={cn('space-y-2', className)}>\n {[1, 2, 3].map(i => (\n <div key={i} className=\"flex items-center gap-2 p-3 border rounded bg-muted/30 animate-pulse\">\n <div className=\"h-4 w-4 bg-muted-foreground/20 rounded\" />\n <div className=\"h-4 flex-1 bg-muted-foreground/20 rounded\" />\n </div>\n ))}\n </div>\n );\n }\n\n if (attachments.length === 0) {\n return (\n <div className={cn('text-center py-6 text-sm text-muted-foreground border rounded-lg bg-muted/20', className)}>\n {emptyMessage}\n </div>\n );\n }\n\n return (\n <div className={cn('space-y-2', className)}>\n {attachments.map((anexo, indice) => {\n const chave = anexo.chave || anexo.id || `${anexo.nomeOriginal}-${indice}`;\n const estadoCarregamentoAtual = estadosCarregamento[anexo.chave || anexo.nomeOriginal];\n const estaBaixando = estadoCarregamentoAtual === 'download';\n const estaVisualizando = estadoCarregamentoAtual === 'view';\n\n // Badge de status\n const badgeStatus = (() => {\n switch (anexo.status) {\n case 'completed':\n return (\n <Badge variant=\"outline\" className=\"bg-success/10 text-success-emphasis border-success/20 hover:bg-success/10\">\n ✓ Enviado\n </Badge>\n );\n case 'uploading':\n return (\n <Badge variant=\"outline\" className=\"bg-info/10 text-info-emphasis border-info/20 hover:bg-info/10\">\n Enviando...\n </Badge>\n );\n case 'failed':\n return (\n <Badge variant=\"outline\" className=\"bg-destructive/10 text-destructive-emphasis border-destructive/20 hover:bg-destructive/10\">\n ✗ Erro\n </Badge>\n );\n case 'retrying':\n return (\n <Badge variant=\"outline\" className=\"bg-warning/10 text-warning-emphasis border-warning/20 hover:bg-warning/10\">\n Tentando...\n </Badge>\n );\n default:\n return null;\n }\n })();\n\n if (variant === 'detailed') {\n return (\n <div\n key={chave}\n className={cn(\n 'p-4 border rounded-lg bg-card transition-colors',\n anexo.status === 'failed' && 'border-destructive/30 bg-destructive/5',\n )}\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex items-start gap-3 flex-1 min-w-0\">\n <Paperclip className=\"h-5 w-5 text-muted-foreground mt-0.5 flex-shrink-0\" />\n\n <div className=\"flex-1 min-w-0\">\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <p className=\"text-sm font-medium truncate\">\n {anexo.nomeOriginal}\n </p>\n </TooltipTrigger>\n <TooltipContent>\n <p className=\"text-xs\">{anexo.nomeOriginal}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n\n <div className=\"flex items-center gap-2 mt-1 text-xs text-muted-foreground\">\n {anexo.tamanhoBytes && (\n <span>{formatarTamanhoArquivo(anexo.tamanhoBytes)}</span>\n )}\n {anexo.tamanhoBytes && anexo.dataUpload && (\n <span>•</span>\n )}\n {anexo.dataUpload && (\n <span>{formatarData(anexo.dataUpload)}</span>\n )}\n </div>\n\n {anexo.status === 'uploading' && typeof anexo.progress === 'number' && (\n <Progress value={anexo.progress} className=\"h-1 mt-2\" />\n )}\n\n {anexo.status === 'failed' && anexo.erro && (\n <div className=\"flex items-center gap-1 mt-2 text-xs text-destructive-emphasis\">\n <AlertCircle className=\"h-3 w-3\" />\n <span>{anexo.erro}</span>\n </div>\n )}\n </div>\n </div>\n\n <div className=\"flex items-center gap-2 flex-shrink-0\">\n {badgeStatus}\n\n {anexo.status === 'completed' && (\n <>\n {showView && onView && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => gerenciarAcao(anexo, 'view', onView)}\n disabled={estaVisualizando}\n aria-label={`Visualizar ${anexo.nomeOriginal}`}\n >\n <Eye className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Visualizar</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n\n {showDownload && onDownload && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => gerenciarAcao(anexo, 'download', onDownload)}\n disabled={estaBaixando}\n aria-label={`Baixar ${anexo.nomeOriginal}`}\n >\n <Download className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Baixar</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n\n {showRemove && onRemove && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 text-destructive-emphasis hover:text-destructive-emphasis\"\n onClick={() => onRemove(anexo)}\n aria-label={`Remover ${anexo.nomeOriginal}`}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Remover</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </>\n )}\n </div>\n </div>\n </div>\n );\n }\n\n // Variante: compact\n return (\n <div\n key={chave}\n className={cn(\n 'flex items-center justify-between gap-2 p-3 border rounded-lg bg-muted/30 transition-colors',\n anexo.status === 'failed' && 'border-destructive/30 bg-destructive/5',\n )}\n >\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <Paperclip className=\"h-4 w-4 text-muted-foreground flex-shrink-0\" />\n\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <span className=\"text-sm truncate\">\n {truncarNomeArquivo(anexo.nomeOriginal, maxFilenameLength)}\n </span>\n </TooltipTrigger>\n <TooltipContent>\n <p className=\"max-w-xs break-all\">{anexo.nomeOriginal}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n\n {anexo.status === 'uploading' && typeof anexo.progress === 'number' && (\n <span className=\"text-xs text-muted-foreground flex-shrink-0\">\n {anexo.progress}%\n </span>\n )}\n\n {badgeStatus}\n </div>\n\n {anexo.status === 'completed' && (\n <div className=\"flex items-center gap-1 flex-shrink-0\">\n {showView && onView && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => gerenciarAcao(anexo, 'view', onView)}\n disabled={estaVisualizando}\n aria-label={`Visualizar ${anexo.nomeOriginal}`}\n >\n <Eye className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Visualizar</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n\n {showDownload && onDownload && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => gerenciarAcao(anexo, 'download', onDownload)}\n disabled={estaBaixando}\n aria-label={`Baixar ${anexo.nomeOriginal}`}\n >\n <Download className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Baixar</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n\n {showRemove && onRemove && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 text-destructive-emphasis hover:text-destructive-emphasis\"\n onClick={() => onRemove(anexo)}\n aria-label={`Remover ${anexo.nomeOriginal}`}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Remover</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </div>\n )}\n\n {anexo.status === 'failed' && anexo.erro && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <AlertCircle className=\"h-4 w-4 text-destructive-emphasis flex-shrink-0\" />\n </TooltipTrigger>\n <TooltipContent>\n <p className=\"text-xs\">{anexo.erro}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </div>\n );\n })}\n </div>\n );\n}\n"],"names":["formatarTamanhoArquivo","bytes","formatarData","stringData","data","truncarNomeArquivo","nomeArquivo","comprimentoMaximo","ultimoIndicePonto","extensao","FileAttachmentList","attachments","onDownload","onRemove","onView","showDownload","showRemove","showView","maxFilenameLength","variant","emptyMessage","isLoading","className","estadosCarregamento","setEstadosCarregamento","useState","gerenciarAcao","anexo","acao","callback","chave","anterior","cn","jsxs","jsx","i","indice","estadoCarregamentoAtual","estaBaixando","estaVisualizando","badgeStatus","Badge","Paperclip","TooltipProvider","Tooltip","TooltipTrigger","TooltipContent","Progress","AlertCircle","Fragment","Button","Eye","Download","Trash2"],"mappings":"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"}
@@ -95,7 +95,7 @@ function _({
95
95
  r.dataUpload && /* @__PURE__ */ e("span", { children: K(r.dataUpload) })
96
96
  ] }),
97
97
  r.status === "uploading" && typeof r.progress == "number" && /* @__PURE__ */ e(A, { value: r.progress, className: "h-1 mt-2" }),
98
- r.status === "failed" && r.erro && /* @__PURE__ */ t("div", { className: "flex items-center gap-1 mt-2 text-xs text-destructive", children: [
98
+ r.status === "failed" && r.erro && /* @__PURE__ */ t("div", { className: "flex items-center gap-1 mt-2 text-xs text-destructive-emphasis", children: [
99
99
  /* @__PURE__ */ e(y, { className: "h-3 w-3" }),
100
100
  /* @__PURE__ */ e("span", { children: r.erro })
101
101
  ] })
@@ -140,7 +140,7 @@ function _({
140
140
  {
141
141
  variant: "ghost",
142
142
  size: "icon",
143
- className: "h-8 w-8 text-destructive hover:text-destructive",
143
+ className: "h-8 w-8 text-destructive-emphasis hover:text-destructive-emphasis",
144
144
  onClick: () => c(r),
145
145
  "aria-label": `Remover ${r.nomeOriginal}`,
146
146
  children: /* @__PURE__ */ e(E, { className: "h-4 w-4" })
@@ -210,7 +210,7 @@ function _({
210
210
  {
211
211
  variant: "ghost",
212
212
  size: "icon",
213
- className: "h-8 w-8 text-destructive hover:text-destructive",
213
+ className: "h-8 w-8 text-destructive-emphasis hover:text-destructive-emphasis",
214
214
  onClick: () => c(r),
215
215
  "aria-label": `Remover ${r.nomeOriginal}`,
216
216
  children: /* @__PURE__ */ e(E, { className: "h-4 w-4" })
@@ -220,7 +220,7 @@ function _({
220
220
  ] }) })
221
221
  ] }),
222
222
  r.status === "failed" && r.erro && /* @__PURE__ */ e(a, { children: /* @__PURE__ */ t(l, { children: [
223
- /* @__PURE__ */ e(n, { asChild: !0, children: /* @__PURE__ */ e(y, { className: "h-4 w-4 text-destructive flex-shrink-0" }) }),
223
+ /* @__PURE__ */ e(n, { asChild: !0, children: /* @__PURE__ */ e(y, { className: "h-4 w-4 text-destructive-emphasis flex-shrink-0" }) }),
224
224
  /* @__PURE__ */ e(d, { children: /* @__PURE__ */ e("p", { className: "text-xs", children: r.erro }) })
225
225
  ] }) })
226
226
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"file-attachment-list.js","sources":["../../../../src/components/ui/forms/file-attachment-list.tsx"],"sourcesContent":["import { AlertCircle, Download, Eye, Paperclip, Trash2 } from 'lucide-react';\nimport { useState } from 'react';\n\nimport { Badge } from '../primitives/badge';\nimport { Button } from '../primitives/button';\nimport { Progress } from '../primitives/progress';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../overlays/tooltip';\nimport { cn } from '../utils';\n\n/**\n * Interface para um anexo de arquivo\n */\nexport interface FileAttachment {\n id?: string;\n nomeOriginal: string;\n chave?: string;\n tamanhoBytes?: number;\n dataUpload?: string;\n status?: 'completed' | 'uploading' | 'failed' | 'retrying';\n progress?: number;\n erro?: string;\n}\n\n/**\n * Props do componente FileAttachmentList\n */\nexport interface FileAttachmentListProps {\n /** Lista de anexos a serem exibidos */\n attachments: FileAttachment[];\n\n /** Callback quando usuário clica em download */\n onDownload?: (attachment: FileAttachment) => void | Promise<void>;\n\n /** Callback quando usuário clica em remover */\n onRemove?: (attachment: FileAttachment) => void;\n\n /** Callback quando usuário clica em visualizar */\n onView?: (attachment: FileAttachment) => void | Promise<void>;\n\n /** Mostrar botão de download */\n showDownload?: boolean;\n\n /** Mostrar botão de remover */\n showRemove?: boolean;\n\n /** Mostrar botão de visualizar */\n showView?: boolean;\n\n /** Comprimento máximo do nome do arquivo antes de truncar */\n maxFilenameLength?: number;\n\n /** Variante de exibição */\n variant?: 'compact' | 'detailed';\n\n /** Mensagem quando lista está vazia */\n emptyMessage?: string;\n\n /** Estado de loading geral */\n isLoading?: boolean;\n\n /** Classe CSS adicional */\n className?: string;\n}\n\n/**\n * Formata o tamanho do arquivo em formato legível\n */\nfunction formatarTamanhoArquivo(bytes?: number): string {\n if (!bytes) return '';\n\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;\n}\n\n/**\n * Formata a data em formato brasileiro\n */\nfunction formatarData(stringData?: string): string {\n if (!stringData) return '';\n\n try {\n const data = new Date(stringData);\n if (isNaN(data.getTime())) return stringData;\n return data.toLocaleDateString('pt-BR', {\n day: '2-digit',\n month: '2-digit',\n year: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n } catch {\n return stringData;\n }\n}\n\n/**\n * Trunca o nome do arquivo mantendo a extensão\n */\nfunction truncarNomeArquivo(nomeArquivo: string, comprimentoMaximo: number): string {\n if (nomeArquivo.length <= comprimentoMaximo) return nomeArquivo;\n\n const ultimoIndicePonto = nomeArquivo.lastIndexOf('.');\n if (ultimoIndicePonto === -1) {\n return nomeArquivo.substring(0, comprimentoMaximo - 3) + '...';\n }\n\n const extensao = nomeArquivo.substring(ultimoIndicePonto);\n const nome = nomeArquivo.substring(0, ultimoIndicePonto);\n const nomeTruncado = nome.substring(0, comprimentoMaximo - extensao.length - 3) + '...';\n\n return nomeTruncado + extensao;\n}\n\n/**\n * Componente para exibir lista de anexos com ações (download, view, remove)\n */\nexport function FileAttachmentList({\n attachments,\n onDownload,\n onRemove,\n onView,\n showDownload = true,\n showRemove = false,\n showView = false,\n maxFilenameLength = 40,\n variant = 'compact',\n emptyMessage = 'Nenhum anexo',\n isLoading = false,\n className,\n}: FileAttachmentListProps) {\n const [estadosCarregamento, setEstadosCarregamento] = useState<Record<string, 'download' | 'view' | null>>({});\n\n const gerenciarAcao = async (\n anexo: FileAttachment,\n acao: 'download' | 'view',\n callback?: (attachment: FileAttachment) => void | Promise<void>,\n ) => {\n if (!callback) return;\n\n const chave = anexo.chave || anexo.nomeOriginal;\n setEstadosCarregamento(anterior => ({ ...anterior, [chave]: acao }));\n\n try {\n await callback(anexo);\n } finally {\n setEstadosCarregamento(anterior => ({ ...anterior, [chave]: null }));\n }\n };\n\n if (isLoading) {\n return (\n <div className={cn('space-y-2', className)}>\n {[1, 2, 3].map(i => (\n <div key={i} className=\"flex items-center gap-2 p-3 border rounded bg-muted/30 animate-pulse\">\n <div className=\"h-4 w-4 bg-muted-foreground/20 rounded\" />\n <div className=\"h-4 flex-1 bg-muted-foreground/20 rounded\" />\n </div>\n ))}\n </div>\n );\n }\n\n if (attachments.length === 0) {\n return (\n <div className={cn('text-center py-6 text-sm text-muted-foreground border rounded-lg bg-muted/20', className)}>\n {emptyMessage}\n </div>\n );\n }\n\n return (\n <div className={cn('space-y-2', className)}>\n {attachments.map((anexo, indice) => {\n const chave = anexo.chave || anexo.id || `${anexo.nomeOriginal}-${indice}`;\n const estadoCarregamentoAtual = estadosCarregamento[anexo.chave || anexo.nomeOriginal];\n const estaBaixando = estadoCarregamentoAtual === 'download';\n const estaVisualizando = estadoCarregamentoAtual === 'view';\n\n // Badge de status\n const badgeStatus = (() => {\n switch (anexo.status) {\n case 'completed':\n return (\n <Badge variant=\"outline\" className=\"bg-success/10 text-success-emphasis border-success/20 hover:bg-success/10\">\n ✓ Enviado\n </Badge>\n );\n case 'uploading':\n return (\n <Badge variant=\"outline\" className=\"bg-info/10 text-info-emphasis border-info/20 hover:bg-info/10\">\n Enviando...\n </Badge>\n );\n case 'failed':\n return (\n <Badge variant=\"outline\" className=\"bg-destructive/10 text-destructive-emphasis border-destructive/20 hover:bg-destructive/10\">\n ✗ Erro\n </Badge>\n );\n case 'retrying':\n return (\n <Badge variant=\"outline\" className=\"bg-warning/10 text-warning-emphasis border-warning/20 hover:bg-warning/10\">\n Tentando...\n </Badge>\n );\n default:\n return null;\n }\n })();\n\n if (variant === 'detailed') {\n return (\n <div\n key={chave}\n className={cn(\n 'p-4 border rounded-lg bg-card transition-colors',\n anexo.status === 'failed' && 'border-destructive/30 bg-destructive/5',\n )}\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex items-start gap-3 flex-1 min-w-0\">\n <Paperclip className=\"h-5 w-5 text-muted-foreground mt-0.5 flex-shrink-0\" />\n\n <div className=\"flex-1 min-w-0\">\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <p className=\"text-sm font-medium truncate\">\n {anexo.nomeOriginal}\n </p>\n </TooltipTrigger>\n <TooltipContent>\n <p className=\"text-xs\">{anexo.nomeOriginal}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n\n <div className=\"flex items-center gap-2 mt-1 text-xs text-muted-foreground\">\n {anexo.tamanhoBytes && (\n <span>{formatarTamanhoArquivo(anexo.tamanhoBytes)}</span>\n )}\n {anexo.tamanhoBytes && anexo.dataUpload && (\n <span>•</span>\n )}\n {anexo.dataUpload && (\n <span>{formatarData(anexo.dataUpload)}</span>\n )}\n </div>\n\n {anexo.status === 'uploading' && typeof anexo.progress === 'number' && (\n <Progress value={anexo.progress} className=\"h-1 mt-2\" />\n )}\n\n {anexo.status === 'failed' && anexo.erro && (\n <div className=\"flex items-center gap-1 mt-2 text-xs text-destructive\">\n <AlertCircle className=\"h-3 w-3\" />\n <span>{anexo.erro}</span>\n </div>\n )}\n </div>\n </div>\n\n <div className=\"flex items-center gap-2 flex-shrink-0\">\n {badgeStatus}\n\n {anexo.status === 'completed' && (\n <>\n {showView && onView && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => gerenciarAcao(anexo, 'view', onView)}\n disabled={estaVisualizando}\n aria-label={`Visualizar ${anexo.nomeOriginal}`}\n >\n <Eye className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Visualizar</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n\n {showDownload && onDownload && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => gerenciarAcao(anexo, 'download', onDownload)}\n disabled={estaBaixando}\n aria-label={`Baixar ${anexo.nomeOriginal}`}\n >\n <Download className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Baixar</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n\n {showRemove && onRemove && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 text-destructive hover:text-destructive\"\n onClick={() => onRemove(anexo)}\n aria-label={`Remover ${anexo.nomeOriginal}`}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Remover</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </>\n )}\n </div>\n </div>\n </div>\n );\n }\n\n // Variante: compact\n return (\n <div\n key={chave}\n className={cn(\n 'flex items-center justify-between gap-2 p-3 border rounded-lg bg-muted/30 transition-colors',\n anexo.status === 'failed' && 'border-destructive/30 bg-destructive/5',\n )}\n >\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <Paperclip className=\"h-4 w-4 text-muted-foreground flex-shrink-0\" />\n\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <span className=\"text-sm truncate\">\n {truncarNomeArquivo(anexo.nomeOriginal, maxFilenameLength)}\n </span>\n </TooltipTrigger>\n <TooltipContent>\n <p className=\"max-w-xs break-all\">{anexo.nomeOriginal}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n\n {anexo.status === 'uploading' && typeof anexo.progress === 'number' && (\n <span className=\"text-xs text-muted-foreground flex-shrink-0\">\n {anexo.progress}%\n </span>\n )}\n\n {badgeStatus}\n </div>\n\n {anexo.status === 'completed' && (\n <div className=\"flex items-center gap-1 flex-shrink-0\">\n {showView && onView && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => gerenciarAcao(anexo, 'view', onView)}\n disabled={estaVisualizando}\n aria-label={`Visualizar ${anexo.nomeOriginal}`}\n >\n <Eye className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Visualizar</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n\n {showDownload && onDownload && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => gerenciarAcao(anexo, 'download', onDownload)}\n disabled={estaBaixando}\n aria-label={`Baixar ${anexo.nomeOriginal}`}\n >\n <Download className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Baixar</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n\n {showRemove && onRemove && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 text-destructive hover:text-destructive\"\n onClick={() => onRemove(anexo)}\n aria-label={`Remover ${anexo.nomeOriginal}`}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Remover</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </div>\n )}\n\n {anexo.status === 'failed' && anexo.erro && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <AlertCircle className=\"h-4 w-4 text-destructive flex-shrink-0\" />\n </TooltipTrigger>\n <TooltipContent>\n <p className=\"text-xs\">{anexo.erro}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </div>\n );\n })}\n </div>\n );\n}\n"],"names":["formatarTamanhoArquivo","bytes","formatarData","stringData","data","truncarNomeArquivo","nomeArquivo","comprimentoMaximo","ultimoIndicePonto","extensao","FileAttachmentList","attachments","onDownload","onRemove","onView","showDownload","showRemove","showView","maxFilenameLength","variant","emptyMessage","isLoading","className","estadosCarregamento","setEstadosCarregamento","useState","gerenciarAcao","anexo","acao","callback","chave","anterior","cn","jsxs","jsx","i","indice","estadoCarregamentoAtual","estaBaixando","estaVisualizando","badgeStatus","Badge","Paperclip","TooltipProvider","Tooltip","TooltipTrigger","TooltipContent","Progress","AlertCircle","Fragment","Button","Eye","Download","Trash2"],"mappings":"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"}
1
+ {"version":3,"file":"file-attachment-list.js","sources":["../../../../src/components/ui/forms/file-attachment-list.tsx"],"sourcesContent":["import { AlertCircle, Download, Eye, Paperclip, Trash2 } from 'lucide-react';\nimport { useState } from 'react';\n\nimport { Badge } from '../primitives/badge';\nimport { Button } from '../primitives/button';\nimport { Progress } from '../primitives/progress';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../overlays/tooltip';\nimport { cn } from '../utils';\n\n/**\n * Interface para um anexo de arquivo\n */\nexport interface FileAttachment {\n id?: string;\n nomeOriginal: string;\n chave?: string;\n tamanhoBytes?: number;\n dataUpload?: string;\n status?: 'completed' | 'uploading' | 'failed' | 'retrying';\n progress?: number;\n erro?: string;\n}\n\n/**\n * Props do componente FileAttachmentList\n */\nexport interface FileAttachmentListProps {\n /** Lista de anexos a serem exibidos */\n attachments: FileAttachment[];\n\n /** Callback quando usuário clica em download */\n onDownload?: (attachment: FileAttachment) => void | Promise<void>;\n\n /** Callback quando usuário clica em remover */\n onRemove?: (attachment: FileAttachment) => void;\n\n /** Callback quando usuário clica em visualizar */\n onView?: (attachment: FileAttachment) => void | Promise<void>;\n\n /** Mostrar botão de download */\n showDownload?: boolean;\n\n /** Mostrar botão de remover */\n showRemove?: boolean;\n\n /** Mostrar botão de visualizar */\n showView?: boolean;\n\n /** Comprimento máximo do nome do arquivo antes de truncar */\n maxFilenameLength?: number;\n\n /** Variante de exibição */\n variant?: 'compact' | 'detailed';\n\n /** Mensagem quando lista está vazia */\n emptyMessage?: string;\n\n /** Estado de loading geral */\n isLoading?: boolean;\n\n /** Classe CSS adicional */\n className?: string;\n}\n\n/**\n * Formata o tamanho do arquivo em formato legível\n */\nfunction formatarTamanhoArquivo(bytes?: number): string {\n if (!bytes) return '';\n\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;\n}\n\n/**\n * Formata a data em formato brasileiro\n */\nfunction formatarData(stringData?: string): string {\n if (!stringData) return '';\n\n try {\n const data = new Date(stringData);\n if (isNaN(data.getTime())) return stringData;\n return data.toLocaleDateString('pt-BR', {\n day: '2-digit',\n month: '2-digit',\n year: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n } catch {\n return stringData;\n }\n}\n\n/**\n * Trunca o nome do arquivo mantendo a extensão\n */\nfunction truncarNomeArquivo(nomeArquivo: string, comprimentoMaximo: number): string {\n if (nomeArquivo.length <= comprimentoMaximo) return nomeArquivo;\n\n const ultimoIndicePonto = nomeArquivo.lastIndexOf('.');\n if (ultimoIndicePonto === -1) {\n return nomeArquivo.substring(0, comprimentoMaximo - 3) + '...';\n }\n\n const extensao = nomeArquivo.substring(ultimoIndicePonto);\n const nome = nomeArquivo.substring(0, ultimoIndicePonto);\n const nomeTruncado = nome.substring(0, comprimentoMaximo - extensao.length - 3) + '...';\n\n return nomeTruncado + extensao;\n}\n\n/**\n * Componente para exibir lista de anexos com ações (download, view, remove)\n */\nexport function FileAttachmentList({\n attachments,\n onDownload,\n onRemove,\n onView,\n showDownload = true,\n showRemove = false,\n showView = false,\n maxFilenameLength = 40,\n variant = 'compact',\n emptyMessage = 'Nenhum anexo',\n isLoading = false,\n className,\n}: FileAttachmentListProps) {\n const [estadosCarregamento, setEstadosCarregamento] = useState<Record<string, 'download' | 'view' | null>>({});\n\n const gerenciarAcao = async (\n anexo: FileAttachment,\n acao: 'download' | 'view',\n callback?: (attachment: FileAttachment) => void | Promise<void>,\n ) => {\n if (!callback) return;\n\n const chave = anexo.chave || anexo.nomeOriginal;\n setEstadosCarregamento(anterior => ({ ...anterior, [chave]: acao }));\n\n try {\n await callback(anexo);\n } finally {\n setEstadosCarregamento(anterior => ({ ...anterior, [chave]: null }));\n }\n };\n\n if (isLoading) {\n return (\n <div className={cn('space-y-2', className)}>\n {[1, 2, 3].map(i => (\n <div key={i} className=\"flex items-center gap-2 p-3 border rounded bg-muted/30 animate-pulse\">\n <div className=\"h-4 w-4 bg-muted-foreground/20 rounded\" />\n <div className=\"h-4 flex-1 bg-muted-foreground/20 rounded\" />\n </div>\n ))}\n </div>\n );\n }\n\n if (attachments.length === 0) {\n return (\n <div className={cn('text-center py-6 text-sm text-muted-foreground border rounded-lg bg-muted/20', className)}>\n {emptyMessage}\n </div>\n );\n }\n\n return (\n <div className={cn('space-y-2', className)}>\n {attachments.map((anexo, indice) => {\n const chave = anexo.chave || anexo.id || `${anexo.nomeOriginal}-${indice}`;\n const estadoCarregamentoAtual = estadosCarregamento[anexo.chave || anexo.nomeOriginal];\n const estaBaixando = estadoCarregamentoAtual === 'download';\n const estaVisualizando = estadoCarregamentoAtual === 'view';\n\n // Badge de status\n const badgeStatus = (() => {\n switch (anexo.status) {\n case 'completed':\n return (\n <Badge variant=\"outline\" className=\"bg-success/10 text-success-emphasis border-success/20 hover:bg-success/10\">\n ✓ Enviado\n </Badge>\n );\n case 'uploading':\n return (\n <Badge variant=\"outline\" className=\"bg-info/10 text-info-emphasis border-info/20 hover:bg-info/10\">\n Enviando...\n </Badge>\n );\n case 'failed':\n return (\n <Badge variant=\"outline\" className=\"bg-destructive/10 text-destructive-emphasis border-destructive/20 hover:bg-destructive/10\">\n ✗ Erro\n </Badge>\n );\n case 'retrying':\n return (\n <Badge variant=\"outline\" className=\"bg-warning/10 text-warning-emphasis border-warning/20 hover:bg-warning/10\">\n Tentando...\n </Badge>\n );\n default:\n return null;\n }\n })();\n\n if (variant === 'detailed') {\n return (\n <div\n key={chave}\n className={cn(\n 'p-4 border rounded-lg bg-card transition-colors',\n anexo.status === 'failed' && 'border-destructive/30 bg-destructive/5',\n )}\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex items-start gap-3 flex-1 min-w-0\">\n <Paperclip className=\"h-5 w-5 text-muted-foreground mt-0.5 flex-shrink-0\" />\n\n <div className=\"flex-1 min-w-0\">\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <p className=\"text-sm font-medium truncate\">\n {anexo.nomeOriginal}\n </p>\n </TooltipTrigger>\n <TooltipContent>\n <p className=\"text-xs\">{anexo.nomeOriginal}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n\n <div className=\"flex items-center gap-2 mt-1 text-xs text-muted-foreground\">\n {anexo.tamanhoBytes && (\n <span>{formatarTamanhoArquivo(anexo.tamanhoBytes)}</span>\n )}\n {anexo.tamanhoBytes && anexo.dataUpload && (\n <span>•</span>\n )}\n {anexo.dataUpload && (\n <span>{formatarData(anexo.dataUpload)}</span>\n )}\n </div>\n\n {anexo.status === 'uploading' && typeof anexo.progress === 'number' && (\n <Progress value={anexo.progress} className=\"h-1 mt-2\" />\n )}\n\n {anexo.status === 'failed' && anexo.erro && (\n <div className=\"flex items-center gap-1 mt-2 text-xs text-destructive-emphasis\">\n <AlertCircle className=\"h-3 w-3\" />\n <span>{anexo.erro}</span>\n </div>\n )}\n </div>\n </div>\n\n <div className=\"flex items-center gap-2 flex-shrink-0\">\n {badgeStatus}\n\n {anexo.status === 'completed' && (\n <>\n {showView && onView && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => gerenciarAcao(anexo, 'view', onView)}\n disabled={estaVisualizando}\n aria-label={`Visualizar ${anexo.nomeOriginal}`}\n >\n <Eye className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Visualizar</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n\n {showDownload && onDownload && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => gerenciarAcao(anexo, 'download', onDownload)}\n disabled={estaBaixando}\n aria-label={`Baixar ${anexo.nomeOriginal}`}\n >\n <Download className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Baixar</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n\n {showRemove && onRemove && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 text-destructive-emphasis hover:text-destructive-emphasis\"\n onClick={() => onRemove(anexo)}\n aria-label={`Remover ${anexo.nomeOriginal}`}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Remover</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </>\n )}\n </div>\n </div>\n </div>\n );\n }\n\n // Variante: compact\n return (\n <div\n key={chave}\n className={cn(\n 'flex items-center justify-between gap-2 p-3 border rounded-lg bg-muted/30 transition-colors',\n anexo.status === 'failed' && 'border-destructive/30 bg-destructive/5',\n )}\n >\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <Paperclip className=\"h-4 w-4 text-muted-foreground flex-shrink-0\" />\n\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <span className=\"text-sm truncate\">\n {truncarNomeArquivo(anexo.nomeOriginal, maxFilenameLength)}\n </span>\n </TooltipTrigger>\n <TooltipContent>\n <p className=\"max-w-xs break-all\">{anexo.nomeOriginal}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n\n {anexo.status === 'uploading' && typeof anexo.progress === 'number' && (\n <span className=\"text-xs text-muted-foreground flex-shrink-0\">\n {anexo.progress}%\n </span>\n )}\n\n {badgeStatus}\n </div>\n\n {anexo.status === 'completed' && (\n <div className=\"flex items-center gap-1 flex-shrink-0\">\n {showView && onView && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => gerenciarAcao(anexo, 'view', onView)}\n disabled={estaVisualizando}\n aria-label={`Visualizar ${anexo.nomeOriginal}`}\n >\n <Eye className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Visualizar</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n\n {showDownload && onDownload && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => gerenciarAcao(anexo, 'download', onDownload)}\n disabled={estaBaixando}\n aria-label={`Baixar ${anexo.nomeOriginal}`}\n >\n <Download className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Baixar</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n\n {showRemove && onRemove && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 text-destructive-emphasis hover:text-destructive-emphasis\"\n onClick={() => onRemove(anexo)}\n aria-label={`Remover ${anexo.nomeOriginal}`}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Remover</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </div>\n )}\n\n {anexo.status === 'failed' && anexo.erro && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <AlertCircle className=\"h-4 w-4 text-destructive-emphasis flex-shrink-0\" />\n </TooltipTrigger>\n <TooltipContent>\n <p className=\"text-xs\">{anexo.erro}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </div>\n );\n })}\n </div>\n );\n}\n"],"names":["formatarTamanhoArquivo","bytes","formatarData","stringData","data","truncarNomeArquivo","nomeArquivo","comprimentoMaximo","ultimoIndicePonto","extensao","FileAttachmentList","attachments","onDownload","onRemove","onView","showDownload","showRemove","showView","maxFilenameLength","variant","emptyMessage","isLoading","className","estadosCarregamento","setEstadosCarregamento","useState","gerenciarAcao","anexo","acao","callback","chave","anterior","cn","jsxs","jsx","i","indice","estadoCarregamentoAtual","estaBaixando","estaVisualizando","badgeStatus","Badge","Paperclip","TooltipProvider","Tooltip","TooltipTrigger","TooltipContent","Progress","AlertCircle","Fragment","Button","Eye","Download","Trash2"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),w=require("lucide-react"),o=require("react"),g=require("../utils.cjs");function R(n,s){const u=s*1024*1024;return n.size>u?`Arquivo muito grande. Máximo: ${s}MB`:null}function W(n,s){if(!s)return null;const u=s.split(",").map(r=>r.trim().toLowerCase()),c=n.name.toLowerCase(),i=n.type.toLowerCase();return u.some(r=>{if(r.includes("*")){const[j]=r.split("/");return i.startsWith(j+"/")}return r.startsWith(".")?c.endsWith(r):i===r})?null:"Tipo de arquivo não suportado"}function M({onFilesSelected:n,accept:s,multiple:u=!0,maxFiles:c=10,maxSizeMB:i=50,disabled:a=!1,isUploading:r=!1,title:j="Clique para fazer upload de arquivos",description:b,icon:k,className:T,onError:m}){const[l,q]=o.useState(!1),p=o.useRef(null),y=o.useCallback(e=>{m==null||m(e)},[m]),h=o.useCallback(e=>{if(!e||e.length===0)return;const v=Array.from(e);if(v.length>c){y(`Máximo de ${c} arquivo(s) permitido(s)`);return}const f=[],x=[];for(const d of v){const A=R(d,i);if(A){x.push(`${d.name}: ${A}`);continue}const N=W(d,s);if(N){x.push(`${d.name}: ${N}`);continue}f.push(d)}x.length>0&&y(x.join(`
2
- `)),f.length>0&&n(f),p.current&&(p.current.value="")},[c,i,s,n,y]),$=o.useCallback(()=>{var e;a||r||(e=p.current)==null||e.click()},[a,r]),D=o.useCallback(e=>{h(e.target.files)},[h]),P=o.useCallback(e=>{e.preventDefault(),e.stopPropagation(),!a&&!r&&q(!0)},[a,r]),V=o.useCallback(e=>{e.preventDefault(),e.stopPropagation(),q(!1)},[]),L=o.useCallback(e=>{e.preventDefault(),e.stopPropagation(),q(!1),!(a||r)&&h(e.dataTransfer.files)},[a,r,h]),C=b||(()=>{const e=[];if(s){const v=s.split(",").map(f=>f.trim().replace(".","").toUpperCase()).join(", ");e.push(v)}return i&&e.push(`máx ${i}MB cada`),e.join(" • ")})();return t.jsxs("div",{className:g.cn("relative border-2 border-dashed rounded-lg p-8 text-center transition-all cursor-pointer","hover:border-primary/50 hover:bg-muted/30",l&&"border-primary bg-primary/5 scale-[1.02]",(a||r)&&"opacity-50 cursor-not-allowed hover:border-dashed hover:bg-transparent",r&&"animate-pulse",T),onClick:$,onDragOver:P,onDragLeave:V,onDrop:L,children:[t.jsx("input",{ref:p,type:"file",multiple:u,accept:s,className:"hidden",onChange:D,disabled:a||r}),t.jsxs("div",{className:"flex flex-col items-center gap-3",children:[k||t.jsx("div",{className:g.cn("transition-transform",l&&"scale-110"),children:r?t.jsx("div",{className:"h-12 w-12 mx-auto",children:t.jsxs("svg",{className:"animate-spin h-12 w-12 text-primary",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",children:[t.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),t.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]})}):t.jsx(w.Upload,{className:g.cn("h-12 w-12 mx-auto text-muted-foreground transition-colors",l&&"text-primary")})}),t.jsxs("div",{className:"space-y-1",children:[t.jsx("p",{className:g.cn("font-medium transition-colors",l&&"text-primary",r&&"text-muted-foreground"),children:r?"Enviando arquivos...":l?"Solte os arquivos aqui":j}),C&&t.jsx("p",{className:"text-xs text-muted-foreground",children:C}),!a&&!r&&u&&c>1&&t.jsxs("p",{className:"text-xs text-muted-foreground",children:["Você pode selecionar até ",c," arquivo(s)"]})]}),a&&t.jsxs("div",{className:"flex items-center gap-1 text-xs text-muted-foreground",children:[t.jsx(w.AlertCircle,{className:"h-3 w-3"}),t.jsx("span",{children:"Upload desabilitado"})]})]})]})}exports.FileUploadZone=M;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),w=require("lucide-react"),a=require("react"),m=require("../utils.cjs");function R(n,o){const u=o*1024*1024;return n.size>u?`Arquivo muito grande. Máximo: ${o}MB`:null}function W(n,o){if(!o)return null;const u=o.split(",").map(r=>r.trim().toLowerCase()),c=n.name.toLowerCase(),i=n.type.toLowerCase();return u.some(r=>{if(r.includes("*")){const[j]=r.split("/");return i.startsWith(j+"/")}return r.startsWith(".")?c.endsWith(r):i===r})?null:"Tipo de arquivo não suportado"}function M({onFilesSelected:n,accept:o,multiple:u=!0,maxFiles:c=10,maxSizeMB:i=50,disabled:s=!1,isUploading:r=!1,title:j="Clique para fazer upload de arquivos",description:N,icon:k,className:D,onError:p}){const[l,y]=a.useState(!1),v=a.useRef(null),b=a.useCallback(e=>{p==null||p(e)},[p]),h=a.useCallback(e=>{if(!e||e.length===0)return;const x=Array.from(e);if(x.length>c){b(`Máximo de ${c} arquivo(s) permitido(s)`);return}const f=[],g=[];for(const d of x){const C=R(d,i);if(C){g.push(`${d.name}: ${C}`);continue}const A=W(d,o);if(A){g.push(`${d.name}: ${A}`);continue}f.push(d)}g.length>0&&b(g.join(`
2
+ `)),f.length>0&&n(f),v.current&&(v.current.value="")},[c,i,o,n,b]),T=a.useCallback(()=>{var e;s||r||(e=v.current)==null||e.click()},[s,r]),$=a.useCallback(e=>{h(e.target.files)},[h]),P=a.useCallback(e=>{e.preventDefault(),e.stopPropagation(),!s&&!r&&y(!0)},[s,r]),V=a.useCallback(e=>{e.preventDefault(),e.stopPropagation(),y(!1)},[]),L=a.useCallback(e=>{e.preventDefault(),e.stopPropagation(),y(!1),!(s||r)&&h(e.dataTransfer.files)},[s,r,h]),q=N||(()=>{const e=[];if(o){const x=o.split(",").map(f=>f.trim().replace(".","").toUpperCase()).join(", ");e.push(x)}return i&&e.push(`máx ${i}MB cada`),e.join(" • ")})();return t.jsxs("div",{className:m.cn("relative border-2 border-dashed rounded-lg p-8 text-center transition-all cursor-pointer","hover:border-primary/50 hover:bg-muted/30","focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",l&&"border-primary bg-primary/5 scale-[1.02]",s&&"opacity-50 cursor-not-allowed hover:border-dashed hover:bg-transparent",r&&"cursor-progress hover:border-dashed hover:bg-transparent",r&&"animate-pulse",D),role:"button",tabIndex:s||r?-1:0,"aria-disabled":s||r,onClick:T,onKeyDown:m.pressableKeyDown,onDragOver:P,onDragLeave:V,onDrop:L,children:[t.jsx("input",{ref:v,type:"file",multiple:u,accept:o,className:"hidden",onChange:$,disabled:s||r}),t.jsxs("div",{className:"flex flex-col items-center gap-3",children:[k||t.jsx("div",{className:m.cn("transition-transform",l&&"scale-110"),children:r?t.jsx("div",{className:"h-12 w-12 mx-auto",children:t.jsxs("svg",{className:"animate-spin h-12 w-12 text-primary",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",children:[t.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),t.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]})}):t.jsx(w.Upload,{className:m.cn("h-12 w-12 mx-auto text-muted-foreground transition-colors",l&&"text-primary")})}),t.jsxs("div",{className:"space-y-1",children:[t.jsx("p",{className:m.cn("font-medium transition-colors",l&&"text-primary",r&&"text-muted-foreground"),children:r?"Enviando arquivos...":l?"Solte os arquivos aqui":j}),q&&t.jsx("p",{className:"text-xs text-muted-foreground",children:q}),!s&&!r&&u&&c>1&&t.jsxs("p",{className:"text-xs text-muted-foreground",children:["Você pode selecionar até ",c," arquivo(s)"]})]}),s&&t.jsxs("div",{className:"flex items-center gap-1 text-xs text-muted-foreground",children:[t.jsx(w.AlertCircle,{className:"h-3 w-3"}),t.jsx("span",{children:"Upload desabilitado"})]})]})]})}exports.FileUploadZone=M;
3
3
  //# sourceMappingURL=file-upload-zone.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-upload-zone.cjs","sources":["../../../../src/components/ui/forms/file-upload-zone.tsx"],"sourcesContent":["import { AlertCircle, Upload } from 'lucide-react';\nimport { useCallback, useRef, useState } from 'react';\n\nimport { cn } from '../utils';\n\n/**\n * Props do componente FileUploadZone\n */\nexport interface FileUploadZoneProps {\n /** Callback quando arquivos são selecionados */\n onFilesSelected: (files: File[]) => void;\n\n /** Tipos de arquivo aceitos (ex: \".pdf,.doc,.docx\" ou \"image/*\") */\n accept?: string;\n\n /** Permitir múltiplos arquivos */\n multiple?: boolean;\n\n /** Número máximo de arquivos */\n maxFiles?: number;\n\n /** Tamanho máximo em MB */\n maxSizeMB?: number;\n\n /** Desabilitar upload */\n disabled?: boolean;\n\n /** Estado de loading/upload em andamento */\n isUploading?: boolean;\n\n /** Título da zona de upload */\n title?: string;\n\n /** Descrição da zona de upload */\n description?: string;\n\n /** Ícone customizado */\n icon?: React.ReactNode;\n\n /** Classe CSS adicional */\n className?: string;\n\n /** Callback quando houver erro de validação */\n onError?: (error: string) => void;\n}\n\n/**\n * Valida o tamanho do arquivo\n */\nfunction validarTamanhoArquivo(arquivo: File, tamanhoMaximoMB: number): string | null {\n const bytesMaximos = tamanhoMaximoMB * 1024 * 1024;\n if (arquivo.size > bytesMaximos) {\n return `Arquivo muito grande. Máximo: ${tamanhoMaximoMB}MB`;\n }\n return null;\n}\n\n/**\n * Valida o tipo do arquivo\n */\nfunction validarTipoArquivo(arquivo: File, tiposAceitos?: string): string | null {\n if (!tiposAceitos) return null;\n\n const tiposAceitosArray = tiposAceitos.split(',').map(t => t.trim().toLowerCase());\n const nomeArquivo = arquivo.name.toLowerCase();\n const tipoArquivo = arquivo.type.toLowerCase();\n\n const eValido = tiposAceitosArray.some(tipo => {\n // Wildcard (ex: image/*)\n if (tipo.includes('*')) {\n const [categoria] = tipo.split('/');\n return tipoArquivo.startsWith(categoria + '/');\n }\n\n // Extensão (ex: .pdf)\n if (tipo.startsWith('.')) {\n return nomeArquivo.endsWith(tipo);\n }\n\n // MIME type exato\n return tipoArquivo === tipo;\n });\n\n if (!eValido) {\n return 'Tipo de arquivo não suportado';\n }\n\n return null;\n}\n\n/**\n * Componente de zona de upload com drag-and-drop\n */\nexport function FileUploadZone({\n onFilesSelected,\n accept,\n multiple = true,\n maxFiles = 10,\n maxSizeMB = 50,\n disabled = false,\n isUploading = false,\n title = 'Clique para fazer upload de arquivos',\n description,\n icon,\n className,\n onError,\n}: FileUploadZoneProps) {\n const [estaArrastando, setEstaArrastando] = useState(false);\n const refInput = useRef<HTMLInputElement>(null);\n\n const gerenciarErro = useCallback((erro: string) => {\n onError?.(erro);\n }, [onError]);\n\n const validarEProcessarArquivos = useCallback((arquivos: FileList | null) => {\n if (!arquivos || arquivos.length === 0) return;\n\n const arrayArquivos = Array.from(arquivos);\n\n // Validar número de arquivos\n if (arrayArquivos.length > maxFiles) {\n gerenciarErro(`Máximo de ${maxFiles} arquivo(s) permitido(s)`);\n return;\n }\n\n // Validar cada arquivo\n const arquivosValidos: File[] = [];\n const erros: string[] = [];\n\n for (const arquivo of arrayArquivos) {\n // Validar tamanho\n const erroTamanho = validarTamanhoArquivo(arquivo, maxSizeMB);\n if (erroTamanho) {\n erros.push(`${arquivo.name}: ${erroTamanho}`);\n continue;\n }\n\n // Validar tipo\n const erroTipo = validarTipoArquivo(arquivo, accept);\n if (erroTipo) {\n erros.push(`${arquivo.name}: ${erroTipo}`);\n continue;\n }\n\n arquivosValidos.push(arquivo);\n }\n\n // Mostrar erros\n if (erros.length > 0) {\n gerenciarErro(erros.join('\\n'));\n }\n\n // Processar arquivos válidos\n if (arquivosValidos.length > 0) {\n onFilesSelected(arquivosValidos);\n }\n\n // Limpar input\n if (refInput.current) {\n refInput.current.value = '';\n }\n }, [maxFiles, maxSizeMB, accept, onFilesSelected, gerenciarErro]);\n\n const gerenciarClique = useCallback(() => {\n if (disabled || isUploading) return;\n refInput.current?.click();\n }, [disabled, isUploading]);\n\n const gerenciarMudancaArquivo = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n validarEProcessarArquivos(e.target.files);\n }, [validarEProcessarArquivos]);\n\n const gerenciarArrastarSobre = useCallback((e: React.DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n e.stopPropagation();\n if (!disabled && !isUploading) {\n setEstaArrastando(true);\n }\n }, [disabled, isUploading]);\n\n const gerenciarArrastarSair = useCallback((e: React.DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n e.stopPropagation();\n setEstaArrastando(false);\n }, []);\n\n const gerenciarSoltar = useCallback((e: React.DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n e.stopPropagation();\n setEstaArrastando(false);\n\n if (disabled || isUploading) return;\n\n validarEProcessarArquivos(e.dataTransfer.files);\n }, [disabled, isUploading, validarEProcessarArquivos]);\n\n const descricaoPadrao = description || (() => {\n const partes: string[] = [];\n\n if (accept) {\n const tipos = accept.split(',').map(t => t.trim().replace('.', '').toUpperCase()).join(', ');\n partes.push(tipos);\n }\n\n if (maxSizeMB) {\n partes.push(`máx ${maxSizeMB}MB cada`);\n }\n\n return partes.join(' • ');\n })();\n\n return (\n <div\n className={cn(\n 'relative border-2 border-dashed rounded-lg p-8 text-center transition-all cursor-pointer',\n 'hover:border-primary/50 hover:bg-muted/30',\n estaArrastando && 'border-primary bg-primary/5 scale-[1.02]',\n (disabled || isUploading) && 'opacity-50 cursor-not-allowed hover:border-dashed hover:bg-transparent',\n isUploading && 'animate-pulse',\n className,\n )}\n onClick={gerenciarClique}\n onDragOver={gerenciarArrastarSobre}\n onDragLeave={gerenciarArrastarSair}\n onDrop={gerenciarSoltar}\n >\n <input\n ref={refInput}\n type=\"file\"\n multiple={multiple}\n accept={accept}\n className=\"hidden\"\n onChange={gerenciarMudancaArquivo}\n disabled={disabled || isUploading}\n />\n\n <div className=\"flex flex-col items-center gap-3\">\n {icon || (\n <div className={cn(\n 'transition-transform',\n estaArrastando && 'scale-110',\n )}>\n {isUploading ? (\n <div className=\"h-12 w-12 mx-auto\">\n <svg className=\"animate-spin h-12 w-12 text-primary\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\"></circle>\n <path className=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n </div>\n ) : (\n <Upload className={cn(\n 'h-12 w-12 mx-auto text-muted-foreground transition-colors',\n estaArrastando && 'text-primary',\n )} />\n )}\n </div>\n )}\n\n <div className=\"space-y-1\">\n <p className={cn(\n 'font-medium transition-colors',\n estaArrastando && 'text-primary',\n isUploading && 'text-muted-foreground',\n )}>\n {isUploading ? 'Enviando arquivos...' : estaArrastando ? 'Solte os arquivos aqui' : title}\n </p>\n\n {descricaoPadrao && (\n <p className=\"text-xs text-muted-foreground\">\n {descricaoPadrao}\n </p>\n )}\n\n {!disabled && !isUploading && multiple && maxFiles > 1 && (\n <p className=\"text-xs text-muted-foreground\">\n Você pode selecionar até {maxFiles} arquivo(s)\n </p>\n )}\n </div>\n\n {disabled && (\n <div className=\"flex items-center gap-1 text-xs text-muted-foreground\">\n <AlertCircle className=\"h-3 w-3\" />\n <span>Upload desabilitado</span>\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"names":["validarTamanhoArquivo","arquivo","tamanhoMaximoMB","bytesMaximos","validarTipoArquivo","tiposAceitos","tiposAceitosArray","t","nomeArquivo","tipoArquivo","tipo","categoria","FileUploadZone","onFilesSelected","accept","multiple","maxFiles","maxSizeMB","disabled","isUploading","title","description","icon","className","onError","estaArrastando","setEstaArrastando","useState","refInput","useRef","gerenciarErro","useCallback","erro","validarEProcessarArquivos","arquivos","arrayArquivos","arquivosValidos","erros","erroTamanho","erroTipo","gerenciarClique","_a","gerenciarMudancaArquivo","gerenciarArrastarSobre","gerenciarArrastarSair","gerenciarSoltar","descricaoPadrao","partes","tipos","jsxs","cn","jsx","Upload","AlertCircle"],"mappings":"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"}
1
+ {"version":3,"file":"file-upload-zone.cjs","sources":["../../../../src/components/ui/forms/file-upload-zone.tsx"],"sourcesContent":["import { AlertCircle, Upload } from 'lucide-react';\nimport { useCallback, useRef, useState } from 'react';\n\nimport { cn, pressableKeyDown } from '../utils';\n\n/**\n * Props do componente FileUploadZone\n */\nexport interface FileUploadZoneProps {\n /** Callback quando arquivos são selecionados */\n onFilesSelected: (files: File[]) => void;\n\n /** Tipos de arquivo aceitos (ex: \".pdf,.doc,.docx\" ou \"image/*\") */\n accept?: string;\n\n /** Permitir múltiplos arquivos */\n multiple?: boolean;\n\n /** Número máximo de arquivos */\n maxFiles?: number;\n\n /** Tamanho máximo em MB */\n maxSizeMB?: number;\n\n /** Desabilitar upload */\n disabled?: boolean;\n\n /** Estado de loading/upload em andamento */\n isUploading?: boolean;\n\n /** Título da zona de upload */\n title?: string;\n\n /** Descrição da zona de upload */\n description?: string;\n\n /** Ícone customizado */\n icon?: React.ReactNode;\n\n /** Classe CSS adicional */\n className?: string;\n\n /** Callback quando houver erro de validação */\n onError?: (error: string) => void;\n}\n\n/**\n * Valida o tamanho do arquivo\n */\nfunction validarTamanhoArquivo(arquivo: File, tamanhoMaximoMB: number): string | null {\n const bytesMaximos = tamanhoMaximoMB * 1024 * 1024;\n if (arquivo.size > bytesMaximos) {\n return `Arquivo muito grande. Máximo: ${tamanhoMaximoMB}MB`;\n }\n return null;\n}\n\n/**\n * Valida o tipo do arquivo\n */\nfunction validarTipoArquivo(arquivo: File, tiposAceitos?: string): string | null {\n if (!tiposAceitos) return null;\n\n const tiposAceitosArray = tiposAceitos.split(',').map(t => t.trim().toLowerCase());\n const nomeArquivo = arquivo.name.toLowerCase();\n const tipoArquivo = arquivo.type.toLowerCase();\n\n const eValido = tiposAceitosArray.some(tipo => {\n // Wildcard (ex: image/*)\n if (tipo.includes('*')) {\n const [categoria] = tipo.split('/');\n return tipoArquivo.startsWith(categoria + '/');\n }\n\n // Extensão (ex: .pdf)\n if (tipo.startsWith('.')) {\n return nomeArquivo.endsWith(tipo);\n }\n\n // MIME type exato\n return tipoArquivo === tipo;\n });\n\n if (!eValido) {\n return 'Tipo de arquivo não suportado';\n }\n\n return null;\n}\n\n/**\n * Componente de zona de upload com drag-and-drop\n */\nexport function FileUploadZone({\n onFilesSelected,\n accept,\n multiple = true,\n maxFiles = 10,\n maxSizeMB = 50,\n disabled = false,\n isUploading = false,\n title = 'Clique para fazer upload de arquivos',\n description,\n icon,\n className,\n onError,\n}: FileUploadZoneProps) {\n const [estaArrastando, setEstaArrastando] = useState(false);\n const refInput = useRef<HTMLInputElement>(null);\n\n const gerenciarErro = useCallback((erro: string) => {\n onError?.(erro);\n }, [onError]);\n\n const validarEProcessarArquivos = useCallback((arquivos: FileList | null) => {\n if (!arquivos || arquivos.length === 0) return;\n\n const arrayArquivos = Array.from(arquivos);\n\n // Validar número de arquivos\n if (arrayArquivos.length > maxFiles) {\n gerenciarErro(`Máximo de ${maxFiles} arquivo(s) permitido(s)`);\n return;\n }\n\n // Validar cada arquivo\n const arquivosValidos: File[] = [];\n const erros: string[] = [];\n\n for (const arquivo of arrayArquivos) {\n // Validar tamanho\n const erroTamanho = validarTamanhoArquivo(arquivo, maxSizeMB);\n if (erroTamanho) {\n erros.push(`${arquivo.name}: ${erroTamanho}`);\n continue;\n }\n\n // Validar tipo\n const erroTipo = validarTipoArquivo(arquivo, accept);\n if (erroTipo) {\n erros.push(`${arquivo.name}: ${erroTipo}`);\n continue;\n }\n\n arquivosValidos.push(arquivo);\n }\n\n // Mostrar erros\n if (erros.length > 0) {\n gerenciarErro(erros.join('\\n'));\n }\n\n // Processar arquivos válidos\n if (arquivosValidos.length > 0) {\n onFilesSelected(arquivosValidos);\n }\n\n // Limpar input\n if (refInput.current) {\n refInput.current.value = '';\n }\n }, [maxFiles, maxSizeMB, accept, onFilesSelected, gerenciarErro]);\n\n const gerenciarClique = useCallback(() => {\n if (disabled || isUploading) return;\n refInput.current?.click();\n }, [disabled, isUploading]);\n\n const gerenciarMudancaArquivo = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n validarEProcessarArquivos(e.target.files);\n }, [validarEProcessarArquivos]);\n\n const gerenciarArrastarSobre = useCallback((e: React.DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n e.stopPropagation();\n if (!disabled && !isUploading) {\n setEstaArrastando(true);\n }\n }, [disabled, isUploading]);\n\n const gerenciarArrastarSair = useCallback((e: React.DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n e.stopPropagation();\n setEstaArrastando(false);\n }, []);\n\n const gerenciarSoltar = useCallback((e: React.DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n e.stopPropagation();\n setEstaArrastando(false);\n\n if (disabled || isUploading) return;\n\n validarEProcessarArquivos(e.dataTransfer.files);\n }, [disabled, isUploading, validarEProcessarArquivos]);\n\n const descricaoPadrao = description || (() => {\n const partes: string[] = [];\n\n if (accept) {\n const tipos = accept.split(',').map(t => t.trim().replace('.', '').toUpperCase()).join(', ');\n partes.push(tipos);\n }\n\n if (maxSizeMB) {\n partes.push(`máx ${maxSizeMB}MB cada`);\n }\n\n return partes.join(' • ');\n })();\n\n return (\n <div\n className={cn(\n 'relative border-2 border-dashed rounded-lg p-8 text-center transition-all cursor-pointer',\n 'hover:border-primary/50 hover:bg-muted/30',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n estaArrastando && 'border-primary bg-primary/5 scale-[1.02]',\n disabled && 'opacity-50 cursor-not-allowed hover:border-dashed hover:bg-transparent',\n isUploading && 'cursor-progress hover:border-dashed hover:bg-transparent',\n isUploading && 'animate-pulse',\n className,\n )}\n role=\"button\"\n tabIndex={disabled || isUploading ? -1 : 0}\n aria-disabled={disabled || isUploading}\n onClick={gerenciarClique}\n onKeyDown={pressableKeyDown}\n onDragOver={gerenciarArrastarSobre}\n onDragLeave={gerenciarArrastarSair}\n onDrop={gerenciarSoltar}\n >\n <input\n ref={refInput}\n type=\"file\"\n multiple={multiple}\n accept={accept}\n className=\"hidden\"\n onChange={gerenciarMudancaArquivo}\n disabled={disabled || isUploading}\n />\n\n <div className=\"flex flex-col items-center gap-3\">\n {icon || (\n <div className={cn(\n 'transition-transform',\n estaArrastando && 'scale-110',\n )}>\n {isUploading ? (\n <div className=\"h-12 w-12 mx-auto\">\n <svg className=\"animate-spin h-12 w-12 text-primary\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\"></circle>\n <path className=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n </div>\n ) : (\n <Upload className={cn(\n 'h-12 w-12 mx-auto text-muted-foreground transition-colors',\n estaArrastando && 'text-primary',\n )} />\n )}\n </div>\n )}\n\n <div className=\"space-y-1\">\n <p className={cn(\n 'font-medium transition-colors',\n estaArrastando && 'text-primary',\n isUploading && 'text-muted-foreground',\n )}>\n {isUploading ? 'Enviando arquivos...' : estaArrastando ? 'Solte os arquivos aqui' : title}\n </p>\n\n {descricaoPadrao && (\n <p className=\"text-xs text-muted-foreground\">\n {descricaoPadrao}\n </p>\n )}\n\n {!disabled && !isUploading && multiple && maxFiles > 1 && (\n <p className=\"text-xs text-muted-foreground\">\n Você pode selecionar até {maxFiles} arquivo(s)\n </p>\n )}\n </div>\n\n {disabled && (\n <div className=\"flex items-center gap-1 text-xs text-muted-foreground\">\n <AlertCircle className=\"h-3 w-3\" />\n <span>Upload desabilitado</span>\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"names":["validarTamanhoArquivo","arquivo","tamanhoMaximoMB","bytesMaximos","validarTipoArquivo","tiposAceitos","tiposAceitosArray","t","nomeArquivo","tipoArquivo","tipo","categoria","FileUploadZone","onFilesSelected","accept","multiple","maxFiles","maxSizeMB","disabled","isUploading","title","description","icon","className","onError","estaArrastando","setEstaArrastando","useState","refInput","useRef","gerenciarErro","useCallback","erro","validarEProcessarArquivos","arquivos","arrayArquivos","arquivosValidos","erros","erroTamanho","erroTipo","gerenciarClique","_a","gerenciarMudancaArquivo","gerenciarArrastarSobre","gerenciarArrastarSair","gerenciarSoltar","descricaoPadrao","partes","tipos","jsxs","cn","pressableKeyDown","jsx","Upload","AlertCircle"],"mappings":"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"}