@snksergio/design-system 0.45.0 → 0.47.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 (86) hide show
  1. package/README.md +1 -1
  2. package/dist-lib/chunks/app-shell-mocks-kWIVSzLs.mjs.map +1 -1
  3. package/dist-lib/chunks/app-shell-mocks-oO_IV3Gw.cjs.map +1 -1
  4. package/dist-lib/chunks/{avatar-DFWEwBKu.mjs → avatar-Cj_m-wJy.mjs} +42 -42
  5. package/dist-lib/chunks/avatar-Cj_m-wJy.mjs.map +1 -0
  6. package/dist-lib/chunks/avatar-eM5txRFZ.cjs.map +1 -1
  7. package/dist-lib/chunks/chat-v2-mocks-BV9Wha_Z.cjs.map +1 -1
  8. package/dist-lib/chunks/chat-v2-mocks-DvZRkhmz.mjs.map +1 -1
  9. package/dist-lib/chunks/{input-CfmzMYtd.mjs → input-CwRzwVPt.mjs} +2 -2
  10. package/dist-lib/chunks/{input-CfmzMYtd.mjs.map → input-CwRzwVPt.mjs.map} +1 -1
  11. package/dist-lib/chunks/{kpi-delta-B_1xjDu_.mjs → kpi-delta-D9p1xD4T.mjs} +3 -3
  12. package/dist-lib/chunks/{kpi-delta-B_1xjDu_.mjs.map → kpi-delta-D9p1xD4T.mjs.map} +1 -1
  13. package/dist-lib/chunks/{kpi-delta-CXGg2nBx.cjs → kpi-delta-DwQWNM-F.cjs} +2 -2
  14. package/dist-lib/chunks/{kpi-delta-CXGg2nBx.cjs.map → kpi-delta-DwQWNM-F.cjs.map} +1 -1
  15. package/dist-lib/chunks/{page-header--cPS_Z-a.mjs → page-header-DUxZjGdR.mjs} +2 -2
  16. package/dist-lib/chunks/page-header-DUxZjGdR.mjs.map +1 -0
  17. package/dist-lib/chunks/page-header-DvAJoEfb.cjs.map +1 -1
  18. package/dist-lib/chunks/{panel-DtQi10ps.mjs → panel-BlMiCA9Z.mjs} +17 -7
  19. package/dist-lib/chunks/panel-BlMiCA9Z.mjs.map +1 -0
  20. package/dist-lib/chunks/{panel-4aMDou7z.cjs → panel-DTVjD2gJ.cjs} +14 -4
  21. package/dist-lib/chunks/panel-DTVjD2gJ.cjs.map +1 -0
  22. package/dist-lib/chunks/{sheet-D1vQth7X.mjs → sheet-Bc-LMBDF.mjs} +2 -2
  23. package/dist-lib/chunks/sheet-Bc-LMBDF.mjs.map +1 -0
  24. package/dist-lib/chunks/sheet-j-d_UX7R.cjs.map +1 -1
  25. package/dist-lib/chunks/{toggle-group-CFiAGdm7.mjs → toggle-group-Bol3G73g.mjs} +55 -19
  26. package/dist-lib/chunks/toggle-group-Bol3G73g.mjs.map +1 -0
  27. package/dist-lib/chunks/{toggle-group-BC4eS3Gt.cjs → toggle-group-sXg1B2wN.cjs} +42 -6
  28. package/dist-lib/chunks/toggle-group-sXg1B2wN.cjs.map +1 -0
  29. package/dist-lib/chunks/{useTheme-C9Y6vxTf.cjs → useTheme-BB3QhUpu.cjs} +5 -2
  30. package/dist-lib/chunks/useTheme-BB3QhUpu.cjs.map +1 -0
  31. package/dist-lib/chunks/{useTheme-DCmzLBUR.mjs → useTheme-DNqHuA6o.mjs} +6 -3
  32. package/dist-lib/chunks/useTheme-DNqHuA6o.mjs.map +1 -0
  33. package/dist-lib/index.cjs +93 -5
  34. package/dist-lib/index.cjs.map +1 -1
  35. package/dist-lib/index.mjs +235 -147
  36. package/dist-lib/index.mjs.map +1 -1
  37. package/dist-lib/preview/chat.cjs +1 -1
  38. package/dist-lib/preview/chat.cjs.map +1 -1
  39. package/dist-lib/preview/chat.mjs +3 -3
  40. package/dist-lib/preview/chat.mjs.map +1 -1
  41. package/dist-lib/preview/clientes.cjs +2 -2
  42. package/dist-lib/preview/clientes.mjs +6 -6
  43. package/dist-lib/preview/dashboard.cjs +2 -2
  44. package/dist-lib/preview/dashboard.mjs +4 -4
  45. package/dist-lib/shadcn.cjs +2 -14
  46. package/dist-lib/shadcn.cjs.map +1 -1
  47. package/dist-lib/shadcn.mjs +56 -69
  48. package/dist-lib/shadcn.mjs.map +1 -1
  49. package/dist-lib/src/components/index.d.ts +1 -0
  50. package/dist-lib/src/components/index.d.ts.map +1 -1
  51. package/dist-lib/src/components/shadcn/tabs.d.ts +40 -8
  52. package/dist-lib/src/components/shadcn/tabs.d.ts.map +1 -1
  53. package/dist-lib/src/components/ui/AppShell/app-shell.types.d.ts +10 -3
  54. package/dist-lib/src/components/ui/AppShell/app-shell.types.d.ts.map +1 -1
  55. package/dist-lib/src/components/ui/DataTable/hooks/use-grab-to-scroll.d.ts.map +1 -1
  56. package/dist-lib/src/components/ui/MenuSidebar/sidebar-brand.d.ts +15 -0
  57. package/dist-lib/src/components/ui/MenuSidebar/sidebar-brand.d.ts.map +1 -1
  58. package/dist-lib/src/components/ui/ScreenLoader/index.d.ts +3 -0
  59. package/dist-lib/src/components/ui/ScreenLoader/index.d.ts.map +1 -0
  60. package/dist-lib/src/components/ui/ScreenLoader/screen-loader.d.ts +21 -0
  61. package/dist-lib/src/components/ui/ScreenLoader/screen-loader.d.ts.map +1 -0
  62. package/dist-lib/src/components/ui/ScreenLoader/screen-loader.styles.d.ts +111 -0
  63. package/dist-lib/src/components/ui/ScreenLoader/screen-loader.styles.d.ts.map +1 -0
  64. package/dist-lib/src/components/ui/ScreenLoader/screen-loader.types.d.ts +26 -0
  65. package/dist-lib/src/components/ui/ScreenLoader/screen-loader.types.d.ts.map +1 -0
  66. package/dist-lib/src/components/ui/SingleMenuSidebar/header.d.ts.map +1 -1
  67. package/dist-lib/src/components/ui/SingleMenuSidebar/single-menu-sidebar.types.d.ts +8 -4
  68. package/dist-lib/src/components/ui/SingleMenuSidebar/single-menu-sidebar.types.d.ts.map +1 -1
  69. package/dist-lib/src/components/ui/Spinner/spinner.styles.d.ts +9 -0
  70. package/dist-lib/src/components/ui/Spinner/spinner.styles.d.ts.map +1 -1
  71. package/dist-lib/theme/brand-blue.css +110 -110
  72. package/dist-lib/theme/brand-green.css +110 -110
  73. package/dist-lib/theme/brand-pay.css +189 -189
  74. package/dist-lib/theme/brand-vibrant.css +148 -148
  75. package/dist-lib/tokens.cjs.map +1 -1
  76. package/dist-lib/tokens.mjs.map +1 -1
  77. package/package.json +1 -1
  78. package/dist-lib/chunks/avatar-DFWEwBKu.mjs.map +0 -1
  79. package/dist-lib/chunks/page-header--cPS_Z-a.mjs.map +0 -1
  80. package/dist-lib/chunks/panel-4aMDou7z.cjs.map +0 -1
  81. package/dist-lib/chunks/panel-DtQi10ps.mjs.map +0 -1
  82. package/dist-lib/chunks/sheet-D1vQth7X.mjs.map +0 -1
  83. package/dist-lib/chunks/toggle-group-BC4eS3Gt.cjs.map +0 -1
  84. package/dist-lib/chunks/toggle-group-CFiAGdm7.mjs.map +0 -1
  85. package/dist-lib/chunks/useTheme-C9Y6vxTf.cjs.map +0 -1
  86. package/dist-lib/chunks/useTheme-DCmzLBUR.mjs.map +0 -1
@@ -1,7 +1,7 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import * as React from "react";
3
3
  import { cva } from "class-variance-authority";
