@iclips/ui 2.0.0 → 2.0.2

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.
package/MIGRATION-v2.md CHANGED
@@ -2,7 +2,8 @@
2
2
 
3
3
  `2.0.0` agrupa a reforma da lib para padrão de mercado. As seções 1–4 são
4
4
  renomeações de tipo / empacotamento; as **5–8 são as mudanças estruturais**
5
- (tree-shaking, CSS sob demanda, saída das features de produto, toast).
5
+ (tree-shaking, CSS sob demanda, saída das features de produto, toast); as
6
+ **11–13 são de conformidade visual** — a 11 muda o visual do app consumidor.
6
7
 
7
8
  ## 1. Tipos com nome em português → inglês
8
9
 
@@ -19,62 +20,62 @@ Ele faz substituição por palavra inteira dos identificadores abaixo em imports
19
20
  referências de tipo. Os nomes antigos são distintos o suficiente para não colidir,
20
21
  mas revise o diff.
21
22
 
22
- | Antes | Depois |
23
- |---|---|
24
- | `CampoFiltro` | `FilterField` |
25
- | `CondicaoFiltro` | `FilterCondition` |
26
- | `ConfigServidorLateral` | `ServerSideConfig` |
27
- | `DadosContrato` | `ContractData` |
28
- | `DadosItemBreadcrumb` | `BreadcrumbItemData` |
29
- | `EventoTimeline` | `TimelineEvent` |
30
- | `FiltroAtivo` | `ActiveFilter` |
31
- | `FiltroSalvo` | `SavedFilter` |
32
- | `GrupoNavSecundaria` | `SecondaryNavGroup` |
33
- | `GrupoOpcaoFiltro` | `FilterOptionGroup` |
34
- | `ItemMenuUsuarioLayoutApp` | `AppLayoutUserMenuItem` |
35
- | `ItemNavPrimaria` | `PrimaryNavItem` |
36
- | `ItemNavSecundaria` | `SecondaryNavItem` |
37
- | `OpcaoEmblemaEditavel` | `EditableBadgeOption` |
38
- | `OpcoesUsarImpressaoContrato` | `UsePrintContractOptions` |
39
- | `PredefinicaoIntervaloData` | `DateRangePreset` |
40
- | `PropsBarraFiltros` | `FilterBarProps` |
41
- | `PropsBotaoSocial` | `SocialButtonProps` |
42
- | `PropsCabecalhoColuna` | `TableHeadProps` |
43
- | `PropsCabecalhoPagina` | `PageHeaderProps` |
44
- | `PropsCabecalhoTabela` | `TableHeaderProps` |
45
- | `PropsCartaoKPI` | `KPICardProps` |
46
- | `PropsCartaoKanban` | `KanbanGenericCardProps` |
47
- | `PropsCelulaTabela` | `TableCellProps` |
48
- | `PropsChipFiltro` | `FilterChipProps` |
49
- | `PropsConstrutorFiltro` | `FilterBuilderProps` |
50
- | `PropsCorpoTabela` | `TableBodyProps` |
51
- | `PropsDialogoEdicaoTarefa` | `TaskEditDialogProps` |
52
- | `PropsEmblemaEditavel` | `EditableBadgeProps` |
53
- | `PropsEntradaSenha` | `PasswordInputProps` |
54
- | `PropsFiltrosSalvos` | `SavedFiltersProps` |
55
- | `PropsImpressaoContrato` | `ContractPrintProps` |
56
- | `PropsLayoutAutenticacao` | `AuthLayoutProps` |
57
- | `PropsLegendaTabela` | `TableCaptionProps` |
58
- | `PropsLinhaTabela` | `TableRowProps` |
59
- | `PropsListaMencoes` | `MentionListProps` |
60
- | `PropsLogoMarca` | `BrandLogoProps` |
61
- | `PropsMenuUsuarioLayoutApp` | `AppLayoutUserMenuProps` |
62
- | `PropsNavPrimariaLayoutApp` | `AppLayoutPrimaryNavProps` |
23
+ | Antes | Depois |
24
+ | ----------------------------- | ---------------------------- |
25
+ | `CampoFiltro` | `FilterField` |
26
+ | `CondicaoFiltro` | `FilterCondition` |
27
+ | `ConfigServidorLateral` | `ServerSideConfig` |
28
+ | `DadosContrato` | `ContractData` |
29
+ | `DadosItemBreadcrumb` | `BreadcrumbItemData` |
30
+ | `EventoTimeline` | `TimelineEvent` |
31
+ | `FiltroAtivo` | `ActiveFilter` |
32
+ | `FiltroSalvo` | `SavedFilter` |
33
+ | `GrupoNavSecundaria` | `SecondaryNavGroup` |
34
+ | `GrupoOpcaoFiltro` | `FilterOptionGroup` |
35
+ | `ItemMenuUsuarioLayoutApp` | `AppLayoutUserMenuItem` |
36
+ | `ItemNavPrimaria` | `PrimaryNavItem` |
37
+ | `ItemNavSecundaria` | `SecondaryNavItem` |
38
+ | `OpcaoEmblemaEditavel` | `EditableBadgeOption` |
39
+ | `OpcoesUsarImpressaoContrato` | `UsePrintContractOptions` |
40
+ | `PredefinicaoIntervaloData` | `DateRangePreset` |
41
+ | `PropsBarraFiltros` | `FilterBarProps` |
42
+ | `PropsBotaoSocial` | `SocialButtonProps` |
43
+ | `PropsCabecalhoColuna` | `TableHeadProps` |
44
+ | `PropsCabecalhoPagina` | `PageHeaderProps` |
45
+ | `PropsCabecalhoTabela` | `TableHeaderProps` |
46
+ | `PropsCartaoKPI` | `KPICardProps` |
47
+ | `PropsCartaoKanban` | `KanbanGenericCardProps` |
48
+ | `PropsCelulaTabela` | `TableCellProps` |
49
+ | `PropsChipFiltro` | `FilterChipProps` |
50
+ | `PropsConstrutorFiltro` | `FilterBuilderProps` |
51
+ | `PropsCorpoTabela` | `TableBodyProps` |
52
+ | `PropsDialogoEdicaoTarefa` | `TaskEditDialogProps` |
53
+ | `PropsEmblemaEditavel` | `EditableBadgeProps` |
54
+ | `PropsEntradaSenha` | `PasswordInputProps` |
55
+ | `PropsFiltrosSalvos` | `SavedFiltersProps` |
56
+ | `PropsImpressaoContrato` | `ContractPrintProps` |
57
+ | `PropsLayoutAutenticacao` | `AuthLayoutProps` |
58
+ | `PropsLegendaTabela` | `TableCaptionProps` |
59
+ | `PropsLinhaTabela` | `TableRowProps` |
60
+ | `PropsListaMencoes` | `MentionListProps` |
61
+ | `PropsLogoMarca` | `BrandLogoProps` |
62
+ | `PropsMenuUsuarioLayoutApp` | `AppLayoutUserMenuProps` |
63
+ | `PropsNavPrimariaLayoutApp` | `AppLayoutPrimaryNavProps` |
63
64
  | `PropsNavSecundariaLayoutApp` | `AppLayoutSecondaryNavProps` |
64
- | `PropsPaginacaoTabela` | `TablePaginationProps` |
65
- | `PropsRodapeTabela` | `TableFooterProps` |
66
- | `PropsSeletorData` | `DatePickerProps` |
67
- | `PropsSeletorHora` | `TimePickerProps` |
68
- | `PropsSeletorIntervaloData` | `DateRangePickerProps` |
69
- | `PropsSeletorIntervaloMes` | `MonthRangePickerProps` |
70
- | `PropsTabelaDadosAvancada` | `AdvancedDataTableProps` |
71
- | `ResponsavelCartaoKanban` | `KanbanCardAssignee` |
72
- | `RotulosPaginacaoTabela` | `TablePaginationLabels` |
73
- | `SubItemNavPrimaria` | `PrimaryNavSubItem` |
74
- | `TagCartaoKanban` | `KanbanCardTag` |
75
- | `TarefaGantt` | `GanttTask` |
76
- | `UsuarioLayoutApp` | `AppLayoutUser` |
77
- | `UsuarioTimeline` | `TimelineUser` |
65
+ | `PropsPaginacaoTabela` | `TablePaginationProps` |
66
+ | `PropsRodapeTabela` | `TableFooterProps` |
67
+ | `PropsSeletorData` | `DatePickerProps` |
68
+ | `PropsSeletorHora` | `TimePickerProps` |
69
+ | `PropsSeletorIntervaloData` | `DateRangePickerProps` |
70
+ | `PropsSeletorIntervaloMes` | `MonthRangePickerProps` |
71
+ | `PropsTabelaDadosAvancada` | `AdvancedDataTableProps` |
72
+ | `ResponsavelCartaoKanban` | `KanbanCardAssignee` |
73
+ | `RotulosPaginacaoTabela` | `TablePaginationLabels` |
74
+ | `SubItemNavPrimaria` | `PrimaryNavSubItem` |
75
+ | `TagCartaoKanban` | `KanbanCardTag` |
76
+ | `TarefaGantt` | `GanttTask` |
77
+ | `UsuarioLayoutApp` | `AppLayoutUser` |
78
+ | `UsuarioTimeline` | `TimelineUser` |
78
79
 
79
80
  ## 2. Componentes de editor → subpath `@iclips/ui/editor`
80
81
 
@@ -136,7 +137,7 @@ qualquer stack). Novo opcional para quem usa Tailwind v4 e quer bundle menor:
136
137
  ```css
137
138
  @import "tailwindcss";
138
139
  @import "@iclips/ui/preset.css";
139
- @source "../node_modules/@iclips/ui/dist/components/ui/primitives/button.js"; /* os que você usa */
140
+ @source "../node_modules/@iclips/ui/dist/components/ui/primitives/button.js"; /* os que você usa */
140
141
  ```
141
142
 
142
143
  Requer `tw-animate-css` (peer opcional). Ver README.
@@ -170,7 +171,8 @@ reimplemente):
170
171
  ## 8. Toast unificado
171
172
 
172
173
  `alertToast` e `AlertToastProvider` **removidos**. A API única é `toast` (sonner)
173
- + `<Toaster />`.
174
+
175
+ - `<Toaster />`.
174
176
 
175
177
  ```bash
176
178
  node node_modules/@iclips/ui/scripts/codemod-v2-toast.mjs "src/**/*.{ts,tsx}"
@@ -212,3 +214,36 @@ subpath `@iclips/ui/editor` **não mudam** — deep import nunca foi suportado.
212
214
  ```
213
215
 
214
216
  O `@source ".../dist"` (lib inteira) continua igual.
