@snksergio/design-system 0.67.0 → 0.68.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 (123) hide show
  1. package/dist-lib/ai/componentes/AppShell.md +1 -1
  2. package/dist-lib/ai/componentes/Chip.md +11 -0
  3. package/dist-lib/ai/componentes/Combobox.md +23 -0
  4. package/dist-lib/ai/componentes/DatePicker.md +15 -0
  5. package/dist-lib/ai/componentes/FileUploadField.md +23 -0
  6. package/dist-lib/ai/componentes/Header.md +9 -0
  7. package/dist-lib/ai/componentes/Kpi.md +14 -1
  8. package/dist-lib/ai/componentes/MenuSidebar.md +3 -3
  9. package/dist-lib/ai/componentes/PageHeader.md +6 -0
  10. package/dist-lib/ai/componentes/_primitivos.md +9 -2
  11. package/dist-lib/ai/global/componentes.md +20 -2
  12. package/dist-lib/ai/manifest.json +2 -2
  13. package/dist-lib/shadcn.cjs +1 -0
  14. package/dist-lib/shadcn.cjs.map +1 -1
  15. package/dist-lib/shadcn.mjs +2 -1
  16. package/dist-lib/src/components/shadcn/alert-dialog.cjs +13 -2
  17. package/dist-lib/src/components/shadcn/alert-dialog.cjs.map +1 -1
  18. package/dist-lib/src/components/shadcn/alert-dialog.d.ts +21 -1
  19. package/dist-lib/src/components/shadcn/alert-dialog.d.ts.map +1 -1
  20. package/dist-lib/src/components/shadcn/alert-dialog.mjs +13 -2
  21. package/dist-lib/src/components/shadcn/alert-dialog.mjs.map +1 -1
  22. package/dist-lib/src/components/shadcn/card.cjs +22 -2
  23. package/dist-lib/src/components/shadcn/card.cjs.map +1 -1
  24. package/dist-lib/src/components/shadcn/card.d.ts +10 -1
  25. package/dist-lib/src/components/shadcn/card.d.ts.map +1 -1
  26. package/dist-lib/src/components/shadcn/card.mjs +22 -2
  27. package/dist-lib/src/components/shadcn/card.mjs.map +1 -1
  28. package/dist-lib/src/components/shadcn/clickable-surface.cjs +28 -4
  29. package/dist-lib/src/components/shadcn/clickable-surface.cjs.map +1 -1
  30. package/dist-lib/src/components/shadcn/clickable-surface.d.ts +26 -2
  31. package/dist-lib/src/components/shadcn/clickable-surface.d.ts.map +1 -1
  32. package/dist-lib/src/components/shadcn/clickable-surface.mjs +28 -4
  33. package/dist-lib/src/components/shadcn/clickable-surface.mjs.map +1 -1
  34. package/dist-lib/src/components/shadcn/command.cjs +26 -5
  35. package/dist-lib/src/components/shadcn/command.cjs.map +1 -1
  36. package/dist-lib/src/components/shadcn/command.d.ts +49 -2
  37. package/dist-lib/src/components/shadcn/command.d.ts.map +1 -1
  38. package/dist-lib/src/components/shadcn/command.mjs +26 -5
  39. package/dist-lib/src/components/shadcn/command.mjs.map +1 -1
  40. package/dist-lib/src/components/shadcn/input-group.d.ts +1 -1
  41. package/dist-lib/src/components/shadcn/input-otp.d.ts +1 -1
  42. package/dist-lib/src/components/shadcn/input.d.ts +1 -1
  43. package/dist-lib/src/components/shadcn/sheet.d.ts +1 -1
  44. package/dist-lib/src/components/ui/AppShell/app-shell.types.d.ts +1 -1
  45. package/dist-lib/src/components/ui/Chip/chip.cjs +7 -0
  46. package/dist-lib/src/components/ui/Chip/chip.cjs.map +1 -1
  47. package/dist-lib/src/components/ui/Chip/chip.d.ts.map +1 -1
  48. package/dist-lib/src/components/ui/Chip/chip.mjs +7 -0
  49. package/dist-lib/src/components/ui/Chip/chip.mjs.map +1 -1
  50. package/dist-lib/src/components/ui/Chip/chip.styles.cjs.map +1 -1
  51. package/dist-lib/src/components/ui/Chip/chip.styles.mjs.map +1 -1
  52. package/dist-lib/src/components/ui/Combobox/combobox.cjs +60 -22
  53. package/dist-lib/src/components/ui/Combobox/combobox.cjs.map +1 -1
  54. package/dist-lib/src/components/ui/Combobox/combobox.d.ts +2 -1
  55. package/dist-lib/src/components/ui/Combobox/combobox.d.ts.map +1 -1
  56. package/dist-lib/src/components/ui/Combobox/combobox.mjs +44 -22
  57. package/dist-lib/src/components/ui/Combobox/combobox.mjs.map +1 -1
  58. package/dist-lib/src/components/ui/Combobox/combobox.styles.cjs +5 -1
  59. package/dist-lib/src/components/ui/Combobox/combobox.styles.cjs.map +1 -1
  60. package/dist-lib/src/components/ui/Combobox/combobox.styles.d.ts +18 -0
  61. package/dist-lib/src/components/ui/Combobox/combobox.styles.d.ts.map +1 -1
  62. package/dist-lib/src/components/ui/Combobox/combobox.styles.mjs +5 -1
  63. package/dist-lib/src/components/ui/Combobox/combobox.styles.mjs.map +1 -1
  64. package/dist-lib/src/components/ui/Combobox/combobox.types.d.ts +21 -0
  65. package/dist-lib/src/components/ui/Combobox/combobox.types.d.ts.map +1 -1
  66. package/dist-lib/src/components/ui/DatePicker/datepicker.cjs +21 -3
  67. package/dist-lib/src/components/ui/DatePicker/datepicker.cjs.map +1 -1
  68. package/dist-lib/src/components/ui/DatePicker/datepicker.d.ts +10 -0
  69. package/dist-lib/src/components/ui/DatePicker/datepicker.d.ts.map +1 -1
  70. package/dist-lib/src/components/ui/DatePicker/datepicker.mjs +21 -3
  71. package/dist-lib/src/components/ui/DatePicker/datepicker.mjs.map +1 -1
  72. package/dist-lib/src/components/ui/FileUploadField/file-upload-field.cjs +1 -4
  73. package/dist-lib/src/components/ui/FileUploadField/file-upload-field.cjs.map +1 -1
  74. package/dist-lib/src/components/ui/FileUploadField/file-upload-field.d.ts.map +1 -1
  75. package/dist-lib/src/components/ui/FileUploadField/file-upload-field.mjs +1 -4
  76. package/dist-lib/src/components/ui/FileUploadField/file-upload-field.mjs.map +1 -1
  77. package/dist-lib/src/components/ui/FileUploadField/file-upload-field.types.d.ts +6 -0
  78. package/dist-lib/src/components/ui/FileUploadField/file-upload-field.types.d.ts.map +1 -1
  79. package/dist-lib/src/components/ui/Header/header-search.cjs +6 -4
  80. package/dist-lib/src/components/ui/Header/header-search.cjs.map +1 -1
  81. package/dist-lib/src/components/ui/Header/header-search.d.ts +14 -3
  82. package/dist-lib/src/components/ui/Header/header-search.d.ts.map +1 -1
  83. package/dist-lib/src/components/ui/Header/header-search.mjs +6 -4
  84. package/dist-lib/src/components/ui/Header/header-search.mjs.map +1 -1
  85. package/dist-lib/src/components/ui/Kpi/kpi-delta.cjs +5 -0
  86. package/dist-lib/src/components/ui/Kpi/kpi-delta.cjs.map +1 -1
  87. package/dist-lib/src/components/ui/Kpi/kpi-delta.d.ts.map +1 -1
  88. package/dist-lib/src/components/ui/Kpi/kpi-delta.mjs +5 -0
  89. package/dist-lib/src/components/ui/Kpi/kpi-delta.mjs.map +1 -1
  90. package/dist-lib/src/components/ui/Kpi/kpi-group.cjs.map +1 -1
  91. package/dist-lib/src/components/ui/Kpi/kpi-group.mjs.map +1 -1
  92. package/dist-lib/src/components/ui/Kpi/kpi.cjs +8 -3
  93. package/dist-lib/src/components/ui/Kpi/kpi.cjs.map +1 -1
  94. package/dist-lib/src/components/ui/Kpi/kpi.d.ts +1 -1
  95. package/dist-lib/src/components/ui/Kpi/kpi.d.ts.map +1 -1
  96. package/dist-lib/src/components/ui/Kpi/kpi.mjs +8 -3
  97. package/dist-lib/src/components/ui/Kpi/kpi.mjs.map +1 -1
  98. package/dist-lib/src/components/ui/Kpi/kpi.types.d.ts +9 -0
  99. package/dist-lib/src/components/ui/Kpi/kpi.types.d.ts.map +1 -1
  100. package/dist-lib/src/components/ui/MenuSidebar/sidebar.types.d.ts +1 -1
  101. package/dist-lib/src/components/ui/PageHeader/page-header.styles.cjs +4 -1
  102. package/dist-lib/src/components/ui/PageHeader/page-header.styles.cjs.map +1 -1
  103. package/dist-lib/src/components/ui/PageHeader/page-header.styles.d.ts +9 -0
  104. package/dist-lib/src/components/ui/PageHeader/page-header.styles.d.ts.map +1 -1
  105. package/dist-lib/src/components/ui/PageHeader/page-header.styles.mjs +4 -1
  106. package/dist-lib/src/components/ui/PageHeader/page-header.styles.mjs.map +1 -1
  107. package/dist-lib/src/components/ui/PageHeader/page-header.types.d.ts +11 -4
  108. package/dist-lib/src/components/ui/PageHeader/page-header.types.d.ts.map +1 -1
  109. package/dist-lib/src/components/ui/Table/table-span-row.cjs.map +1 -1
  110. package/dist-lib/src/components/ui/Table/table-span-row.mjs.map +1 -1
  111. package/dist-lib/src/lib/utils.cjs.map +1 -1
  112. package/dist-lib/src/lib/utils.mjs.map +1 -1
  113. package/dist-lib/src/utils/tv.cjs.map +1 -1
  114. package/dist-lib/src/utils/tv.mjs.map +1 -1
  115. package/dist-lib/src/utils/tw-merge-config.cjs.map +1 -1
  116. package/dist-lib/src/utils/tw-merge-config.mjs.map +1 -1
  117. package/dist-lib/src/utils/use-title-se-truncado.cjs +34 -0
  118. package/dist-lib/src/utils/use-title-se-truncado.cjs.map +1 -0
  119. package/dist-lib/src/utils/use-title-se-truncado.d.ts +30 -0
  120. package/dist-lib/src/utils/use-title-se-truncado.d.ts.map +1 -0
  121. package/dist-lib/src/utils/use-title-se-truncado.mjs +34 -0
  122. package/dist-lib/src/utils/use-title-se-truncado.mjs.map +1 -0
  123. package/package.json +1 -1