4
- import { c as cn } from "./avatar-DFWEwBKu.mjs";
4
+ import { c as cn } from "./avatar-Cj_m-wJy.mjs";
5
5
  const inputVariants = cva(
6
6
  [
7
7
  "flex w-full",
@@ -73,4 +73,4 @@ export {
73
73
  Input as I,
74
74
  inputVariants as i
75
75
  };
76
- //# sourceMappingURL=input-CfmzMYtd.mjs.map
76
+ //# sourceMappingURL=input-CwRzwVPt.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"input-CfmzMYtd.mjs","sources":["../../src/components/shadcn/input.tsx"],"sourcesContent":["import * as React from \"react\";\r\nimport { cva, type VariantProps } from \"class-variance-authority\";\r\nimport { cn } from \"@/lib/utils\";\r\n\r\n/**\r\n * Input — alinhado com `.tbl-form-input` do design-and-table-v2.\r\n *\r\n * Specs base (md, default):\r\n * - h: 40px (form-lg), px: 12px (pad-xl), radius: 10px (radius-lg)\r\n * - bg-input (light) / dark:bg-bg-muted\r\n * - border: 1px solid border-input\r\n * - font: 13px, color fg-default, placeholder fg-muted\r\n * - focus: border + shadow-sh-ring por state\r\n *\r\n * Pra inputs com prefixo/sufixo/ícone/botão dentro → use `<InputGroup>`.\r\n * Este componente é puro (só o <input>) — sem wrapper, sem adornments inline.\r\n */\r\n\r\nexport type InputState = \"default\" | \"error\" | \"warning\" | \"success\";\r\n\r\nconst inputVariants = cva(\r\n [\r\n \"flex w-full\",\r\n \"bg-bg-input dark:bg-bg-muted\",\r\n \"hover:bg-bg-input-hover dark:hover:bg-bg-muted-hover\",\r\n \"border border-border-input rounded-radius-lg\",\r\n \"px-pad-xl\",\r\n \"text-body-sm font-normal text-fg-default placeholder:text-fg-muted placeholder:opacity-70\",\r\n \"transition-[border-color,box-shadow,background-color] outline-none\",\r\n \"disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-bg-input dark:disabled:hover:bg-bg-muted\",\r\n \"file:inline-flex file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-fg-default\",\r\n // type=file — escopado no atributo de propósito, pra não mexer em nenhum\r\n // outro input (este é primitivo compartilhado).\r\n //\r\n // · `block` + `align-content:center`: o conteúdo do file input (botão +\r\n // nome do arquivo) vive no SHADOW DOM, então `align-items` NÃO o move —\r\n // medido: com `items-center` o computed vira `center` e o pixel não sai\r\n // do lugar. O que centra é `align-content` num container de BLOCO\r\n // (CSS Align L3), que aplica ao conteúdo em fluxo. Testados e reprovados:\r\n // `items-center`, `align-content` sobre flex (com e sem wrap), `grid` +\r\n // `place-content`, e `::file-selector-button { margin-block: auto }`.\r\n // Preferido a `line-height` = altura da caixa, que centraria também mas\r\n // exigiria um px mágico por size (28/32/36/40) desacoplado dos tokens de\r\n // `form-*`. Piso: Chrome 123+ / Safari 17.6+ / Firefox 125+; abaixo disso\r\n // degrada pro alinhamento antigo, sem quebrar nada.\r\n // · `text-fg-muted`: o \"Nenhum arquivo escolhido\" vinha em fg-default\r\n // (0.98), destoando de `placeholder:text-fg-muted` de todo input do DS.\r\n // O CSS não distingue vazio de preenchido num file input, então o nome do\r\n // arquivo escolhido também fica muted — trade-off registrado no gotcha de\r\n // `shadcn/USAGE.md`; pra UX de upload de verdade use `FileUploadField`.\r\n \"[&[type=file]]:block [&[type=file]]:[align-content:center] [&[type=file]]:text-fg-muted\",\r\n ],\r\n {\r\n variants: {\r\n size: {\r\n xxs: \"min-h-form-xs rounded-radius-md\",\r\n xs: \"min-h-form-sm rounded-radius-md\",\r\n sm: \"min-h-form-md\",\r\n md: \"min-h-form-lg\",\r\n },\r\n state: {\r\n default: \"focus-visible:border-border-brand focus-visible:shadow-sh-ring\",\r\n error: \"border-border-danger-muted focus-visible:border-border-danger-muted focus-visible:shadow-sh-ring-danger\",\r\n warning: \"border-border-warning-muted focus-visible:border-border-warning-muted focus-visible:shadow-sh-ring-warning\",\r\n success: \"border-border-success-muted focus-visible:border-border-success-muted focus-visible:shadow-sh-ring-success\",\r\n },\r\n },\r\n defaultVariants: {\r\n size: \"md\",\r\n state: \"default\",\r\n },\r\n },\r\n);\r\n\r\nexport type InputVariantProps = VariantProps<typeof inputVariants>;\r\n\r\nexport interface InputProps\r\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"size\">,\r\n InputVariantProps {}\r\n\r\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\r\n ({ className, type, size, state, ...props }, ref) => {\r\n return (\r\n <input\r\n type={type}\r\n ref={ref}\r\n className={cn(inputVariants({ size, state }), className)}\r\n {...props}\r\n />\r\n );\r\n },\r\n);\r\nInput.displayName = \"Input\";\r\n\r\nexport { Input, inputVariants };\r\n"],"names":[],"mappings":";;;;AAoBA,MAAM,gBAAgB;AAAA,EACpB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAoBA;AAAA,EAAA;AAAA,EAEF;AAAA,IACE,UAAU;AAAA,MACR,MAAM;AAAA,QACJ,KAAK;AAAA,QACL,IAAK;AAAA,QACL,IAAK;AAAA,QACL,IAAK;AAAA,MAAA;AAAA,MAEP,OAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAS;AAAA,QACT,SAAS;AAAA,QACT,SAAS;AAAA,MAAA;AAAA,IACX;AAAA,IAEF,iBAAiB;AAAA,MACf,MAAM;AAAA,MACN,OAAO;AAAA,IAAA;AAAA,EACT;AAEJ;AAQA,MAAM,QAAQ,MAAM;AAAA,EAClB,CAAC,EAAE,WAAW,MAAM,MAAM,OAAO,GAAG,MAAA,GAAS,QAAQ;AACnD,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,WAAW,GAAG,cAAc,EAAE,MAAM,MAAA,CAAO,GAAG,SAAS;AAAA,QACtD,GAAG;AAAA,MAAA;AAAA,IAAA;AAAA,EAGV;AACF;AACA,MAAM,cAAc;"}
1
+ {"version":3,"file":"input-CwRzwVPt.mjs","sources":["../../src/components/shadcn/input.tsx"],"sourcesContent":["import * as React from \"react\";\r\nimport { cva, type VariantProps } from \"class-variance-authority\";\r\nimport { cn } from \"@/lib/utils\";\r\n\r\n/**\r\n * Input — alinhado com `.tbl-form-input` do design-and-table-v2.\r\n *\r\n * Specs base (md, default):\r\n * - h: 40px (form-lg), px: 12px (pad-xl), radius: 10px (radius-lg)\r\n * - bg-input (light) / dark:bg-bg-muted\r\n * - border: 1px solid border-input\r\n * - font: 13px, color fg-default, placeholder fg-muted\r\n * - focus: border + shadow-sh-ring por state\r\n *\r\n * Pra inputs com prefixo/sufixo/ícone/botão dentro → use `<InputGroup>`.\r\n * Este componente é puro (só o <input>) — sem wrapper, sem adornments inline.\r\n */\r\n\r\nexport type InputState = \"default\" | \"error\" | \"warning\" | \"success\";\r\n\r\nconst inputVariants = cva(\r\n [\r\n \"flex w-full\",\r\n \"bg-bg-input dark:bg-bg-muted\",\r\n \"hover:bg-bg-input-hover dark:hover:bg-bg-muted-hover\",\r\n \"border border-border-input rounded-radius-lg\",\r\n \"px-pad-xl\",\r\n \"text-body-sm font-normal text-fg-default placeholder:text-fg-muted placeholder:opacity-70\",\r\n \"transition-[border-color,box-shadow,background-color] outline-none\",\r\n \"disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-bg-input dark:disabled:hover:bg-bg-muted\",\r\n \"file:inline-flex file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-fg-default\",\r\n // type=file — escopado no atributo de propósito, pra não mexer em nenhum\r\n // outro input (este é primitivo compartilhado).\r\n //\r\n // · `block` + `align-content:center`: o conteúdo do file input (botão +\r\n // nome do arquivo) vive no SHADOW DOM, então `align-items` NÃO o move —\r\n // medido: com `items-center` o computed vira `center` e o pixel não sai\r\n // do lugar. O que centra é `align-content` num container de BLOCO\r\n // (CSS Align L3), que aplica ao conteúdo em fluxo. Testados e reprovados:\r\n // `items-center`, `align-content` sobre flex (com e sem wrap), `grid` +\r\n // `place-content`, e `::file-selector-button { margin-block: auto }`.\r\n // Preferido a `line-height` = altura da caixa, que centraria também mas\r\n // exigiria um px mágico por size (28/32/36/40) desacoplado dos tokens de\r\n // `form-*`. Piso: Chrome 123+ / Safari 17.6+ / Firefox 125+; abaixo disso\r\n // degrada pro alinhamento antigo, sem quebrar nada.\r\n // · `text-fg-muted`: o \"Nenhum arquivo escolhido\" vinha em fg-default\r\n // (0.98), destoando de `placeholder:text-fg-muted` de todo input do DS.\r\n // O CSS não distingue vazio de preenchido num file input, então o nome do\r\n // arquivo escolhido também fica muted — trade-off registrado no gotcha de\r\n // `shadcn/USAGE.md`; pra UX de upload de verdade use `FileUploadField`.\r\n \"[&[type=file]]:block [&[type=file]]:[align-content:center] [&[type=file]]:text-fg-muted\",\r\n ],\r\n {\r\n variants: {\r\n size: {\r\n xxs: \"min-h-form-xs rounded-radius-md\",\r\n xs: \"min-h-form-sm rounded-radius-md\",\r\n sm: \"min-h-form-md\",\r\n md: \"min-h-form-lg\",\r\n },\r\n state: {\r\n default: \"focus-visible:border-border-brand focus-visible:shadow-sh-ring\",\r\n error: \"border-border-danger-muted focus-visible:border-border-danger-muted focus-visible:shadow-sh-ring-danger\",\r\n warning: \"border-border-warning-muted focus-visible:border-border-warning-muted focus-visible:shadow-sh-ring-warning\",\r\n success: \"border-border-success-muted focus-visible:border-border-success-muted focus-visible:shadow-sh-ring-success\",\r\n },\r\n },\r\n defaultVariants: {\r\n size: \"md\",\r\n state: \"default\",\r\n },\r\n },\r\n);\r\n\r\nexport type InputVariantProps = VariantProps<typeof inputVariants>;\r\n\r\nexport interface InputProps\r\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"size\">,\r\n InputVariantProps {}\r\n\r\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\r\n ({ className, type, size, state, ...props }, ref) => {\r\n return (\r\n <input\r\n type={type}\r\n ref={ref}\r\n className={cn(inputVariants({ size, state }), className)}\r\n {...props}\r\n />\r\n );\r\n },\r\n);\r\nInput.displayName = \"Input\";\r\n\r\nexport { Input, inputVariants };\r\n"],"names":[],"mappings":";;;;AAoBA,MAAM,gBAAgB;AAAA,EACpB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAoBA;AAAA,EAAA;AAAA,EAEF;AAAA,IACE,UAAU;AAAA,MACR,MAAM;AAAA,QACJ,KAAK;AAAA,QACL,IAAK;AAAA,QACL,IAAK;AAAA,QACL,IAAK;AAAA,MAAA;AAAA,MAEP,OAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAS;AAAA,QACT,SAAS;AAAA,QACT,SAAS;AAAA,MAAA;AAAA,IACX;AAAA,IAEF,iBAAiB;AAAA,MACf,MAAM;AAAA,MACN,OAAO;AAAA,IAAA;AAAA,EACT;AAEJ;AAQA,MAAM,QAAQ,MAAM;AAAA,EAClB,CAAC,EAAE,WAAW,MAAM,MAAM,OAAO,GAAG,MAAA,GAAS,QAAQ;AACnD,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,WAAW,GAAG,cAAc,EAAE,MAAM,MAAA,CAAO,GAAG,SAAS;AAAA,QACtD,GAAG;AAAA,MAAA;AAAA,IAAA;AAAA,EAGV;AACF;AACA,MAAM,cAAc;"}
@@ -1,8 +1,8 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { createContext, useContext } from "react";
3
- import { t as tv, c as cn } from "./avatar-DFWEwBKu.mjs";
3
+ import { a8 as tv, c as cn } from "./avatar-Cj_m-wJy.mjs";
4
4
  import { TrendingUp } from "lucide-react";
5
- import { C as Chip } from "./useTheme-DCmzLBUR.mjs";
5
+ import { C as Chip } from "./useTheme-DNqHuA6o.mjs";
6
6
  const kpi = tv({
7
7
  slots: {
8
8
  root: "flex flex-col gap-gp-lg",
@@ -147,4 +147,4 @@ export {
147
147
  Kpi as a,
148
148
  KpiDelta as b
149
149
  };
150
- //# sourceMappingURL=kpi-delta-B_1xjDu_.mjs.map
150
+ //# sourceMappingURL=kpi-delta-D9p1xD4T.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"kpi-delta-B_1xjDu_.mjs","sources":["../../src/components/ui/Kpi/kpi.styles.ts","../../src/components/ui/Kpi/kpi-group.tsx","../../src/components/ui/Kpi/kpi.tsx","../../src/components/ui/Kpi/kpi-delta.tsx"],"sourcesContent":["import { tv } from \"@/utils/tv\";\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════\r\n Kpi — estilos (tv). 100% sobre tokens do DS, theme-aware.\r\n ══════════════════════════════════════════════════════════════════════════ */\r\n\r\nexport const kpi = tv({\r\n slots: {\r\n root: \"flex flex-col gap-gp-lg\",\r\n header: \"flex items-start justify-between gap-gp-md\",\r\n label: \"m-0 text-body-md font-semibold text-fg-default\",\r\n iconBox:\r\n \"grid size-form-lg shrink-0 place-items-center rounded-radius-lg [&>svg]:size-icon-md\",\r\n main: \"flex flex-col gap-gp-xs\",\r\n valueRow: \"flex flex-wrap items-center gap-gp-md\",\r\n value:\r\n \"leading-none text-fg-default [font-variant-numeric:tabular-nums]\",\r\n hint: \"text-caption-sm text-fg-subtle\",\r\n chart: \"mt-gp-xs\",\r\n footnote:\r\n \"mt-pad-md border-t border-border-subtle pt-pad-lg text-caption-md text-fg-muted\",\r\n },\r\n variants: {\r\n // Tamanho do valor de destaque — presets `stat-*` (número de métrica).\r\n // Default `md` (24px) = idêntico ao antigo `body-2xl`. Weight/leading tight\r\n // vêm do preset + slot; pareado com tabular-nums.\r\n size: {\r\n sm: { value: \"text-stat-sm\" },\r\n md: { value: \"text-stat-md\" },\r\n lg: { value: \"text-stat-lg\" },\r\n xl: { value: \"text-stat-xl\" },\r\n },\r\n surface: {\r\n card: {\r\n root: \"rounded-radius-xl border border-border-subtle bg-bg-surface p-pad-3xl shadow-sh-sm\",\r\n },\r\n plain: { root: \"p-pad-3xl\" },\r\n },\r\n tone: {\r\n brand: { iconBox: \"bg-bg-brand-subtle text-fg-brand\" },\r\n success: { iconBox: \"bg-bg-success-muted text-fg-success\" },\r\n warning: { iconBox: \"bg-bg-warning-muted text-fg-warning\" },\r\n info: { iconBox: \"bg-bg-info-muted text-fg-info\" },\r\n danger: { iconBox: \"bg-bg-danger-muted text-fg-danger\" },\r\n neutral: { iconBox: \"bg-bg-muted text-fg-muted\" },\r\n },\r\n },\r\n defaultVariants: {\r\n size: \"md\",\r\n surface: \"card\",\r\n tone: \"neutral\",\r\n },\r\n});\r\n\r\nexport const kpiGroup = tv({\r\n base: \"grid w-full\",\r\n variants: {\r\n columns: {\r\n 2: \"grid-cols-1 sm:grid-cols-2\",\r\n 3: \"grid-cols-1 sm:grid-cols-2 lg:grid-cols-3\",\r\n 4: \"grid-cols-1 sm:grid-cols-2 lg:grid-cols-4\",\r\n 5: \"grid-cols-1 sm:grid-cols-2 lg:grid-cols-5\",\r\n 6: \"grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-6\",\r\n },\r\n divided: {\r\n // 1 card único com divisórias (linha no mobile, coluna no sm+)\r\n true: \"overflow-hidden rounded-radius-xl border border-border-subtle bg-bg-surface shadow-sh-sm divide-y divide-border-subtle sm:divide-y-0 sm:divide-x\",\r\n false: \"gap-gp-2xl\",\r\n },\r\n },\r\n defaultVariants: {\r\n columns: 4,\r\n divided: false,\r\n },\r\n});\r\n","\"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) e\r\n * `divided` (vira 1 card único com divisórias entre os KPIs).\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 return (\r\n <KpiSurfaceContext.Provider value={divided ? \"plain\" : \"card\"}>\r\n <div className={cn(kpiGroup({ columns, divided }), className)}>\r\n {children}\r\n </div>\r\n </KpiSurfaceContext.Provider>\r\n );\r\n}\r\n\r\nKpiGroup.displayName = \"KpiGroup\";\r\n","\"use client\";\r\n\r\nimport { useContext } from \"react\";\r\nimport { cn } from \"@/lib/utils\";\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\nexport function Kpi({\r\n label,\r\n value,\r\n delta,\r\n hint,\r\n icon,\r\n tone = \"neutral\",\r\n size = \"md\",\r\n footnote,\r\n children,\r\n surface,\r\n className,\r\n}: KpiProps) {\r\n const inherited = useContext(KpiSurfaceContext);\r\n const s = kpi({ size, surface: surface ?? inherited, tone });\r\n\r\n return (\r\n <article className={cn(s.root(), className)}>\r\n <header className={s.header()}>\r\n <h3 className={s.label()}>{label}</h3>\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 className={s.value()}>{value}</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 </article>\r\n );\r\n}\r\n\r\nKpi.displayName = \"Kpi\";\r\n","\"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":"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"}
1
+ {"version":3,"file":"kpi-delta-D9p1xD4T.mjs","sources":["../../src/components/ui/Kpi/kpi.styles.ts","../../src/components/ui/Kpi/kpi-group.tsx","../../src/components/ui/Kpi/kpi.tsx","../../src/components/ui/Kpi/kpi-delta.tsx"],"sourcesContent":["import { tv } from \"@/utils/tv\";\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════\r\n Kpi — estilos (tv). 100% sobre tokens do DS, theme-aware.\r\n ══════════════════════════════════════════════════════════════════════════ */\r\n\r\nexport const kpi = tv({\r\n slots: {\r\n root: \"flex flex-col gap-gp-lg\",\r\n header: \"flex items-start justify-between gap-gp-md\",\r\n label: \"m-0 text-body-md font-semibold text-fg-default\",\r\n iconBox:\r\n \"grid size-form-lg shrink-0 place-items-center rounded-radius-lg [&>svg]:size-icon-md\",\r\n main: \"flex flex-col gap-gp-xs\",\r\n valueRow: \"flex flex-wrap items-center gap-gp-md\",\r\n value:\r\n \"leading-none text-fg-default [font-variant-numeric:tabular-nums]\",\r\n hint: \"text-caption-sm text-fg-subtle\",\r\n chart: \"mt-gp-xs\",\r\n footnote:\r\n \"mt-pad-md border-t border-border-subtle pt-pad-lg text-caption-md text-fg-muted\",\r\n },\r\n variants: {\r\n // Tamanho do valor de destaque — presets `stat-*` (número de métrica).\r\n // Default `md` (24px) = idêntico ao antigo `body-2xl`. Weight/leading tight\r\n // vêm do preset + slot; pareado com tabular-nums.\r\n size: {\r\n sm: { value: \"text-stat-sm\" },\r\n md: { value: \"text-stat-md\" },\r\n lg: { value: \"text-stat-lg\" },\r\n xl: { value: \"text-stat-xl\" },\r\n },\r\n surface: {\r\n card: {\r\n root: \"rounded-radius-xl border border-border-subtle bg-bg-surface p-pad-3xl shadow-sh-sm\",\r\n },\r\n plain: { root: \"p-pad-3xl\" },\r\n },\r\n tone: {\r\n brand: { iconBox: \"bg-bg-brand-subtle text-fg-brand\" },\r\n success: { iconBox: \"bg-bg-success-muted text-fg-success\" },\r\n warning: { iconBox: \"bg-bg-warning-muted text-fg-warning\" },\r\n info: { iconBox: \"bg-bg-info-muted text-fg-info\" },\r\n danger: { iconBox: \"bg-bg-danger-muted text-fg-danger\" },\r\n neutral: { iconBox: \"bg-bg-muted text-fg-muted\" },\r\n },\r\n },\r\n defaultVariants: {\r\n size: \"md\",\r\n surface: \"card\",\r\n tone: \"neutral\",\r\n },\r\n});\r\n\r\nexport const kpiGroup = tv({\r\n base: \"grid w-full\",\r\n variants: {\r\n columns: {\r\n 2: \"grid-cols-1 sm:grid-cols-2\",\r\n 3: \"grid-cols-1 sm:grid-cols-2 lg:grid-cols-3\",\r\n 4: \"grid-cols-1 sm:grid-cols-2 lg:grid-cols-4\",\r\n 5: \"grid-cols-1 sm:grid-cols-2 lg:grid-cols-5\",\r\n 6: \"grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-6\",\r\n },\r\n divided: {\r\n // 1 card único com divisórias (linha no mobile, coluna no sm+)\r\n true: \"overflow-hidden rounded-radius-xl border border-border-subtle bg-bg-surface shadow-sh-sm divide-y divide-border-subtle sm:divide-y-0 sm:divide-x\",\r\n false: \"gap-gp-2xl\",\r\n },\r\n },\r\n defaultVariants: {\r\n columns: 4,\r\n divided: false,\r\n },\r\n});\r\n","\"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) e\r\n * `divided` (vira 1 card único com divisórias entre os KPIs).\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 return (\r\n <KpiSurfaceContext.Provider value={divided ? \"plain\" : \"card\"}>\r\n <div className={cn(kpiGroup({ columns, divided }), className)}>\r\n {children}\r\n </div>\r\n </KpiSurfaceContext.Provider>\r\n );\r\n}\r\n\r\nKpiGroup.displayName = \"KpiGroup\";\r\n","\"use client\";\r\n\r\nimport { useContext } from \"react\";\r\nimport { cn } from \"@/lib/utils\";\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\nexport function Kpi({\r\n label,\r\n value,\r\n delta,\r\n hint,\r\n icon,\r\n tone = \"neutral\",\r\n size = \"md\",\r\n footnote,\r\n children,\r\n surface,\r\n className,\r\n}: KpiProps) {\r\n const inherited = useContext(KpiSurfaceContext);\r\n const s = kpi({ size, surface: surface ?? inherited, tone });\r\n\r\n return (\r\n <article className={cn(s.root(), className)}>\r\n <header className={s.header()}>\r\n <h3 className={s.label()}>{label}</h3>\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 className={s.value()}>{value}</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 </article>\r\n );\r\n}\r\n\r\nKpi.displayName = \"Kpi\";\r\n","\"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":"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"}
@@ -3,7 +3,7 @@ const jsxRuntime = require("react/jsx-runtime");
3
3
  const React = require("react");
4
4
  const avatar = require("./avatar-eM5txRFZ.cjs");
5
5
  const lucideReact = require("lucide-react");
6
- const useTheme = require("./useTheme-C9Y6vxTf.cjs");
6
+ const useTheme = require("./useTheme-BB3QhUpu.cjs");
7
7
  const kpi = avatar.tv({
8
8
  slots: {
9
9
  root: "flex flex-col gap-gp-lg",
@@ -146,4 +146,4 @@ KpiDelta.displayName = "KpiDelta";
146
146
  exports.Kpi = Kpi;
147
147
  exports.KpiDelta = KpiDelta;
148
148
  exports.KpiGroup = KpiGroup;
149
- //# sourceMappingURL=kpi-delta-CXGg2nBx.cjs.map
149
+ //# sourceMappingURL=kpi-delta-DwQWNM-F.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"kpi-delta-CXGg2nBx.cjs","sources":["../../src/components/ui/Kpi/kpi.styles.ts","../../src/components/ui/Kpi/kpi-group.tsx","../../src/components/ui/Kpi/kpi.tsx","../../src/components/ui/Kpi/kpi-delta.tsx"],"sourcesContent":["import { tv } from \"@/utils/tv\";\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════\r\n Kpi — estilos (tv). 100% sobre tokens do DS, theme-aware.\r\n ══════════════════════════════════════════════════════════════════════════ */\r\n\r\nexport const kpi = tv({\r\n slots: {\r\n root: \"flex flex-col gap-gp-lg\",\r\n header: \"flex items-start justify-between gap-gp-md\",\r\n label: \"m-0 text-body-md font-semibold text-fg-default\",\r\n iconBox:\r\n \"grid size-form-lg shrink-0 place-items-center rounded-radius-lg [&>svg]:size-icon-md\",\r\n main: \"flex flex-col gap-gp-xs\",\r\n valueRow: \"flex flex-wrap items-center gap-gp-md\",\r\n value:\r\n \"leading-none text-fg-default [font-variant-numeric:tabular-nums]\",\r\n hint: \"text-caption-sm text-fg-subtle\",\r\n chart: \"mt-gp-xs\",\r\n footnote:\r\n \"mt-pad-md border-t border-border-subtle pt-pad-lg text-caption-md text-fg-muted\",\r\n },\r\n variants: {\r\n // Tamanho do valor de destaque — presets `stat-*` (número de métrica).\r\n // Default `md` (24px) = idêntico ao antigo `body-2xl`. Weight/leading tight\r\n // vêm do preset + slot; pareado com tabular-nums.\r\n size: {\r\n sm: { value: \"text-stat-sm\" },\r\n md: { value: \"text-stat-md\" },\r\n lg: { value: \"text-stat-lg\" },\r\n xl: { value: \"text-stat-xl\" },\r\n },\r\n surface: {\r\n card: {\r\n root: \"rounded-radius-xl border border-border-subtle bg-bg-surface p-pad-3xl shadow-sh-sm\",\r\n },\r\n plain: { root: \"p-pad-3xl\" },\r\n },\r\n tone: {\r\n brand: { iconBox: \"bg-bg-brand-subtle text-fg-brand\" },\r\n success: { iconBox: \"bg-bg-success-muted text-fg-success\" },\r\n warning: { iconBox: \"bg-bg-warning-muted text-fg-warning\" },\r\n info: { iconBox: \"bg-bg-info-muted text-fg-info\" },\r\n danger: { iconBox: \"bg-bg-danger-muted text-fg-danger\" },\r\n neutral: { iconBox: \"bg-bg-muted text-fg-muted\" },\r\n },\r\n },\r\n defaultVariants: {\r\n size: \"md\",\r\n surface: \"card\",\r\n tone: \"neutral\",\r\n },\r\n});\r\n\r\nexport const kpiGroup = tv({\r\n base: \"grid w-full\",\r\n variants: {\r\n columns: {\r\n 2: \"grid-cols-1 sm:grid-cols-2\",\r\n 3: \"grid-cols-1 sm:grid-cols-2 lg:grid-cols-3\",\r\n 4: \"grid-cols-1 sm:grid-cols-2 lg:grid-cols-4\",\r\n 5: \"grid-cols-1 sm:grid-cols-2 lg:grid-cols-5\",\r\n 6: \"grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-6\",\r\n },\r\n divided: {\r\n // 1 card único com divisórias (linha no mobile, coluna no sm+)\r\n true: \"overflow-hidden rounded-radius-xl border border-border-subtle bg-bg-surface shadow-sh-sm divide-y divide-border-subtle sm:divide-y-0 sm:divide-x\",\r\n false: \"gap-gp-2xl\",\r\n },\r\n },\r\n defaultVariants: {\r\n columns: 4,\r\n divided: false,\r\n },\r\n});\r\n","\"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) e\r\n * `divided` (vira 1 card único com divisórias entre os KPIs).\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 return (\r\n <KpiSurfaceContext.Provider value={divided ? \"plain\" : \"card\"}>\r\n <div className={cn(kpiGroup({ columns, divided }), className)}>\r\n {children}\r\n </div>\r\n </KpiSurfaceContext.Provider>\r\n );\r\n}\r\n\r\nKpiGroup.displayName = \"KpiGroup\";\r\n","\"use client\";\r\n\r\nimport { useContext } from \"react\";\r\nimport { cn } from \"@/lib/utils\";\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\nexport function Kpi({\r\n label,\r\n value,\r\n delta,\r\n hint,\r\n icon,\r\n tone = \"neutral\",\r\n size = \"md\",\r\n footnote,\r\n children,\r\n surface,\r\n className,\r\n}: KpiProps) {\r\n const inherited = useContext(KpiSurfaceContext);\r\n const s = kpi({ size, surface: surface ?? inherited, tone });\r\n\r\n return (\r\n <article className={cn(s.root(), className)}>\r\n <header className={s.header()}>\r\n <h3 className={s.label()}>{label}</h3>\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 className={s.value()}>{value}</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 </article>\r\n );\r\n}\r\n\r\nKpi.displayName = \"Kpi\";\r\n","\"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":["tv","createContext","jsx","cn","useContext","jsxs","Chip","TrendingUp"],"mappings":"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"}
1
+ {"version":3,"file":"kpi-delta-DwQWNM-F.cjs","sources":["../../src/components/ui/Kpi/kpi.styles.ts","../../src/components/ui/Kpi/kpi-group.tsx","../../src/components/ui/Kpi/kpi.tsx","../../src/components/ui/Kpi/kpi-delta.tsx"],"sourcesContent":["import { tv } from \"@/utils/tv\";\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════\r\n Kpi — estilos (tv). 100% sobre tokens do DS, theme-aware.\r\n ══════════════════════════════════════════════════════════════════════════ */\r\n\r\nexport const kpi = tv({\r\n slots: {\r\n root: \"flex flex-col gap-gp-lg\",\r\n header: \"flex items-start justify-between gap-gp-md\",\r\n label: \"m-0 text-body-md font-semibold text-fg-default\",\r\n iconBox:\r\n \"grid size-form-lg shrink-0 place-items-center rounded-radius-lg [&>svg]:size-icon-md\",\r\n main: \"flex flex-col gap-gp-xs\",\r\n valueRow: \"flex flex-wrap items-center gap-gp-md\",\r\n value:\r\n \"leading-none text-fg-default [font-variant-numeric:tabular-nums]\",\r\n hint: \"text-caption-sm text-fg-subtle\",\r\n chart: \"mt-gp-xs\",\r\n footnote:\r\n \"mt-pad-md border-t border-border-subtle pt-pad-lg text-caption-md text-fg-muted\",\r\n },\r\n variants: {\r\n // Tamanho do valor de destaque — presets `stat-*` (número de métrica).\r\n // Default `md` (24px) = idêntico ao antigo `body-2xl`. Weight/leading tight\r\n // vêm do preset + slot; pareado com tabular-nums.\r\n size: {\r\n sm: { value: \"text-stat-sm\" },\r\n md: { value: \"text-stat-md\" },\r\n lg: { value: \"text-stat-lg\" },\r\n xl: { value: \"text-stat-xl\" },\r\n },\r\n surface: {\r\n card: {\r\n root: \"rounded-radius-xl border border-border-subtle bg-bg-surface p-pad-3xl shadow-sh-sm\",\r\n },\r\n plain: { root: \"p-pad-3xl\" },\r\n },\r\n tone: {\r\n brand: { iconBox: \"bg-bg-brand-subtle text-fg-brand\" },\r\n success: { iconBox: \"bg-bg-success-muted text-fg-success\" },\r\n warning: { iconBox: \"bg-bg-warning-muted text-fg-warning\" },\r\n info: { iconBox: \"bg-bg-info-muted text-fg-info\" },\r\n danger: { iconBox: \"bg-bg-danger-muted text-fg-danger\" },\r\n neutral: { iconBox: \"bg-bg-muted text-fg-muted\" },\r\n },\r\n },\r\n defaultVariants: {\r\n size: \"md\",\r\n surface: \"card\",\r\n tone: \"neutral\",\r\n },\r\n});\r\n\r\nexport const kpiGroup = tv({\r\n base: \"grid w-full\",\r\n variants: {\r\n columns: {\r\n 2: \"grid-cols-1 sm:grid-cols-2\",\r\n 3: \"grid-cols-1 sm:grid-cols-2 lg:grid-cols-3\",\r\n 4: \"grid-cols-1 sm:grid-cols-2 lg:grid-cols-4\",\r\n 5: \"grid-cols-1 sm:grid-cols-2 lg:grid-cols-5\",\r\n 6: \"grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-6\",\r\n },\r\n divided: {\r\n // 1 card único com divisórias (linha no mobile, coluna no sm+)\r\n true: \"overflow-hidden rounded-radius-xl border border-border-subtle bg-bg-surface shadow-sh-sm divide-y divide-border-subtle sm:divide-y-0 sm:divide-x\",\r\n false: \"gap-gp-2xl\",\r\n },\r\n },\r\n defaultVariants: {\r\n columns: 4,\r\n divided: false,\r\n },\r\n});\r\n","\"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) e\r\n * `divided` (vira 1 card único com divisórias entre os KPIs).\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 return (\r\n <KpiSurfaceContext.Provider value={divided ? \"plain\" : \"card\"}>\r\n <div className={cn(kpiGroup({ columns, divided }), className)}>\r\n {children}\r\n </div>\r\n </KpiSurfaceContext.Provider>\r\n );\r\n}\r\n\r\nKpiGroup.displayName = \"KpiGroup\";\r\n","\"use client\";\r\n\r\nimport { useContext } from \"react\";\r\nimport { cn } from \"@/lib/utils\";\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\nexport function Kpi({\r\n label,\r\n value,\r\n delta,\r\n hint,\r\n icon,\r\n tone = \"neutral\",\r\n size = \"md\",\r\n footnote,\r\n children,\r\n surface,\r\n className,\r\n}: KpiProps) {\r\n const inherited = useContext(KpiSurfaceContext);\r\n const s = kpi({ size, surface: surface ?? inherited, tone });\r\n\r\n return (\r\n <article className={cn(s.root(), className)}>\r\n <header className={s.header()}>\r\n <h3 className={s.label()}>{label}</h3>\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 className={s.value()}>{value}</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 </article>\r\n );\r\n}\r\n\r\nKpi.displayName = \"Kpi\";\r\n","\"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":["tv","createContext","jsx","cn","useContext","jsxs","Chip","TrendingUp"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
- import { t as tv, c as cn } from "./avatar-DFWEwBKu.mjs";
2
+ import { a8 as tv, c as cn } from "./avatar-Cj_m-wJy.mjs";
3
3
  const pageHeaderStyles = tv({
4
4
  slots: {
5
5
  root: "shrink-0 flex flex-col gap-gp-md",
@@ -75,4 +75,4 @@ export {
75
75
  PageHeader as P,
76
76
  pageHeaderStyles as p
77
77
  };
78
- //# sourceMappingURL=page-header--cPS_Z-a.mjs.map
78
+ //# sourceMappingURL=page-header-DUxZjGdR.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-header-DUxZjGdR.mjs","sources":["../../src/components/ui/PageHeader/page-header.styles.ts","../../src/components/ui/PageHeader/page-header.tsx"],"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\",\r\n title: \"m-0 text-title-lg font-bold tracking-[-0.01em] text-fg-default\",\r\n description: [\r\n \"m-0 text-body-md text-fg-subtle leading-[1.5]\",\r\n \"whitespace-nowrap overflow-hidden text-ellipsis\",\r\n ],\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 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 hideTextOnMobile: true,\r\n mobileFluid: true,\r\n },\r\n});\r\n","import { cn } from \"@/lib/utils\";\nimport { pageHeaderStyles } from \"./page-header.styles\";\nimport type { PageHeaderProps } from \"./page-header.types\";\n\n/**\n * PageHeader — bloco de título reutilizável colocado dentro do body do\n * `<AppShell>`. Cobre o caso comum:\n *\n * - Título (h1) + descrição (sub) + badge (chip ao lado)\n * - Slot de ações à direita (botões / dropdowns)\n * - Slot livre abaixo pra tabs, filtros ou qualquer conteúdo extra\n *\n * Mobile-ready por default:\n * - Title/description/badge somem em viewports pequenas\n * (Header global do AppShell já mostra title/breadcrumb)\n * - O último botão do `actions` vira fluid (CTA full-width)\n *\n * @example\n * ```tsx\n * <PageHeader\n * title=\"Clientes\"\n * description=\"Gerencie sua base de clientes.\"\n * badge={<Chip color=\"primary\" variant=\"soft\">87 registros</Chip>}\n * actions={\n * <>\n * <Button variant=\"outline\" size=\"icon-md\"><MoreHorizontal /></Button>\n * <Button variant=\"filled\" color=\"primary\">Novo cliente</Button>\n * </>\n * }\n * />\n * ```\n *\n * @example com tabs abaixo (slot children):\n * ```tsx\n * <PageHeader title=\"Configurações\" actions={<Button>Salvar</Button>}>\n * <Tabs ... />\n * </PageHeader>\n * ```\n */\nexport function PageHeader({\n title,\n description,\n badge,\n actions,\n children,\n hideTextOnMobile = true,\n fluidPrimaryOnMobile = true,\n className,\n}: PageHeaderProps) {\n const s = pageHeaderStyles({\n hideTextOnMobile,\n mobileFluid: fluidPrimaryOnMobile,\n });\n\n const hasText = !!(title || description || badge);\n const hasTopRow = hasText || !!actions;\n\n return (\n <header className={cn(s.root(), className)}>\n {hasTopRow && (\n <div className={s.topRow()}>\n {hasText && (\n <div className={s.textCol()}>\n {(title || badge) && (\n <div className={s.titleRow()}>\n {title && <h1 className={s.title()}>{title}</h1>}\n {badge}\n </div>\n )}\n {description && <p className={s.description()}>{description}</p>}\n </div>\n )}\n {actions && <div className={s.actionsRow()}>{actions}</div>}\n </div>\n )}\n {children && <div className={s.extraRow()}>{children}</div>}\n </header>\n );\n}\n\nPageHeader.displayName = \"PageHeader\";\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,MACX;AAAA,MACA;AAAA,IAAA;AAAA,IAEF,YAAY;AAAA;AAAA;AAAA,IAGZ,UAAU;AAAA,EAAA;AAAA,EAEZ,UAAU;AAAA,IACR,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,kBAAkB;AAAA,IAClB,aAAa;AAAA,EAAA;AAEjB,CAAC;AClBM,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,mBAAmB;AAAA,EACnB,uBAAuB;AAAA,EACvB;AACF,GAAoB;AAClB,QAAM,IAAI,iBAAiB;AAAA,IACzB;AAAA,IACA,aAAa;AAAA,EAAA,CACd;AAED,QAAM,UAAU,CAAC,EAAE,SAAS,eAAe;AAC3C,QAAM,YAAY,WAAW,CAAC,CAAC;AAE/B,SACE,qBAAC,YAAO,WAAW,GAAG,EAAE,KAAA,GAAQ,SAAS,GACtC,UAAA;AAAA,IAAA,aACC,qBAAC,OAAA,EAAI,WAAW,EAAE,UACf,UAAA;AAAA,MAAA,WACC,qBAAC,OAAA,EAAI,WAAW,EAAE,WACd,UAAA;AAAA,SAAA,SAAS,UACT,qBAAC,OAAA,EAAI,WAAW,EAAE,YACf,UAAA;AAAA,UAAA,6BAAU,MAAA,EAAG,WAAW,EAAE,MAAA,GAAU,UAAA,OAAM;AAAA,UAC1C;AAAA,QAAA,GACH;AAAA,QAED,eAAe,oBAAC,KAAA,EAAE,WAAW,EAAE,YAAA,GAAgB,UAAA,YAAA,CAAY;AAAA,MAAA,GAC9D;AAAA,MAED,WAAW,oBAAC,OAAA,EAAI,WAAW,EAAE,WAAA,GAAe,UAAA,QAAA,CAAQ;AAAA,IAAA,GACvD;AAAA,IAED,YAAY,oBAAC,OAAA,EAAI,WAAW,EAAE,SAAA,GAAa,SAAA,CAAS;AAAA,EAAA,GACvD;AAEJ;AAEA,WAAW,cAAc;"}
@@ -1 +1 @@
1
- {"version":3,"file":"page-header-DvAJoEfb.cjs","sources":["../../src/components/ui/PageHeader/page-header.styles.ts","../../src/components/ui/PageHeader/page-header.tsx"],"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\",\r\n title: \"m-0 text-title-lg font-bold tracking-[-0.01em] text-fg-default\",\r\n description: [\r\n \"m-0 text-body-md text-fg-subtle leading-[1.5]\",\r\n \"whitespace-nowrap overflow-hidden text-ellipsis\",\r\n ],\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 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 hideTextOnMobile: true,\r\n mobileFluid: true,\r\n },\r\n});\r\n","import { cn } from \"@/lib/utils\";\r\nimport { pageHeaderStyles } from \"./page-header.styles\";\r\nimport type { PageHeaderProps } from \"./page-header.types\";\r\n\r\n/**\r\n * PageHeader — bloco de título reutilizável colocado dentro do body do\r\n * `<AppShell>`. Cobre o caso comum:\r\n *\r\n * - Título (h1) + descrição (sub) + badge (chip ao lado)\r\n * - Slot de ações à direita (botões / dropdowns)\r\n * - Slot livre abaixo pra tabs, filtros ou qualquer conteúdo extra\r\n *\r\n * Mobile-ready por default:\r\n * - Title/description/badge somem em viewports pequenas\r\n * (Header global do AppShell já mostra title/breadcrumb)\r\n * - O último botão do `actions` vira fluid (CTA full-width)\r\n *\r\n * @example\r\n * ```tsx\r\n * <PageHeader\r\n * title=\"Clientes\"\r\n * description=\"Gerencie sua base de clientes.\"\r\n * badge={<Chip color=\"primary\" variant=\"soft\">87 registros</Chip>}\r\n * actions={\r\n * <>\r\n * <Button variant=\"outline\" size=\"icon-md\"><MoreHorizontal /></Button>\r\n * <Button variant=\"filled\" color=\"primary\">Novo cliente</Button>\r\n * </>\r\n * }\r\n * />\r\n * ```\r\n *\r\n * @example com tabs abaixo (slot children):\r\n * ```tsx\r\n * <PageHeader title=\"Configurações\" actions={<Button>Salvar</Button>}>\r\n * <Tabs ... />\r\n * </PageHeader>\r\n * ```\r\n */\r\nexport function PageHeader({\r\n title,\r\n description,\r\n badge,\r\n actions,\r\n children,\r\n hideTextOnMobile = true,\r\n fluidPrimaryOnMobile = true,\r\n className,\r\n}: PageHeaderProps) {\r\n const s = pageHeaderStyles({\r\n hideTextOnMobile,\r\n mobileFluid: fluidPrimaryOnMobile,\r\n });\r\n\r\n const hasText = !!(title || description || badge);\r\n const hasTopRow = hasText || !!actions;\r\n\r\n return (\r\n <header className={cn(s.root(), className)}>\r\n {hasTopRow && (\r\n <div className={s.topRow()}>\r\n {hasText && (\r\n <div className={s.textCol()}>\r\n {(title || badge) && (\r\n <div className={s.titleRow()}>\r\n {title && <h1 className={s.title()}>{title}</h1>}\r\n {badge}\r\n </div>\r\n )}\r\n {description && <p className={s.description()}>{description}</p>}\r\n </div>\r\n )}\r\n {actions && <div className={s.actionsRow()}>{actions}</div>}\r\n </div>\r\n )}\r\n {children && <div className={s.extraRow()}>{children}</div>}\r\n </header>\r\n );\r\n}\r\n\r\nPageHeader.displayName = \"PageHeader\";\r\n"],"names":["tv","jsxs","cn","jsx"],"mappings":";;;AAkBO,MAAM,mBAAmBA,OAAAA,GAAG;AAAA,EACjC,OAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,UAAU;AAAA,IACV,OAAO;AAAA,IACP,aAAa;AAAA,MACX;AAAA,MACA;AAAA,IAAA;AAAA,IAEF,YAAY;AAAA;AAAA;AAAA,IAGZ,UAAU;AAAA,EAAA;AAAA,EAEZ,UAAU;AAAA,IACR,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,kBAAkB;AAAA,IAClB,aAAa;AAAA,EAAA;AAEjB,CAAC;AClBM,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,mBAAmB;AAAA,EACnB,uBAAuB;AAAA,EACvB;AACF,GAAoB;AAClB,QAAM,IAAI,iBAAiB;AAAA,IACzB;AAAA,IACA,aAAa;AAAA,EAAA,CACd;AAED,QAAM,UAAU,CAAC,EAAE,SAAS,eAAe;AAC3C,QAAM,YAAY,WAAW,CAAC,CAAC;AAE/B,SACEC,2BAAAA,KAAC,YAAO,WAAWC,OAAAA,GAAG,EAAE,KAAA,GAAQ,SAAS,GACtC,UAAA;AAAA,IAAA,aACCD,2BAAAA,KAAC,OAAA,EAAI,WAAW,EAAE,UACf,UAAA;AAAA,MAAA,WACCA,2BAAAA,KAAC,OAAA,EAAI,WAAW,EAAE,WACd,UAAA;AAAA,SAAA,SAAS,UACTA,2BAAAA,KAAC,OAAA,EAAI,WAAW,EAAE,YACf,UAAA;AAAA,UAAA,wCAAU,MAAA,EAAG,WAAW,EAAE,MAAA,GAAU,UAAA,OAAM;AAAA,UAC1C;AAAA,QAAA,GACH;AAAA,QAED,eAAeE,2BAAAA,IAAC,KAAA,EAAE,WAAW,EAAE,YAAA,GAAgB,UAAA,YAAA,CAAY;AAAA,MAAA,GAC9D;AAAA,MAED,WAAWA,2BAAAA,IAAC,OAAA,EAAI,WAAW,EAAE,WAAA,GAAe,UAAA,QAAA,CAAQ;AAAA,IAAA,GACvD;AAAA,IAED,YAAYA,2BAAAA,IAAC,OAAA,EAAI,WAAW,EAAE,SAAA,GAAa,SAAA,CAAS;AAAA,EAAA,GACvD;AAEJ;AAEA,WAAW,cAAc;;;"}
1
+ {"version":3,"file":"page-header-DvAJoEfb.cjs","sources":["../../src/components/ui/PageHeader/page-header.styles.ts","../../src/components/ui/PageHeader/page-header.tsx"],"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\",\r\n title: \"m-0 text-title-lg font-bold tracking-[-0.01em] text-fg-default\",\r\n description: [\r\n \"m-0 text-body-md text-fg-subtle leading-[1.5]\",\r\n \"whitespace-nowrap overflow-hidden text-ellipsis\",\r\n ],\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 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 hideTextOnMobile: true,\r\n mobileFluid: true,\r\n },\r\n});\r\n","import { cn } from \"@/lib/utils\";\nimport { pageHeaderStyles } from \"./page-header.styles\";\nimport type { PageHeaderProps } from \"./page-header.types\";\n\n/**\n * PageHeader — bloco de título reutilizável colocado dentro do body do\n * `<AppShell>`. Cobre o caso comum:\n *\n * - Título (h1) + descrição (sub) + badge (chip ao lado)\n * - Slot de ações à direita (botões / dropdowns)\n * - Slot livre abaixo pra tabs, filtros ou qualquer conteúdo extra\n *\n * Mobile-ready por default:\n * - Title/description/badge somem em viewports pequenas\n * (Header global do AppShell já mostra title/breadcrumb)\n * - O último botão do `actions` vira fluid (CTA full-width)\n *\n * @example\n * ```tsx\n * <PageHeader\n * title=\"Clientes\"\n * description=\"Gerencie sua base de clientes.\"\n * badge={<Chip color=\"primary\" variant=\"soft\">87 registros</Chip>}\n * actions={\n * <>\n * <Button variant=\"outline\" size=\"icon-md\"><MoreHorizontal /></Button>\n * <Button variant=\"filled\" color=\"primary\">Novo cliente</Button>\n * </>\n * }\n * />\n * ```\n *\n * @example com tabs abaixo (slot children):\n * ```tsx\n * <PageHeader title=\"Configurações\" actions={<Button>Salvar</Button>}>\n * <Tabs ... />\n * </PageHeader>\n * ```\n */\nexport function PageHeader({\n title,\n description,\n badge,\n actions,\n children,\n hideTextOnMobile = true,\n fluidPrimaryOnMobile = true,\n className,\n}: PageHeaderProps) {\n const s = pageHeaderStyles({\n hideTextOnMobile,\n mobileFluid: fluidPrimaryOnMobile,\n });\n\n const hasText = !!(title || description || badge);\n const hasTopRow = hasText || !!actions;\n\n return (\n <header className={cn(s.root(), className)}>\n {hasTopRow && (\n <div className={s.topRow()}>\n {hasText && (\n <div className={s.textCol()}>\n {(title || badge) && (\n <div className={s.titleRow()}>\n {title && <h1 className={s.title()}>{title}</h1>}\n {badge}\n </div>\n )}\n {description && <p className={s.description()}>{description}</p>}\n </div>\n )}\n {actions && <div className={s.actionsRow()}>{actions}</div>}\n </div>\n )}\n {children && <div className={s.extraRow()}>{children}</div>}\n </header>\n );\n}\n\nPageHeader.displayName = \"PageHeader\";\n"],"names":["tv","jsxs","cn","jsx"],"mappings":";;;AAkBO,MAAM,mBAAmBA,OAAAA,GAAG;AAAA,EACjC,OAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,UAAU;AAAA,IACV,OAAO;AAAA,IACP,aAAa;AAAA,MACX;AAAA,MACA;AAAA,IAAA;AAAA,IAEF,YAAY;AAAA;AAAA;AAAA,IAGZ,UAAU;AAAA,EAAA;AAAA,EAEZ,UAAU;AAAA,IACR,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,kBAAkB;AAAA,IAClB,aAAa;AAAA,EAAA;AAEjB,CAAC;AClBM,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,mBAAmB;AAAA,EACnB,uBAAuB;AAAA,EACvB;AACF,GAAoB;AAClB,QAAM,IAAI,iBAAiB;AAAA,IACzB;AAAA,IACA,aAAa;AAAA,EAAA,CACd;AAED,QAAM,UAAU,CAAC,EAAE,SAAS,eAAe;AAC3C,QAAM,YAAY,WAAW,CAAC,CAAC;AAE/B,SACEC,2BAAAA,KAAC,YAAO,WAAWC,OAAAA,GAAG,EAAE,KAAA,GAAQ,SAAS,GACtC,UAAA;AAAA,IAAA,aACCD,2BAAAA,KAAC,OAAA,EAAI,WAAW,EAAE,UACf,UAAA;AAAA,MAAA,WACCA,2BAAAA,KAAC,OAAA,EAAI,WAAW,EAAE,WACd,UAAA;AAAA,SAAA,SAAS,UACTA,2BAAAA,KAAC,OAAA,EAAI,WAAW,EAAE,YACf,UAAA;AAAA,UAAA,wCAAU,MAAA,EAAG,WAAW,EAAE,MAAA,GAAU,UAAA,OAAM;AAAA,UAC1C;AAAA,QAAA,GACH;AAAA,QAED,eAAeE,2BAAAA,IAAC,KAAA,EAAE,WAAW,EAAE,YAAA,GAAgB,UAAA,YAAA,CAAY;AAAA,MAAA,GAC9D;AAAA,MAED,WAAWA,2BAAAA,IAAC,OAAA,EAAI,WAAW,EAAE,WAAA,GAAe,UAAA,QAAA,CAAQ;AAAA,IAAA,GACvD;AAAA,IAED,YAAYA,2BAAAA,IAAC,OAAA,EAAI,WAAW,EAAE,SAAA,GAAa,SAAA,CAAS;AAAA,EAAA,GACvD;AAEJ;AAEA,WAAW,cAAc;;;"}
@@ -3,14 +3,14 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
4
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
5
5
  import { forwardRef, createContext, useContext, useId, useRef, useState, useCallback, useEffect, useMemo, Fragment as Fragment$1, useImperativeHandle, memo } from "react";
6
- import { A as AlertDialog, c as AlertDialogContent, f as AlertDialogHeader, i as AlertDialogTitle, d as AlertDialogDescription, e as AlertDialogFooter, b as AlertDialogCancel, a as AlertDialogAction, T as Textarea, S as Select, D as SelectTrigger, E as SelectValue, u as SelectContent, w as SelectItem, l as Checkbox, Q as Switch, C as Calendar$1, R as getPaginationRange, P as Pagination, o as PaginationFirst, t as PaginationPrevious, m as PaginationContent, p as PaginationItem, n as PaginationEllipsis, r as PaginationLink, s as PaginationNext, q as PaginationLast, N as SheetTitle, I as SheetDescription, G as SheetClose, F as Sheet, O as SheetTrigger, L as SheetOverlay } from "./sheet-D1vQth7X.mjs";
6
+ import { A as AlertDialog, c as AlertDialogContent, f as AlertDialogHeader, i as AlertDialogTitle, d as AlertDialogDescription, e as AlertDialogFooter, b as AlertDialogCancel, a as AlertDialogAction, T as Textarea, S as Select, D as SelectTrigger, E as SelectValue, u as SelectContent, w as SelectItem, l as Checkbox, Q as Switch, C as Calendar$1, R as getPaginationRange, P as Pagination, o as PaginationFirst, t as PaginationPrevious, m as PaginationContent, p as PaginationItem, n as PaginationEllipsis, r as PaginationLink, s as PaginationNext, q as PaginationLast, N as SheetTitle, I as SheetDescription, G as SheetClose, F as Sheet, O as SheetTrigger, L as SheetOverlay } from "./sheet-Bc-LMBDF.mjs";
7
7
  import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext, closestCorners, DragOverlay, useDroppable, useDraggable, closestCenter } from "@dnd-kit/core";
8
8
  import { useSortable, sortableKeyboardCoordinates, SortableContext, horizontalListSortingStrategy, arrayMove } from "@dnd-kit/sortable";
9
9
  import { useVirtualizer } from "@tanstack/react-virtual";
10
- import { t as tv, B as Button, c as cn, R as InputGroup, U as InputGroupInput, S as InputGroupAddon, V as InputGroupText, X as Popover, $ as PopoverTrigger, _ as PopoverContent, f as Command, j as CommandInput, l as CommandList, h as CommandEmpty, i as CommandGroup, k as CommandItem, y as DropdownMenu, Q as DropdownMenuTrigger, E as DropdownMenuContent, H as DropdownMenuLabel, L as DropdownMenuSeparator, G as DropdownMenuItem, D as Dialog, p as DialogContent, o as DialogClose, w as DialogTitle, q as DialogDescription, Y as PopoverAnchor } from "./avatar-DFWEwBKu.mjs";
10
+ import { a8 as tv, a7 as Button, c as cn, P as InputGroup, S as InputGroupInput, Q as InputGroupAddon, T as InputGroupText, V as Popover, Z as PopoverTrigger, Y as PopoverContent, f as Command, j as CommandInput, l as CommandList, h as CommandEmpty, i as CommandGroup, k as CommandItem, x as DropdownMenu, O as DropdownMenuTrigger, z as DropdownMenuContent, F as DropdownMenuLabel, J as DropdownMenuSeparator, E as DropdownMenuItem, D as Dialog, p as DialogContent, o as DialogClose, v as DialogTitle, q as DialogDescription, W as PopoverAnchor } from "./avatar-Cj_m-wJy.mjs";
11
11
  import { X, CheckCircle2, AlertCircle, AlertTriangle, Info, ChevronDown, Check, ArrowUp, ArrowDown, ArrowUpDown, Search, CircleX, MoreHorizontal, Filter, ChevronLeft, GripVertical, Pin, PinOff, Plus, Trash2, Eye, Users, ChevronRight, Columns, SlidersHorizontal, Minimize2, Maximize2, Type, Hash, Calendar, ToggleLeft, DollarSign, Percent, AtSign, Phone, Link, ExternalLink, User, Tag, Tags, CalendarClock, Inbox, SearchX, FilterX, PinIcon, EyeOff, Loader2, Copy, Rows3, LayoutGrid, Settings2, RefreshCw, Table as Table$1, FileText, List as List$1, Rows4, Rows2 } from "lucide-react";
12
- import { C as Chip, w as useMediaQuery } from "./useTheme-DCmzLBUR.mjs";
13
- import { I as Input } from "./input-CfmzMYtd.mjs";
12
+ import { C as Chip, w as useMediaQuery } from "./useTheme-DNqHuA6o.mjs";
13
+ import { I as Input } from "./input-CwRzwVPt.mjs";
14
14
  import { createPortal } from "react-dom";
15
15
  import { Draggable, Droppable, DragDropContext } from "@hello-pangea/dnd";
16
16
  import { CSS } from "@dnd-kit/utilities";
@@ -9628,7 +9628,16 @@ function useGrabToScroll(scrollContainerRef, enabled, thresholdPx = 6) {
9628
9628
  ].join(",");
9629
9629
  const prevCursor = scroller.style.cursor;
9630
9630
  const prevUserSelect = scroller.style.userSelect;
9631
- scroller.style.cursor = "grab";
9631
+ const syncCursor = () => {
9632
+ const rolavel = scroller.scrollWidth > scroller.clientWidth;
9633
+ scroller.style.cursor = rolavel ? "grab" : prevCursor;
9634
+ };
9635
+ syncCursor();
9636
+ const ro = typeof ResizeObserver === "function" ? new ResizeObserver(syncCursor) : null;
9637
+ if (ro) {
9638
+ ro.observe(scroller);
9639
+ if (scroller.firstElementChild) ro.observe(scroller.firstElementChild);
9640
+ }
9632
9641
  let isPointerDown = false;
9633
9642
  let isDragging = false;
9634
9643
  let activePointerId = null;
@@ -9680,7 +9689,7 @@ function useGrabToScroll(scrollContainerRef, enabled, thresholdPx = 6) {
9680
9689
  isPointerDown = false;
9681
9690
  isDragging = false;
9682
9691
  activePointerId = null;
9683
- scroller.style.cursor = "grab";
9692
+ syncCursor();
9684
9693
  scroller.style.userSelect = prevUserSelect;
9685
9694
  try {
9686
9695
  scroller.releasePointerCapture(event.pointerId);
@@ -9698,6 +9707,7 @@ function useGrabToScroll(scrollContainerRef, enabled, thresholdPx = 6) {
9698
9707
  scroller.removeEventListener("pointermove", onPointerMove);
9699
9708
  scroller.removeEventListener("pointerup", finish);
9700
9709
  scroller.removeEventListener("pointercancel", finish);
9710
+ ro?.disconnect();
9701
9711
  scroller.style.cursor = prevCursor;
9702
9712
  scroller.style.userSelect = prevUserSelect;
9703
9713
  };
@@ -13055,4 +13065,4 @@ export {
13055
13065
  DataTableActionsCell as y,
13056
13066
  DataTableEditCell as z
13057
13067
  };
13058
- //# sourceMappingURL=panel-DtQi10ps.mjs.map
13068
+ //# sourceMappingURL=panel-BlMiCA9Z.mjs.map