217
+
218
+ ---
219
+
220
+ ## 11. `styles.css` não estiliza mais elementos nus (BREAKING visual)
221
+
222
+ Removido o bloco `@layer base` com `h1..h6 / p / label / button / input`
223
+ (`font-size`/`font-weight`/`line-height` por seletor de elemento).
224
+
225
+ **O que muda no app consumidor:** `<h1>`..`<h6>` sem classe `text-*` ficam no
226
+ tamanho do Preflight do Tailwind (sem escala); `<p>`, `<label>`, `<button>` e
227
+ `<input>` nus herdam o tamanho do `body` em vez de `--text-base` explícito.
228
+
229
+ **O que fazer:** aplicar utilitários (`text-3xl font-semibold`, `text-sm`…) nos
230
+ elementos afetados. Se preferir manter o comportamento antigo globalmente,
231
+ recrie o bloco no `@layer base` do próprio app — mas o recomendado é estilizar
232
+ por componente/utilitário. Escala do Figma: `Fundamentos/Tipografia` no Storybook.
233
+
234
+ Os componentes da lib (`Button`, `Input`, etc.) não são afetados — cada um já
235
+ define a própria tipografia.
236
+
237
+ ## 12. Cores: componentes usam só tokens semânticos (sem ação necessária)
238
+
239
+ Componentes que tinham paleta Tailwind crua (`text-gray-700`, `bg-purple-50`) ou
240
+ hex (`#7F26BF`) agora usam `text-foreground` / `text-muted-foreground` /
241
+ `bg-accent` / `bg-primary` / tokens de status. **Nenhuma mudança de API.** Efeito
242
+ visível: esses componentes passam a respeitar o dark mode. No light mode a
243
+ diferença é mínima.
244
+
245
+ ## 13. `ImageWithFallback` saiu do índice público
246
+
247
+ `import { ImageWithFallback } from "@iclips/ui"` deixa de existir. Era um helper
248
+ de scaffold do Figma Make. Se algum app o usava, copie o componente (~30 linhas)
249
+ para o próprio projeto.
@@ -1,2 +1,2 @@
1
- "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),f=require("react"),s=require("../layout/card.cjs"),h=require("../primitives/badge.cjs"),c=require("../primitives/skeleton.cjs"),l=require("lucide-react"),x=require("../utils.cjs");function g(t){const n=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const r in t)if(r!=="default"){const a=Object.getOwnPropertyDescriptor(t,r);Object.defineProperty(n,r,a.get?a:{enumerable:!0,get:()=>t[r]})}}return n.default=t,Object.freeze(n)}const N=g(f),m=N.forwardRef(({title:t,primaryContent:n,secondaryContent:r,trendValue:a,trendLabel:u,icon:j=l.Activity,isLoading:p=!1,onClick:i,className:d},o)=>p?e.jsxs(s.Card,{ref:o,className:d,children:[e.jsx(s.CardHeader,{className:"pb-1",children:e.jsxs(s.CardTitle,{className:"text-sm flex items-center gap-2",children:[e.jsx(c.Skeleton,{className:"h-4 w-4 rounded"}),e.jsx(c.Skeleton,{className:"h-4 w-24"})]})}),e.jsxs(s.CardContent,{className:"space-y-1 pt-0",children:[e.jsx(c.Skeleton,{className:"h-8 w-32"}),e.jsx(c.Skeleton,{className:"h-3 w-full"})]})]}):e.jsxs(s.Card,{ref:o,onClick:i,className:x.cn(i&&"cursor-pointer hover:bg-accent/50 transition-colors",d),children:[e.jsx(s.CardHeader,{className:"pb-1",children:e.jsxs(s.CardTitle,{className:"text-sm flex items-center gap-2 text-muted-foreground",children:[e.jsx(j,{className:"h-4 w-4 text-muted-foreground"}),t]})}),e.jsxs(s.CardContent,{className:"space-y-1 pt-0",children:[e.jsxs("div",{className:"flex items-baseline flex-wrap gap-2",children:[e.jsx("span",{className:"text-2xl font-bold",children:n}),a!==void 0&&e.jsxs(h.Badge,{variant:"secondary",className:x.cn("px-1.5 py-0 h-auto text-xs",a>0?"text-green-600":"text-red-600"),children:[a>0?e.jsx(l.TrendingUp,{className:"h-3 w-3 mr-0.5 inline"}):e.jsx(l.TrendingDown,{className:"h-3 w-3 mr-0.5 inline"}),u]})]}),r&&e.jsx("p",{className:"text-xs text-muted-foreground",children:r})]})]}));m.displayName="KPICard";exports.KPICard=m;
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),p=require("react"),c=require("../layout/card.cjs"),N=require("../primitives/badge.cjs"),l=require("../primitives/skeleton.cjs"),i=require("lucide-react"),m=require("../utils.cjs");function g(s){const r=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(s){for(const t in s)if(t!=="default"){const a=Object.getOwnPropertyDescriptor(s,t);Object.defineProperty(r,t,a.get?a:{enumerable:!0,get:()=>s[t]})}}return r.default=s,Object.freeze(r)}const b=g(p),u=b.forwardRef(({title:s,primaryContent:r,secondaryContent:t,trendValue:a,trendLabel:x,icon:j=i.Activity,isLoading:n=!1,onClick:o,className:h},f)=>{const d=!n&&!!o;return e.jsxs(c.Card,{ref:f,onClick:d?o:void 0,className:m.cn(d&&"cursor-pointer hover:bg-accent/50 transition-colors",h),children:[e.jsx(c.CardHeader,{className:"pb-1",children:e.jsx(c.CardTitle,{className:"flex items-center gap-2 text-sm text-muted-foreground",children:n?e.jsxs(e.Fragment,{children:[e.jsx(l.Skeleton,{className:"size-4 shrink-0 rounded"}),e.jsx(l.Skeleton,{className:"h-4 w-24"})]}):e.jsxs(e.Fragment,{children:[e.jsx(j,{className:"size-4 shrink-0 text-muted-foreground"}),e.jsx("span",{className:"truncate",children:s})]})})}),e.jsxs(c.CardContent,{className:"space-y-1 pt-0",children:[e.jsxs("div",{className:"flex items-baseline gap-2",children:[n?e.jsx(l.Skeleton,{className:"h-8 w-28"}):e.jsx("span",{className:"min-w-0 truncate text-2xl font-bold",title:r,children:r}),!n&&a!==void 0&&e.jsxs(N.Badge,{variant:"secondary",className:m.cn("h-auto shrink-0 px-1.5 py-0 text-xs",a>0?"text-green-600":"text-red-600"),children:[a>0?e.jsx(i.TrendingUp,{className:"mr-0.5 inline h-3 w-3"}):e.jsx(i.TrendingDown,{className:"mr-0.5 inline h-3 w-3"}),x]})]}),e.jsx("div",{className:"min-h-4 text-xs text-muted-foreground",children:n?e.jsx(l.Skeleton,{className:"h-3 w-full max-w-40"}):t&&e.jsx("span",{className:"block truncate",children:t})})]})]})});u.displayName="KPICard";exports.KPICard=u;
2
2
  //# sourceMappingURL=kpi-card.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"kpi-card.cjs","sources":["../../../../src/components/ui/charts/kpi-card.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { Card, CardContent, CardHeader, CardTitle } from \"../layout/card\";\nimport { Badge } from \"../primitives/badge\";\nimport { Skeleton } from \"../primitives/skeleton\";\nimport { TrendingUp, TrendingDown, Activity } from \"lucide-react\";\nimport { cn } from \"../utils\";\n\nexport interface KPICardProps {\n /**\n * Título do KPI (ex: \"Receita Mensal\")\n */\n title: string;\n\n /**\n * Valor principal em destaque (ex: \"R$ 127.361,23\")\n */\n primaryContent: string;\n\n /**\n * Texto secundário descritivo (ex: \"vs. mês anterior\")\n */\n secondaryContent?: string;\n\n /**\n * Valor de tendência para exibir badge com seta\n * Positivo = verde + seta para cima\n * Negativo = vermelho + seta para baixo\n */\n trendValue?: number;\n\n /**\n * Label customizado para tendência (default: \"+X%\" ou \"-X%\")\n */\n trendLabel?: string;\n\n /**\n * Ícone a ser exibido no header (componente Lucide React)\n */\n icon?: React.ComponentType<{ className?: string }>;\n\n /**\n * Estado de loading - exibe skeleton\n */\n isLoading?: boolean;\n\n /**\n * Handler de click - torna o card clicável com hover\n */\n onClick?: () => void;\n\n /**\n * Classes CSS adicionais\n */\n className?: string;\n}\n\nexport const KPICard = React.forwardRef<HTMLDivElement, KPICardProps>(\n (\n {\n title,\n primaryContent,\n secondaryContent,\n trendValue,\n trendLabel,\n icon: Icon = Activity,\n isLoading = false,\n onClick,\n className,\n },\n ref\n ) => {\n // Estado de loading\n if (isLoading) {\n return (\n <Card ref={ref} className={className}>\n <CardHeader className=\"pb-1\">\n <CardTitle className=\"text-sm flex items-center gap-2\">\n <Skeleton className=\"h-4 w-4 rounded\" />\n <Skeleton className=\"h-4 w-24\" />\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-1 pt-0\">\n <Skeleton className=\"h-8 w-32\" />\n <Skeleton className=\"h-3 w-full\" />\n </CardContent>\n </Card>\n );\n }\n\n // Renderização normal\n return (\n <Card\n ref={ref}\n onClick={onClick}\n className={cn(\n onClick && \"cursor-pointer hover:bg-accent/50 transition-colors\",\n className\n )}\n >\n <CardHeader className=\"pb-1\">\n <CardTitle className=\"text-sm flex items-center gap-2 text-muted-foreground\">\n <Icon className=\"h-4 w-4 text-muted-foreground\" />\n {title}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-1 pt-0\">\n <div className=\"flex items-baseline flex-wrap gap-2\">\n <span className=\"text-2xl font-bold\">{primaryContent}</span>\n {trendValue !== undefined && (\n <Badge\n variant=\"secondary\"\n className={cn(\n \"px-1.5 py-0 h-auto text-xs\",\n trendValue > 0 ? \"text-green-600\" : \"text-red-600\"\n )}\n >\n {trendValue > 0 ? (\n <TrendingUp className=\"h-3 w-3 mr-0.5 inline\" />\n ) : (\n <TrendingDown className=\"h-3 w-3 mr-0.5 inline\" />\n )}\n {trendLabel}\n </Badge>\n )}\n </div>\n {secondaryContent && (\n <p className=\"text-xs text-muted-foreground\">{secondaryContent}</p>\n )}\n </CardContent>\n </Card>\n );\n }\n);\n\nKPICard.displayName = \"KPICard\";\n"],"names":["KPICard","React","title","primaryContent","secondaryContent","trendValue","trendLabel","Icon","Activity","isLoading","onClick","className","ref","jsxs","Card","jsx","CardHeader","CardTitle","Skeleton","CardContent","cn","Badge","TrendingUp","TrendingDown"],"mappings":"glBA0DaA,EAAUC,EAAM,WAC3B,CACE,CACE,MAAAC,EACA,eAAAC,EACA,iBAAAC,EACA,WAAAC,EACA,WAAAC,EACA,KAAMC,EAAOC,EAAAA,SACb,UAAAC,EAAY,GACZ,QAAAC,EACA,UAAAC,CAAA,EAEFC,IAGIH,EAEAI,EAAAA,KAACC,EAAAA,KAAA,CAAK,IAAAF,EAAU,UAAAD,EACd,SAAA,CAAAI,EAAAA,IAACC,EAAAA,YAAW,UAAU,OACpB,SAAAH,EAAAA,KAACI,YAAA,CAAU,UAAU,kCACnB,SAAA,CAAAF,EAAAA,IAACG,EAAAA,SAAA,CAAS,UAAU,iBAAA,CAAkB,EACtCH,EAAAA,IAACG,EAAAA,SAAA,CAAS,UAAU,UAAA,CAAW,CAAA,CAAA,CACjC,CAAA,CACF,EACAL,EAAAA,KAACM,EAAAA,YAAA,CAAY,UAAU,iBACrB,SAAA,CAAAJ,EAAAA,IAACG,EAAAA,SAAA,CAAS,UAAU,UAAA,CAAW,EAC/BH,EAAAA,IAACG,EAAAA,SAAA,CAAS,UAAU,YAAA,CAAa,CAAA,CAAA,CACnC,CAAA,EACF,EAMFL,EAAAA,KAACC,EAAAA,KAAA,CACC,IAAAF,EACA,QAAAF,EACA,UAAWU,EAAAA,GACTV,GAAW,sDACXC,CAAA,EAGF,SAAA,CAAAI,EAAAA,IAACC,EAAAA,YAAW,UAAU,OACpB,SAAAH,EAAAA,KAACI,YAAA,CAAU,UAAU,wDACnB,SAAA,CAAAF,EAAAA,IAACR,EAAA,CAAK,UAAU,+BAAA,CAAgC,EAC/CL,CAAA,CAAA,CACH,CAAA,CACF,EACAW,EAAAA,KAACM,EAAAA,YAAA,CAAY,UAAU,iBACrB,SAAA,CAAAN,EAAAA,KAAC,MAAA,CAAI,UAAU,sCACb,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,UAAU,qBAAsB,SAAAZ,EAAe,EACpDE,IAAe,QACdQ,EAAAA,KAACQ,EAAAA,MAAA,CACC,QAAQ,YACR,UAAWD,EAAAA,GACT,6BACAf,EAAa,EAAI,iBAAmB,cAAA,EAGrC,SAAA,CAAAA,EAAa,QACXiB,EAAAA,WAAA,CAAW,UAAU,wBAAwB,EAE9CP,EAAAA,IAACQ,EAAAA,aAAA,CAAa,UAAU,uBAAA,CAAwB,EAEjDjB,CAAA,CAAA,CAAA,CACH,EAEJ,EACCF,GACCW,EAAAA,IAAC,IAAA,CAAE,UAAU,gCAAiC,SAAAX,CAAA,CAAiB,CAAA,CAAA,CAEnE,CAAA,CAAA,CAAA,CAIR,EAEAJ,EAAQ,YAAc"}
