ivt
Version:
Ivt Components Library
1 lines • 11.9 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","sources":["../../src/utils/string.ts","../../src/components/ui/combobox/combobox.tsx"],"sourcesContent":["const specialCharacterMap = [\n\t[\"á\", \"a\"],\n\t[\"à\", \"a\"],\n\t[\"ã\", \"a\"],\n\t[\"â\", \"a\"],\n\t[\"é\", \"e\"],\n\t[\"ê\", \"e\"],\n\t[\"í\", \"i\"],\n\t[\"ì\", \"i\"],\n\t[\"ó\", \"o\"],\n\t[\"ô\", \"o\"],\n\t[\"õ\", \"o\"],\n\t[\"ú\", \"u\"],\n\t[\"ù\", \"u\"],\n\t[\"ç\", \"c\"],\n] as const;\n\nconst lowercaseExceptions = [\"de\", \"da\", \"do\", \"das\", \"dos\", \"em\", \"para\", \"por\", \"a\", \"e\", \"o\"];\n\n/**\n * Remove acentos e caracteres especiais, mantendo letras equivalentes.\n */\nexport function removeSpecialCharacters(value: string): string {\n\tlet result = `${value}`.trim();\n\tfor (const [char, replacement] of specialCharacterMap) {\n\t\tresult = result.split(char).join(replacement);\n\t\tresult = result.split(char.toUpperCase()).join(replacement.toUpperCase());\n\t}\n\treturn result;\n}\n\n/**\n * Capitaliza cada palavra (primeira letra maiúscula).\n */\nexport function capitalize(value: string): string {\n\tif (!value) return \"\";\n\treturn value\n\t\t.toLowerCase()\n\t\t.split(\" \")\n\t\t.map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n\t\t.join(\" \");\n}\n\n/**\n * Capitaliza ignorando preposições como \"de\", \"da\", etc.\n * Também normaliza acentos antes da capitalização.\n */\nexport function capitalizeSpecial(value: string): string {\n\tif (!value) return \"\";\n\n\tconst clean = removeSpecialCharacters(value.toLowerCase());\n\n\treturn clean\n\t\t.split(\" \")\n\t\t.map((word, index) => {\n\t\t\tif (index !== 0 && lowercaseExceptions.includes(word)) {\n\t\t\t\treturn word.toLowerCase();\n\t\t\t}\n\t\t\treturn word.charAt(0).toUpperCase() + word.slice(1);\n\t\t})\n\t\t.join(\" \");\n}\n","\"use client\";\n\nimport { Check, ChevronsUpDown } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n\tCommand,\n\tCommandEmpty,\n\tCommandGroup,\n\tCommandInput,\n\tCommandItem,\n\tCommandList,\n} from \"@/components/ui/command\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"@/components/ui/popover\";\nimport { cn } from \"@/lib/utils\";\nimport { removeSpecialCharacters } from \"@/utils/string\";\n\ninterface ComboboxItem {\n\tvalue: string;\n\tlabel: string;\n}\n\ninterface ComboboxProps {\n\t/**\n\t * A lista de itens a serem exibidos no combobox.\n\t * Cada item deve ter 'value' e 'label'.\n\t */\n\titems: ComboboxItem[];\n\t/**\n\t * O valor atualmente selecionado no combobox.\n\t */\n\tvalue: string;\n\t/**\n\t * Função de callback para quando um item é selecionado.\n\t * Recebe o novo valor selecionado.\n\t */\n\tonValueChange: (newValue: string) => void;\n\t/**\n\t * Placeholder para o botão do combobox quando nenhum item está selecionado.\n\t * @default \"Select item...\"\n\t */\n\tplaceholder?: string;\n\t/**\n\t * Placeholder para o campo de busca dentro do combobox.\n\t * @default \"Search item...\"\n\t */\n\tsearchPlaceholder?: string;\n\t/**\n\t * Mensagem exibida quando nenhum item é encontrado na busca.\n\t * @default \"No item found.\"\n\t */\n\temptyMessage?: string;\n\t/**\n\t * Largura do combobox (e do popover).\n\t * @default \"w-[200px]\"\n\t */\n\twidthClassName?: string;\n\t/**\n\t * Classes CSS adicionais para o combobox principal.\n\t */\n\tclassName?: string;\n\t/**\n\t * Título do grupo de comandos.\n\t */\n\tgroupHeading?: string;\n\t/**\n * \n\tAtiva ou desativa a normalização da busca, removendo acentos e caracteres especiais.\n\tQuando **true** (padrão), a busca ignora diferenças de acentuação — útil para buscas mais flexíveis.\n\tQuando **false**, a busca será literal, sensível a acentuação.\n */\n\tnormalizeSearch?: boolean;\n\t/**\n\t * Desabilita a interação com o combobox.\n\t */\n\tdisabled?: boolean;\n}\n\nexport function Combobox({\n\titems,\n\tvalue,\n\tonValueChange,\n\tplaceholder = \"Selecione um item...\",\n\tsearchPlaceholder = \"Busque um item...\",\n\temptyMessage = \"Nenhum item encontrado.\",\n\twidthClassName = \"w-fit\",\n\tclassName,\n\tgroupHeading,\n\tnormalizeSearch = true,\n\tdisabled = false,\n}: ComboboxProps) {\n\tconst [open, setOpen] = React.useState(false);\n\tconst [search, setSearch] = React.useState(\"\");\n\n\tconst normalize = React.useCallback(\n\t\t(text: string) =>\n\t\t\tnormalizeSearch ? removeSpecialCharacters(text).toLowerCase() : text.toLowerCase(),\n\t\t[normalizeSearch],\n\t);\n\n\tconst filteredItems = React.useMemo(() => {\n\t\tconst normalizedSearch = normalize(search);\n\n\t\tconst result = items.filter((item) => {\n\t\t\tconst normalizedLabel = normalize(item.label);\n\t\t\tconst normalizedValue = normalize(item.value);\n\n\t\t\treturn (\n\t\t\t\tnormalizedLabel.includes(normalizedSearch) || normalizedValue.includes(normalizedSearch)\n\t\t\t);\n\t\t});\n\n\t\treturn result;\n\t}, [items, search, normalize]);\n\n\tconst handleSelect = (currentValue: string) => {\n\t\tonValueChange(currentValue === value ? \"\" : currentValue);\n\t\tsetTimeout(() => setSearch(\"\"), 150);\n\t\tsetOpen(false);\n\t};\n\n\treturn (\n\t\t<Popover open={open} onOpenChange={setOpen}>\n\t\t\t<PopoverTrigger asChild>\n\t\t\t\t<Button\n\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\trole=\"combobox\"\n\t\t\t\t\taria-expanded={open}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tclassName={cn(widthClassName, \"justify-between\", className)}\n\t\t\t\t>\n\t\t\t\t\t{value\n\t\t\t\t\t\t? (items.find((item) => item.value === value)?.label ?? emptyMessage)\n\t\t\t\t\t\t: placeholder}\n\t\t\t\t\t<ChevronsUpDown className=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />\n\t\t\t\t</Button>\n\t\t\t</PopoverTrigger>\n\n\t\t\t<PopoverContent\n\t\t\t\talign=\"start\"\n\t\t\t\tclassName={cn(widthClassName, \"p-0\")}\n\t\t\t\tonOpenAutoFocus={(e) => e.preventDefault()}\n\t\t\t>\n\t\t\t\t<Command shouldFilter={false}>\n\t\t\t\t\t<CommandInput\n\t\t\t\t\t\tplaceholder={searchPlaceholder}\n\t\t\t\t\t\tclassName=\"h-9\"\n\t\t\t\t\t\tvalue={search}\n\t\t\t\t\t\tonValueChange={setSearch}\n\t\t\t\t\t/>\n\t\t\t\t\t<CommandList>\n\t\t\t\t\t\t{filteredItems.length === 0 ? (\n\t\t\t\t\t\t\t<CommandEmpty>{emptyMessage}</CommandEmpty>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<CommandGroup heading={groupHeading}>\n\t\t\t\t\t\t\t\t{filteredItems.map((item) => (\n\t\t\t\t\t\t\t\t\t<CommandItem\n\t\t\t\t\t\t\t\t\t\tkey={item.value}\n\t\t\t\t\t\t\t\t\t\tvalue={item.value}\n\t\t\t\t\t\t\t\t\t\tonSelect={() => handleSelect(item.value)}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{item.label}\n\t\t\t\t\t\t\t\t\t\t<Check\n\t\t\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\t\t\"ml-auto h-4 w-4\",\n\t\t\t\t\t\t\t\t\t\t\t\tvalue === item.value ? \"opacity-100\" : \"opacity-0\",\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</CommandItem>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</CommandGroup>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</CommandList>\n\t\t\t\t</Command>\n\t\t\t</PopoverContent>\n\t\t</Popover>\n\t);\n}\n"],"names":["specialCharacterMap","removeSpecialCharacters","value","result","trim","char","replacement","split","join","toUpperCase","Combobox","items","onValueChange","placeholder","searchPlaceholder","emptyMessage","widthClassName","className","groupHeading","normalizeSearch","disabled","open","setOpen","React","useState","search","setSearch","normalize","useCallback","text","toLowerCase","filteredItems","useMemo","normalizedSearch","filter","item","normalizedLabel","label","normalizedValue","includes","handleSelect","currentValue","setTimeout","Popover","onOpenChange","PopoverTrigger","asChild","Button","variant","role","aria-expanded","cn","find","ChevronsUpDown","PopoverContent","align","onOpenAutoFocus","e","preventDefault","Command","shouldFilter","CommandInput","CommandList","length","CommandEmpty","CommandGroup","heading","map","CommandItem","key","onSelect","Check"],"mappings":"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"}