@@ -13,12 +13,14 @@ function HeaderSearch({
13
13
  commandEmptyMessage = "Nenhum resultado encontrado.",
14
14
  hotkey = { key: "k", meta: true, ctrl: true },
15
15
  onOpen,
16
+ ariaLabel = "Abrir busca",
16
17
  className
17
18
  }) {
18
19
  const [open, setOpen] = useState(false);
19
20
  const delegado = Boolean(onOpen);
20
21
  const abrir = () => onOpen ? onOpen() : setOpen(true);
21
22
  useEffect(() => {
23
+ if (hotkey === false) return;
22
24
  const handler = (e) => {
23
25
  if (e.key.toLowerCase() !== hotkey.key.toLowerCase()) return;
24
26
  const meta = hotkey.meta && e.metaKey;
@@ -31,7 +33,7 @@ function HeaderSearch({
31
33
  };
32
34
  window.addEventListener("keydown", handler);
33
35
  return () => window.removeEventListener("keydown", handler);
34
- }, [hotkey.key, hotkey.meta, hotkey.ctrl, onOpen]);
36
+ }, [hotkey, onOpen]);
35
37
  return /* @__PURE__ */ jsxs(Fragment, { children: [
36
38
  /* @__PURE__ */ jsxs(
37
39
  "button",
@@ -39,7 +41,7 @@ function HeaderSearch({
39
41
  type: "button",
40
42
  className: cn(searchFakeInput(), "hidden md:inline-flex", className),
41
43
  onClick: abrir,
42
- "aria-label": "Abrir busca",
44
+ "aria-label": ariaLabel,
43
45
  children: [
44
46
  /* @__PURE__ */ jsx(Search, { className: searchFakeInputIcon(), strokeWidth: 1.8 }),
45
47
  /* @__PURE__ */ jsx("span", { className: searchFakeInputText(), children: placeholder }),
@@ -55,8 +57,8 @@ function HeaderSearch({
55
57
  size: "icon-sm",
56
58
  className: "md:hidden rounded-radius-md",
57
59
  onClick: abrir,
58
- "aria-label": "Abrir busca",
59
- title: `Buscar (${shortcut})`,
60
+ "aria-label": ariaLabel,
61
+ title: hotkey === false ? ariaLabel : `${ariaLabel} (${shortcut})`,
60
62
  children: /* @__PURE__ */ jsx(Search, {})
61
63
  }
62
64
  ),
@@ -1 +1 @@
1
- {"version":3,"file":"header-search.mjs","sources":["../../../../../src/components/ui/Header/header-search.tsx"],"sourcesContent":["import { useEffect, useState } from \"react\";\r\nimport { Search } from \"lucide-react\";\r\nimport { cn } from \"@/lib/utils\";\r\nimport { Button } from \"@/components/ui/Button/button\";\r\nimport {\r\n CommandDialog,\r\n CommandInput,\r\n CommandList,\r\n CommandEmpty,\r\n CommandGroup,\r\n CommandItem,\r\n CommandSeparator,\r\n CommandShortcut,\r\n} from \"@/components/shadcn/command\";\r\nimport {\r\n searchFakeInput,\r\n searchFakeInputIcon,\r\n searchFakeInputText,\r\n searchFakeInputKbd,\r\n} from \"./header.styles\";\r\nimport type { HeaderCommandGroup } from \"./header.types\";\r\n\r\nexport type HeaderSearchProps = {\r\n placeholder?: string;\r\n shortcut?: string;\r\n commandGroups?: HeaderCommandGroup[];\r\n commandPlaceholder?: string;\r\n commandEmptyMessage?: string;\r\n /** Atalho de teclado pra abrir (default: cmd/ctrl + k) */\r\n hotkey?: { key: string; meta?: boolean; ctrl?: boolean };\r\n /**\r\n * Delega a abertura: quando passado, o clique no campo e o atalho chamam ISTO em vez\r\n * de abrir a paleta interna — e o `CommandDialog` do componente não é montado.\r\n *\r\n * Existe porque o `open` era `useState` interno, sem saída: um app que já tem a\r\n * própria paleta global (Ctrl+K com busca assíncrona, histórico, navegação por rota)\r\n * não conseguia reaproveitá-la. Só dava pra preencher a NOSSA paleta por\r\n * `commandGroups`, que é dado estático — sem busca assíncrona nem render custom.\r\n *\r\n * Com `onOpen`, o header entrega só o campo falso (que é o que ele faz de melhor:\r\n * aparência e atalho consistentes) e a paleta é sua.\r\n */\r\n onOpen?: () => void;\r\n className?: string;\r\n};\r\n\r\n/**\r\n * Fake input no header que abre Command palette ao click.\r\n * Atalho ⌘K (Mac) / Ctrl+K (Windows) registrado globalmente.\r\n */\r\nexport function HeaderSearch({\r\n placeholder = \"Buscar...\",\r\n shortcut = \"⌘K\",\r\n commandGroups = [],\r\n commandPlaceholder = \"Digite um comando ou busque...\",\r\n commandEmptyMessage = \"Nenhum resultado encontrado.\",\r\n hotkey = { key: \"k\", meta: true, ctrl: true },\r\n onOpen,\r\n className,\r\n}: HeaderSearchProps) {\r\n const [open, setOpen] = useState(false);\r\n const delegado = Boolean(onOpen);\r\n const abrir = () => (onOpen ? onOpen() : setOpen(true));\r\n\r\n // Atalho global (⌘K / Ctrl+K)\r\n useEffect(() => {\r\n const handler = (e: KeyboardEvent) => {\r\n if (e.key.toLowerCase() !== hotkey.key.toLowerCase()) return;\r\n const meta = hotkey.meta && e.metaKey;\r\n const ctrl = hotkey.ctrl && e.ctrlKey;\r\n if (meta || ctrl) {\r\n e.preventDefault();\r\n if (onOpen) onOpen();\r\n else setOpen((o) => !o);\r\n }\r\n };\r\n window.addEventListener(\"keydown\", handler);\r\n return () => window.removeEventListener(\"keydown\", handler);\r\n }, [hotkey.key, hotkey.meta, hotkey.ctrl, onOpen]);\r\n\r\n return (\r\n <>\r\n {/* Desktop: fake input completo com placeholder + atalho */}\r\n <button\r\n type=\"button\"\r\n className={cn(searchFakeInput(), \"hidden md:inline-flex\", className)}\r\n onClick={abrir}\r\n aria-label=\"Abrir busca\"\r\n >\r\n <Search className={searchFakeInputIcon()} strokeWidth={1.8} />\r\n <span className={searchFakeInputText()}>{placeholder}</span>\r\n <kbd className={searchFakeInputKbd()}>{shortcut}</kbd>\r\n </button>\r\n\r\n {/* Mobile: icon-button (mesma altura/style dos triggers do header) */}\r\n <Button\r\n color=\"secondary\"\r\n variant=\"outline\"\r\n size=\"icon-sm\"\r\n className=\"md:hidden rounded-radius-md\"\r\n onClick={abrir}\r\n aria-label=\"Abrir busca\"\r\n title={`Buscar (${shortcut})`}\r\n >\r\n <Search />\r\n </Button>\r\n\r\n {/* Com `onOpen` a paleta é do consumidor — não montamos a nossa. */}\r\n {!delegado && (\r\n <CommandDialog open={open} onOpenChange={setOpen}>\r\n <CommandInput placeholder={commandPlaceholder} />\r\n <CommandList>\r\n <CommandEmpty>{commandEmptyMessage}</CommandEmpty>\r\n {commandGroups.map((group, gIdx) => (\r\n <CommandGroupBlock\r\n key={group.heading}\r\n group={group}\r\n isLast={gIdx === commandGroups.length - 1}\r\n onSelect={() => setOpen(false)}\r\n />\r\n ))}\r\n </CommandList>\r\n </CommandDialog>\r\n )}\r\n </>\r\n );\r\n}\r\n\r\nfunction CommandGroupBlock({\r\n group,\r\n isLast,\r\n onSelect,\r\n}: {\r\n group: HeaderCommandGroup;\r\n isLast: boolean;\r\n onSelect: () => void;\r\n}) {\r\n return (\r\n <>\r\n <CommandGroup heading={group.heading}>\r\n {group.items.map((item) => {\r\n const Icon = item.icon;\r\n return (\r\n <CommandItem\r\n key={item.id ?? item.label}\r\n value={item.id ?? item.label}\r\n keywords={item.keywords}\r\n onSelect={() => {\r\n item.onSelect();\r\n onSelect();\r\n }}\r\n className={item.destructive ? \"text-fg-danger [&_svg]:text-fg-danger\" : undefined}\r\n >\r\n {Icon && <Icon />}\r\n <span>{item.label}</span>\r\n {item.shortcut && <CommandShortcut>{item.shortcut}</CommandShortcut>}\r\n </CommandItem>\r\n );\r\n })}\r\n </CommandGroup>\r\n {!isLast && <CommandSeparator />}\r\n </>\r\n );\r\n}\r\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"header-search.mjs","sources":["../../../../../src/components/ui/Header/header-search.tsx"],"sourcesContent":["import { useEffect, useState } from \"react\";\r\nimport { Search } from \"lucide-react\";\r\nimport { cn } from \"@/lib/utils\";\r\nimport { Button } from \"@/components/ui/Button/button\";\r\nimport {\r\n CommandDialog,\r\n CommandInput,\r\n CommandList,\r\n CommandEmpty,\r\n CommandGroup,\r\n CommandItem,\r\n CommandSeparator,\r\n CommandShortcut,\r\n} from \"@/components/shadcn/command\";\r\nimport {\r\n searchFakeInput,\r\n searchFakeInputIcon,\r\n searchFakeInputText,\r\n searchFakeInputKbd,\r\n} from \"./header.styles\";\r\nimport type { HeaderCommandGroup } from \"./header.types\";\r\n\r\nexport type HeaderSearchProps = {\r\n placeholder?: string;\r\n shortcut?: string;\r\n commandGroups?: HeaderCommandGroup[];\r\n commandPlaceholder?: string;\r\n commandEmptyMessage?: string;\r\n /**\r\n * Atalho de teclado pra abrir (default: cmd/ctrl + k).\r\n *\r\n * `false` desliga o listener global — use quando o app JÁ registra o próprio ⌘K: dois\r\n * listeners no mesmo atalho brigam, e o consumidor não tinha como desligar o nosso.\r\n */\r\n hotkey?: { key: string; meta?: boolean; ctrl?: boolean } | false;\r\n /**\r\n * Nome acessível do campo e do botão-ícone. Default \"Abrir busca\".\r\n * Era fixo em português — não dava pra traduzir nem pra dizer o que a busca busca\r\n * (\"Buscar tickets\").\r\n */\r\n ariaLabel?: string;\r\n /**\r\n * Delega a abertura: quando passado, o clique no campo e o atalho chamam ISTO em vez\r\n * de abrir a paleta interna — e o `CommandDialog` do componente não é montado.\r\n *\r\n * Existe porque o `open` era `useState` interno, sem saída: um app que já tem a\r\n * própria paleta global (Ctrl+K com busca assíncrona, histórico, navegação por rota)\r\n * não conseguia reaproveitá-la. Só dava pra preencher a NOSSA paleta por\r\n * `commandGroups`, que é dado estático — sem busca assíncrona nem render custom.\r\n *\r\n * Com `onOpen`, o header entrega só o campo falso (que é o que ele faz de melhor:\r\n * aparência e atalho consistentes) e a paleta é sua.\r\n */\r\n onOpen?: () => void;\r\n className?: string;\r\n};\r\n\r\n/**\r\n * Fake input no header que abre Command palette ao click.\r\n * Atalho ⌘K (Mac) / Ctrl+K (Windows) registrado globalmente.\r\n */\r\nexport function HeaderSearch({\r\n placeholder = \"Buscar...\",\r\n shortcut = \"⌘K\",\r\n commandGroups = [],\r\n commandPlaceholder = \"Digite um comando ou busque...\",\r\n commandEmptyMessage = \"Nenhum resultado encontrado.\",\r\n hotkey = { key: \"k\", meta: true, ctrl: true },\r\n onOpen,\r\n ariaLabel = \"Abrir busca\",\r\n className,\r\n}: HeaderSearchProps) {\r\n const [open, setOpen] = useState(false);\r\n const delegado = Boolean(onOpen);\r\n const abrir = () => (onOpen ? onOpen() : setOpen(true));\r\n\r\n // Atalho global (⌘K / Ctrl+K)\r\n useEffect(() => {\r\n if (hotkey === false) return;\r\n const handler = (e: KeyboardEvent) => {\r\n if (e.key.toLowerCase() !== hotkey.key.toLowerCase()) return;\r\n const meta = hotkey.meta && e.metaKey;\r\n const ctrl = hotkey.ctrl && e.ctrlKey;\r\n if (meta || ctrl) {\r\n e.preventDefault();\r\n if (onOpen) onOpen();\r\n else setOpen((o) => !o);\r\n }\r\n };\r\n window.addEventListener(\"keydown\", handler);\r\n return () => window.removeEventListener(\"keydown\", handler);\r\n }, [hotkey, onOpen]);\r\n\r\n return (\r\n <>\r\n {/* Desktop: fake input completo com placeholder + atalho */}\r\n <button\r\n type=\"button\"\r\n className={cn(searchFakeInput(), \"hidden md:inline-flex\", className)}\r\n onClick={abrir}\r\n aria-label={ariaLabel}\r\n >\r\n <Search className={searchFakeInputIcon()} strokeWidth={1.8} />\r\n <span className={searchFakeInputText()}>{placeholder}</span>\r\n <kbd className={searchFakeInputKbd()}>{shortcut}</kbd>\r\n </button>\r\n\r\n {/* Mobile: icon-button (mesma altura/style dos triggers do header) */}\r\n <Button\r\n color=\"secondary\"\r\n variant=\"outline\"\r\n size=\"icon-sm\"\r\n className=\"md:hidden rounded-radius-md\"\r\n onClick={abrir}\r\n aria-label={ariaLabel}\r\n title={hotkey === false ? ariaLabel : `${ariaLabel} (${shortcut})`}\r\n >\r\n <Search />\r\n </Button>\r\n\r\n {/* Com `onOpen` a paleta é do consumidor — não montamos a nossa. */}\r\n {!delegado && (\r\n <CommandDialog open={open} onOpenChange={setOpen}>\r\n <CommandInput placeholder={commandPlaceholder} />\r\n <CommandList>\r\n <CommandEmpty>{commandEmptyMessage}</CommandEmpty>\r\n {commandGroups.map((group, gIdx) => (\r\n <CommandGroupBlock\r\n key={group.heading}\r\n group={group}\r\n isLast={gIdx === commandGroups.length - 1}\r\n onSelect={() => setOpen(false)}\r\n />\r\n ))}\r\n </CommandList>\r\n </CommandDialog>\r\n )}\r\n </>\r\n );\r\n}\r\n\r\nfunction CommandGroupBlock({\r\n group,\r\n isLast,\r\n onSelect,\r\n}: {\r\n group: HeaderCommandGroup;\r\n isLast: boolean;\r\n onSelect: () => void;\r\n}) {\r\n return (\r\n <>\r\n <CommandGroup heading={group.heading}>\r\n {group.items.map((item) => {\r\n const Icon = item.icon;\r\n return (\r\n <CommandItem\r\n key={item.id ?? item.label}\r\n value={item.id ?? item.label}\r\n keywords={item.keywords}\r\n onSelect={() => {\r\n item.onSelect();\r\n onSelect();\r\n }}\r\n className={item.destructive ? \"text-fg-danger [&_svg]:text-fg-danger\" : undefined}\r\n >\r\n {Icon && <Icon />}\r\n <span>{item.label}</span>\r\n {item.shortcut && <CommandShortcut>{item.shortcut}</CommandShortcut>}\r\n </CommandItem>\r\n );\r\n })}\r\n </CommandGroup>\r\n {!isLast && <CommandSeparator />}\r\n </>\r\n );\r\n}\r\n"],"names":[],"mappings":"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"}
@@ -16,6 +16,7 @@ function KpiDelta({
16
16
  const isNegative = signed && typeof value === "string" && value.trim().startsWith("-");
17
17
  const resolvedTone = tone ?? (signed ? isNegative ? "danger" : "success" : "success");
18
18
  const resolvedDirection = direction ?? (signed ? isNegative ? "down" : "up" : void 0);
19
+ const direcaoAcessivel = resolvedDirection === "up" ? "aumento de" : resolvedDirection === "down" ? "queda de" : null;
19
20
  return /* @__PURE__ */ jsxRuntime.jsxs(
20
21
  chip.Chip,
21
22
  {
@@ -25,6 +26,10 @@ function KpiDelta({
25
26
  shape: "pill",
26
27
  className,
27
28
  children: [
29
+ direcaoAcessivel && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "sr-only", children: [
30
+ direcaoAcessivel,
31
+ " "
32
+ ] }),
28
33
  resolvedDirection && /* @__PURE__ */ jsxRuntime.jsx(
29
34
  lucideReact.TrendingUp,
30
35
  {
@@ -1 +1 @@
1
- {"version":3,"file":"kpi-delta.cjs","sources":["../../../../../src/components/ui/Kpi/kpi-delta.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport { TrendingUp } from \"lucide-react\";\r\nimport { cn } from \"@/lib/utils\";\r\nimport { Chip } from \"@/components/ui/Chip\";\r\nimport type { KpiDeltaProps } from \"./kpi.types\";\r\n\r\n/**\r\n * KpiDelta — pílula de variação (sobre o Chip). Tom semântico explícito\r\n * (success/danger/neutral) + seta opcional. O tom é decisão do consumidor —\r\n * \"subir\" nem sempre é positivo (ex.: tempo de espera).\r\n *\r\n * `signed` deriva tom+seta do sinal do `value` (\"-\" → danger/down; senão\r\n * success/up). `tone`/`direction` explícitos sempre vencem.\r\n */\r\nexport function KpiDelta({\r\n value,\r\n tone,\r\n direction,\r\n signed = false,\r\n className,\r\n}: KpiDeltaProps) {\r\n const isNegative =\r\n signed && typeof value === \"string\" && value.trim().startsWith(\"-\");\r\n const resolvedTone = tone ?? (signed ? (isNegative ? \"danger\" : \"success\") : \"success\");\r\n const resolvedDirection = direction ?? (signed ? (isNegative ? \"down\" : \"up\") : undefined);\r\n\r\n return (\r\n <Chip\r\n color={resolvedTone}\r\n variant=\"soft\"\r\n size=\"sm\"\r\n shape=\"pill\"\r\n className={className}\r\n >\r\n {resolvedDirection && (\r\n <TrendingUp\r\n className={cn(\"size-[12px]\", resolvedDirection === \"down\" && \"rotate-180\")}\r\n aria-hidden\r\n />\r\n )}\r\n {value}\r\n </Chip>\r\n );\r\n}\r\n\r\nKpiDelta.displayName = \"KpiDelta\";\r\n"],"names":["jsxs","Chip","jsx","TrendingUp","cn"],"mappings":";;;;;;;;AAeO,SAAS,SAAS;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT;AACF,GAAkB;AAChB,QAAM,aACJ,UAAU,OAAO,UAAU,YAAY,MAAM,KAAA,EAAO,WAAW,GAAG;AACpE,QAAM,eAAe,SAAS,SAAU,aAAa,WAAW,YAAa;AAC7E,QAAM,oBAAoB,cAAc,SAAU,aAAa,SAAS,OAAQ;AAEhF,SACEA,2BAAAA;AAAAA,IAACC,KAAAA;AAAAA,IAAA;AAAA,MACC,OAAO;AAAA,MACP,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACN;AAAA,MAEC,UAAA;AAAA,QAAA,qBACCC,2BAAAA;AAAAA,UAACC,YAAAA;AAAAA,UAAA;AAAA,YACC,WAAWC,MAAAA,GAAG,eAAe,sBAAsB,UAAU,YAAY;AAAA,YACzE,eAAW;AAAA,UAAA;AAAA,QAAA;AAAA,QAGd;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGP;AAEA,SAAS,cAAc;;"}
1
+ {"version":3,"file":"kpi-delta.cjs","sources":["../../../../../src/components/ui/Kpi/kpi-delta.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport { TrendingUp } from \"lucide-react\";\r\nimport { cn } from \"@/lib/utils\";\r\nimport { Chip } from \"@/components/ui/Chip\";\r\nimport type { KpiDeltaProps } from \"./kpi.types\";\r\n\r\n/**\r\n * KpiDelta — pílula de variação (sobre o Chip). Tom semântico explícito\r\n * (success/danger/neutral) + seta opcional. O tom é decisão do consumidor —\r\n * \"subir\" nem sempre é positivo (ex.: tempo de espera).\r\n *\r\n * `signed` deriva tom+seta do sinal do `value` (\"-\" → danger/down; senão\r\n * success/up). `tone`/`direction` explícitos sempre vencem.\r\n */\r\nexport function KpiDelta({\r\n value,\r\n tone,\r\n direction,\r\n signed = false,\r\n className,\r\n}: KpiDeltaProps) {\r\n const isNegative =\r\n signed && typeof value === \"string\" && value.trim().startsWith(\"-\");\r\n const resolvedTone = tone ?? (signed ? (isNegative ? \"danger\" : \"success\") : \"success\");\r\n const resolvedDirection = direction ?? (signed ? (isNegative ? \"down\" : \"up\") : undefined);\r\n /**\r\n * A seta é `aria-hidden` (decorativa), então sem isto a direção existia SÓ em cor e\r\n * ícone — invisível pra leitor de tela e pra quem não distingue as cores. O texto vai\r\n * antes do valor porque é assim que se lê: \"aumento de 18%\".\r\n */\r\n const direcaoAcessivel =\r\n resolvedDirection === \"up\" ? \"aumento de\" : resolvedDirection === \"down\" ? \"queda de\" : null;\r\n\r\n return (\r\n <Chip\r\n color={resolvedTone}\r\n variant=\"soft\"\r\n size=\"sm\"\r\n shape=\"pill\"\r\n className={className}\r\n >\r\n {direcaoAcessivel && <span className=\"sr-only\">{direcaoAcessivel} </span>}\r\n {resolvedDirection && (\r\n <TrendingUp\r\n className={cn(\"size-[12px]\", resolvedDirection === \"down\" && \"rotate-180\")}\r\n aria-hidden\r\n />\r\n )}\r\n {value}\r\n </Chip>\r\n );\r\n}\r\n\r\nKpiDelta.displayName = \"KpiDelta\";\r\n"],"names":["jsxs","Chip","jsx","TrendingUp","cn"],"mappings":";;;;;;;;AAeO,SAAS,SAAS;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT;AACF,GAAkB;AAChB,QAAM,aACJ,UAAU,OAAO,UAAU,YAAY,MAAM,KAAA,EAAO,WAAW,GAAG;AACpE,QAAM,eAAe,SAAS,SAAU,aAAa,WAAW,YAAa;AAC7E,QAAM,oBAAoB,cAAc,SAAU,aAAa,SAAS,OAAQ;AAMhF,QAAM,mBACJ,sBAAsB,OAAO,eAAe,sBAAsB,SAAS,aAAa;AAE1F,SACEA,2BAAAA;AAAAA,IAACC,KAAAA;AAAAA,IAAA;AAAA,MACC,OAAO;AAAA,MACP,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACN;AAAA,MAEC,UAAA;AAAA,QAAA,oBAAoBD,2BAAAA,KAAC,QAAA,EAAK,WAAU,WAAW,UAAA;AAAA,UAAA;AAAA,UAAiB;AAAA,QAAA,GAAC;AAAA,QACjE,qBACCE,2BAAAA;AAAAA,UAACC,YAAAA;AAAAA,UAAA;AAAA,YACC,WAAWC,MAAAA,GAAG,eAAe,sBAAsB,UAAU,YAAY;AAAA,YACzE,eAAW;AAAA,UAAA;AAAA,QAAA;AAAA,QAGd;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGP;AAEA,SAAS,cAAc;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"kpi-delta.d.ts","sourceRoot":"","sources":["../../../../../src/components/ui/Kpi/kpi-delta.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,IAAI,EACJ,SAAS,EACT,MAAc,EACd,SAAS,GACV,EAAE,aAAa,2CAuBf;yBA7Be,QAAQ"}
1
+ {"version":3,"file":"kpi-delta.d.ts","sourceRoot":"","sources":["../../../../../src/components/ui/Kpi/kpi-delta.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,IAAI,EACJ,SAAS,EACT,MAAc,EACd,SAAS,GACV,EAAE,aAAa,2CA+Bf;yBArCe,QAAQ"}
@@ -14,6 +14,7 @@ function KpiDelta({
14
14
  const isNegative = signed && typeof value === "string" && value.trim().startsWith("-");
15
15
  const resolvedTone = tone ?? (signed ? isNegative ? "danger" : "success" : "success");
16
16
  const resolvedDirection = direction ?? (signed ? isNegative ? "down" : "up" : void 0);
17
+ const direcaoAcessivel = resolvedDirection === "up" ? "aumento de" : resolvedDirection === "down" ? "queda de" : null;
17
18
  return /* @__PURE__ */ jsxs(
18
19
  Chip,
19
20
  {
@@ -23,6 +24,10 @@ function KpiDelta({
23
24
  shape: "pill",
24
25
  className,
25
26
  children: [
27
+ direcaoAcessivel && /* @__PURE__ */ jsxs("span", { className: "sr-only", children: [
28
+ direcaoAcessivel,
29
+ " "
30
+ ] }),
26
31
  resolvedDirection && /* @__PURE__ */ jsx(
27
32
  TrendingUp,
28
33
  {
@@ -1 +1 @@
1
- {"version":3,"file":"kpi-delta.mjs","sources":["../../../../../src/components/ui/Kpi/kpi-delta.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport { TrendingUp } from \"lucide-react\";\r\nimport { cn } from \"@/lib/utils\";\r\nimport { Chip } from \"@/components/ui/Chip\";\r\nimport type { KpiDeltaProps } from \"./kpi.types\";\r\n\r\n/**\r\n * KpiDelta — pílula de variação (sobre o Chip). Tom semântico explícito\r\n * (success/danger/neutral) + seta opcional. O tom é decisão do consumidor —\r\n * \"subir\" nem sempre é positivo (ex.: tempo de espera).\r\n *\r\n * `signed` deriva tom+seta do sinal do `value` (\"-\" → danger/down; senão\r\n * success/up). `tone`/`direction` explícitos sempre vencem.\r\n */\r\nexport function KpiDelta({\r\n value,\r\n tone,\r\n direction,\r\n signed = false,\r\n className,\r\n}: KpiDeltaProps) {\r\n const isNegative =\r\n signed && typeof value === \"string\" && value.trim().startsWith(\"-\");\r\n const resolvedTone = tone ?? (signed ? (isNegative ? \"danger\" : \"success\") : \"success\");\r\n const resolvedDirection = direction ?? (signed ? (isNegative ? \"down\" : \"up\") : undefined);\r\n\r\n return (\r\n <Chip\r\n color={resolvedTone}\r\n variant=\"soft\"\r\n size=\"sm\"\r\n shape=\"pill\"\r\n className={className}\r\n >\r\n {resolvedDirection && (\r\n <TrendingUp\r\n className={cn(\"size-[12px]\", resolvedDirection === \"down\" && \"rotate-180\")}\r\n aria-hidden\r\n />\r\n )}\r\n {value}\r\n </Chip>\r\n );\r\n}\r\n\r\nKpiDelta.displayName = \"KpiDelta\";\r\n"],"names":[],"mappings":";;;;;;AAeO,SAAS,SAAS;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT;AACF,GAAkB;AAChB,QAAM,aACJ,UAAU,OAAO,UAAU,YAAY,MAAM,KAAA,EAAO,WAAW,GAAG;AACpE,QAAM,eAAe,SAAS,SAAU,aAAa,WAAW,YAAa;AAC7E,QAAM,oBAAoB,cAAc,SAAU,aAAa,SAAS,OAAQ;AAEhF,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAO;AAAA,MACP,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACN;AAAA,MAEC,UAAA;AAAA,QAAA,qBACC;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAW,GAAG,eAAe,sBAAsB,UAAU,YAAY;AAAA,YACzE,eAAW;AAAA,UAAA;AAAA,QAAA;AAAA,QAGd;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGP;AAEA,SAAS,cAAc;"}
1
+ {"version":3,"file":"kpi-delta.mjs","sources":["../../../../../src/components/ui/Kpi/kpi-delta.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport { TrendingUp } from \"lucide-react\";\r\nimport { cn } from \"@/lib/utils\";\r\nimport { Chip } from \"@/components/ui/Chip\";\r\nimport type { KpiDeltaProps } from \"./kpi.types\";\r\n\r\n/**\r\n * KpiDelta — pílula de variação (sobre o Chip). Tom semântico explícito\r\n * (success/danger/neutral) + seta opcional. O tom é decisão do consumidor —\r\n * \"subir\" nem sempre é positivo (ex.: tempo de espera).\r\n *\r\n * `signed` deriva tom+seta do sinal do `value` (\"-\" → danger/down; senão\r\n * success/up). `tone`/`direction` explícitos sempre vencem.\r\n */\r\nexport function KpiDelta({\r\n value,\r\n tone,\r\n direction,\r\n signed = false,\r\n className,\r\n}: KpiDeltaProps) {\r\n const isNegative =\r\n signed && typeof value === \"string\" && value.trim().startsWith(\"-\");\r\n const resolvedTone = tone ?? (signed ? (isNegative ? \"danger\" : \"success\") : \"success\");\r\n const resolvedDirection = direction ?? (signed ? (isNegative ? \"down\" : \"up\") : undefined);\r\n /**\r\n * A seta é `aria-hidden` (decorativa), então sem isto a direção existia SÓ em cor e\r\n * ícone — invisível pra leitor de tela e pra quem não distingue as cores. O texto vai\r\n * antes do valor porque é assim que se lê: \"aumento de 18%\".\r\n */\r\n const direcaoAcessivel =\r\n resolvedDirection === \"up\" ? \"aumento de\" : resolvedDirection === \"down\" ? \"queda de\" : null;\r\n\r\n return (\r\n <Chip\r\n color={resolvedTone}\r\n variant=\"soft\"\r\n size=\"sm\"\r\n shape=\"pill\"\r\n className={className}\r\n >\r\n {direcaoAcessivel && <span className=\"sr-only\">{direcaoAcessivel} </span>}\r\n {resolvedDirection && (\r\n <TrendingUp\r\n className={cn(\"size-[12px]\", resolvedDirection === \"down\" && \"rotate-180\")}\r\n aria-hidden\r\n />\r\n )}\r\n {value}\r\n </Chip>\r\n );\r\n}\r\n\r\nKpiDelta.displayName = \"KpiDelta\";\r\n"],"names":[],"mappings":";;;;;;AAeO,SAAS,SAAS;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT;AACF,GAAkB;AAChB,QAAM,aACJ,UAAU,OAAO,UAAU,YAAY,MAAM,KAAA,EAAO,WAAW,GAAG;AACpE,QAAM,eAAe,SAAS,SAAU,aAAa,WAAW,YAAa;AAC7E,QAAM,oBAAoB,cAAc,SAAU,aAAa,SAAS,OAAQ;AAMhF,QAAM,mBACJ,sBAAsB,OAAO,eAAe,sBAAsB,SAAS,aAAa;AAE1F,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAO;AAAA,MACP,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACN;AAAA,MAEC,UAAA;AAAA,QAAA,oBAAoB,qBAAC,QAAA,EAAK,WAAU,WAAW,UAAA;AAAA,UAAA;AAAA,UAAiB;AAAA,QAAA,GAAC;AAAA,QACjE,qBACC;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAW,GAAG,eAAe,sBAAsB,UAAU,YAAY;AAAA,YACzE,eAAW;AAAA,UAAA;AAAA,QAAA;AAAA,QAGd;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGP;AAEA,SAAS,cAAc;"}
@@ -1 +1 @@
1
- {"version":3,"file":"kpi-group.cjs","sources":["../../../../../src/components/ui/Kpi/kpi-group.tsx"],"sourcesContent":["\"use client\";\n\nimport { createContext } from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport { kpiGroup } from \"./kpi.styles\";\nimport type { KpiGroupProps } from \"./kpi.types\";\n\n/** Superfície herdada pelos `Kpi` filhos (card normal vs plain dentro de divided). */\nexport const KpiSurfaceContext = createContext<\"card\" | \"plain\">(\"card\");\n\n/**\n * KpiGroup — layout de composição pros `Kpi`. `columns` (responsivo por CONTAINER\n * QUERY) e `divided` (vira 1 card único com divisórias entre os KPIs).\n *\n * ⚠️ O `@container` vive num wrapper em volta do grid, e não no próprio grid: em CSS\n * um elemento NÃO consulta o próprio tamanho — `@container` marca o contexto pros\n * DESCENDENTES. Grid e wrapper no mesmo nó fariam as variantes `@md:`/`@3xl:` lerem o\n * container de fora (ou nenhum), e o layout voltaria a quebrar pelo motivo errado.\n *\n * O `className` continua indo pro GRID, como antes — ninguém precisa mudar chamada.\n */\nexport function KpiGroup({\n columns = 4,\n divided = false,\n children,\n className,\n}: KpiGroupProps) {\n const s = kpiGroup({ columns, divided });\n\n return (\n <KpiSurfaceContext.Provider value={divided ? \"plain\" : \"card\"}>\n <div className={s.wrapper()}>\n <div className={cn(s.grid(), className)}>\n {children}\n </div>\n </div>\n </KpiSurfaceContext.Provider>\n );\n}\n\nKpiGroup.displayName = \"KpiGroup\";\n"],"names":["createContext","kpiGroup","jsx","cn"],"mappings":";;;;;;AAQO,MAAM,oBAAoBA,MAAAA,cAAgC,MAAM;AAahE,SAAS,SAAS;AAAA,EACvB,UAAU;AAAA,EACV,UAAU;AAAA,EACV;AAAA,EACA;AACF,GAAkB;AAChB,QAAM,IAAIC,WAAAA,SAAS,EAAE,SAAS,SAAS;AAEvC,SACEC,2BAAAA,IAAC,kBAAkB,UAAlB,EAA2B,OAAO,UAAU,UAAU,QACrD,UAAAA,2BAAAA,IAAC,OAAA,EAAI,WAAW,EAAE,WAChB,UAAAA,2BAAAA,IAAC,OAAA,EAAI,WAAWC,MAAAA,GAAG,EAAE,KAAA,GAAQ,SAAS,GACnC,SAAA,CACH,EAAA,CACF,EAAA,CACF;AAEJ;AAEA,SAAS,cAAc;;;"}
1
+ {"version":3,"file":"kpi-group.cjs","sources":["../../../../../src/components/ui/Kpi/kpi-group.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport { createContext } from \"react\";\r\nimport { cn } from \"@/lib/utils\";\r\nimport { kpiGroup } from \"./kpi.styles\";\r\nimport type { KpiGroupProps } from \"./kpi.types\";\r\n\r\n/** Superfície herdada pelos `Kpi` filhos (card normal vs plain dentro de divided). */\r\nexport const KpiSurfaceContext = createContext<\"card\" | \"plain\">(\"card\");\r\n\r\n/**\r\n * KpiGroup — layout de composição pros `Kpi`. `columns` (responsivo por CONTAINER\r\n * QUERY) e `divided` (vira 1 card único com divisórias entre os KPIs).\r\n *\r\n * ⚠️ O `@container` vive num wrapper em volta do grid, e não no próprio grid: em CSS\r\n * um elemento NÃO consulta o próprio tamanho — `@container` marca o contexto pros\r\n * DESCENDENTES. Grid e wrapper no mesmo nó fariam as variantes `@md:`/`@3xl:` lerem o\r\n * container de fora (ou nenhum), e o layout voltaria a quebrar pelo motivo errado.\r\n *\r\n * O `className` continua indo pro GRID, como antes — ninguém precisa mudar chamada.\r\n */\r\nexport function KpiGroup({\r\n columns = 4,\r\n divided = false,\r\n children,\r\n className,\r\n}: KpiGroupProps) {\r\n const s = kpiGroup({ columns, divided });\r\n\r\n return (\r\n <KpiSurfaceContext.Provider value={divided ? \"plain\" : \"card\"}>\r\n <div className={s.wrapper()}>\r\n <div className={cn(s.grid(), className)}>\r\n {children}\r\n </div>\r\n </div>\r\n </KpiSurfaceContext.Provider>\r\n );\r\n}\r\n\r\nKpiGroup.displayName = \"KpiGroup\";\r\n"],"names":["createContext","kpiGroup","jsx","cn"],"mappings":";;;;;;AAQO,MAAM,oBAAoBA,MAAAA,cAAgC,MAAM;AAahE,SAAS,SAAS;AAAA,EACvB,UAAU;AAAA,EACV,UAAU;AAAA,EACV;AAAA,EACA;AACF,GAAkB;AAChB,QAAM,IAAIC,WAAAA,SAAS,EAAE,SAAS,SAAS;AAEvC,SACEC,2BAAAA,IAAC,kBAAkB,UAAlB,EAA2B,OAAO,UAAU,UAAU,QACrD,UAAAA,2BAAAA,IAAC,OAAA,EAAI,WAAW,EAAE,WAChB,UAAAA,2BAAAA,IAAC,OAAA,EAAI,WAAWC,MAAAA,GAAG,EAAE,KAAA,GAAQ,SAAS,GACnC,SAAA,CACH,EAAA,CACF,EAAA,CACF;AAEJ;AAEA,SAAS,cAAc;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"kpi-group.mjs","sources":["../../../../../src/components/ui/Kpi/kpi-group.tsx"],"sourcesContent":["\"use client\";\n\nimport { createContext } from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport { kpiGroup } from \"./kpi.styles\";\nimport type { KpiGroupProps } from \"./kpi.types\";\n\n/** Superfície herdada pelos `Kpi` filhos (card normal vs plain dentro de divided). */\nexport const KpiSurfaceContext = createContext<\"card\" | \"plain\">(\"card\");\n\n/**\n * KpiGroup — layout de composição pros `Kpi`. `columns` (responsivo por CONTAINER\n * QUERY) e `divided` (vira 1 card único com divisórias entre os KPIs).\n *\n * ⚠️ O `@container` vive num wrapper em volta do grid, e não no próprio grid: em CSS\n * um elemento NÃO consulta o próprio tamanho — `@container` marca o contexto pros\n * DESCENDENTES. Grid e wrapper no mesmo nó fariam as variantes `@md:`/`@3xl:` lerem o\n * container de fora (ou nenhum), e o layout voltaria a quebrar pelo motivo errado.\n *\n * O `className` continua indo pro GRID, como antes — ninguém precisa mudar chamada.\n */\nexport function KpiGroup({\n columns = 4,\n divided = false,\n children,\n className,\n}: KpiGroupProps) {\n const s = kpiGroup({ columns, divided });\n\n return (\n <KpiSurfaceContext.Provider value={divided ? \"plain\" : \"card\"}>\n <div className={s.wrapper()}>\n <div className={cn(s.grid(), className)}>\n {children}\n </div>\n </div>\n </KpiSurfaceContext.Provider>\n );\n}\n\nKpiGroup.displayName = \"KpiGroup\";\n"],"names":[],"mappings":";;;;AAQO,MAAM,oBAAoB,cAAgC,MAAM;AAahE,SAAS,SAAS;AAAA,EACvB,UAAU;AAAA,EACV,UAAU;AAAA,EACV;AAAA,EACA;AACF,GAAkB;AAChB,QAAM,IAAI,SAAS,EAAE,SAAS,SAAS;AAEvC,SACE,oBAAC,kBAAkB,UAAlB,EAA2B,OAAO,UAAU,UAAU,QACrD,UAAA,oBAAC,OAAA,EAAI,WAAW,EAAE,WAChB,UAAA,oBAAC,OAAA,EAAI,WAAW,GAAG,EAAE,KAAA,GAAQ,SAAS,GACnC,SAAA,CACH,EAAA,CACF,EAAA,CACF;AAEJ;AAEA,SAAS,cAAc;"}
1
+ {"version":3,"file":"kpi-group.mjs","sources":["../../../../../src/components/ui/Kpi/kpi-group.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport { createContext } from \"react\";\r\nimport { cn } from \"@/lib/utils\";\r\nimport { kpiGroup } from \"./kpi.styles\";\r\nimport type { KpiGroupProps } from \"./kpi.types\";\r\n\r\n/** Superfície herdada pelos `Kpi` filhos (card normal vs plain dentro de divided). */\r\nexport const KpiSurfaceContext = createContext<\"card\" | \"plain\">(\"card\");\r\n\r\n/**\r\n * KpiGroup — layout de composição pros `Kpi`. `columns` (responsivo por CONTAINER\r\n * QUERY) e `divided` (vira 1 card único com divisórias entre os KPIs).\r\n *\r\n * ⚠️ O `@container` vive num wrapper em volta do grid, e não no próprio grid: em CSS\r\n * um elemento NÃO consulta o próprio tamanho — `@container` marca o contexto pros\r\n * DESCENDENTES. Grid e wrapper no mesmo nó fariam as variantes `@md:`/`@3xl:` lerem o\r\n * container de fora (ou nenhum), e o layout voltaria a quebrar pelo motivo errado.\r\n *\r\n * O `className` continua indo pro GRID, como antes — ninguém precisa mudar chamada.\r\n */\r\nexport function KpiGroup({\r\n columns = 4,\r\n divided = false,\r\n children,\r\n className,\r\n}: KpiGroupProps) {\r\n const s = kpiGroup({ columns, divided });\r\n\r\n return (\r\n <KpiSurfaceContext.Provider value={divided ? \"plain\" : \"card\"}>\r\n <div className={s.wrapper()}>\r\n <div className={cn(s.grid(), className)}>\r\n {children}\r\n </div>\r\n </div>\r\n </KpiSurfaceContext.Provider>\r\n );\r\n}\r\n\r\nKpiGroup.displayName = \"KpiGroup\";\r\n"],"names":[],"mappings":";;;;AAQO,MAAM,oBAAoB,cAAgC,MAAM;AAahE,SAAS,SAAS;AAAA,EACvB,UAAU;AAAA,EACV,UAAU;AAAA,EACV;AAAA,EACA;AACF,GAAkB;AAChB,QAAM,IAAI,SAAS,EAAE,SAAS,SAAS;AAEvC,SACE,oBAAC,kBAAkB,UAAlB,EAA2B,OAAO,UAAU,UAAU,QACrD,UAAA,oBAAC,OAAA,EAAI,WAAW,EAAE,WAChB,UAAA,oBAAC,OAAA,EAAI,WAAW,GAAG,EAAE,KAAA,GAAQ,SAAS,GACnC,SAAA,CACH,EAAA,CACF,EAAA,CACF;AAEJ;AAEA,SAAS,cAAc;"}
@@ -6,6 +6,7 @@ const lucideReact = require("lucide-react");
6
6
  const utils = require("../../../lib/utils.cjs");
7
7
  const clickableSurface = require("../../shadcn/clickable-surface.cjs");
8
8
  const tooltip = require("../../shadcn/tooltip.cjs");
9
+ const useTitleSeTruncado = require("../../../utils/use-title-se-truncado.cjs");
9
10
  const kpi_styles = require("./kpi.styles.cjs");
10
11
  const kpiGroup = require("./kpi-group.cjs");
11
12
  function Kpi({
@@ -14,6 +15,8 @@ function Kpi({
14
15
  delta,
15
16
  hint,
16
17
  helperText,
18
+ helperSide = "top",
19
+ helperMaxWidth,
17
20
  icon,
18
21
  tone = "neutral",
19
22
  size = "md",
@@ -27,12 +30,14 @@ function Kpi({
27
30
  className
28
31
  }) {
29
32
  const inherited = React.useContext(kpiGroup.KpiSurfaceContext);
33
+ const rotulo = useTitleSeTruncado.useTitleSeTruncado(label);
34
+ const valor = useTitleSeTruncado.useTitleSeTruncado(value);
30
35
  const interactive = Boolean(onClick || href);
31
36
  const s = kpi_styles.kpi({ size, surface: surface ?? inherited, tone, interactive });
32
37
  return /* @__PURE__ */ jsxRuntime.jsxs("article", { className: utils.cn(s.root(), className), children: [
33
38
  /* @__PURE__ */ jsxRuntime.jsxs("header", { className: s.header(), children: [
34
39
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 items-start gap-gp-xs", children: [
35
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: s.label(), children: label }),
40
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { ref: rotulo.ref, className: s.label(), title: rotulo.title, children: label }),
36
41
  helperText && /* @__PURE__ */ jsxRuntime.jsxs(tooltip.Tooltip, { children: [
37
42
  /* @__PURE__ */ jsxRuntime.jsx(
38
43
  tooltip.TooltipTrigger,
@@ -43,14 +48,14 @@ function Kpi({
43
48
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.HelpCircle, { "aria-hidden": true })
44
49
  }
45
50
  ),
46
- /* @__PURE__ */ jsxRuntime.jsx(tooltip.TooltipContent, { children: helperText })
51
+ /* @__PURE__ */ jsxRuntime.jsx(tooltip.TooltipContent, { side: helperSide, className: helperMaxWidth, children: helperText })
47
52
  ] })
48
53
  ] }),
49
54
  icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: s.iconBox(), "aria-hidden": true, children: icon })
50
55
  ] }),
51
56
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: s.main(), children: [
52
57
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: s.valueRow(), children: [
53
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: s.value(), children: value }),
58
+ /* @__PURE__ */ jsxRuntime.jsx("span", { ref: valor.ref, className: s.value(), title: valor.title, children: value }),
54
59
  delta
55
60
  ] }),
56
61
  hint && /* @__PURE__ */ jsxRuntime.jsx("span", { className: s.hint(), children: hint })
@@ -1 +1 @@
1
- {"version":3,"file":"kpi.cjs","sources":["../../../../../src/components/ui/Kpi/kpi.tsx"],"sourcesContent":["\"use client\";\n\nimport { useContext } from \"react\";\nimport { HelpCircle } from \"lucide-react\";\n\nimport { cn } from \"@/lib/utils\";\nimport { ClickableSurface } from \"@/components/shadcn/clickable-surface\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/shadcn/tooltip\";\nimport { kpi } from \"./kpi.styles\";\nimport { KpiSurfaceContext } from \"./kpi-group\";\nimport type { KpiProps } from \"./kpi.types\";\n\n/**\n * Kpi — card de KPI composável: header (label + ícone por tone), valor +\n * delta, hint, slot livre (sparkline/chart) e footnote. Use dentro de\n * `KpiGroup` pra rows/grids; dentro de `KpiGroup divided` ele vira \"plain\".\n *\n * Com `onClick`/`href` o card inteiro vira alvo de drill-down — ver `ClickableSurface`\n * pra por que a raiz continua `<article>`.\n */\nexport function Kpi({\n label,\n value,\n delta,\n hint,\n helperText,\n icon,\n tone = \"neutral\",\n size = \"md\",\n footnote,\n children,\n surface,\n onClick,\n href,\n target,\n renderLink,\n className,\n}: KpiProps) {\n const inherited = useContext(KpiSurfaceContext);\n const interactive = Boolean(onClick || href);\n const s = kpi({ size, surface: surface ?? inherited, tone, interactive });\n\n return (\n <article className={cn(s.root(), className)}>\n <header className={s.header()}>\n <div className=\"flex min-w-0 items-start gap-gp-xs\">\n <h3 className={s.label()}>{label}</h3>\n {helperText && (\n <Tooltip>\n <TooltipTrigger\n type=\"button\"\n className={s.helpButton()}\n aria-label={`Ajuda sobre ${label}`}\n >\n <HelpCircle aria-hidden />\n </TooltipTrigger>\n <TooltipContent>{helperText}</TooltipContent>\n </Tooltip>\n )}\n </div>\n {icon && (\n <span className={s.iconBox()} aria-hidden>\n {icon}\n </span>\n )}\n </header>\n <div className={s.main()}>\n <div className={s.valueRow()}>\n <span className={s.value()}>{value}</span>\n {delta}\n </div>\n {hint && <span className={s.hint()}>{hint}</span>}\n </div>\n {children && <div className={s.chart()}>{children}</div>}\n {footnote && <div className={s.footnote()}>{footnote}</div>}\n <ClickableSurface\n label={label}\n onClick={onClick}\n href={href}\n target={target}\n renderLink={renderLink}\n />\n </article>\n );\n}\n\nKpi.displayName = \"Kpi\";\n"],"names":["useContext","KpiSurfaceContext","kpi","jsxs","cn","jsx","Tooltip","TooltipTrigger","HelpCircle","TooltipContent","ClickableSurface"],"mappings":";;;;;;;;;;AAwBO,SAAS,IAAI;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAa;AACX,QAAM,YAAYA,MAAAA,WAAWC,0BAAiB;AAC9C,QAAM,cAAc,QAAQ,WAAW,IAAI;AAC3C,QAAM,IAAIC,eAAI,EAAE,MAAM,SAAS,WAAW,WAAW,MAAM,aAAa;AAExE,SACEC,2BAAAA,KAAC,aAAQ,WAAWC,MAAAA,GAAG,EAAE,KAAA,GAAQ,SAAS,GACxC,UAAA;AAAA,IAAAD,2BAAAA,KAAC,UAAA,EAAO,WAAW,EAAE,OAAA,GACnB,UAAA;AAAA,MAAAA,2BAAAA,KAAC,OAAA,EAAI,WAAU,sCACb,UAAA;AAAA,QAAAE,+BAAC,MAAA,EAAG,WAAW,EAAE,SAAU,UAAA,OAAM;AAAA,QAChC,8CACEC,iBAAA,EACC,UAAA;AAAA,UAAAD,2BAAAA;AAAAA,YAACE,QAAAA;AAAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAW,EAAE,WAAA;AAAA,cACb,cAAY,eAAe,KAAK;AAAA,cAEhC,UAAAF,2BAAAA,IAACG,YAAAA,YAAA,EAAW,eAAW,KAAA,CAAC;AAAA,YAAA;AAAA,UAAA;AAAA,UAE1BH,2BAAAA,IAACI,QAAAA,kBAAgB,UAAA,WAAA,CAAW;AAAA,QAAA,EAAA,CAC9B;AAAA,MAAA,GAEJ;AAAA,MACC,uCACE,QAAA,EAAK,WAAW,EAAE,QAAA,GAAW,eAAW,MACtC,UAAA,KAAA,CACH;AAAA,IAAA,GAEJ;AAAA,IACAN,2BAAAA,KAAC,OAAA,EAAI,WAAW,EAAE,QAChB,UAAA;AAAA,MAAAA,2BAAAA,KAAC,OAAA,EAAI,WAAW,EAAE,SAAA,GAChB,UAAA;AAAA,QAAAE,+BAAC,QAAA,EAAK,WAAW,EAAE,SAAU,UAAA,OAAM;AAAA,QAClC;AAAA,MAAA,GACH;AAAA,MACC,QAAQA,2BAAAA,IAAC,QAAA,EAAK,WAAW,EAAE,KAAA,GAAS,UAAA,KAAA,CAAK;AAAA,IAAA,GAC5C;AAAA,IACC,YAAYA,2BAAAA,IAAC,OAAA,EAAI,WAAW,EAAE,MAAA,GAAU,UAAS;AAAA,IACjD,YAAYA,2BAAAA,IAAC,OAAA,EAAI,WAAW,EAAE,SAAA,GAAa,UAAA,UAAS;AAAA,IACrDA,2BAAAA;AAAAA,MAACK,iBAAAA;AAAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GACF;AAEJ;AAEA,IAAI,cAAc;;"}
1
+ {"version":3,"file":"kpi.cjs","sources":["../../../../../src/components/ui/Kpi/kpi.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport { useContext } from \"react\";\r\nimport { HelpCircle } from \"lucide-react\";\r\n\r\nimport { cn } from \"@/lib/utils\";\r\nimport { ClickableSurface } from \"@/components/shadcn/clickable-surface\";\r\nimport {\r\n Tooltip,\r\n TooltipContent,\r\n TooltipTrigger,\r\n} from \"@/components/shadcn/tooltip\";\r\nimport { useTitleSeTruncado } from \"@/utils/use-title-se-truncado\";\r\nimport { kpi } from \"./kpi.styles\";\r\nimport { KpiSurfaceContext } from \"./kpi-group\";\r\nimport type { KpiProps } from \"./kpi.types\";\r\n\r\n/**\r\n * Kpi — card de KPI composável: header (label + ícone por tone), valor +\r\n * delta, hint, slot livre (sparkline/chart) e footnote. Use dentro de\r\n * `KpiGroup` pra rows/grids; dentro de `KpiGroup divided` ele vira \"plain\".\r\n *\r\n * Com `onClick`/`href` o card inteiro vira alvo de drill-down — ver `ClickableSurface`\r\n * pra por que a raiz continua `<article>`.\r\n */\r\nexport function Kpi({\r\n label,\r\n value,\r\n delta,\r\n hint,\r\n helperText,\r\n helperSide = \"top\",\r\n helperMaxWidth,\r\n icon,\r\n tone = \"neutral\",\r\n size = \"md\",\r\n footnote,\r\n children,\r\n surface,\r\n onClick,\r\n href,\r\n target,\r\n renderLink,\r\n className,\r\n}: KpiProps) {\r\n const inherited = useContext(KpiSurfaceContext);\r\n const rotulo = useTitleSeTruncado<HTMLHeadingElement>(label);\r\n const valor = useTitleSeTruncado<HTMLSpanElement>(value);\r\n const interactive = Boolean(onClick || href);\r\n const s = kpi({ size, surface: surface ?? inherited, tone, interactive });\r\n\r\n return (\r\n <article className={cn(s.root(), className)}>\r\n <header className={s.header()}>\r\n <div className=\"flex min-w-0 items-start gap-gp-xs\">\r\n {/*\r\n `title` SÓ quando o texto está de fato cortado — ver `useTitleSeTruncado`.\r\n Incondicional (a 1ª versão disto) põe tooltip nativo em TODO hover, inclusive\r\n nos casos em que o rótulo cabe inteiro. Numa grade de 8 KPIs vira ruído.\r\n */}\r\n <h3 ref={rotulo.ref} className={s.label()} title={rotulo.title}>\r\n {label}\r\n </h3>\r\n {helperText && (\r\n <Tooltip>\r\n <TooltipTrigger\r\n type=\"button\"\r\n className={s.helpButton()}\r\n aria-label={`Ajuda sobre ${label}`}\r\n >\r\n <HelpCircle aria-hidden />\r\n </TooltipTrigger>\r\n <TooltipContent side={helperSide} className={helperMaxWidth}>\r\n {helperText}\r\n </TooltipContent>\r\n </Tooltip>\r\n )}\r\n </div>\r\n {icon && (\r\n <span className={s.iconBox()} aria-hidden>\r\n {icon}\r\n </span>\r\n )}\r\n </header>\r\n <div className={s.main()}>\r\n <div className={s.valueRow()}>\r\n <span ref={valor.ref} className={s.value()} title={valor.title}>\r\n {value}\r\n </span>\r\n {delta}\r\n </div>\r\n {hint && <span className={s.hint()}>{hint}</span>}\r\n </div>\r\n {children && <div className={s.chart()}>{children}</div>}\r\n {footnote && <div className={s.footnote()}>{footnote}</div>}\r\n <ClickableSurface\r\n label={label}\r\n onClick={onClick}\r\n href={href}\r\n target={target}\r\n renderLink={renderLink}\r\n />\r\n </article>\r\n );\r\n}\r\n\r\nKpi.displayName = \"Kpi\";\r\n"],"names":["useContext","KpiSurfaceContext","useTitleSeTruncado","kpi","jsxs","cn","jsx","Tooltip","TooltipTrigger","HelpCircle","TooltipContent","ClickableSurface"],"mappings":";;;;;;;;;;;AAyBO,SAAS,IAAI;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAa;AACX,QAAM,YAAYA,MAAAA,WAAWC,0BAAiB;AAC9C,QAAM,SAASC,mBAAAA,mBAAuC,KAAK;AAC3D,QAAM,QAAQA,mBAAAA,mBAAoC,KAAK;AACvD,QAAM,cAAc,QAAQ,WAAW,IAAI;AAC3C,QAAM,IAAIC,eAAI,EAAE,MAAM,SAAS,WAAW,WAAW,MAAM,aAAa;AAExE,SACEC,2BAAAA,KAAC,aAAQ,WAAWC,MAAAA,GAAG,EAAE,KAAA,GAAQ,SAAS,GACxC,UAAA;AAAA,IAAAD,2BAAAA,KAAC,UAAA,EAAO,WAAW,EAAE,OAAA,GACnB,UAAA;AAAA,MAAAA,2BAAAA,KAAC,OAAA,EAAI,WAAU,sCAMb,UAAA;AAAA,QAAAE,2BAAAA,IAAC,MAAA,EAAG,KAAK,OAAO,KAAK,WAAW,EAAE,MAAA,GAAS,OAAO,OAAO,OACtD,UAAA,MAAA,CACH;AAAA,QACC,8CACEC,iBAAA,EACC,UAAA;AAAA,UAAAD,2BAAAA;AAAAA,YAACE,QAAAA;AAAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAW,EAAE,WAAA;AAAA,cACb,cAAY,eAAe,KAAK;AAAA,cAEhC,UAAAF,2BAAAA,IAACG,YAAAA,YAAA,EAAW,eAAW,KAAA,CAAC;AAAA,YAAA;AAAA,UAAA;AAAA,yCAEzBC,QAAAA,gBAAA,EAAe,MAAM,YAAY,WAAW,gBAC1C,UAAA,WAAA,CACH;AAAA,QAAA,EAAA,CACF;AAAA,MAAA,GAEJ;AAAA,MACC,uCACE,QAAA,EAAK,WAAW,EAAE,QAAA,GAAW,eAAW,MACtC,UAAA,KAAA,CACH;AAAA,IAAA,GAEJ;AAAA,IACAN,2BAAAA,KAAC,OAAA,EAAI,WAAW,EAAE,QAChB,UAAA;AAAA,MAAAA,2BAAAA,KAAC,OAAA,EAAI,WAAW,EAAE,SAAA,GAChB,UAAA;AAAA,QAAAE,2BAAAA,IAAC,QAAA,EAAK,KAAK,MAAM,KAAK,WAAW,EAAE,MAAA,GAAS,OAAO,MAAM,OACtD,UAAA,MAAA,CACH;AAAA,QACC;AAAA,MAAA,GACH;AAAA,MACC,QAAQA,2BAAAA,IAAC,QAAA,EAAK,WAAW,EAAE,KAAA,GAAS,UAAA,KAAA,CAAK;AAAA,IAAA,GAC5C;AAAA,IACC,YAAYA,2BAAAA,IAAC,OAAA,EAAI,WAAW,EAAE,MAAA,GAAU,UAAS;AAAA,IACjD,YAAYA,2BAAAA,IAAC,OAAA,EAAI,WAAW,EAAE,SAAA,GAAa,UAAA,UAAS;AAAA,IACrDA,2BAAAA;AAAAA,MAACK,iBAAAA;AAAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GACF;AAEJ;AAEA,IAAI,cAAc;;"}
@@ -7,7 +7,7 @@ import { KpiProps } from './kpi.types';
7
7
  * Com `onClick`/`href` o card inteiro vira alvo de drill-down — ver `ClickableSurface`
8
8
  * pra por que a raiz continua `<article>`.
9
9
  */
10
- export declare function Kpi({ label, value, delta, hint, helperText, icon, tone, size, footnote, children, surface, onClick, href, target, renderLink, className, }: KpiProps): import("react/jsx-runtime").JSX.Element;
10
+ export declare function Kpi({ label, value, delta, hint, helperText, helperSide, helperMaxWidth, icon, tone, size, footnote, children, surface, onClick, href, target, renderLink, className, }: KpiProps): import("react/jsx-runtime").JSX.Element;
11
11
  export declare namespace Kpi {
12
12
  var displayName: string;
13
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"kpi.d.ts","sourceRoot":"","sources":["../../../../../src/components/ui/Kpi/kpi.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C;;;;;;;GAOG;AACH,wBAAgB,GAAG,CAAC,EAClB,KAAK,EACL,KAAK,EACL,KAAK,EACL,IAAI,EACJ,UAAU,EACV,IAAI,EACJ,IAAgB,EAChB,IAAW,EACX,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,OAAO,EACP,IAAI,EACJ,MAAM,EACN,UAAU,EACV,SAAS,GACV,EAAE,QAAQ,2CA+CV;yBAhEe,GAAG"}
1
+ {"version":3,"file":"kpi.d.ts","sourceRoot":"","sources":["../../../../../src/components/ui/Kpi/kpi.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C;;;;;;;GAOG;AACH,wBAAgB,GAAG,CAAC,EAClB,KAAK,EACL,KAAK,EACL,KAAK,EACL,IAAI,EACJ,UAAU,EACV,UAAkB,EAClB,cAAc,EACd,IAAI,EACJ,IAAgB,EAChB,IAAW,EACX,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,OAAO,EACP,IAAI,EACJ,MAAM,EACN,UAAU,EACV,SAAS,GACV,EAAE,QAAQ,2CA4DV;yBA/Ee,GAAG"}
@@ -4,6 +4,7 @@ import { HelpCircle } from "lucide-react";
4
4
  import { cn } from "../../../lib/utils.mjs";
5
5
  import { ClickableSurface } from "../../shadcn/clickable-surface.mjs";
6
6
  import { Tooltip, TooltipTrigger, TooltipContent } from "../../shadcn/tooltip.mjs";
7
+ import { useTitleSeTruncado } from "../../../utils/use-title-se-truncado.mjs";
7
8
  import { kpi } from "./kpi.styles.mjs";
8
9
  import { KpiSurfaceContext } from "./kpi-group.mjs";
9
10
  function Kpi({
@@ -12,6 +13,8 @@ function Kpi({
12
13
  delta,
13
14
  hint,
14
15
  helperText,
16
+ helperSide = "top",
17
+ helperMaxWidth,
15
18
  icon,
16
19
  tone = "neutral",
17
20
  size = "md",
@@ -25,12 +28,14 @@ function Kpi({
25
28
  className
26
29
  }) {
27
30
  const inherited = useContext(KpiSurfaceContext);
31
+ const rotulo = useTitleSeTruncado(label);
32
+ const valor = useTitleSeTruncado(value);
28
33
  const interactive = Boolean(onClick || href);
29
34
  const s = kpi({ size, surface: surface ?? inherited, tone, interactive });
30
35
  return /* @__PURE__ */ jsxs("article", { className: cn(s.root(), className), children: [
31
36
  /* @__PURE__ */ jsxs("header", { className: s.header(), children: [
32
37
  /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-start gap-gp-xs", children: [
33
- /* @__PURE__ */ jsx("h3", { className: s.label(), children: label }),
38
+ /* @__PURE__ */ jsx("h3", { ref: rotulo.ref, className: s.label(), title: rotulo.title, children: label }),
34
39
  helperText && /* @__PURE__ */ jsxs(Tooltip, { children: [
35
40
  /* @__PURE__ */ jsx(
36
41
  TooltipTrigger,
@@ -41,14 +46,14 @@ function Kpi({
41
46
  children: /* @__PURE__ */ jsx(HelpCircle, { "aria-hidden": true })
42
47
  }
43
48
  ),
44
- /* @__PURE__ */ jsx(TooltipContent, { children: helperText })
49
+ /* @__PURE__ */ jsx(TooltipContent, { side: helperSide, className: helperMaxWidth, children: helperText })
45
50
  ] })
46
51
  ] }),
47
52
  icon && /* @__PURE__ */ jsx("span", { className: s.iconBox(), "aria-hidden": true, children: icon })
48
53
  ] }),
49
54
  /* @__PURE__ */ jsxs("div", { className: s.main(), children: [
50
55
  /* @__PURE__ */ jsxs("div", { className: s.valueRow(), children: [
51
- /* @__PURE__ */ jsx("span", { className: s.value(), children: value }),
56
+ /* @__PURE__ */ jsx("span", { ref: valor.ref, className: s.value(), title: valor.title, children: value }),
52
57
  delta
53
58
  ] }),
54
59
  hint && /* @__PURE__ */ jsx("span", { className: s.hint(), children: hint })
@@ -1 +1 @@
1
- {"version":3,"file":"kpi.mjs","sources":["../../../../../src/components/ui/Kpi/kpi.tsx"],"sourcesContent":["\"use client\";\n\nimport { useContext } from \"react\";\nimport { HelpCircle } from \"lucide-react\";\n\nimport { cn } from \"@/lib/utils\";\nimport { ClickableSurface } from \"@/components/shadcn/clickable-surface\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/shadcn/tooltip\";\nimport { kpi } from \"./kpi.styles\";\nimport { KpiSurfaceContext } from \"./kpi-group\";\nimport type { KpiProps } from \"./kpi.types\";\n\n/**\n * Kpi — card de KPI composável: header (label + ícone por tone), valor +\n * delta, hint, slot livre (sparkline/chart) e footnote. Use dentro de\n * `KpiGroup` pra rows/grids; dentro de `KpiGroup divided` ele vira \"plain\".\n *\n * Com `onClick`/`href` o card inteiro vira alvo de drill-down — ver `ClickableSurface`\n * pra por que a raiz continua `<article>`.\n */\nexport function Kpi({\n label,\n value,\n delta,\n hint,\n helperText,\n icon,\n tone = \"neutral\",\n size = \"md\",\n footnote,\n children,\n surface,\n onClick,\n href,\n target,\n renderLink,\n className,\n}: KpiProps) {\n const inherited = useContext(KpiSurfaceContext);\n const interactive = Boolean(onClick || href);\n const s = kpi({ size, surface: surface ?? inherited, tone, interactive });\n\n return (\n <article className={cn(s.root(), className)}>\n <header className={s.header()}>\n <div className=\"flex min-w-0 items-start gap-gp-xs\">\n <h3 className={s.label()}>{label}</h3>\n {helperText && (\n <Tooltip>\n <TooltipTrigger\n type=\"button\"\n className={s.helpButton()}\n aria-label={`Ajuda sobre ${label}`}\n >\n <HelpCircle aria-hidden />\n </TooltipTrigger>\n <TooltipContent>{helperText}</TooltipContent>\n </Tooltip>\n )}\n </div>\n {icon && (\n <span className={s.iconBox()} aria-hidden>\n {icon}\n </span>\n )}\n </header>\n <div className={s.main()}>\n <div className={s.valueRow()}>\n <span className={s.value()}>{value}</span>\n {delta}\n </div>\n {hint && <span className={s.hint()}>{hint}</span>}\n </div>\n {children && <div className={s.chart()}>{children}</div>}\n {footnote && <div className={s.footnote()}>{footnote}</div>}\n <ClickableSurface\n label={label}\n onClick={onClick}\n href={href}\n target={target}\n renderLink={renderLink}\n />\n </article>\n );\n}\n\nKpi.displayName = \"Kpi\";\n"],"names":[],"mappings":";;;;;;;;AAwBO,SAAS,IAAI;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAa;AACX,QAAM,YAAY,WAAW,iBAAiB;AAC9C,QAAM,cAAc,QAAQ,WAAW,IAAI;AAC3C,QAAM,IAAI,IAAI,EAAE,MAAM,SAAS,WAAW,WAAW,MAAM,aAAa;AAExE,SACE,qBAAC,aAAQ,WAAW,GAAG,EAAE,KAAA,GAAQ,SAAS,GACxC,UAAA;AAAA,IAAA,qBAAC,UAAA,EAAO,WAAW,EAAE,OAAA,GACnB,UAAA;AAAA,MAAA,qBAAC,OAAA,EAAI,WAAU,sCACb,UAAA;AAAA,QAAA,oBAAC,MAAA,EAAG,WAAW,EAAE,SAAU,UAAA,OAAM;AAAA,QAChC,mCACE,SAAA,EACC,UAAA;AAAA,UAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAW,EAAE,WAAA;AAAA,cACb,cAAY,eAAe,KAAK;AAAA,cAEhC,UAAA,oBAAC,YAAA,EAAW,eAAW,KAAA,CAAC;AAAA,YAAA;AAAA,UAAA;AAAA,UAE1B,oBAAC,kBAAgB,UAAA,WAAA,CAAW;AAAA,QAAA,EAAA,CAC9B;AAAA,MAAA,GAEJ;AAAA,MACC,4BACE,QAAA,EAAK,WAAW,EAAE,QAAA,GAAW,eAAW,MACtC,UAAA,KAAA,CACH;AAAA,IAAA,GAEJ;AAAA,IACA,qBAAC,OAAA,EAAI,WAAW,EAAE,QAChB,UAAA;AAAA,MAAA,qBAAC,OAAA,EAAI,WAAW,EAAE,SAAA,GAChB,UAAA;AAAA,QAAA,oBAAC,QAAA,EAAK,WAAW,EAAE,SAAU,UAAA,OAAM;AAAA,QAClC;AAAA,MAAA,GACH;AAAA,MACC,QAAQ,oBAAC,QAAA,EAAK,WAAW,EAAE,KAAA,GAAS,UAAA,KAAA,CAAK;AAAA,IAAA,GAC5C;AAAA,IACC,YAAY,oBAAC,OAAA,EAAI,WAAW,EAAE,MAAA,GAAU,UAAS;AAAA,IACjD,YAAY,oBAAC,OAAA,EAAI,WAAW,EAAE,SAAA,GAAa,UAAA,UAAS;AAAA,IACrD;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GACF;AAEJ;AAEA,IAAI,cAAc;"}
1
+ {"version":3,"file":"kpi.mjs","sources":["../../../../../src/components/ui/Kpi/kpi.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport { useContext } from \"react\";\r\nimport { HelpCircle } from \"lucide-react\";\r\n\r\nimport { cn } from \"@/lib/utils\";\r\nimport { ClickableSurface } from \"@/components/shadcn/clickable-surface\";\r\nimport {\r\n Tooltip,\r\n TooltipContent,\r\n TooltipTrigger,\r\n} from \"@/components/shadcn/tooltip\";\r\nimport { useTitleSeTruncado } from \"@/utils/use-title-se-truncado\";\r\nimport { kpi } from \"./kpi.styles\";\r\nimport { KpiSurfaceContext } from \"./kpi-group\";\r\nimport type { KpiProps } from \"./kpi.types\";\r\n\r\n/**\r\n * Kpi — card de KPI composável: header (label + ícone por tone), valor +\r\n * delta, hint, slot livre (sparkline/chart) e footnote. Use dentro de\r\n * `KpiGroup` pra rows/grids; dentro de `KpiGroup divided` ele vira \"plain\".\r\n *\r\n * Com `onClick`/`href` o card inteiro vira alvo de drill-down — ver `ClickableSurface`\r\n * pra por que a raiz continua `<article>`.\r\n */\r\nexport function Kpi({\r\n label,\r\n value,\r\n delta,\r\n hint,\r\n helperText,\r\n helperSide = \"top\",\r\n helperMaxWidth,\r\n icon,\r\n tone = \"neutral\",\r\n size = \"md\",\r\n footnote,\r\n children,\r\n surface,\r\n onClick,\r\n href,\r\n target,\r\n renderLink,\r\n className,\r\n}: KpiProps) {\r\n const inherited = useContext(KpiSurfaceContext);\r\n const rotulo = useTitleSeTruncado<HTMLHeadingElement>(label);\r\n const valor = useTitleSeTruncado<HTMLSpanElement>(value);\r\n const interactive = Boolean(onClick || href);\r\n const s = kpi({ size, surface: surface ?? inherited, tone, interactive });\r\n\r\n return (\r\n <article className={cn(s.root(), className)}>\r\n <header className={s.header()}>\r\n <div className=\"flex min-w-0 items-start gap-gp-xs\">\r\n {/*\r\n `title` SÓ quando o texto está de fato cortado — ver `useTitleSeTruncado`.\r\n Incondicional (a 1ª versão disto) põe tooltip nativo em TODO hover, inclusive\r\n nos casos em que o rótulo cabe inteiro. Numa grade de 8 KPIs vira ruído.\r\n */}\r\n <h3 ref={rotulo.ref} className={s.label()} title={rotulo.title}>\r\n {label}\r\n </h3>\r\n {helperText && (\r\n <Tooltip>\r\n <TooltipTrigger\r\n type=\"button\"\r\n className={s.helpButton()}\r\n aria-label={`Ajuda sobre ${label}`}\r\n >\r\n <HelpCircle aria-hidden />\r\n </TooltipTrigger>\r\n <TooltipContent side={helperSide} className={helperMaxWidth}>\r\n {helperText}\r\n </TooltipContent>\r\n </Tooltip>\r\n )}\r\n </div>\r\n {icon && (\r\n <span className={s.iconBox()} aria-hidden>\r\n {icon}\r\n </span>\r\n )}\r\n </header>\r\n <div className={s.main()}>\r\n <div className={s.valueRow()}>\r\n <span ref={valor.ref} className={s.value()} title={valor.title}>\r\n {value}\r\n </span>\r\n {delta}\r\n </div>\r\n {hint && <span className={s.hint()}>{hint}</span>}\r\n </div>\r\n {children && <div className={s.chart()}>{children}</div>}\r\n {footnote && <div className={s.footnote()}>{footnote}</div>}\r\n <ClickableSurface\r\n label={label}\r\n onClick={onClick}\r\n href={href}\r\n target={target}\r\n renderLink={renderLink}\r\n />\r\n </article>\r\n );\r\n}\r\n\r\nKpi.displayName = \"Kpi\";\r\n"],"names":[],"mappings":";;;;;;;;;AAyBO,SAAS,IAAI;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAa;AACX,QAAM,YAAY,WAAW,iBAAiB;AAC9C,QAAM,SAAS,mBAAuC,KAAK;AAC3D,QAAM,QAAQ,mBAAoC,KAAK;AACvD,QAAM,cAAc,QAAQ,WAAW,IAAI;AAC3C,QAAM,IAAI,IAAI,EAAE,MAAM,SAAS,WAAW,WAAW,MAAM,aAAa;AAExE,SACE,qBAAC,aAAQ,WAAW,GAAG,EAAE,KAAA,GAAQ,SAAS,GACxC,UAAA;AAAA,IAAA,qBAAC,UAAA,EAAO,WAAW,EAAE,OAAA,GACnB,UAAA;AAAA,MAAA,qBAAC,OAAA,EAAI,WAAU,sCAMb,UAAA;AAAA,QAAA,oBAAC,MAAA,EAAG,KAAK,OAAO,KAAK,WAAW,EAAE,MAAA,GAAS,OAAO,OAAO,OACtD,UAAA,MAAA,CACH;AAAA,QACC,mCACE,SAAA,EACC,UAAA;AAAA,UAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAW,EAAE,WAAA;AAAA,cACb,cAAY,eAAe,KAAK;AAAA,cAEhC,UAAA,oBAAC,YAAA,EAAW,eAAW,KAAA,CAAC;AAAA,YAAA;AAAA,UAAA;AAAA,8BAEzB,gBAAA,EAAe,MAAM,YAAY,WAAW,gBAC1C,UAAA,WAAA,CACH;AAAA,QAAA,EAAA,CACF;AAAA,MAAA,GAEJ;AAAA,MACC,4BACE,QAAA,EAAK,WAAW,EAAE,QAAA,GAAW,eAAW,MACtC,UAAA,KAAA,CACH;AAAA,IAAA,GAEJ;AAAA,IACA,qBAAC,OAAA,EAAI,WAAW,EAAE,QAChB,UAAA;AAAA,MAAA,qBAAC,OAAA,EAAI,WAAW,EAAE,SAAA,GAChB,UAAA;AAAA,QAAA,oBAAC,QAAA,EAAK,KAAK,MAAM,KAAK,WAAW,EAAE,MAAA,GAAS,OAAO,MAAM,OACtD,UAAA,MAAA,CACH;AAAA,QACC;AAAA,MAAA,GACH;AAAA,MACC,QAAQ,oBAAC,QAAA,EAAK,WAAW,EAAE,KAAA,GAAS,UAAA,KAAA,CAAK;AAAA,IAAA,GAC5C;AAAA,IACC,YAAY,oBAAC,OAAA,EAAI,WAAW,EAAE,MAAA,GAAU,UAAS;AAAA,IACjD,YAAY,oBAAC,OAAA,EAAI,WAAW,EAAE,SAAA,GAAa,UAAA,UAAS;AAAA,IACrD;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GACF;AAEJ;AAEA,IAAI,cAAc;"}
@@ -47,6 +47,15 @@ export interface KpiProps {
47
47
  * Use pra explicar COMO a métrica é calculada; não repita o rótulo.
48
48
  */
49
49
  helperText?: ReactNode;
50
+ /** Lado do tooltip do `helperText`. Default "top". */
51
+ helperSide?: "top" | "right" | "bottom" | "left";
52
+ /**
53
+ * Largura máxima do tooltip do `helperText`. Default `max-w-tooltip-lg` (320px).
54
+ *
55
+ * Existe porque texto de ajuda longo num tooltip estreito vira uma coluna alta e
56
+ * difícil de ler — passe `max-w-page-xs` e similares pra soltar.
57
+ */
58
+ helperMaxWidth?: string;
50
59
  /** Ícone (lucide etc.) — renderizado num container colorido por `tone`. */
51
60
  icon?: ReactNode;
52
61
  /** Tom do container do ícone. Default: "neutral". */
@@ -1 +1 @@
1
- {"version":3,"file":"kpi.types.d.ts","sourceRoot":"","sources":["../../../../../src/components/ui/Kpi/kpi.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAExD;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,GAAG,CAAC,EAAE,GAAG,CAAC,iBAAiB,CAAC,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,kBAAkB,KAAK,SAAS,CAAC;AAEvE,kDAAkD;AAClD,MAAM,MAAM,OAAO,GACf,OAAO,GACP,SAAS,GACT,SAAS,GACT,MAAM,GACN,QAAQ,GACR,SAAS,CAAC;AAEd,MAAM,WAAW,aAAa;IAC5B,4CAA4C;IAC5C,KAAK,EAAE,SAAS,CAAC;IACjB,gFAAgF;IAChF,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IACxC,sCAAsC;IACtC,SAAS,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;IAC1B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,KAAK,EAAE,SAAS,CAAC;IACjB,sDAAsD;IACtD,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,6DAA6D;IAC7D,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;OAGG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,2EAA2E;IAC3E,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,qDAAqD;IACrD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;OAGG;IACH,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IACjC,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAU3B,sEAAsE;IACtE,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAC/C,+EAA+E;IAC/E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,UAAU,CAAC,EAAE,eAAe,CAAC;IAE7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpC,oEAAoE;IACpE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
1
+ {"version":3,"file":"kpi.types.d.ts","sourceRoot":"","sources":["../../../../../src/components/ui/Kpi/kpi.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAExD;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,GAAG,CAAC,EAAE,GAAG,CAAC,iBAAiB,CAAC,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,kBAAkB,KAAK,SAAS,CAAC;AAEvE,kDAAkD;AAClD,MAAM,MAAM,OAAO,GACf,OAAO,GACP,SAAS,GACT,SAAS,GACT,MAAM,GACN,QAAQ,GACR,SAAS,CAAC;AAEd,MAAM,WAAW,aAAa;IAC5B,4CAA4C;IAC5C,KAAK,EAAE,SAAS,CAAC;IACjB,gFAAgF;IAChF,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IACxC,sCAAsC;IACtC,SAAS,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;IAC1B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,KAAK,EAAE,SAAS,CAAC;IACjB,sDAAsD;IACtD,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,6DAA6D;IAC7D,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;OAGG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,sDAAsD;IACtD,UAAU,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IACjD;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,2EAA2E;IAC3E,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,qDAAqD;IACrD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;OAGG;IACH,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IACjC,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAU3B,sEAAsE;IACtE,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAC/C,+EAA+E;IAC/E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,UAAU,CAAC,EAAE,eAAe,CAAC;IAE7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpC,oEAAoE;IACpE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
@@ -36,7 +36,7 @@ export type SidebarLinkRenderProps = {
36
36
  *
37
37
  * ```tsx
38
38
  * import { Link } from "react-router-dom";
39
- * <AppShell renderLink={(p) => <Link {...p} to={p.href} />} />
39
+ * <AppShell renderLink={({ href, ...p }) => <Link {...p} to={href} />} />
40
40
  * ```
41
41
  *
42
42
  * ⚠️ **É render-prop, não `linkComponent`, de propósito.** Um prop que recebe *tipo de
@@ -43,7 +43,10 @@ const pageHeaderStyles = tv.tv({
43
43
  descriptionLines: {
44
44
  1: { description: "whitespace-nowrap overflow-hidden text-ellipsis" },
45
45
  2: { description: "line-clamp-2" },
46
- 3: { description: "line-clamp-3" }
46
+ 3: { description: "line-clamp-3" },
47
+ // Sem corte: a descrição cresce. Não é o default porque header é âncora de
48
+ // leitura — mas com conteúdo composto (link, chip, seletor) cortar é pior.
49
+ none: { description: "" }
47
50
  },
48
51
  hideTextOnMobile: {
49
52
  true: { textCol: "max-md:hidden" },
@@ -1 +1 @@
1
- {"version":3,"file":"page-header.styles.cjs","sources":["../../../../../src/components/ui/PageHeader/page-header.styles.ts"],"sourcesContent":["import { tv } from \"@/utils/tv\";\r\n\r\n/**\r\n * PageHeader styles — bloco de título de página colocado dentro do body\r\n * do `<AppShell>`.\r\n *\r\n * Layout desktop:\r\n * ┌──────────────────────────────────────────────────────────┐\r\n * │ [title] [badge] [action1] [action2] [CTA] │\r\n * │ description │\r\n * ├──────────────────────────────────────────────────────────┤\r\n * │ {children — ex: <Tabs />} │\r\n * └──────────────────────────────────────────────────────────┘\r\n *\r\n * Mobile:\r\n * - Text section sai (hideTextOnMobile, default true)\r\n * - Actions ocupam toda a largura; último botão vira fluid (CTA primary)\r\n */\r\nexport const pageHeaderStyles = tv({\r\n slots: {\r\n root: \"shrink-0 flex flex-col gap-gp-md\",\r\n topRow: \"flex items-center justify-between gap-gp-2xl\",\r\n textCol: \"flex flex-col gap-gp-xs min-w-0 flex-1\",\r\n titleRow: \"flex items-center gap-gp-md min-w-0\",\r\n title: \"m-0 text-title-lg font-bold tracking-[-0.01em] text-fg-default\",\r\n description: \"m-0 text-body-md text-fg-subtle leading-[1.5]\",\r\n actionsRow: \"flex items-center gap-gp-sm shrink-0\",\r\n // mt-gp-xl: +20px somados ao gap-gp-md (12px) do root = ~32px de respiro\r\n // entre o título/descrição e o slot de conteúdo (tabs/filtros).\r\n extraRow: \"w-full mt-gp-xl\",\r\n },\r\n variants: {\r\n /**\r\n * Título em uma linha (default, `false`) ou quebrando em várias.\r\n *\r\n * ⚠️ Default `true` = o comportamento que o PageHeader SEMPRE teve. O título nunca\r\n * teve truncate (só a descrição tinha), então um título longo quebrava. A primeira\r\n * versão desta prop veio com default `false` e teria truncado todo título longo já\r\n * existente — mudança de default que ninguém pediu, num PR que já carrega uma quebra\r\n * deliberada. Quem quer uma linha só pede `titleWrap={false}`.\r\n *\r\n * O caso que originou a prop era o inverso: um consumidor recriou o header por fora\r\n * porque nome longo de projeto virava \"Relatório de atendimento por…\". Com o default\r\n * certo, esse caso já estava atendido — o que faltava era poder DESLIGAR.\r\n */\r\n titleWrap: {\r\n true: { titleRow: \"flex-wrap\", title: \"[overflow-wrap:anywhere]\" },\r\n false: { title: \"truncate\" },\r\n },\r\n /**\r\n * Quantas linhas a descrição ocupa antes de cortar.\r\n *\r\n * O degrau 1 mantém as classes ORIGINAIS (`whitespace-nowrap` + ellipsis) em vez do\r\n * `line-clamp-1` equivalente: o line-clamp troca o `display` pra `-webkit-box`, e\r\n * trocar o display de um filho de flex por uma equivalência \"visualmente igual\" é o\r\n * tipo de detalhe que só aparece numa tela específica.\r\n */\r\n descriptionLines: {\r\n 1: { description: \"whitespace-nowrap overflow-hidden text-ellipsis\" },\r\n 2: { description: \"line-clamp-2\" },\r\n 3: { description: \"line-clamp-3\" },\r\n },\r\n hideTextOnMobile: {\r\n true: { textCol: \"max-md:hidden\" },\r\n false: {},\r\n },\r\n /**\r\n * Mobile: actions ocupa o espaço (text hidden) + último filho vira fluid.\r\n * Off = mantém actions square e shrink-0 (mesmo comportamento desktop).\r\n */\r\n mobileFluid: {\r\n true: {\r\n actionsRow: [\r\n \"max-md:shrink max-md:flex-1 max-md:justify-end\",\r\n \"max-md:[&>:last-child]:flex-1\",\r\n ],\r\n },\r\n false: {},\r\n },\r\n },\r\n defaultVariants: {\r\n titleWrap: true,\r\n descriptionLines: 1,\r\n hideTextOnMobile: true,\r\n mobileFluid: true,\r\n },\r\n});\r\n"],"names":["tv"],"mappings":";;;AAkBO,MAAM,mBAAmBA,GAAAA,GAAG;AAAA,EACjC,OAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,UAAU;AAAA,IACV,OAAO;AAAA,IACP,aAAa;AAAA,IACb,YAAY;AAAA;AAAA;AAAA,IAGZ,UAAU;AAAA,EAAA;AAAA,EAEZ,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAcR,WAAW;AAAA,MACT,MAAM,EAAE,UAAU,aAAa,OAAO,2BAAA;AAAA,MACtC,OAAO,EAAE,OAAO,WAAA;AAAA,IAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAU7B,kBAAkB;AAAA,MAChB,GAAG,EAAE,aAAa,kDAAA;AAAA,MAClB,GAAG,EAAE,aAAa,eAAA;AAAA,MAClB,GAAG,EAAE,aAAa,eAAA;AAAA,IAAe;AAAA,IAEnC,kBAAkB;AAAA,MAChB,MAAM,EAAE,SAAS,gBAAA;AAAA,MACjB,OAAO,CAAA;AAAA,IAAC;AAAA;AAAA;AAAA;AAAA;AAAA,IAMV,aAAa;AAAA,MACX,MAAM;AAAA,QACJ,YAAY;AAAA,UACV;AAAA,UACA;AAAA,QAAA;AAAA,MACF;AAAA,MAEF,OAAO,CAAA;AAAA,IAAC;AAAA,EACV;AAAA,EAEF,iBAAiB;AAAA,IACf,WAAW;AAAA,IACX,kBAAkB;AAAA,IAClB,kBAAkB;AAAA,IAClB,aAAa;AAAA,EAAA;AAEjB,CAAC;;"}
1
+ {"version":3,"file":"page-header.styles.cjs","sources":["../../../../../src/components/ui/PageHeader/page-header.styles.ts"],"sourcesContent":["import { tv } from \"@/utils/tv\";\r\n\r\n/**\r\n * PageHeader styles — bloco de título de página colocado dentro do body\r\n * do `<AppShell>`.\r\n *\r\n * Layout desktop:\r\n * ┌──────────────────────────────────────────────────────────┐\r\n * │ [title] [badge] [action1] [action2] [CTA] │\r\n * │ description │\r\n * ├──────────────────────────────────────────────────────────┤\r\n * │ {children — ex: <Tabs />} │\r\n * └──────────────────────────────────────────────────────────┘\r\n *\r\n * Mobile:\r\n * - Text section sai (hideTextOnMobile, default true)\r\n * - Actions ocupam toda a largura; último botão vira fluid (CTA primary)\r\n */\r\nexport const pageHeaderStyles = tv({\r\n slots: {\r\n root: \"shrink-0 flex flex-col gap-gp-md\",\r\n topRow: \"flex items-center justify-between gap-gp-2xl\",\r\n textCol: \"flex flex-col gap-gp-xs min-w-0 flex-1\",\r\n titleRow: \"flex items-center gap-gp-md min-w-0\",\r\n title: \"m-0 text-title-lg font-bold tracking-[-0.01em] text-fg-default\",\r\n description: \"m-0 text-body-md text-fg-subtle leading-[1.5]\",\r\n actionsRow: \"flex items-center gap-gp-sm shrink-0\",\r\n // mt-gp-xl: +20px somados ao gap-gp-md (12px) do root = ~32px de respiro\r\n // entre o título/descrição e o slot de conteúdo (tabs/filtros).\r\n extraRow: \"w-full mt-gp-xl\",\r\n },\r\n variants: {\r\n /**\r\n * Título em uma linha (default, `false`) ou quebrando em várias.\r\n *\r\n * ⚠️ Default `true` = o comportamento que o PageHeader SEMPRE teve. O título nunca\r\n * teve truncate (só a descrição tinha), então um título longo quebrava. A primeira\r\n * versão desta prop veio com default `false` e teria truncado todo título longo já\r\n * existente — mudança de default que ninguém pediu, num PR que já carrega uma quebra\r\n * deliberada. Quem quer uma linha só pede `titleWrap={false}`.\r\n *\r\n * O caso que originou a prop era o inverso: um consumidor recriou o header por fora\r\n * porque nome longo de projeto virava \"Relatório de atendimento por…\". Com o default\r\n * certo, esse caso já estava atendido — o que faltava era poder DESLIGAR.\r\n */\r\n titleWrap: {\r\n true: { titleRow: \"flex-wrap\", title: \"[overflow-wrap:anywhere]\" },\r\n false: { title: \"truncate\" },\r\n },\r\n /**\r\n * Quantas linhas a descrição ocupa antes de cortar.\r\n *\r\n * O degrau 1 mantém as classes ORIGINAIS (`whitespace-nowrap` + ellipsis) em vez do\r\n * `line-clamp-1` equivalente: o line-clamp troca o `display` pra `-webkit-box`, e\r\n * trocar o display de um filho de flex por uma equivalência \"visualmente igual\" é o\r\n * tipo de detalhe que só aparece numa tela específica.\r\n */\r\n descriptionLines: {\r\n 1: { description: \"whitespace-nowrap overflow-hidden text-ellipsis\" },\r\n 2: { description: \"line-clamp-2\" },\r\n 3: { description: \"line-clamp-3\" },\r\n // Sem corte: a descrição cresce. Não é o default porque header é âncora de\r\n // leitura — mas com conteúdo composto (link, chip, seletor) cortar é pior.\r\n none: { description: \"\" },\r\n },\r\n hideTextOnMobile: {\r\n true: { textCol: \"max-md:hidden\" },\r\n false: {},\r\n },\r\n /**\r\n * Mobile: actions ocupa o espaço (text hidden) + último filho vira fluid.\r\n * Off = mantém actions square e shrink-0 (mesmo comportamento desktop).\r\n */\r\n mobileFluid: {\r\n true: {\r\n actionsRow: [\r\n \"max-md:shrink max-md:flex-1 max-md:justify-end\",\r\n \"max-md:[&>:last-child]:flex-1\",\r\n ],\r\n },\r\n false: {},\r\n },\r\n },\r\n defaultVariants: {\r\n titleWrap: true,\r\n descriptionLines: 1,\r\n hideTextOnMobile: true,\r\n mobileFluid: true,\r\n },\r\n});\r\n"],"names":["tv"],"mappings":";;;AAkBO,MAAM,mBAAmBA,GAAAA,GAAG;AAAA,EACjC,OAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,UAAU;AAAA,IACV,OAAO;AAAA,IACP,aAAa;AAAA,IACb,YAAY;AAAA;AAAA;AAAA,IAGZ,UAAU;AAAA,EAAA;AAAA,EAEZ,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAcR,WAAW;AAAA,MACT,MAAM,EAAE,UAAU,aAAa,OAAO,2BAAA;AAAA,MACtC,OAAO,EAAE,OAAO,WAAA;AAAA,IAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAU7B,kBAAkB;AAAA,MAChB,GAAG,EAAE,aAAa,kDAAA;AAAA,MAClB,GAAG,EAAE,aAAa,eAAA;AAAA,MAClB,GAAG,EAAE,aAAa,eAAA;AAAA;AAAA;AAAA,MAGlB,MAAM,EAAE,aAAa,GAAA;AAAA,IAAG;AAAA,IAE1B,kBAAkB;AAAA,MAChB,MAAM,EAAE,SAAS,gBAAA;AAAA,MACjB,OAAO,CAAA;AAAA,IAAC;AAAA;AAAA;AAAA;AAAA;AAAA,IAMV,aAAa;AAAA,MACX,MAAM;AAAA,QACJ,YAAY;AAAA,UACV;AAAA,UACA;AAAA,QAAA;AAAA,MACF;AAAA,MAEF,OAAO,CAAA;AAAA,IAAC;AAAA,EACV;AAAA,EAEF,iBAAiB;AAAA,IACf,WAAW;AAAA,IACX,kBAAkB;AAAA,IAClB,kBAAkB;AAAA,IAClB,aAAa;AAAA,EAAA;AAEjB,CAAC;;"}
@@ -55,6 +55,9 @@ export declare const pageHeaderStyles: import('tailwind-variants').TVReturnType<
55
55
  3: {
56
56
  description: string;
57
57
  };
58
+ none: {
59
+ description: string;
60
+ };
58
61
  };
59
62
  hideTextOnMobile: {
60
63
  true: {
@@ -122,6 +125,9 @@ export declare const pageHeaderStyles: import('tailwind-variants').TVReturnType<
122
125
  3: {
123
126
  description: string;
124
127
  };
128
+ none: {
129
+ description: string;
130
+ };
125
131
  };
126
132
  hideTextOnMobile: {
127
133
  true: {
@@ -189,6 +195,9 @@ export declare const pageHeaderStyles: import('tailwind-variants').TVReturnType<
189
195
  3: {
190
196
  description: string;
191
197
  };
198
+ none: {
199
+ description: string;
200
+ };
192
201
  };
193
202
  hideTextOnMobile: {
194
203
  true: {
@@ -1 +1 @@
1
- {"version":3,"file":"page-header.styles.d.ts","sourceRoot":"","sources":["../../../../../src/components/ui/PageHeader/page-header.styles.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,gBAAgB;IAczB;;;;;;;;;;;;OAYG;;;;;;;;;;IAKH;;;;;;;OAOG;;;;;;;;;;;;;;;;;;IAUH;;;OAGG;;;;;;;;;;;;;;;;;IArCH;;;;;;;;;;;;OAYG;;;;;;;;;;IAKH;;;;;;;OAOG;;;;;;;;;;;;;;;;;;IAUH;;;OAGG;;;;;;;;;;;;;;;;;IArCH;;;;;;;;;;;;OAYG;;;;;;;;;;IAKH;;;;;;;OAOG;;;;;;;;;;;;;;;;;;IAUH;;;OAGG;;;;;;;;;;;;;;;;2CAiBL,CAAC"}
1
+ {"version":3,"file":"page-header.styles.d.ts","sourceRoot":"","sources":["../../../../../src/components/ui/PageHeader/page-header.styles.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,gBAAgB;IAczB;;;;;;;;;;;;OAYG;;;;;;;;;;IAKH;;;;;;;OAOG;;;;;;;;;;;;;;;;;;;;;IAaH;;;OAGG;;;;;;;;;;;;;;;;;IAxCH;;;;;;;;;;;;OAYG;;;;;;;;;;IAKH;;;;;;;OAOG;;;;;;;;;;;;;;;;;;;;;IAaH;;;OAGG;;;;;;;;;;;;;;;;;IAxCH;;;;;;;;;;;;OAYG;;;;;;;;;;IAKH;;;;;;;OAOG;;;;;;;;;;;;;;;;;;;;;IAaH;;;OAGG;;;;;;;;;;;;;;;;2CAiBL,CAAC"}
@@ -41,7 +41,10 @@ const pageHeaderStyles = tv({
41
41
  descriptionLines: {
42
42
  1: { description: "whitespace-nowrap overflow-hidden text-ellipsis" },
43
43
  2: { description: "line-clamp-2" },
44
- 3: { description: "line-clamp-3" }
44
+ 3: { description: "line-clamp-3" },
45
+ // Sem corte: a descrição cresce. Não é o default porque header é âncora de
46
+ // leitura — mas com conteúdo composto (link, chip, seletor) cortar é pior.
47
+ none: { description: "" }
45
48
  },
46
49
  hideTextOnMobile: {
47
50
  true: { textCol: "max-md:hidden" },
@@ -1 +1 @@
1
- {"version":3,"file":"page-header.styles.mjs","sources":["../../../../../src/components/ui/PageHeader/page-header.styles.ts"],"sourcesContent":["import { tv } from \"@/utils/tv\";\r\n\r\n/**\r\n * PageHeader styles — bloco de título de página colocado dentro do body\r\n * do `<AppShell>`.\r\n *\r\n * Layout desktop:\r\n * ┌──────────────────────────────────────────────────────────┐\r\n * │ [title] [badge] [action1] [action2] [CTA] │\r\n * │ description │\r\n * ├──────────────────────────────────────────────────────────┤\r\n * │ {children — ex: <Tabs />} │\r\n * └──────────────────────────────────────────────────────────┘\r\n *\r\n * Mobile:\r\n * - Text section sai (hideTextOnMobile, default true)\r\n * - Actions ocupam toda a largura; último botão vira fluid (CTA primary)\r\n */\r\nexport const pageHeaderStyles = tv({\r\n slots: {\r\n root: \"shrink-0 flex flex-col gap-gp-md\",\r\n topRow: \"flex items-center justify-between gap-gp-2xl\",\r\n textCol: \"flex flex-col gap-gp-xs min-w-0 flex-1\",\r\n titleRow: \"flex items-center gap-gp-md min-w-0\",\r\n title: \"m-0 text-title-lg font-bold tracking-[-0.01em] text-fg-default\",\r\n description: \"m-0 text-body-md text-fg-subtle leading-[1.5]\",\r\n actionsRow: \"flex items-center gap-gp-sm shrink-0\",\r\n // mt-gp-xl: +20px somados ao gap-gp-md (12px) do root = ~32px de respiro\r\n // entre o título/descrição e o slot de conteúdo (tabs/filtros).\r\n extraRow: \"w-full mt-gp-xl\",\r\n },\r\n variants: {\r\n /**\r\n * Título em uma linha (default, `false`) ou quebrando em várias.\r\n *\r\n * ⚠️ Default `true` = o comportamento que o PageHeader SEMPRE teve. O título nunca\r\n * teve truncate (só a descrição tinha), então um título longo quebrava. A primeira\r\n * versão desta prop veio com default `false` e teria truncado todo título longo já\r\n * existente — mudança de default que ninguém pediu, num PR que já carrega uma quebra\r\n * deliberada. Quem quer uma linha só pede `titleWrap={false}`.\r\n *\r\n * O caso que originou a prop era o inverso: um consumidor recriou o header por fora\r\n * porque nome longo de projeto virava \"Relatório de atendimento por…\". Com o default\r\n * certo, esse caso já estava atendido — o que faltava era poder DESLIGAR.\r\n */\r\n titleWrap: {\r\n true: { titleRow: \"flex-wrap\", title: \"[overflow-wrap:anywhere]\" },\r\n false: { title: \"truncate\" },\r\n },\r\n /**\r\n * Quantas linhas a descrição ocupa antes de cortar.\r\n *\r\n * O degrau 1 mantém as classes ORIGINAIS (`whitespace-nowrap` + ellipsis) em vez do\r\n * `line-clamp-1` equivalente: o line-clamp troca o `display` pra `-webkit-box`, e\r\n * trocar o display de um filho de flex por uma equivalência \"visualmente igual\" é o\r\n * tipo de detalhe que só aparece numa tela específica.\r\n */\r\n descriptionLines: {\r\n 1: { description: \"whitespace-nowrap overflow-hidden text-ellipsis\" },\r\n 2: { description: \"line-clamp-2\" },\r\n 3: { description: \"line-clamp-3\" },\r\n },\r\n hideTextOnMobile: {\r\n true: { textCol: \"max-md:hidden\" },\r\n false: {},\r\n },\r\n /**\r\n * Mobile: actions ocupa o espaço (text hidden) + último filho vira fluid.\r\n * Off = mantém actions square e shrink-0 (mesmo comportamento desktop).\r\n */\r\n mobileFluid: {\r\n true: {\r\n actionsRow: [\r\n \"max-md:shrink max-md:flex-1 max-md:justify-end\",\r\n \"max-md:[&>:last-child]:flex-1\",\r\n ],\r\n },\r\n false: {},\r\n },\r\n },\r\n defaultVariants: {\r\n titleWrap: true,\r\n descriptionLines: 1,\r\n hideTextOnMobile: true,\r\n mobileFluid: true,\r\n },\r\n});\r\n"],"names":[],"mappings":";AAkBO,MAAM,mBAAmB,GAAG;AAAA,EACjC,OAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,UAAU;AAAA,IACV,OAAO;AAAA,IACP,aAAa;AAAA,IACb,YAAY;AAAA;AAAA;AAAA,IAGZ,UAAU;AAAA,EAAA;AAAA,EAEZ,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAcR,WAAW;AAAA,MACT,MAAM,EAAE,UAAU,aAAa,OAAO,2BAAA;AAAA,MACtC,OAAO,EAAE,OAAO,WAAA;AAAA,IAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAU7B,kBAAkB;AAAA,MAChB,GAAG,EAAE,aAAa,kDAAA;AAAA,MAClB,GAAG,EAAE,aAAa,eAAA;AAAA,MAClB,GAAG,EAAE,aAAa,eAAA;AAAA,IAAe;AAAA,IAEnC,kBAAkB;AAAA,MAChB,MAAM,EAAE,SAAS,gBAAA;AAAA,MACjB,OAAO,CAAA;AAAA,IAAC;AAAA;AAAA;AAAA;AAAA;AAAA,IAMV,aAAa;AAAA,MACX,MAAM;AAAA,QACJ,YAAY;AAAA,UACV;AAAA,UACA;AAAA,QAAA;AAAA,MACF;AAAA,MAEF,OAAO,CAAA;AAAA,IAAC;AAAA,EACV;AAAA,EAEF,iBAAiB;AAAA,IACf,WAAW;AAAA,IACX,kBAAkB;AAAA,IAClB,kBAAkB;AAAA,IAClB,aAAa;AAAA,EAAA;AAEjB,CAAC;"}
1
+ {"version":3,"file":"page-header.styles.mjs","sources":["../../../../../src/components/ui/PageHeader/page-header.styles.ts"],"sourcesContent":["import { tv } from \"@/utils/tv\";\r\n\r\n/**\r\n * PageHeader styles — bloco de título de página colocado dentro do body\r\n * do `<AppShell>`.\r\n *\r\n * Layout desktop:\r\n * ┌──────────────────────────────────────────────────────────┐\r\n * │ [title] [badge] [action1] [action2] [CTA] │\r\n * │ description │\r\n * ├──────────────────────────────────────────────────────────┤\r\n * │ {children — ex: <Tabs />} │\r\n * └──────────────────────────────────────────────────────────┘\r\n *\r\n * Mobile:\r\n * - Text section sai (hideTextOnMobile, default true)\r\n * - Actions ocupam toda a largura; último botão vira fluid (CTA primary)\r\n */\r\nexport const pageHeaderStyles = tv({\r\n slots: {\r\n root: \"shrink-0 flex flex-col gap-gp-md\",\r\n topRow: \"flex items-center justify-between gap-gp-2xl\",\r\n textCol: \"flex flex-col gap-gp-xs min-w-0 flex-1\",\r\n titleRow: \"flex items-center gap-gp-md min-w-0\",\r\n title: \"m-0 text-title-lg font-bold tracking-[-0.01em] text-fg-default\",\r\n description: \"m-0 text-body-md text-fg-subtle leading-[1.5]\",\r\n actionsRow: \"flex items-center gap-gp-sm shrink-0\",\r\n // mt-gp-xl: +20px somados ao gap-gp-md (12px) do root = ~32px de respiro\r\n // entre o título/descrição e o slot de conteúdo (tabs/filtros).\r\n extraRow: \"w-full mt-gp-xl\",\r\n },\r\n variants: {\r\n /**\r\n * Título em uma linha (default, `false`) ou quebrando em várias.\r\n *\r\n * ⚠️ Default `true` = o comportamento que o PageHeader SEMPRE teve. O título nunca\r\n * teve truncate (só a descrição tinha), então um título longo quebrava. A primeira\r\n * versão desta prop veio com default `false` e teria truncado todo título longo já\r\n * existente — mudança de default que ninguém pediu, num PR que já carrega uma quebra\r\n * deliberada. Quem quer uma linha só pede `titleWrap={false}`.\r\n *\r\n * O caso que originou a prop era o inverso: um consumidor recriou o header por fora\r\n * porque nome longo de projeto virava \"Relatório de atendimento por…\". Com o default\r\n * certo, esse caso já estava atendido — o que faltava era poder DESLIGAR.\r\n */\r\n titleWrap: {\r\n true: { titleRow: \"flex-wrap\", title: \"[overflow-wrap:anywhere]\" },\r\n false: { title: \"truncate\" },\r\n },\r\n /**\r\n * Quantas linhas a descrição ocupa antes de cortar.\r\n *\r\n * O degrau 1 mantém as classes ORIGINAIS (`whitespace-nowrap` + ellipsis) em vez do\r\n * `line-clamp-1` equivalente: o line-clamp troca o `display` pra `-webkit-box`, e\r\n * trocar o display de um filho de flex por uma equivalência \"visualmente igual\" é o\r\n * tipo de detalhe que só aparece numa tela específica.\r\n */\r\n descriptionLines: {\r\n 1: { description: \"whitespace-nowrap overflow-hidden text-ellipsis\" },\r\n 2: { description: \"line-clamp-2\" },\r\n 3: { description: \"line-clamp-3\" },\r\n // Sem corte: a descrição cresce. Não é o default porque header é âncora de\r\n // leitura — mas com conteúdo composto (link, chip, seletor) cortar é pior.\r\n none: { description: \"\" },\r\n },\r\n hideTextOnMobile: {\r\n true: { textCol: \"max-md:hidden\" },\r\n false: {},\r\n },\r\n /**\r\n * Mobile: actions ocupa o espaço (text hidden) + último filho vira fluid.\r\n * Off = mantém actions square e shrink-0 (mesmo comportamento desktop).\r\n */\r\n mobileFluid: {\r\n true: {\r\n actionsRow: [\r\n \"max-md:shrink max-md:flex-1 max-md:justify-end\",\r\n \"max-md:[&>:last-child]:flex-1\",\r\n ],\r\n },\r\n false: {},\r\n },\r\n },\r\n defaultVariants: {\r\n titleWrap: true,\r\n descriptionLines: 1,\r\n hideTextOnMobile: true,\r\n mobileFluid: true,\r\n },\r\n});\r\n"],"names":[],"mappings":";AAkBO,MAAM,mBAAmB,GAAG;AAAA,EACjC,OAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,UAAU;AAAA,IACV,OAAO;AAAA,IACP,aAAa;AAAA,IACb,YAAY;AAAA;AAAA;AAAA,IAGZ,UAAU;AAAA,EAAA;AAAA,EAEZ,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAcR,WAAW;AAAA,MACT,MAAM,EAAE,UAAU,aAAa,OAAO,2BAAA;AAAA,MACtC,OAAO,EAAE,OAAO,WAAA;AAAA,IAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAU7B,kBAAkB;AAAA,MAChB,GAAG,EAAE,aAAa,kDAAA;AAAA,MAClB,GAAG,EAAE,aAAa,eAAA;AAAA,MAClB,GAAG,EAAE,aAAa,eAAA;AAAA;AAAA;AAAA,MAGlB,MAAM,EAAE,aAAa,GAAA;AAAA,IAAG;AAAA,IAE1B,kBAAkB;AAAA,MAChB,MAAM,EAAE,SAAS,gBAAA;AAAA,MACjB,OAAO,CAAA;AAAA,IAAC;AAAA;AAAA;AAAA;AAAA;AAAA,IAMV,aAAa;AAAA,MACX,MAAM;AAAA,QACJ,YAAY;AAAA,UACV;AAAA,UACA;AAAA,QAAA;AAAA,MACF;AAAA,MAEF,OAAO,CAAA;AAAA,IAAC;AAAA,EACV;AAAA,EAEF,iBAAiB;AAAA,IACf,WAAW;AAAA,IACX,kBAAkB;AAAA,IAClB,kBAAkB;AAAA,IAClB,aAAa;AAAA,EAAA;AAEjB,CAAC;"}
@@ -2,8 +2,14 @@ import { ReactNode } from 'react';
2
2
  export type PageHeaderProps = {
3
3
  /** Título principal da página (h1, text-title-md). */
4
4
  title?: string;
5
- /** Descrição/subtítulo logo abaixo do title. */
6
- description?: string;
5
+ /**
6
+ * Descrição/subtítulo logo abaixo do title.
7
+ *
8
+ * Aceita nó, e não só texto: a linha secundária de uma página costuma ter um link, um
9
+ * `Chip` de status ou um seletor de período junto. Com `string` apenas, o consumidor
10
+ * recriava o header inteiro por causa de um `<a>`.
11
+ */
12
+ description?: ReactNode;
7
13
  /**
8
14
  * Chip/badge inline ao lado do title (ex: contador de registros, status).
9
15
  * Aceita qualquer ReactNode mas normalmente é um `<Chip>` do DS.
@@ -30,9 +36,10 @@ export type PageHeaderProps = {
30
36
  */
31
37
  titleWrap?: boolean;
32
38
  /**
33
- * Linhas da descrição antes de cortar: 1 (default, igual ao anterior), 2 ou 3.
39
+ * Linhas da descrição antes de cortar: 1 (default, igual ao anterior), 2, 3 ou
40
+ * `"none"` (sem corte — a descrição cresce o quanto precisar).
34
41
  */
35
- descriptionLines?: 1 | 2 | 3;
42
+ descriptionLines?: 1 | 2 | 3 | "none";
36
43
  /**
37
44
  * Em mobile (<md), esconde o bloco title/description/badge.
38
45
  * - Default: `true` (pq o AppShell global já mostra o breadcrumb/título
@@ -1 +1 @@
1
- {"version":3,"file":"page-header.types.d.ts","sourceRoot":"","sources":["../../../../../src/components/ui/PageHeader/page-header.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,MAAM,eAAe,GAAG;IAC5B,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;;OAIG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,gBAAgB,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAE7B;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC"}
1
+ {"version":3,"file":"page-header.types.d.ts","sourceRoot":"","sources":["../../../../../src/components/ui/PageHeader/page-header.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,MAAM,eAAe,GAAG;IAC5B,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;;OAIG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;IAEtC;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC"}