1
+ {"version":3,"file":"kpi-card.cjs","sources":["../../../../src/components/ui/charts/kpi-card.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { Card, CardContent, CardHeader, CardTitle } from \"../layout/card\";\nimport { Badge } from \"../primitives/badge\";\nimport { Skeleton } from \"../primitives/skeleton\";\nimport { TrendingUp, TrendingDown, Activity } from \"lucide-react\";\nimport { cn } from \"../utils\";\n\nexport interface KPICardProps {\n /**\n * Título do KPI (ex: \"Receita Mensal\"). Fica em uma linha (trunca com \"…\").\n */\n title: string;\n\n /**\n * Valor principal em destaque (ex: \"R$ 127.361,23\"). Fica em uma linha\n * (trunca com \"…\"; o valor completo aparece no `title` nativo ao passar o mouse).\n */\n primaryContent: string;\n\n /**\n * Texto secundário descritivo (ex: \"vs. mês anterior\"). Uma linha.\n */\n secondaryContent?: string;\n\n /**\n * Valor de tendência para exibir badge com seta\n * Positivo = verde + seta para cima\n * Negativo = vermelho + seta para baixo\n */\n trendValue?: number;\n\n /**\n * Label customizado para tendência (default: \"+X%\" ou \"-X%\")\n */\n trendLabel?: string;\n\n /**\n * Ícone a ser exibido no header (componente Lucide React)\n */\n icon?: React.ComponentType<{ className?: string }>;\n\n /**\n * Estado de loading - exibe skeleton com a mesma altura do estado final.\n */\n isLoading?: boolean;\n\n /**\n * Handler de click - torna o card clicável com hover\n */\n onClick?: () => void;\n\n /**\n * Classes CSS adicionais\n */\n className?: string;\n}\n\n/**\n * KPICard — card de métrica com título, valor em destaque, tendência e texto\n * secundário. O estado de `isLoading` reserva exatamente a mesma altura do\n * estado final (mesma árvore de layout, só troca o conteúdo por `Skeleton`),\n * então não há salto quando os dados chegam. Título, valor e texto secundário\n * ficam sempre em uma linha.\n */\nexport const KPICard = React.forwardRef<HTMLDivElement, KPICardProps>(\n (\n {\n title,\n primaryContent,\n secondaryContent,\n trendValue,\n trendLabel,\n icon: Icon = Activity,\n isLoading = false,\n onClick,\n className,\n },\n ref\n ) => {\n const clickable = !isLoading && !!onClick;\n\n return (\n <Card\n ref={ref}\n onClick={clickable ? onClick : undefined}\n className={cn(\n clickable && \"cursor-pointer hover:bg-accent/50 transition-colors\",\n className\n )}\n >\n <CardHeader className=\"pb-1\">\n <CardTitle className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n {isLoading ? (\n <>\n <Skeleton className=\"size-4 shrink-0 rounded\" />\n <Skeleton className=\"h-4 w-24\" />\n </>\n ) : (\n <>\n <Icon className=\"size-4 shrink-0 text-muted-foreground\" />\n <span className=\"truncate\">{title}</span>\n </>\n )}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-1 pt-0\">\n <div className=\"flex items-baseline gap-2\">\n {isLoading ? (\n <Skeleton className=\"h-8 w-28\" />\n ) : (\n <span\n className=\"min-w-0 truncate text-2xl font-bold\"\n title={primaryContent}\n >\n {primaryContent}\n </span>\n )}\n {!isLoading && trendValue !== undefined && (\n <Badge\n variant=\"secondary\"\n className={cn(\n \"h-auto shrink-0 px-1.5 py-0 text-xs\",\n trendValue > 0 ? \"text-green-600\" : \"text-red-600\"\n )}\n >\n {trendValue > 0 ? (\n <TrendingUp className=\"mr-0.5 inline h-3 w-3\" />\n ) : (\n <TrendingDown className=\"mr-0.5 inline h-3 w-3\" />\n )}\n {trendLabel}\n </Badge>\n )}\n </div>\n <div className=\"min-h-4 text-xs text-muted-foreground\">\n {isLoading ? (\n <Skeleton className=\"h-3 w-full max-w-40\" />\n ) : (\n secondaryContent && (\n <span className=\"block truncate\">{secondaryContent}</span>\n )\n )}\n </div>\n </CardContent>\n </Card>\n );\n }\n);\n\nKPICard.displayName = \"KPICard\";\n"],"names":["KPICard","React","title","primaryContent","secondaryContent","trendValue","trendLabel","Icon","Activity","isLoading","onClick","className","ref","clickable","jsxs","Card","cn","jsx","CardHeader","CardTitle","Fragment","Skeleton","CardContent","Badge","TrendingUp","TrendingDown"],"mappings":"glBAkEaA,EAAUC,EAAM,WAC3B,CACE,CACE,MAAAC,EACA,eAAAC,EACA,iBAAAC,EACA,WAAAC,EACA,WAAAC,EACA,KAAMC,EAAOC,EAAAA,SACb,UAAAC,EAAY,GACZ,QAAAC,EACA,UAAAC,CAAA,EAEFC,IACG,CACH,MAAMC,EAAY,CAACJ,GAAa,CAAC,CAACC,EAElC,OACEI,EAAAA,KAACC,EAAAA,KAAA,CACC,IAAAH,EACA,QAASC,EAAYH,EAAU,OAC/B,UAAWM,EAAAA,GACTH,GAAa,sDACbF,CAAA,EAGF,SAAA,CAAAM,EAAAA,IAACC,EAAAA,WAAA,CAAW,UAAU,OACpB,SAAAD,EAAAA,IAACE,EAAAA,WAAU,UAAU,wDAClB,WACCL,EAAAA,KAAAM,EAAAA,SAAA,CACE,SAAA,CAAAH,EAAAA,IAACI,EAAAA,SAAA,CAAS,UAAU,yBAAA,CAA0B,EAC9CJ,EAAAA,IAACI,EAAAA,SAAA,CAAS,UAAU,UAAA,CAAW,CAAA,CAAA,CACjC,EAEAP,EAAAA,KAAAM,EAAAA,SAAA,CACE,SAAA,CAAAH,EAAAA,IAACV,EAAA,CAAK,UAAU,uCAAA,CAAwC,EACxDU,EAAAA,IAAC,OAAA,CAAK,UAAU,WAAY,SAAAf,CAAA,CAAM,CAAA,CAAA,CACpC,EAEJ,EACF,EACAY,EAAAA,KAACQ,EAAAA,YAAA,CAAY,UAAU,iBACrB,SAAA,CAAAR,EAAAA,KAAC,MAAA,CAAI,UAAU,4BACZ,SAAA,CAAAL,EACCQ,EAAAA,IAACI,EAAAA,SAAA,CAAS,UAAU,UAAA,CAAW,EAE/BJ,EAAAA,IAAC,OAAA,CACC,UAAU,sCACV,MAAOd,EAEN,SAAAA,CAAA,CAAA,EAGJ,CAACM,GAAaJ,IAAe,QAC5BS,EAAAA,KAACS,EAAAA,MAAA,CACC,QAAQ,YACR,UAAWP,EAAAA,GACT,sCACAX,EAAa,EAAI,iBAAmB,cAAA,EAGrC,SAAA,CAAAA,EAAa,QACXmB,EAAAA,WAAA,CAAW,UAAU,wBAAwB,EAE9CP,EAAAA,IAACQ,EAAAA,aAAA,CAAa,UAAU,uBAAA,CAAwB,EAEjDnB,CAAA,CAAA,CAAA,CACH,EAEJ,QACC,MAAA,CAAI,UAAU,wCACZ,SAAAG,QACEY,EAAAA,SAAA,CAAS,UAAU,qBAAA,CAAsB,EAE1CjB,GACEa,EAAAA,IAAC,OAAA,CAAK,UAAU,iBAAkB,WAAiB,CAAA,CAGzD,CAAA,CAAA,CACF,CAAA,CAAA,CAAA,CAGN,CACF,EAEAjB,EAAQ,YAAc"}
@@ -1,71 +1,75 @@
1
1
  "use client";
2
- import { jsxs as r, jsx as e } from "react/jsx-runtime";
3
- import * as u from "react";
4
- import { Card as i, CardHeader as n, CardTitle as o, CardContent as d } from "../layout/card.js";
5
- import { Badge as w } from "../primitives/badge.js";
6
- import { Skeleton as a } from "../primitives/skeleton.js";
7
- import { Activity as b, TrendingUp as v, TrendingDown as y } from "lucide-react";
8
- import { cn as p } from "../utils.js";
9
- const C = u.forwardRef(
2
+ import { jsxs as r, jsx as e, Fragment as i } from "react/jsx-runtime";
3
+ import * as f from "react";
4
+ import { Card as u, CardHeader as w, CardTitle as g, CardContent as v } from "../layout/card.js";
5
+ import { Badge as b } from "../primitives/badge.js";
6
+ import { Skeleton as s } from "../primitives/skeleton.js";
7
+ import { Activity as k, TrendingUp as C, TrendingDown as y } from "lucide-react";
8
+ import { cn as o } from "../utils.js";
9
+ const T = f.forwardRef(
10
10
  ({
11
- title: h,
12
- primaryContent: x,
13
- secondaryContent: t,
14
- trendValue: s,
15
- trendLabel: f,
16
- icon: N = b,
17
- isLoading: g = !1,
18
- onClick: l,
19
- className: c
20
- }, m) => g ? /* @__PURE__ */ r(i, { ref: m, className: c, children: [
21
- /* @__PURE__ */ e(n, { className: "pb-1", children: /* @__PURE__ */ r(o, { className: "text-sm flex items-center gap-2", children: [
22
- /* @__PURE__ */ e(a, { className: "h-4 w-4 rounded" }),
23
- /* @__PURE__ */ e(a, { className: "h-4 w-24" })
24
- ] }) }),
25
- /* @__PURE__ */ r(d, { className: "space-y-1 pt-0", children: [
26
- /* @__PURE__ */ e(a, { className: "h-8 w-32" }),
27
- /* @__PURE__ */ e(a, { className: "h-3 w-full" })
28
- ] })
29
- ] }) : /* @__PURE__ */ r(
30
- i,
31
- {
32
- ref: m,
33
- onClick: l,
34
- className: p(
35
- l && "cursor-pointer hover:bg-accent/50 transition-colors",
36
- c
37
- ),
38
- children: [
39
- /* @__PURE__ */ e(n, { className: "pb-1", children: /* @__PURE__ */ r(o, { className: "text-sm flex items-center gap-2 text-muted-foreground", children: [
40
- /* @__PURE__ */ e(N, { className: "h-4 w-4 text-muted-foreground" }),
41
- h
42
- ] }) }),
43
- /* @__PURE__ */ r(d, { className: "space-y-1 pt-0", children: [
44
- /* @__PURE__ */ r("div", { className: "flex items-baseline flex-wrap gap-2", children: [
45
- /* @__PURE__ */ e("span", { className: "text-2xl font-bold", children: x }),
46
- s !== void 0 && /* @__PURE__ */ r(
47
- w,
48
- {
49
- variant: "secondary",
50
- className: p(
51
- "px-1.5 py-0 h-auto text-xs",
52
- s > 0 ? "text-green-600" : "text-red-600"
53
- ),
54
- children: [
55
- s > 0 ? /* @__PURE__ */ e(v, { className: "h-3 w-3 mr-0.5 inline" }) : /* @__PURE__ */ e(y, { className: "h-3 w-3 mr-0.5 inline" }),
56
- f
57
- ]
58
- }
59
- )
60
- ] }),
61
- t && /* @__PURE__ */ e("p", { className: "text-xs text-muted-foreground", children: t })
62
- ] })
63
- ]
64
- }
65
- )
11
+ title: d,
12
+ primaryContent: c,
13
+ secondaryContent: l,
14
+ trendValue: t,
15
+ trendLabel: h,
16
+ icon: p = k,
17
+ isLoading: a = !1,
18
+ onClick: n,
19
+ className: x
20
+ }, N) => {
21
+ const m = !a && !!n;
22
+ return /* @__PURE__ */ r(
23
+ u,
24
+ {
25
+ ref: N,
26
+ onClick: m ? n : void 0,
27
+ className: o(
28
+ m && "cursor-pointer hover:bg-accent/50 transition-colors",
29
+ x
30
+ ),
31
+ children: [
32
+ /* @__PURE__ */ e(w, { className: "pb-1", children: /* @__PURE__ */ e(g, { className: "flex items-center gap-2 text-sm text-muted-foreground", children: a ? /* @__PURE__ */ r(i, { children: [
33
+ /* @__PURE__ */ e(s, { className: "size-4 shrink-0 rounded" }),
34
+ /* @__PURE__ */ e(s, { className: "h-4 w-24" })
35
+ ] }) : /* @__PURE__ */ r(i, { children: [
36
+ /* @__PURE__ */ e(p, { className: "size-4 shrink-0 text-muted-foreground" }),
37
+ /* @__PURE__ */ e("span", { className: "truncate", children: d })
38
+ ] }) }) }),
39
+ /* @__PURE__ */ r(v, { className: "space-y-1 pt-0", children: [
40
+ /* @__PURE__ */ r("div", { className: "flex items-baseline gap-2", children: [
41
+ a ? /* @__PURE__ */ e(s, { className: "h-8 w-28" }) : /* @__PURE__ */ e(
42
+ "span",
43
+ {
44
+ className: "min-w-0 truncate text-2xl font-bold",
45
+ title: c,
46
+ children: c
47
+ }
48
+ ),
49
+ !a && t !== void 0 && /* @__PURE__ */ r(
50
+ b,
51
+ {
52
+ variant: "secondary",
53
+ className: o(
54
+ "h-auto shrink-0 px-1.5 py-0 text-xs",
55
+ t > 0 ? "text-green-600" : "text-red-600"
56
+ ),
57
+ children: [
58
+ t > 0 ? /* @__PURE__ */ e(C, { className: "mr-0.5 inline h-3 w-3" }) : /* @__PURE__ */ e(y, { className: "mr-0.5 inline h-3 w-3" }),
59
+ h
60
+ ]
61
+ }
62
+ )
63
+ ] }),
64
+ /* @__PURE__ */ e("div", { className: "min-h-4 text-xs text-muted-foreground", children: a ? /* @__PURE__ */ e(s, { className: "h-3 w-full max-w-40" }) : l && /* @__PURE__ */ e("span", { className: "block truncate", children: l }) })
65
+ ] })
66
+ ]
67
+ }
68
+ );
69
+ }
66
70
  );
67
- C.displayName = "KPICard";
71
+ T.displayName = "KPICard";
68
72
  export {
69
- C as KPICard
73
+ T as KPICard
70
74
  };
71
75
  //# sourceMappingURL=kpi-card.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"kpi-card.js","sources":["../../../../src/components/ui/charts/kpi-card.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { Card, CardContent, CardHeader, CardTitle } from \"../layout/card\";\nimport { Badge } from \"../primitives/badge\";\nimport { Skeleton } from \"../primitives/skeleton\";\nimport { TrendingUp, TrendingDown, Activity } from \"lucide-react\";\nimport { cn } from \"../utils\";\n\nexport interface KPICardProps {\n /**\n * Título do KPI (ex: \"Receita Mensal\")\n */\n title: string;\n\n /**\n * Valor principal em destaque (ex: \"R$ 127.361,23\")\n */\n primaryContent: string;\n\n /**\n * Texto secundário descritivo (ex: \"vs. mês anterior\")\n */\n secondaryContent?: string;\n\n /**\n * Valor de tendência para exibir badge com seta\n * Positivo = verde + seta para cima\n * Negativo = vermelho + seta para baixo\n */\n trendValue?: number;\n\n /**\n * Label customizado para tendência (default: \"+X%\" ou \"-X%\")\n */\n trendLabel?: string;\n\n /**\n * Ícone a ser exibido no header (componente Lucide React)\n */\n icon?: React.ComponentType<{ className?: string }>;\n\n /**\n * Estado de loading - exibe skeleton\n */\n isLoading?: boolean;\n\n /**\n * Handler de click - torna o card clicável com hover\n */\n onClick?: () => void;\n\n /**\n * Classes CSS adicionais\n */\n className?: string;\n}\n\nexport const KPICard = React.forwardRef<HTMLDivElement, KPICardProps>(\n (\n {\n title,\n primaryContent,\n secondaryContent,\n trendValue,\n trendLabel,\n icon: Icon = Activity,\n isLoading = false,\n onClick,\n className,\n },\n ref\n ) => {\n // Estado de loading\n if (isLoading) {\n return (\n <Card ref={ref} className={className}>\n <CardHeader className=\"pb-1\">\n <CardTitle className=\"text-sm flex items-center gap-2\">\n <Skeleton className=\"h-4 w-4 rounded\" />\n <Skeleton className=\"h-4 w-24\" />\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-1 pt-0\">\n <Skeleton className=\"h-8 w-32\" />\n <Skeleton className=\"h-3 w-full\" />\n </CardContent>\n </Card>\n );\n }\n\n // Renderização normal\n return (\n <Card\n ref={ref}\n onClick={onClick}\n className={cn(\n onClick && \"cursor-pointer hover:bg-accent/50 transition-colors\",\n className\n )}\n >\n <CardHeader className=\"pb-1\">\n <CardTitle className=\"text-sm flex items-center gap-2 text-muted-foreground\">\n <Icon className=\"h-4 w-4 text-muted-foreground\" />\n {title}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-1 pt-0\">\n <div className=\"flex items-baseline flex-wrap gap-2\">\n <span className=\"text-2xl font-bold\">{primaryContent}</span>\n {trendValue !== undefined && (\n <Badge\n variant=\"secondary\"\n className={cn(\n \"px-1.5 py-0 h-auto text-xs\",\n trendValue > 0 ? \"text-green-600\" : \"text-red-600\"\n )}\n >\n {trendValue > 0 ? (\n <TrendingUp className=\"h-3 w-3 mr-0.5 inline\" />\n ) : (\n <TrendingDown className=\"h-3 w-3 mr-0.5 inline\" />\n )}\n {trendLabel}\n </Badge>\n )}\n </div>\n {secondaryContent && (\n <p className=\"text-xs text-muted-foreground\">{secondaryContent}</p>\n )}\n </CardContent>\n </Card>\n );\n }\n);\n\nKPICard.displayName = \"KPICard\";\n"],"names":["KPICard","React","title","primaryContent","secondaryContent","trendValue","trendLabel","Icon","Activity","isLoading","onClick","className","ref","jsxs","Card","jsx","CardHeader","CardTitle","Skeleton","CardContent","cn","Badge","TrendingUp","TrendingDown"],"mappings":";;;;;;;;AA0DO,MAAMA,IAAUC,EAAM;AAAA,EAC3B,CACE;AAAA,IACE,OAAAC;AAAA,IACA,gBAAAC;AAAA,IACA,kBAAAC;AAAA,IACA,YAAAC;AAAA,IACA,YAAAC;AAAA,IACA,MAAMC,IAAOC;AAAA,IACb,WAAAC,IAAY;AAAA,IACZ,SAAAC;AAAA,IACA,WAAAC;AAAA,EAAA,GAEFC,MAGIH,IAEA,gBAAAI,EAACC,GAAA,EAAK,KAAAF,GAAU,WAAAD,GACd,UAAA;AAAA,IAAA,gBAAAI,EAACC,KAAW,WAAU,QACpB,UAAA,gBAAAH,EAACI,GAAA,EAAU,WAAU,mCACnB,UAAA;AAAA,MAAA,gBAAAF,EAACG,GAAA,EAAS,WAAU,kBAAA,CAAkB;AAAA,MACtC,gBAAAH,EAACG,GAAA,EAAS,WAAU,WAAA,CAAW;AAAA,IAAA,EAAA,CACjC,EAAA,CACF;AAAA,IACA,gBAAAL,EAACM,GAAA,EAAY,WAAU,kBACrB,UAAA;AAAA,MAAA,gBAAAJ,EAACG,GAAA,EAAS,WAAU,WAAA,CAAW;AAAA,MAC/B,gBAAAH,EAACG,GAAA,EAAS,WAAU,aAAA,CAAa;AAAA,IAAA,EAAA,CACnC;AAAA,EAAA,GACF,IAMF,gBAAAL;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,KAAAF;AAAA,MACA,SAAAF;AAAA,MACA,WAAWU;AAAA,QACTV,KAAW;AAAA,QACXC;AAAA,MAAA;AAAA,MAGF,UAAA;AAAA,QAAA,gBAAAI,EAACC,KAAW,WAAU,QACpB,UAAA,gBAAAH,EAACI,GAAA,EAAU,WAAU,yDACnB,UAAA;AAAA,UAAA,gBAAAF,EAACR,GAAA,EAAK,WAAU,gCAAA,CAAgC;AAAA,UAC/CL;AAAA,QAAA,EAAA,CACH,EAAA,CACF;AAAA,QACA,gBAAAW,EAACM,GAAA,EAAY,WAAU,kBACrB,UAAA;AAAA,UAAA,gBAAAN,EAAC,OAAA,EAAI,WAAU,uCACb,UAAA;AAAA,YAAA,gBAAAE,EAAC,QAAA,EAAK,WAAU,sBAAsB,UAAAZ,GAAe;AAAA,YACpDE,MAAe,UACd,gBAAAQ;AAAA,cAACQ;AAAA,cAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,WAAWD;AAAA,kBACT;AAAA,kBACAf,IAAa,IAAI,mBAAmB;AAAA,gBAAA;AAAA,gBAGrC,UAAA;AAAA,kBAAAA,IAAa,sBACXiB,GAAA,EAAW,WAAU,yBAAwB,IAE9C,gBAAAP,EAACQ,GAAA,EAAa,WAAU,wBAAA,CAAwB;AAAA,kBAEjDjB;AAAA,gBAAA;AAAA,cAAA;AAAA,YAAA;AAAA,UACH,GAEJ;AAAA,UACCF,KACC,gBAAAW,EAAC,KAAA,EAAE,WAAU,iCAAiC,UAAAX,EAAA,CAAiB;AAAA,QAAA,EAAA,CAEnE;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAIR;AAEAJ,EAAQ,cAAc;"}
1
+ {"version":3,"file":"kpi-card.js","sources":["../../../../src/components/ui/charts/kpi-card.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { Card, CardContent, CardHeader, CardTitle } from \"../layout/card\";\nimport { Badge } from \"../primitives/badge\";\nimport { Skeleton } from \"../primitives/skeleton\";\nimport { TrendingUp, TrendingDown, Activity } from \"lucide-react\";\nimport { cn } from \"../utils\";\n\nexport interface KPICardProps {\n /**\n * Título do KPI (ex: \"Receita Mensal\"). Fica em uma linha (trunca com \"…\").\n */\n title: string;\n\n /**\n * Valor principal em destaque (ex: \"R$ 127.361,23\"). Fica em uma linha\n * (trunca com \"…\"; o valor completo aparece no `title` nativo ao passar o mouse).\n */\n primaryContent: string;\n\n /**\n * Texto secundário descritivo (ex: \"vs. mês anterior\"). Uma linha.\n */\n secondaryContent?: string;\n\n /**\n * Valor de tendência para exibir badge com seta\n * Positivo = verde + seta para cima\n * Negativo = vermelho + seta para baixo\n */\n trendValue?: number;\n\n /**\n * Label customizado para tendência (default: \"+X%\" ou \"-X%\")\n */\n trendLabel?: string;\n\n /**\n * Ícone a ser exibido no header (componente Lucide React)\n */\n icon?: React.ComponentType<{ className?: string }>;\n\n /**\n * Estado de loading - exibe skeleton com a mesma altura do estado final.\n */\n isLoading?: boolean;\n\n /**\n * Handler de click - torna o card clicável com hover\n */\n onClick?: () => void;\n\n /**\n * Classes CSS adicionais\n */\n className?: string;\n}\n\n/**\n * KPICard — card de métrica com título, valor em destaque, tendência e texto\n * secundário. O estado de `isLoading` reserva exatamente a mesma altura do\n * estado final (mesma árvore de layout, só troca o conteúdo por `Skeleton`),\n * então não há salto quando os dados chegam. Título, valor e texto secundário\n * ficam sempre em uma linha.\n */\nexport const KPICard = React.forwardRef<HTMLDivElement, KPICardProps>(\n (\n {\n title,\n primaryContent,\n secondaryContent,\n trendValue,\n trendLabel,\n icon: Icon = Activity,\n isLoading = false,\n onClick,\n className,\n },\n ref\n ) => {\n const clickable = !isLoading && !!onClick;\n\n return (\n <Card\n ref={ref}\n onClick={clickable ? onClick : undefined}\n className={cn(\n clickable && \"cursor-pointer hover:bg-accent/50 transition-colors\",\n className\n )}\n >\n <CardHeader className=\"pb-1\">\n <CardTitle className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n {isLoading ? (\n <>\n <Skeleton className=\"size-4 shrink-0 rounded\" />\n <Skeleton className=\"h-4 w-24\" />\n </>\n ) : (\n <>\n <Icon className=\"size-4 shrink-0 text-muted-foreground\" />\n <span className=\"truncate\">{title}</span>\n </>\n )}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-1 pt-0\">\n <div className=\"flex items-baseline gap-2\">\n {isLoading ? (\n <Skeleton className=\"h-8 w-28\" />\n ) : (\n <span\n className=\"min-w-0 truncate text-2xl font-bold\"\n title={primaryContent}\n >\n {primaryContent}\n </span>\n )}\n {!isLoading && trendValue !== undefined && (\n <Badge\n variant=\"secondary\"\n className={cn(\n \"h-auto shrink-0 px-1.5 py-0 text-xs\",\n trendValue > 0 ? \"text-green-600\" : \"text-red-600\"\n )}\n >\n {trendValue > 0 ? (\n <TrendingUp className=\"mr-0.5 inline h-3 w-3\" />\n ) : (\n <TrendingDown className=\"mr-0.5 inline h-3 w-3\" />\n )}\n {trendLabel}\n </Badge>\n )}\n </div>\n <div className=\"min-h-4 text-xs text-muted-foreground\">\n {isLoading ? (\n <Skeleton className=\"h-3 w-full max-w-40\" />\n ) : (\n secondaryContent && (\n <span className=\"block truncate\">{secondaryContent}</span>\n )\n )}\n </div>\n </CardContent>\n </Card>\n );\n }\n);\n\nKPICard.displayName = \"KPICard\";\n"],"names":["KPICard","React","title","primaryContent","secondaryContent","trendValue","trendLabel","Icon","Activity","isLoading","onClick","className","ref","clickable","jsxs","Card","cn","jsx","CardHeader","CardTitle","Fragment","Skeleton","CardContent","Badge","TrendingUp","TrendingDown"],"mappings":";;;;;;;;AAkEO,MAAMA,IAAUC,EAAM;AAAA,EAC3B,CACE;AAAA,IACE,OAAAC;AAAA,IACA,gBAAAC;AAAA,IACA,kBAAAC;AAAA,IACA,YAAAC;AAAA,IACA,YAAAC;AAAA,IACA,MAAMC,IAAOC;AAAA,IACb,WAAAC,IAAY;AAAA,IACZ,SAAAC;AAAA,IACA,WAAAC;AAAA,EAAA,GAEFC,MACG;AACH,UAAMC,IAAY,CAACJ,KAAa,CAAC,CAACC;AAElC,WACE,gBAAAI;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,KAAAH;AAAA,QACA,SAASC,IAAYH,IAAU;AAAA,QAC/B,WAAWM;AAAA,UACTH,KAAa;AAAA,UACbF;AAAA,QAAA;AAAA,QAGF,UAAA;AAAA,UAAA,gBAAAM,EAACC,GAAA,EAAW,WAAU,QACpB,UAAA,gBAAAD,EAACE,KAAU,WAAU,yDAClB,cACC,gBAAAL,EAAAM,GAAA,EACE,UAAA;AAAA,YAAA,gBAAAH,EAACI,GAAA,EAAS,WAAU,0BAAA,CAA0B;AAAA,YAC9C,gBAAAJ,EAACI,GAAA,EAAS,WAAU,WAAA,CAAW;AAAA,UAAA,EAAA,CACjC,IAEA,gBAAAP,EAAAM,GAAA,EACE,UAAA;AAAA,YAAA,gBAAAH,EAACV,GAAA,EAAK,WAAU,wCAAA,CAAwC;AAAA,YACxD,gBAAAU,EAAC,QAAA,EAAK,WAAU,YAAY,UAAAf,EAAA,CAAM;AAAA,UAAA,EAAA,CACpC,GAEJ,GACF;AAAA,UACA,gBAAAY,EAACQ,GAAA,EAAY,WAAU,kBACrB,UAAA;AAAA,YAAA,gBAAAR,EAAC,OAAA,EAAI,WAAU,6BACZ,UAAA;AAAA,cAAAL,IACC,gBAAAQ,EAACI,GAAA,EAAS,WAAU,WAAA,CAAW,IAE/B,gBAAAJ;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAU;AAAA,kBACV,OAAOd;AAAA,kBAEN,UAAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,cAGJ,CAACM,KAAaJ,MAAe,UAC5B,gBAAAS;AAAA,gBAACS;AAAA,gBAAA;AAAA,kBACC,SAAQ;AAAA,kBACR,WAAWP;AAAA,oBACT;AAAA,oBACAX,IAAa,IAAI,mBAAmB;AAAA,kBAAA;AAAA,kBAGrC,UAAA;AAAA,oBAAAA,IAAa,sBACXmB,GAAA,EAAW,WAAU,yBAAwB,IAE9C,gBAAAP,EAACQ,GAAA,EAAa,WAAU,wBAAA,CAAwB;AAAA,oBAEjDnB;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,YACH,GAEJ;AAAA,8BACC,OAAA,EAAI,WAAU,yCACZ,UAAAG,sBACEY,GAAA,EAAS,WAAU,sBAAA,CAAsB,IAE1CjB,KACE,gBAAAa,EAAC,QAAA,EAAK,WAAU,kBAAkB,aAAiB,EAAA,CAGzD;AAAA,UAAA,EAAA,CACF;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN;AACF;AAEAjB,EAAQ,cAAc;"}
@@ -1,2 +1,2 @@
1
- "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime"),v=require("date-fns"),J=require("date-fns/locale"),k=require("lucide-react"),Q=require("react"),H=require("../primitives/button.cjs"),U=require("./calendar.cjs"),W=require("./input.cjs"),N=require("../overlays/popover.cjs"),Y=require("./time-picker.cjs"),Z=require("../utils.cjs");function T(r){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(r){for(const d in r)if(d!=="default"){const n=Object.getOwnPropertyDescriptor(r,d);Object.defineProperty(t,d,n.get?n:{enumerable:!0,get:()=>r[d]})}}return t.default=r,Object.freeze(t)}const a=T(Q),w=a.forwardRef(({value:r,onChange:t,placeholder:d="Selecione uma data",disabled:n=!1,minDate:y,maxDate:p,dateFormat:D,locale:m=J.ptBR,className:O,error:S=!1,showTime:o=!1,timeFormat:B="24h",minuteStep:R=5,defaultTime:I="09:00",id:z,name:F},V)=>{const[E,M]=a.useState(!1),[j,f]=a.useState(""),[x,c]=a.useState(!1),b=D||(o?"dd/MM/yyyy HH:mm":"dd/MM/yyyy"),_=a.useMemo(()=>o?["dd/MM/yyyy HH:mm","dd/MM/yyyy HH:mm:ss","dd/MM/yy HH:mm","d/M/yyyy HH:mm","d/M/yy HH:mm"]:["dd/MM/yyyy","dd/MM/yy","d/M/yyyy","d/M/yy","ddMMyyyy","ddMMyy"],[o]);a.useEffect(()=>{r?(f(v.format(r,b,{locale:m})),c(!1)):(f(""),c(!1))},[r,b,m]);const P=a.useMemo(()=>{if(!r)return I;const e=r.getHours().toString().padStart(2,"0"),i=r.getMinutes().toString().padStart(2,"0");return`${e}:${i}`},[r,I]),K=e=>{if(!n){if(!e){t==null||t(void 0);return}if(o){const[i,l]=P.split(":").map(Number);e.setHours(i,l,0,0)}else e.setHours(0,0,0,0);t==null||t(e),o||M(!1)}},h=e=>{if(r){const i=new Date(r),[l,u]=e.split(":").map(Number);i.setHours(l,u,0,0),t==null||t(i)}else{const i=new Date,[l,u]=e.split(":").map(Number);i.setHours(l,u,0,0),t==null||t(i)}},A=e=>{const i=e.trim();if(!i)return null;for(const l of _)try{const u=v.parse(i,l,new Date);if(v.isValid(u)){if(y&&u<y||p&&u>p)continue;return u}}catch{continue}return null},L=e=>{if(n)return;const i=e.target.value;f(i),c(!1)},q=()=>{if(n)return;if(!j.trim()){t==null||t(void 0),c(!1);return}const e=A(j);e?(t==null||t(e),c(!1)):c(!0)},X=e=>{e.key==="Enter"?(e.preventDefault(),q(),x||M(!0)):e.key==="Escape"&&(e.preventDefault(),f(r?v.format(r,b,{locale:m}):""),c(!1))},G=e=>{e.stopPropagation(),t==null||t(void 0),f(""),c(!1)};return s.jsxs(N.Popover,{open:!n&&E,onOpenChange:e=>{n||M(e)},children:[s.jsxs("div",{className:"relative w-full",children:[s.jsx(W.Input,{ref:V,id:z,name:F,value:j,onChange:L,onBlur:q,onKeyDown:X,placeholder:d,disabled:n,"aria-invalid":S||x,className:Z.cn("pr-20",(S||x)&&"border-destructive focus-visible:ring-destructive/20",O)}),s.jsxs("div",{className:"absolute inset-y-0 right-0 flex items-center gap-1 pr-1",children:[j&&!n&&s.jsxs(H.Button,{type:"button",variant:"ghost",size:"sm",className:"h-7 w-7 p-0 hover:bg-transparent",onClick:G,tabIndex:-1,children:[s.jsx(k.X,{className:"h-4 w-4 text-muted-foreground hover:text-foreground"}),s.jsx("span",{className:"sr-only",children:"Limpar"})]}),s.jsx(N.PopoverTrigger,{asChild:!0,children:s.jsx(H.Button,{type:"button",variant:"ghost",size:"sm",className:"h-7 w-7 p-0 hover:bg-transparent",disabled:n,"aria-label":"Abrir calendário",children:s.jsx(k.CalendarIcon,{className:"h-4 w-4 text-muted-foreground"})})})]})]}),s.jsxs(N.PopoverContent,{className:"w-auto p-0",align:"start",children:[s.jsx(U.Calendar,{mode:"single",selected:r,onSelect:K,disabled:e=>!!(y&&e<y||p&&e>p),locale:m,autoFocus:!0,defaultMonth:r||void 0}),o&&s.jsx("div",{className:"border-t p-3",children:s.jsx(Y.TimePicker,{value:P,onChange:h,format:B,minuteStep:R,variant:"inline",showIcon:!0})}),o&&s.jsx("div",{className:"border-t p-3 flex justify-end",children:s.jsx(H.Button,{size:"sm",onClick:()=>M(!1),children:"Confirmar"})})]})]})});w.displayName="DatePicker";exports.DatePicker=w;
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),b=require("date-fns"),Q=require("date-fns/locale"),k=require("lucide-react"),U=require("react"),N=require("../primitives/button.cjs"),W=require("./calendar.cjs"),Y=require("./input.cjs"),C=require("../overlays/popover.cjs"),Z=require("./time-picker.cjs"),T=require("../use-controllable-value.cjs"),$=require("../utils.cjs");function ee(u){const y=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(u){for(const f in u)if(f!=="default"){const m=Object.getOwnPropertyDescriptor(u,f);Object.defineProperty(y,f,m.get?m:{enumerable:!0,get:()=>u[f]})}}return y.default=u,Object.freeze(y)}const d=ee(U),w=d.forwardRef(({value:u,defaultValue:y,onChange:f,placeholder:m="Selecione uma data",disabled:s=!1,minDate:h,maxDate:v,dateFormat:D,locale:g=Q.ptBR,className:O,error:S=!1,showTime:l=!1,timeFormat:V="24h",minuteStep:B=5,defaultTime:q="09:00",id:R,name:z},F)=>{const[n,i]=T.useControllableValue(u,y,f),[E,M]=d.useState(!1),[j,p]=d.useState(""),[x,a]=d.useState(!1),H=D||(l?"dd/MM/yyyy HH:mm":"dd/MM/yyyy"),_=d.useMemo(()=>l?["dd/MM/yyyy HH:mm","dd/MM/yyyy HH:mm:ss","dd/MM/yy HH:mm","d/M/yyyy HH:mm","d/M/yy HH:mm"]:["dd/MM/yyyy","dd/MM/yy","d/M/yyyy","d/M/yy","ddMMyyyy","ddMMyy"],[l]);d.useEffect(()=>{n?(p(b.format(n,H,{locale:g})),a(!1)):(p(""),a(!1))},[n,H,g]);const I=d.useMemo(()=>{if(!n)return q;const e=n.getHours().toString().padStart(2,"0"),r=n.getMinutes().toString().padStart(2,"0");return`${e}:${r}`},[n,q]),K=e=>{if(!s){if(!e){i(void 0);return}if(l){const[r,c]=I.split(":").map(Number);e.setHours(r,c,0,0)}else e.setHours(0,0,0,0);i(e),l||M(!1)}},A=e=>{if(n){const r=new Date(n),[c,o]=e.split(":").map(Number);r.setHours(c,o,0,0),i(r)}else{const r=new Date,[c,o]=e.split(":").map(Number);r.setHours(c,o,0,0),i(r)}},L=e=>{const r=e.trim();if(!r)return null;for(const c of _)try{const o=b.parse(r,c,new Date);if(b.isValid(o)){if(h&&o<h||v&&o>v)continue;return o}}catch{continue}return null},X=e=>{if(s)return;const r=e.target.value.replace(/[^\d/:\s]/g,"");p(r),a(!1)},P=()=>{if(s)return;if(!j.trim()){i(void 0),a(!1);return}const e=L(j);e?(i(e),a(!1)):a(!0)},G=e=>{e.key==="Enter"?(e.preventDefault(),P(),x||M(!0)):e.key==="Escape"&&(e.preventDefault(),p(n?b.format(n,H,{locale:g}):""),a(!1))},J=e=>{e.stopPropagation(),i(void 0),p(""),a(!1)};return t.jsxs(C.Popover,{open:!s&&E,onOpenChange:e=>{s||M(e)},children:[t.jsxs("div",{className:"relative w-full",children:[t.jsx(Y.Input,{ref:F,id:R,name:z,value:j,onChange:X,onBlur:P,onKeyDown:G,placeholder:m,disabled:s,"aria-invalid":S||x,className:$.cn("pr-20",(S||x)&&"border-destructive focus-visible:ring-destructive/20",O)}),t.jsxs("div",{className:"absolute inset-y-0 right-0 flex items-center gap-1 pr-1",children:[j&&!s&&t.jsxs(N.Button,{type:"button",variant:"ghost",size:"sm",className:"h-7 w-7 p-0 hover:bg-transparent",onClick:J,tabIndex:-1,children:[t.jsx(k.X,{className:"h-4 w-4 text-muted-foreground hover:text-foreground"}),t.jsx("span",{className:"sr-only",children:"Limpar"})]}),t.jsx(C.PopoverTrigger,{asChild:!0,children:t.jsx(N.Button,{type:"button",variant:"ghost",size:"sm",className:"h-7 w-7 p-0 hover:bg-transparent",disabled:s,"aria-label":"Abrir calendário",children:t.jsx(k.CalendarIcon,{className:"h-4 w-4 text-muted-foreground"})})})]})]}),t.jsxs(C.PopoverContent,{className:"w-auto p-0",align:"start",children:[t.jsx(W.Calendar,{mode:"single",selected:n,onSelect:K,disabled:e=>!!(h&&e<h||v&&e>v),locale:g,autoFocus:!0,defaultMonth:n||void 0}),l&&t.jsx("div",{className:"border-t p-3",children:t.jsx(Z.TimePicker,{value:I,onChange:A,format:V,minuteStep:B,variant:"inline",showIcon:!0})}),l&&t.jsx("div",{className:"border-t p-3 flex justify-end",children:t.jsx(N.Button,{size:"sm",onClick:()=>M(!1),children:"Confirmar"})})]})]})});w.displayName="DatePicker";exports.DatePicker=w;
2
2
  //# sourceMappingURL=date-picker.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"date-picker.cjs","sources":["../../../../src/components/ui/forms/date-picker.tsx"],"sourcesContent":["\"use client\";\n\nimport { format, isValid, parse, type Locale } from \"date-fns\";\nimport { ptBR } from \"date-fns/locale\";\nimport { CalendarIcon, X } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport { Button } from \"../primitives/button\";\nimport { Calendar } from \"./calendar\";\nimport { Input } from \"./input\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../overlays/popover\";\nimport { TimePicker } from \"./time-picker\";\nimport { cn } from \"../utils\";\n\nexport interface DatePickerProps {\n /**\n * Data selecionada\n */\n value?: Date;\n /**\n * Callback quando a data muda\n */\n onChange?: (date: Date | undefined) => void;\n /**\n * Placeholder do campo\n * @default \"Selecione uma data\"\n */\n placeholder?: string;\n /**\n * Desabilita o componente\n */\n disabled?: boolean;\n /**\n * Data mínima permitida\n */\n minDate?: Date;\n /**\n * Data máxima permitida\n */\n maxDate?: Date;\n /**\n * Formato de exibição da data\n * @default \"dd/MM/yyyy\" ou \"dd/MM/yyyy HH:mm\" se showTime\n */\n dateFormat?: string;\n /**\n * Locale para formatação\n * @default ptBR\n */\n locale?: Locale;\n /**\n * Classes CSS adicionais para o trigger\n */\n className?: string;\n /**\n * Estado de erro\n */\n error?: boolean;\n /**\n * Mostra seletor de hora\n * @default false\n */\n showTime?: boolean;\n /**\n * Formato de hora (12h ou 24h)\n * @default \"24h\"\n */\n timeFormat?: \"12h\" | \"24h\";\n /**\n * Incremento de minutos\n * @default 5\n */\n minuteStep?: 1 | 5 | 10 | 15 | 30;\n /**\n * Horário padrão quando showTime=true e uma data é selecionada\n * @default \"09:00\"\n */\n defaultTime?: string;\n /**\n * ID do campo para acessibilidade\n */\n id?: string;\n /**\n * Nome do campo para formulários\n */\n name?: string;\n}\n\n/**\n * DatePicker - Campo de seleção de data com hora opcional\n *\n * @example\n * // Apenas data\n * <DatePicker\n * value={date}\n * onChange={setDate}\n * placeholder=\"Data de nascimento\"\n * />\n *\n * @example\n * // Data e hora\n * <DatePicker\n * value={appointmentDate}\n * onChange={setAppointmentDate}\n * placeholder=\"Data e hora da reunião\"\n * showTime\n * minuteStep={15}\n * />\n *\n * @example\n * // Com limites\n * <DatePicker\n * value={date}\n * onChange={setDate}\n * minDate={new Date()}\n * maxDate={addMonths(new Date(), 3)}\n * />\n */\nconst DatePicker = React.forwardRef<\n React.ElementRef<typeof Input>,\n DatePickerProps\n>(({\n value,\n onChange,\n placeholder = \"Selecione uma data\",\n disabled = false,\n minDate,\n maxDate,\n dateFormat,\n locale = ptBR,\n className,\n error = false,\n showTime = false,\n timeFormat = \"24h\",\n minuteStep = 5,\n defaultTime = \"09:00\",\n id,\n name,\n}, ref) => {\n const [open, setOpen] = React.useState(false);\n const [inputValue, setInputValue] = React.useState(\"\");\n const [isInvalid, setIsInvalid] = React.useState(false);\n\n // Formato padrão baseado em showTime\n const displayFormat = dateFormat || (showTime ? \"dd/MM/yyyy HH:mm\" : \"dd/MM/yyyy\");\n\n // Formatos aceitos para parsing\n const parseFormats = React.useMemo(() => {\n if (showTime) {\n return [\n \"dd/MM/yyyy HH:mm\",\n \"dd/MM/yyyy HH:mm:ss\",\n \"dd/MM/yy HH:mm\",\n \"d/M/yyyy HH:mm\",\n \"d/M/yy HH:mm\",\n ];\n }\n return [\n \"dd/MM/yyyy\",\n \"dd/MM/yy\",\n \"d/M/yyyy\",\n \"d/M/yy\",\n \"ddMMyyyy\",\n \"ddMMyy\",\n ];\n }, [showTime]);\n\n // Sincroniza inputValue com value\n React.useEffect(() => {\n if (value) {\n setInputValue(format(value, displayFormat, { locale }));\n setIsInvalid(false);\n } else {\n setInputValue(\"\");\n setIsInvalid(false);\n }\n }, [value, displayFormat, locale]);\n\n // Extrai hora/minuto do valor atual\n const currentTime = React.useMemo(() => {\n if (!value) return defaultTime;\n const hours = value.getHours().toString().padStart(2, \"0\");\n const minutes = value.getMinutes().toString().padStart(2, \"0\");\n return `${hours}:${minutes}`;\n }, [value, defaultTime]);\n\n // Handler para seleção de data\n const handleDateSelect = (date: Date | undefined) => {\n if (disabled) return;\n if (!date) {\n onChange?.(undefined);\n return;\n }\n\n if (showTime) {\n // Preserva o horário atual ou usa o padrão\n const [hours, minutes] = currentTime.split(\":\").map(Number);\n date.setHours(hours, minutes, 0, 0);\n } else {\n // Sem hora, zera o horário\n date.setHours(0, 0, 0, 0);\n }\n\n onChange?.(date);\n\n // Fecha o popover se não tiver seleção de hora\n if (!showTime) {\n setOpen(false);\n }\n };\n\n // Handler para mudança de hora\n const handleTimeChange = (time: string) => {\n if (!value) {\n // Se não tem data, cria uma nova com a data de hoje\n const today = new Date();\n const [hours, minutes] = time.split(\":\").map(Number);\n today.setHours(hours, minutes, 0, 0);\n onChange?.(today);\n } else {\n // Atualiza apenas o horário\n const newDate = new Date(value);\n const [hours, minutes] = time.split(\":\").map(Number);\n newDate.setHours(hours, minutes, 0, 0);\n onChange?.(newDate);\n }\n };\n\n // Parse da data digitada\n const parseInputDate = (input: string): Date | null => {\n const trimmed = input.trim();\n if (!trimmed) return null;\n\n // Tenta cada formato\n for (const fmt of parseFormats) {\n try {\n const parsed = parse(trimmed, fmt, new Date());\n if (isValid(parsed)) {\n // Valida limites\n if (minDate && parsed < minDate) continue;\n if (maxDate && parsed > maxDate) continue;\n return parsed;\n }\n } catch {\n continue;\n }\n }\n\n return null;\n };\n\n // Handler para input digitado\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (disabled) return;\n const newValue = e.target.value;\n setInputValue(newValue);\n setIsInvalid(false);\n };\n\n // Handler para blur do input (valida quando sai do campo)\n const handleInputBlur = () => {\n if (disabled) return;\n if (!inputValue.trim()) {\n onChange?.(undefined);\n setIsInvalid(false);\n return;\n }\n\n const parsed = parseInputDate(inputValue);\n if (parsed) {\n onChange?.(parsed);\n setIsInvalid(false);\n } else {\n setIsInvalid(true);\n // Mantém o inputValue para que o usuário possa corrigir\n }\n };\n\n // Handler para Enter no input\n const handleInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n handleInputBlur();\n if (!isInvalid) {\n setOpen(true); // Abre o calendário após validar\n }\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n // Restaura o valor original\n if (value) {\n setInputValue(format(value, displayFormat, { locale }));\n } else {\n setInputValue(\"\");\n }\n setIsInvalid(false);\n }\n };\n\n // Handler para limpar\n const handleClear = (e: React.MouseEvent) => {\n e.stopPropagation();\n onChange?.(undefined);\n setInputValue(\"\");\n setIsInvalid(false);\n };\n\n return (\n <Popover open={!disabled && open} onOpenChange={(o) => { if (!disabled) setOpen(o); }}>\n <div className=\"relative w-full\">\n <Input\n ref={ref}\n id={id}\n name={name}\n value={inputValue}\n onChange={handleInputChange}\n onBlur={handleInputBlur}\n onKeyDown={handleInputKeyDown}\n placeholder={placeholder}\n disabled={disabled}\n aria-invalid={error || isInvalid}\n className={cn(\n \"pr-20\",\n (error || isInvalid) && \"border-destructive focus-visible:ring-destructive/20\",\n className\n )}\n />\n <div className=\"absolute inset-y-0 right-0 flex items-center gap-1 pr-1\">\n {inputValue && !disabled && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 w-7 p-0 hover:bg-transparent\"\n onClick={handleClear}\n tabIndex={-1}\n >\n <X className=\"h-4 w-4 text-muted-foreground hover:text-foreground\" />\n <span className=\"sr-only\">Limpar</span>\n </Button>\n )}\n <PopoverTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 w-7 p-0 hover:bg-transparent\"\n disabled={disabled}\n aria-label=\"Abrir calendário\"\n >\n <CalendarIcon className=\"h-4 w-4 text-muted-foreground\" />\n </Button>\n </PopoverTrigger>\n </div>\n </div>\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\n <Calendar\n mode=\"single\"\n selected={value}\n onSelect={handleDateSelect}\n disabled={(date) => {\n if (minDate && date < minDate) return true;\n if (maxDate && date > maxDate) return true;\n return false;\n }}\n locale={locale}\n autoFocus\n defaultMonth={value || undefined}\n />\n\n {showTime && (\n <div className=\"border-t p-3\">\n <TimePicker\n value={currentTime}\n onChange={handleTimeChange}\n format={timeFormat}\n minuteStep={minuteStep}\n variant=\"inline\"\n showIcon\n />\n </div>\n )}\n\n {showTime && (\n <div className=\"border-t p-3 flex justify-end\">\n <Button\n size=\"sm\"\n onClick={() => setOpen(false)}\n >\n Confirmar\n </Button>\n </div>\n )}\n </PopoverContent>\n </Popover>\n );\n});\n\nDatePicker.displayName = \"DatePicker\";\n\nexport { DatePicker };\n\n"],"names":["DatePicker","React","value","onChange","placeholder","disabled","minDate","maxDate","dateFormat","locale","ptBR","className","error","showTime","timeFormat","minuteStep","defaultTime","id","name","ref","open","setOpen","inputValue","setInputValue","isInvalid","setIsInvalid","displayFormat","parseFormats","format","currentTime","hours","minutes","handleDateSelect","date","handleTimeChange","time","newDate","today","parseInputDate","input","trimmed","fmt","parsed","parse","isValid","handleInputChange","newValue","handleInputBlur","handleInputKeyDown","handleClear","jsxs","Popover","o","jsx","Input","cn","Button","X","PopoverTrigger","CalendarIcon","PopoverContent","Calendar","TimePicker"],"mappings":"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"}
1
+ {"version":3,"file":"date-picker.cjs","sources":["../../../../src/components/ui/forms/date-picker.tsx"],"sourcesContent":["\"use client\";\n\nimport { format, isValid, parse, type Locale } from \"date-fns\";\nimport { ptBR } from \"date-fns/locale\";\nimport { CalendarIcon, X } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport { Button } from \"../primitives/button\";\nimport { Calendar } from \"./calendar\";\nimport { Input } from \"./input\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../overlays/popover\";\nimport { TimePicker } from \"./time-picker\";\nimport { useControllableValue } from \"../use-controllable-value\";\nimport { cn } from \"../utils\";\n\nexport interface DatePickerProps {\n /**\n * Data selecionada (modo controlado). Omita para o modo não-controlado.\n */\n value?: Date;\n /**\n * Valor inicial no modo não-controlado (quando `value` não é passado).\n */\n defaultValue?: Date;\n /**\n * Callback quando a data muda. Chamado nos dois modos.\n */\n onChange?: (date: Date | undefined) => void;\n /**\n * Placeholder do campo\n * @default \"Selecione uma data\"\n */\n placeholder?: string;\n /**\n * Desabilita o componente\n */\n disabled?: boolean;\n /**\n * Data mínima permitida\n */\n minDate?: Date;\n /**\n * Data máxima permitida\n */\n maxDate?: Date;\n /**\n * Formato de exibição da data\n * @default \"dd/MM/yyyy\" ou \"dd/MM/yyyy HH:mm\" se showTime\n */\n dateFormat?: string;\n /**\n * Locale para formatação\n * @default ptBR\n */\n locale?: Locale;\n /**\n * Classes CSS adicionais para o trigger\n */\n className?: string;\n /**\n * Estado de erro\n */\n error?: boolean;\n /**\n * Mostra seletor de hora\n * @default false\n */\n showTime?: boolean;\n /**\n * Formato de hora (12h ou 24h)\n * @default \"24h\"\n */\n timeFormat?: \"12h\" | \"24h\";\n /**\n * Incremento de minutos\n * @default 5\n */\n minuteStep?: 1 | 5 | 10 | 15 | 30;\n /**\n * Horário padrão quando showTime=true e uma data é selecionada\n * @default \"09:00\"\n */\n defaultTime?: string;\n /**\n * ID do campo para acessibilidade\n */\n id?: string;\n /**\n * Nome do campo para formulários\n */\n name?: string;\n}\n\n/**\n * DatePicker - Campo de seleção de data com hora opcional\n *\n * @example\n * // Apenas data\n * <DatePicker\n * value={date}\n * onChange={setDate}\n * placeholder=\"Data de nascimento\"\n * />\n *\n * @example\n * // Data e hora\n * <DatePicker\n * value={appointmentDate}\n * onChange={setAppointmentDate}\n * placeholder=\"Data e hora da reunião\"\n * showTime\n * minuteStep={15}\n * />\n *\n * @example\n * // Com limites\n * <DatePicker\n * value={date}\n * onChange={setDate}\n * minDate={new Date()}\n * maxDate={addMonths(new Date(), 3)}\n * />\n */\nconst DatePicker = React.forwardRef<\n React.ElementRef<typeof Input>,\n DatePickerProps\n>(({\n value: valueProp,\n defaultValue,\n onChange,\n placeholder = \"Selecione uma data\",\n disabled = false,\n minDate,\n maxDate,\n dateFormat,\n locale = ptBR,\n className,\n error = false,\n showTime = false,\n timeFormat = \"24h\",\n minuteStep = 5,\n defaultTime = \"09:00\",\n id,\n name,\n}, ref) => {\n const [value, setValue] = useControllableValue<Date>(valueProp, defaultValue, onChange);\n const [open, setOpen] = React.useState(false);\n const [inputValue, setInputValue] = React.useState(\"\");\n const [isInvalid, setIsInvalid] = React.useState(false);\n\n // Formato padrão baseado em showTime\n const displayFormat = dateFormat || (showTime ? \"dd/MM/yyyy HH:mm\" : \"dd/MM/yyyy\");\n\n // Formatos aceitos para parsing\n const parseFormats = React.useMemo(() => {\n if (showTime) {\n return [\n \"dd/MM/yyyy HH:mm\",\n \"dd/MM/yyyy HH:mm:ss\",\n \"dd/MM/yy HH:mm\",\n \"d/M/yyyy HH:mm\",\n \"d/M/yy HH:mm\",\n ];\n }\n return [\n \"dd/MM/yyyy\",\n \"dd/MM/yy\",\n \"d/M/yyyy\",\n \"d/M/yy\",\n \"ddMMyyyy\",\n \"ddMMyy\",\n ];\n }, [showTime]);\n\n // Sincroniza inputValue com value\n React.useEffect(() => {\n if (value) {\n setInputValue(format(value, displayFormat, { locale }));\n setIsInvalid(false);\n } else {\n setInputValue(\"\");\n setIsInvalid(false);\n }\n }, [value, displayFormat, locale]);\n\n // Extrai hora/minuto do valor atual\n const currentTime = React.useMemo(() => {\n if (!value) return defaultTime;\n const hours = value.getHours().toString().padStart(2, \"0\");\n const minutes = value.getMinutes().toString().padStart(2, \"0\");\n return `${hours}:${minutes}`;\n }, [value, defaultTime]);\n\n // Handler para seleção de data\n const handleDateSelect = (date: Date | undefined) => {\n if (disabled) return;\n if (!date) {\n setValue(undefined);\n return;\n }\n\n if (showTime) {\n // Preserva o horário atual ou usa o padrão\n const [hours, minutes] = currentTime.split(\":\").map(Number);\n date.setHours(hours, minutes, 0, 0);\n } else {\n // Sem hora, zera o horário\n date.setHours(0, 0, 0, 0);\n }\n\n setValue(date);\n\n // Fecha o popover se não tiver seleção de hora\n if (!showTime) {\n setOpen(false);\n }\n };\n\n // Handler para mudança de hora\n const handleTimeChange = (time: string) => {\n if (!value) {\n // Se não tem data, cria uma nova com a data de hoje\n const today = new Date();\n const [hours, minutes] = time.split(\":\").map(Number);\n today.setHours(hours, minutes, 0, 0);\n setValue(today);\n } else {\n // Atualiza apenas o horário\n const newDate = new Date(value);\n const [hours, minutes] = time.split(\":\").map(Number);\n newDate.setHours(hours, minutes, 0, 0);\n setValue(newDate);\n }\n };\n\n // Parse da data digitada\n const parseInputDate = (input: string): Date | null => {\n const trimmed = input.trim();\n if (!trimmed) return null;\n\n // Tenta cada formato\n for (const fmt of parseFormats) {\n try {\n const parsed = parse(trimmed, fmt, new Date());\n if (isValid(parsed)) {\n // Valida limites\n if (minDate && parsed < minDate) continue;\n if (maxDate && parsed > maxDate) continue;\n return parsed;\n }\n } catch {\n continue;\n }\n }\n\n return null;\n };\n\n // Handler para input digitado\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (disabled) return;\n // Campo de data: só aceita dígitos, separadores de data e de hora.\n const newValue = e.target.value.replace(/[^\\d/:\\s]/g, \"\");\n setInputValue(newValue);\n setIsInvalid(false);\n };\n\n // Handler para blur do input (valida quando sai do campo)\n const handleInputBlur = () => {\n if (disabled) return;\n if (!inputValue.trim()) {\n setValue(undefined);\n setIsInvalid(false);\n return;\n }\n\n const parsed = parseInputDate(inputValue);\n if (parsed) {\n setValue(parsed);\n setIsInvalid(false);\n } else {\n setIsInvalid(true);\n // Mantém o inputValue para que o usuário possa corrigir\n }\n };\n\n // Handler para Enter no input\n const handleInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n handleInputBlur();\n if (!isInvalid) {\n setOpen(true); // Abre o calendário após validar\n }\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n // Restaura o valor original\n if (value) {\n setInputValue(format(value, displayFormat, { locale }));\n } else {\n setInputValue(\"\");\n }\n setIsInvalid(false);\n }\n };\n\n // Handler para limpar\n const handleClear = (e: React.MouseEvent) => {\n e.stopPropagation();\n setValue(undefined);\n setInputValue(\"\");\n setIsInvalid(false);\n };\n\n return (\n <Popover open={!disabled && open} onOpenChange={(o) => { if (!disabled) setOpen(o); }}>\n <div className=\"relative w-full\">\n <Input\n ref={ref}\n id={id}\n name={name}\n value={inputValue}\n onChange={handleInputChange}\n onBlur={handleInputBlur}\n onKeyDown={handleInputKeyDown}\n placeholder={placeholder}\n disabled={disabled}\n aria-invalid={error || isInvalid}\n className={cn(\n \"pr-20\",\n (error || isInvalid) && \"border-destructive focus-visible:ring-destructive/20\",\n className\n )}\n />\n <div className=\"absolute inset-y-0 right-0 flex items-center gap-1 pr-1\">\n {inputValue && !disabled && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 w-7 p-0 hover:bg-transparent\"\n onClick={handleClear}\n tabIndex={-1}\n >\n <X className=\"h-4 w-4 text-muted-foreground hover:text-foreground\" />\n <span className=\"sr-only\">Limpar</span>\n </Button>\n )}\n <PopoverTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 w-7 p-0 hover:bg-transparent\"\n disabled={disabled}\n aria-label=\"Abrir calendário\"\n >\n <CalendarIcon className=\"h-4 w-4 text-muted-foreground\" />\n </Button>\n </PopoverTrigger>\n </div>\n </div>\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\n <Calendar\n mode=\"single\"\n selected={value}\n onSelect={handleDateSelect}\n disabled={(date) => {\n if (minDate && date < minDate) return true;\n if (maxDate && date > maxDate) return true;\n return false;\n }}\n locale={locale}\n autoFocus\n defaultMonth={value || undefined}\n />\n\n {showTime && (\n <div className=\"border-t p-3\">\n <TimePicker\n value={currentTime}\n onChange={handleTimeChange}\n format={timeFormat}\n minuteStep={minuteStep}\n variant=\"inline\"\n showIcon\n />\n </div>\n )}\n\n {showTime && (\n <div className=\"border-t p-3 flex justify-end\">\n <Button\n size=\"sm\"\n onClick={() => setOpen(false)}\n >\n Confirmar\n </Button>\n </div>\n )}\n </PopoverContent>\n </Popover>\n );\n});\n\nDatePicker.displayName = \"DatePicker\";\n\nexport { DatePicker };\n\n"],"names":["DatePicker","React","valueProp","defaultValue","onChange","placeholder","disabled","minDate","maxDate","dateFormat","locale","ptBR","className","error","showTime","timeFormat","minuteStep","defaultTime","id","name","ref","value","setValue","useControllableValue","open","setOpen","inputValue","setInputValue","isInvalid","setIsInvalid","displayFormat","parseFormats","format","currentTime","hours","minutes","handleDateSelect","date","handleTimeChange","time","newDate","today","parseInputDate","input","trimmed","fmt","parsed","parse","isValid","handleInputChange","newValue","handleInputBlur","handleInputKeyDown","handleClear","jsxs","Popover","o","jsx","Input","cn","Button","X","PopoverTrigger","CalendarIcon","PopoverContent","Calendar","TimePicker"],"mappings":"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"}