@etus/ui 0.4.0-beta.4 → 0.4.0-beta.6

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 (61) hide show
  1. package/dist/{chunk-F6ZKBK5B.js → chunk-5GE3BQA7.js} +9 -4
  2. package/dist/chunk-5GE3BQA7.js.map +1 -0
  3. package/dist/{chunk-3RJEA2MM.js → chunk-6HEURMY3.js} +102 -65
  4. package/dist/chunk-6HEURMY3.js.map +1 -0
  5. package/dist/{chunk-ZS2WS5NJ.js → chunk-AVR3LVOQ.js} +48 -3
  6. package/dist/chunk-AVR3LVOQ.js.map +1 -0
  7. package/dist/{chunk-AB3S55W5.js → chunk-HT5XM6XK.js} +3 -3
  8. package/dist/{chunk-AB3S55W5.js.map → chunk-HT5XM6XK.js.map} +1 -1
  9. package/dist/{chunk-ICM45N2K.js → chunk-JONTKXGK.js} +24 -22
  10. package/dist/chunk-JONTKXGK.js.map +1 -0
  11. package/dist/{chunk-XXFKDEFH.js → chunk-JUTPDS4E.js} +7 -11
  12. package/dist/chunk-JUTPDS4E.js.map +1 -0
  13. package/dist/{chunk-DDR24GOP.js → chunk-L3Z5FAJE.js} +67 -51
  14. package/dist/chunk-L3Z5FAJE.js.map +1 -0
  15. package/dist/{chunk-RVUO7SDG.js → chunk-LS3WD6IZ.js} +63 -28
  16. package/dist/chunk-LS3WD6IZ.js.map +1 -0
  17. package/dist/{chunk-5ZKKXLPF.js → chunk-VPNFYQBL.js} +10 -15
  18. package/dist/chunk-VPNFYQBL.js.map +1 -0
  19. package/dist/{chunk-5YDFC74M.js → chunk-XD5LE64P.js} +7 -6
  20. package/dist/chunk-XD5LE64P.js.map +1 -0
  21. package/dist/{chunk-CSXT7SKR.js → chunk-YCEZH35U.js} +18 -4
  22. package/dist/chunk-YCEZH35U.js.map +1 -0
  23. package/dist/{chunk-2D6OFVPN.js → chunk-YWA63YN3.js} +22 -2
  24. package/dist/chunk-YWA63YN3.js.map +1 -0
  25. package/dist/components/advanced/index.js +4 -4
  26. package/dist/components/data-display/ChartCard/index.js +1 -3
  27. package/dist/components/data-display/DashboardFilterbar/index.js +1 -1
  28. package/dist/components/data-display/ImageGallery/index.js +8 -1
  29. package/dist/components/data-display/index.js +15 -15
  30. package/dist/components/feedback/Modal/index.js +1 -1
  31. package/dist/components/feedback/Notification/index.js +1 -1
  32. package/dist/components/feedback/index.js +4 -4
  33. package/dist/components/forms/ColorPicker/index.js +1 -1
  34. package/dist/components/forms/DatePicker/index.js +1 -1
  35. package/dist/components/forms/DateRangePicker/index.js +1 -1
  36. package/dist/components/forms/index.js +14 -14
  37. package/dist/components/index.js +70 -70
  38. package/dist/components/layout/Panel/index.js +2 -1
  39. package/dist/components/layout/index.js +3 -3
  40. package/dist/components/navigation/Header/index.js +1 -1
  41. package/dist/components/navigation/Menu/index.js +2 -1
  42. package/dist/components/navigation/Sidebar/index.js +1 -1
  43. package/dist/components/navigation/Toolbar/index.js +1 -1
  44. package/dist/components/navigation/index.js +8 -7
  45. package/dist/components/primitives/index.js +8 -8
  46. package/dist/components/workflow/index.js +7 -7
  47. package/dist/index.d.ts +181 -64
  48. package/dist/index.js +70 -70
  49. package/dist/styles.css +26 -15
  50. package/package.json +2 -2
  51. package/dist/chunk-2D6OFVPN.js.map +0 -1
  52. package/dist/chunk-3RJEA2MM.js.map +0 -1
  53. package/dist/chunk-5YDFC74M.js.map +0 -1
  54. package/dist/chunk-5ZKKXLPF.js.map +0 -1
  55. package/dist/chunk-CSXT7SKR.js.map +0 -1
  56. package/dist/chunk-DDR24GOP.js.map +0 -1
  57. package/dist/chunk-F6ZKBK5B.js.map +0 -1
  58. package/dist/chunk-ICM45N2K.js.map +0 -1
  59. package/dist/chunk-RVUO7SDG.js.map +0 -1
  60. package/dist/chunk-XXFKDEFH.js.map +0 -1
  61. package/dist/chunk-ZS2WS5NJ.js.map +0 -1
@@ -17,7 +17,7 @@ var notificationVariants = cva(
17
17
  },
18
18
  read: {
19
19
  true: "bg-[color:var(--notification-bg-read)]",
20
- false: "bg-[color:var(--notification-bg-unread)]/50"
20
+ false: "bg-[color:var(--notification-bg-unread)]"
21
21
  },
22
22
  interactive: {
23
23
  true: "cursor-pointer hover:bg-[color:var(--notification-bg-hover)] focus-visible:bg-[color:var(--notification-bg-hover)] focus-visible:outline-none",
@@ -32,7 +32,7 @@ var notificationVariants = cva(
32
32
  }
33
33
  );
34
34
  var unreadDotVariants = cva(
35
- "absolute left-[var(--notification-dot-left)] top-[var(--notification-dot-top)] size-[var(--notification-dot-size)] rounded-full",
35
+ "shrink-0 size-[var(--notification-dot-size)] rounded-full",
36
36
  {
37
37
  variants: {
38
38
  variant: {
@@ -114,14 +114,6 @@ function Notification({
114
114
  onKeyDown: handleKeyDown,
115
115
  ...props,
116
116
  children: [
117
- !read && /* @__PURE__ */ jsx(
118
- "span",
119
- {
120
- "aria-hidden": "true",
121
- className: cn(unreadDotVariants({ variant })),
122
- "data-slot": "notification-unread-dot"
123
- }
124
- ),
125
117
  /* @__PURE__ */ jsx("div", { className: "flex-shrink-0", "data-slot": "notification-media", children: icon ? /* @__PURE__ */ jsx(
126
118
  "div",
127
119
  {
@@ -135,18 +127,28 @@ function Notification({
135
127
  ] }) : null }),
136
128
  /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", "data-slot": "notification-content", children: [
137
129
  /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-2", children: [
138
- /* @__PURE__ */ jsx(
139
- "p",
140
- {
141
- className: "text-foreground line-clamp-2 text-sm font-medium",
142
- "data-slot": "notification-title",
143
- children: title
144
- }
145
- ),
130
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-[var(--notification-dot-gap)]", children: [
131
+ !read && /* @__PURE__ */ jsx(
132
+ "span",
133
+ {
134
+ "aria-hidden": "true",
135
+ className: cn(unreadDotVariants({ variant })),
136
+ "data-slot": "notification-unread-dot"
137
+ }
138
+ ),
139
+ /* @__PURE__ */ jsx(
140
+ "p",
141
+ {
142
+ className: "text-foreground line-clamp-2 min-w-0 text-sm font-medium",
143
+ "data-slot": "notification-title",
144
+ children: title
145
+ }
146
+ )
147
+ ] }),
146
148
  formattedTimestamp && /* @__PURE__ */ jsx(
147
149
  "time",
148
150
  {
149
- className: "text-muted-foreground shrink-0 text-xs",
151
+ className: "text-muted-foreground shrink-0 text-2xs font-semibold",
150
152
  "data-slot": "notification-timestamp",
151
153
  dateTime: timestamp instanceof Date ? timestamp.toISOString() : void 0,
152
154
  children: formattedTimestamp
@@ -156,7 +158,7 @@ function Notification({
156
158
  description && /* @__PURE__ */ jsx(
157
159
  "p",
158
160
  {
159
- className: "text-muted-foreground mt-0.5 line-clamp-2 text-sm",
161
+ className: "text-muted-foreground mt-0.5 line-clamp-2 text-xs",
160
162
  "data-slot": "notification-description",
161
163
  children: description
162
164
  }
@@ -221,5 +223,5 @@ function NotificationDismissButton({
221
223
  }
222
224
 
223
225
  export { Notification, NotificationDismissButton, notificationVariants, unreadDotVariants };
224
- //# sourceMappingURL=chunk-ICM45N2K.js.map
225
- //# sourceMappingURL=chunk-ICM45N2K.js.map
226
+ //# sourceMappingURL=chunk-JONTKXGK.js.map
227
+ //# sourceMappingURL=chunk-JONTKXGK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/feedback/Notification/Notification.variants.ts","../src/components/feedback/Notification/Notification.tsx"],"names":[],"mappings":"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","file":"chunk-JONTKXGK.js","sourcesContent":["import { cva } from \"class-variance-authority\"\n\n/**\n * Notification variant styles using CVA\n * Individual notification items for lists, dropdowns, or feeds\n */\nexport const notificationVariants = cva(\n \"relative flex gap-[var(--notification-root-gap)] p-[var(--notification-root-padding)] transition-colors\",\n {\n variants: {\n variant: {\n default: \"\",\n info: \"\",\n success: \"\",\n warning: \"\",\n error: \"\",\n },\n read: {\n true: \"bg-[color:var(--notification-bg-read)]\",\n false: \"bg-[color:var(--notification-bg-unread)]\",\n },\n interactive: {\n true: \"cursor-pointer hover:bg-[color:var(--notification-bg-hover)] focus-visible:bg-[color:var(--notification-bg-hover)] focus-visible:outline-none\",\n false: \"\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n read: false,\n interactive: false,\n },\n }\n)\n\n/**\n * Unread indicator dot styles\n */\nexport const unreadDotVariants = cva(\n \"shrink-0 size-[var(--notification-dot-size)] rounded-full\",\n {\n variants: {\n variant: {\n default: \"bg-[color:var(--notification-dot-color-default)]\",\n info: \"bg-[color:var(--notification-dot-color-info)]\",\n success: \"bg-[color:var(--notification-dot-color-success)]\",\n warning: \"bg-[color:var(--notification-dot-color-warning)]\",\n error: \"bg-[color:var(--notification-dot-color-error)]\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n","import type { NotificationProps, NotificationVariant } from \"./Notification.types\"\n\nimport { Check, Trash2, X } from \"lucide-react\"\n\nimport { cn } from \"../../../lib/utils\"\nimport { Avatar, AvatarFallback, AvatarImage } from \"../../primitives/Avatar\"\nimport { notificationVariants, unreadDotVariants } from \"./Notification.variants\"\n\n/**\n * Format a timestamp into a relative or absolute string\n */\nfunction formatTimestamp(timestamp: Date | string | undefined): string {\n if (!timestamp) return \"\"\n if (typeof timestamp === \"string\") return timestamp\n return timestamp.toLocaleString()\n}\n\n/**\n * Notification component for individual notification items\n *\n * Used in lists, dropdowns, or feeds. Unlike Toast which is temporary\n * and global, Notification is persistent and associated with the user.\n *\n * @example\n * ```tsx\n * <Notification\n * title=\"Nova mensagem\"\n * description=\"Voce recebeu uma nova mensagem de Maria.\"\n * timestamp=\"5 min atras\"\n * />\n * ```\n */\nfunction Notification({\n className,\n variant = \"default\",\n title,\n description,\n timestamp,\n read = false,\n icon,\n avatar,\n avatarSrc,\n avatarFallback,\n onClick,\n onMarkAsRead,\n onDelete,\n actions,\n ...props\n}: NotificationProps) {\n const isInteractive = Boolean(onClick)\n const formattedTimestamp = formatTimestamp(timestamp)\n const showAvatar = Boolean(avatar ?? avatarSrc ?? avatarFallback)\n const showActions = Boolean(onMarkAsRead ?? onDelete ?? actions)\n\n const handleClick = () => {\n if (onClick) {\n onClick()\n }\n }\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLElement>) => {\n if (isInteractive && (event.key === \"Enter\" || event.key === \" \")) {\n event.preventDefault()\n onClick?.()\n }\n if (event.key === \"Delete\" && onDelete) {\n event.preventDefault()\n onDelete()\n }\n }\n\n const handleMarkAsRead = (event: React.MouseEvent) => {\n event.stopPropagation()\n onMarkAsRead?.()\n }\n\n const handleDelete = (event: React.MouseEvent) => {\n event.stopPropagation()\n onDelete?.()\n }\n\n return (\n <article\n className={cn(\n notificationVariants({ variant, read, interactive: isInteractive }),\n className\n )}\n aria-label={`${read ? \"\" : \"Unread: \"}${title}${description ? `. ${description}` : \"\"}${formattedTimestamp ? `. ${formattedTimestamp}` : \"\"}`}\n data-slot=\"notification\"\n data-unread={!read}\n data-variant={variant}\n role=\"article\"\n tabIndex={isInteractive ? 0 : undefined}\n onClick={isInteractive ? handleClick : undefined}\n onKeyDown={handleKeyDown}\n {...props}\n >\n {/* Icon or Avatar */}\n <div className=\"flex-shrink-0\" data-slot=\"notification-media\">\n {icon ? (\n <div\n aria-hidden=\"true\"\n className=\"flex size-10 items-center justify-center\"\n >\n {icon}\n </div>\n ) : showAvatar ? (\n avatar ?? (\n <Avatar size=\"sm\">\n {avatarSrc && (\n <AvatarImage alt=\"\" src={avatarSrc} />\n )}\n <AvatarFallback>{avatarFallback}</AvatarFallback>\n </Avatar>\n )\n ) : null}\n </div>\n\n {/* Content */}\n <div className=\"min-w-0 flex-1\" data-slot=\"notification-content\">\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"flex min-w-0 items-center gap-[var(--notification-dot-gap)]\">\n {!read && (\n <span\n aria-hidden=\"true\"\n className={cn(unreadDotVariants({ variant }))}\n data-slot=\"notification-unread-dot\"\n />\n )}\n <p\n className=\"text-foreground line-clamp-2 min-w-0 text-sm font-medium\"\n data-slot=\"notification-title\"\n >\n {title}\n </p>\n </div>\n {formattedTimestamp && (\n <time\n className=\"text-muted-foreground shrink-0 text-2xs font-semibold\"\n data-slot=\"notification-timestamp\"\n dateTime={timestamp instanceof Date ? timestamp.toISOString() : undefined}\n >\n {formattedTimestamp}\n </time>\n )}\n </div>\n {description && (\n <p\n className=\"text-muted-foreground mt-0.5 line-clamp-2 text-xs\"\n data-slot=\"notification-description\"\n >\n {description}\n </p>\n )}\n {actions && (\n <div className=\"mt-2\" data-slot=\"notification-actions\">\n {actions}\n </div>\n )}\n </div>\n\n {/* Built-in action buttons */}\n {showActions && !actions && (\n <div\n className=\"flex shrink-0 items-center gap-1\"\n data-slot=\"notification-action-buttons\"\n >\n {onMarkAsRead && !read && (\n <button\n aria-label=\"Mark as read\"\n className=\"text-muted-foreground hover:text-foreground hover:bg-accent rounded-md p-1.5 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n data-slot=\"notification-mark-read\"\n type=\"button\"\n onClick={handleMarkAsRead}\n >\n <Check aria-hidden=\"true\" className=\"size-4\" />\n </button>\n )}\n {onDelete && (\n <button\n aria-label=\"Delete notification\"\n className=\"text-muted-foreground hover:text-destructive hover:bg-destructive/10 rounded-md p-1.5 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n data-slot=\"notification-delete\"\n type=\"button\"\n onClick={handleDelete}\n >\n <Trash2 aria-hidden=\"true\" className=\"size-4\" />\n </button>\n )}\n </div>\n )}\n </article>\n )\n}\n\n/**\n * NotificationDismissButton for use within custom actions\n */\nfunction NotificationDismissButton({\n className,\n onClick,\n ...props\n}: React.ComponentPropsWithoutRef<\"button\">) {\n return (\n <button\n className={cn(\n \"text-muted-foreground hover:text-foreground rounded-md p-1 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n className\n )}\n aria-label=\"Dismiss\"\n data-slot=\"notification-dismiss\"\n type=\"button\"\n onClick={onClick}\n {...props}\n >\n <X aria-hidden=\"true\" className=\"size-4\" />\n </button>\n )\n}\n\nexport { Notification, NotificationDismissButton, notificationVariants, unreadDotVariants }\nexport type { NotificationProps, NotificationVariant }\n"]}
@@ -1,5 +1,5 @@
1
+ import { ScrollArea } from './chunk-CNRV2IGH.js';
1
2
  import { cn } from './chunk-HRNDJU7D.js';
2
- import 'react';
3
3
  import { cva } from 'class-variance-authority';
4
4
  import { jsx } from 'react/jsx-runtime';
5
5
 
@@ -69,7 +69,7 @@ var panelHeaderVariants = cva([
69
69
  var panelContentVariants = cva(["flex-1"], {
70
70
  variants: {
71
71
  scrollable: {
72
- true: "overflow-auto",
72
+ true: "min-h-0",
73
73
  false: ""
74
74
  }
75
75
  },
@@ -85,9 +85,6 @@ function Panel({
85
85
  variant,
86
86
  size,
87
87
  position,
88
- collapsible,
89
- collapsed,
90
- onCollapse: _onCollapse,
91
88
  className,
92
89
  ...props
93
90
  }) {
@@ -95,10 +92,7 @@ function Panel({
95
92
  Component,
96
93
  {
97
94
  className: cn(panelVariants({ variant, size, position }), className),
98
- "data-collapsed": collapsed ?? void 0,
99
- "data-collapsible": collapsible ?? void 0,
100
95
  "data-slot": "panel",
101
- "data-state": collapsible ? collapsed ? "collapsed" : "expanded" : void 0,
102
96
  ...props
103
97
  }
104
98
  );
@@ -116,6 +110,7 @@ function PanelHeader({ className, ...props }) {
116
110
  function PanelContent({
117
111
  scrollable = false,
118
112
  className,
113
+ children,
119
114
  ...props
120
115
  }) {
121
116
  return /* @__PURE__ */ jsx(
@@ -123,7 +118,8 @@ function PanelContent({
123
118
  {
124
119
  className: cn(panelContentVariants({ scrollable }), className),
125
120
  "data-slot": "panel-content",
126
- ...props
121
+ ...props,
122
+ children: scrollable ? /* @__PURE__ */ jsx(ScrollArea, { className: "size-full", children }) : children
127
123
  }
128
124
  );
129
125
  }
@@ -139,5 +135,5 @@ function PanelFooter({ className, ...props }) {
139
135
  }
140
136
 
141
137
  export { Panel, PanelContent, PanelFooter, PanelHeader, panelContentVariants, panelFooterVariants, panelHeaderVariants, panelVariants };
142
- //# sourceMappingURL=chunk-XXFKDEFH.js.map
143
- //# sourceMappingURL=chunk-XXFKDEFH.js.map
138
+ //# sourceMappingURL=chunk-JUTPDS4E.js.map
139
+ //# sourceMappingURL=chunk-JUTPDS4E.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/layout/Panel/Panel.variants.ts","../src/components/layout/Panel/Panel.tsx"],"names":[],"mappings":"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","file":"chunk-JUTPDS4E.js","sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\"\n\n/**\n * Panel variant styles\n * Layout container for sidebars, inspectors, and section panels\n */\nexport const panelVariants = cva(\n [\"flex flex-col rounded-[var(--panel-root-radius)]\"],\n {\n variants: {\n /**\n * Visual variant of the panel\n * - default: Background with subtle border\n * - subtle: Muted background, no border\n * - outlined: Border only, no background\n * - elevated: With light shadow\n * - inset: Inner shadow effect\n */\n variant: {\n default: \"bg-[color:var(--panel-variant-default-bg)] border border-[color:var(--panel-root-border-color)]\",\n subtle: \"bg-[color:var(--panel-variant-subtle-bg)]\",\n outlined: \"border border-[color:var(--panel-root-border-color)] bg-transparent\",\n elevated: \"bg-[color:var(--panel-variant-elevated-bg)] shadow-[var(--panel-root-shadow)]\",\n inset: \"bg-[color:var(--panel-variant-subtle-bg)] shadow-inner\",\n },\n /**\n * Width of the panel\n * - xs: 240px (compact sidebar)\n * - sm: 280px (standard sidebar)\n * - md: 320px (medium panel)\n * - lg: 400px (wide panel)\n * - xl: 480px (extra wide panel)\n * - auto: Content width\n * - full: 100% width\n */\n size: {\n xs: \"w-[var(--panel-size-xs)]\",\n sm: \"w-[var(--panel-size-sm)]\",\n md: \"w-[var(--panel-size-md)]\",\n lg: \"w-[var(--panel-size-lg)]\",\n xl: \"w-[var(--panel-size-xl)]\",\n auto: \"w-auto\",\n full: \"w-full\",\n },\n /**\n * Position variant for styling based on panel placement\n * - left: Left-positioned panel (sidebar)\n * - right: Right-positioned panel (inspector)\n * - top: Top-positioned panel\n * - bottom: Bottom-positioned panel\n * - center: Centered panel\n */\n position: {\n left: \"border-r\",\n right: \"border-l\",\n top: \"border-b\",\n bottom: \"border-t\",\n center: \"\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"auto\",\n },\n})\n\n/**\n * PanelHeader variant styles\n * Header section with padding and shrink behavior\n */\nexport const panelHeaderVariants = cva([\n \"px-[var(--panel-header-padding-x)] py-[var(--panel-header-padding-y)] shrink-0\",\n])\n\n/**\n * PanelContent variant styles\n * Main content area with flex-grow. When `scrollable`, the content is routed\n * through the ScrollArea component; `min-h-0` lets the flex child shrink so the\n * ScrollArea can establish its own scroll viewport.\n */\nexport const panelContentVariants = cva([\"flex-1\"], {\n variants: {\n scrollable: {\n true: \"min-h-0\",\n false: \"\",\n },\n },\n defaultVariants: {\n scrollable: false,\n },\n})\n\n/**\n * PanelFooter variant styles\n * Footer section with padding and shrink behavior\n */\nexport const panelFooterVariants = cva([\n \"px-[var(--panel-footer-padding-x)] py-[var(--panel-footer-padding-y)] shrink-0\",\n])\n\nexport type PanelVariantProps = VariantProps<typeof panelVariants>\nexport type PanelContentVariantProps = VariantProps<typeof panelContentVariants>\n","import type {\n PanelContentProps,\n PanelFooterProps,\n PanelHeaderProps,\n PanelProps,\n} from \"./Panel.types\"\n\nimport { cn } from \"../../../lib/utils\"\nimport { ScrollArea } from \"../ScrollArea\"\nimport {\n panelContentVariants,\n panelFooterVariants,\n panelHeaderVariants,\n panelVariants,\n} from \"./Panel.variants\"\n\nfunction Panel({\n as: Component = \"div\",\n variant,\n size,\n position,\n className,\n ...props\n}: PanelProps) {\n return (\n <Component\n className={cn(panelVariants({ variant, size, position }), className)}\n data-slot=\"panel\"\n {...props}\n />\n )\n}\n\nfunction PanelHeader({ className, ...props }: PanelHeaderProps) {\n return (\n <div\n className={cn(panelHeaderVariants(), className)}\n data-slot=\"panel-header\"\n {...props}\n />\n )\n}\n\nfunction PanelContent({\n scrollable = false,\n className,\n children,\n ...props\n}: PanelContentProps) {\n return (\n <div\n className={cn(panelContentVariants({ scrollable }), className)}\n data-slot=\"panel-content\"\n {...props}\n >\n {scrollable ? <ScrollArea className=\"size-full\">{children}</ScrollArea> : children}\n </div>\n )\n}\n\nfunction PanelFooter({ className, ...props }: PanelFooterProps) {\n return (\n <div\n className={cn(panelFooterVariants(), className)}\n data-slot=\"panel-footer\"\n {...props}\n />\n )\n}\n\nexport { Panel, PanelContent, PanelFooter, PanelHeader }\n"]}
@@ -1,4 +1,3 @@
1
- import { LineChart } from './chunk-XV6NXXXP.js';
2
1
  import { SkeletonLoader } from './chunk-QHKOBGLW.js';
3
2
  import { Badge } from './chunk-TNROOKX3.js';
4
3
  import { cn } from './chunk-HRNDJU7D.js';
@@ -7,13 +6,13 @@ import { cva } from 'class-variance-authority';
7
6
  import { jsxs, jsx } from 'react/jsx-runtime';
8
7
 
9
8
  var chartCardVariants = cva(
10
- "transition",
9
+ "rounded-[var(--chart-card-radius)] bg-[color:var(--chart-card-bg)] px-[var(--chart-card-padding-x)] pt-[var(--chart-card-padding-top)] pb-[var(--chart-card-padding-bottom)] text-[color:var(--chart-card-fg)] transition",
11
10
  {
12
11
  variants: {
13
12
  variant: {
14
13
  default: "",
15
- outlined: "border border-border rounded-lg p-4",
16
- elevated: "bg-card rounded-lg p-4 shadow-sm"
14
+ outlined: "border border-[color:var(--chart-card-border)]",
15
+ elevated: "shadow-sm"
17
16
  }
18
17
  },
19
18
  defaultVariants: {
@@ -25,19 +24,19 @@ var chartCardHeaderVariants = cva(
25
24
  "flex items-center justify-between gap-x-2"
26
25
  );
27
26
  var chartCardTitleVariants = cva(
28
- "font-bold text-foreground sm:text-sm"
27
+ "text-[length:var(--chart-card-title-size)] font-[var(--chart-card-title-weight)] leading-[var(--chart-card-title-line-height)] text-[color:var(--chart-card-title-color)]"
29
28
  );
30
29
  var chartCardValueContainerVariants = cva(
31
30
  "mt-2 flex items-baseline justify-between"
32
31
  );
33
32
  var chartCardValueVariants = cva(
34
- "text-xl text-foreground"
33
+ "text-[length:var(--chart-card-value-size)] text-[color:var(--chart-card-value-color)]"
35
34
  );
36
35
  var chartCardPreviousValueVariants = cva(
37
- "text-sm text-muted-foreground"
36
+ "text-sm text-[color:var(--chart-card-previous-color)]"
38
37
  );
39
38
  var chartCardChartVariants = cva(
40
- "mt-6"
39
+ "mt-[var(--chart-card-gap)] h-[var(--chart-card-chart-height)] [&>*]:h-full"
41
40
  );
42
41
  var defaultFormatter = (value) => String(value);
43
42
  function getBadgeColor(value) {
@@ -56,20 +55,22 @@ function formatPercentage(value) {
56
55
  return `${sign}${(value * 100).toFixed(1)}%`;
57
56
  }
58
57
  function ChartCard({
59
- title,
60
- data,
61
- config,
62
- valueFormatter = defaultFormatter,
58
+ badge,
59
+ chart,
60
+ chartHeight,
61
+ className,
63
62
  comparisonPeriod = "no-comparison",
63
+ data,
64
+ emptyMessage,
65
+ featuredIcon,
66
+ footer,
67
+ headerAction,
64
68
  isThumbnail = false,
65
69
  loading = false,
66
- badge,
67
- chartHeight = "h-32",
68
- showTooltip = true,
69
- xAxisKey = "formattedDate",
70
- emptyMessage,
70
+ tabs,
71
+ title,
72
+ valueFormatter = defaultFormatter,
71
73
  variant,
72
- className,
73
74
  ...props
74
75
  }) {
75
76
  const isEmpty = !loading && data.length === 0;
@@ -85,10 +86,11 @@ function ChartCard({
85
86
  }
86
87
  return (totalValue - totalPreviousValue) / totalPreviousValue;
87
88
  }, [comparisonPeriod, totalPreviousValue, totalValue]);
88
- const series = React.useMemo(() => {
89
- return comparisonPeriod === "no-comparison" ? ["value"] : ["value", "previousValue"];
90
- }, [comparisonPeriod]);
91
89
  const showComparison = comparisonPeriod !== "no-comparison";
90
+ const titleLead = /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2", children: [
91
+ featuredIcon && /* @__PURE__ */ jsx("span", { "data-slot": "chart-card-featured-icon", children: featuredIcon }),
92
+ /* @__PURE__ */ jsx("h3", { className: cn(chartCardTitleVariants()), "data-slot": "chart-card-title", children: title })
93
+ ] });
92
94
  if (isEmpty) {
93
95
  return /* @__PURE__ */ jsxs(
94
96
  "article",
@@ -99,14 +101,17 @@ function ChartCard({
99
101
  "data-slot": "chart-card",
100
102
  ...props,
101
103
  children: [
102
- /* @__PURE__ */ jsx("div", { className: cn(chartCardHeaderVariants()), children: /* @__PURE__ */ jsx("h3", { className: cn(chartCardTitleVariants()), children: title }) }),
104
+ /* @__PURE__ */ jsxs("div", { className: cn(chartCardHeaderVariants()), "data-slot": "chart-card-header", children: [
105
+ titleLead,
106
+ headerAction && /* @__PURE__ */ jsx("span", { "data-slot": "chart-card-header-action", children: headerAction })
107
+ ] }),
103
108
  /* @__PURE__ */ jsx(
104
109
  "div",
105
110
  {
106
111
  className: cn(
107
112
  chartCardChartVariants(),
108
113
  chartHeight,
109
- "flex items-center justify-center text-sm text-muted-foreground"
114
+ "flex items-center justify-center text-[length:var(--chart-card-empty-state-caption-size)] text-[color:var(--chart-card-empty-state-caption-color)]"
110
115
  ),
111
116
  "data-slot": "chart-card-empty",
112
117
  children: emptyMessage ?? "No data available"
@@ -125,11 +130,18 @@ function ChartCard({
125
130
  "data-slot": "chart-card",
126
131
  ...props,
127
132
  children: [
128
- /* @__PURE__ */ jsxs("div", { className: cn(chartCardHeaderVariants()), children: [
133
+ /* @__PURE__ */ jsxs("div", { className: cn(chartCardHeaderVariants()), "data-slot": "chart-card-header", children: [
129
134
  /* @__PURE__ */ jsx(SkeletonLoader, { className: "h-4 w-24" }),
130
135
  /* @__PURE__ */ jsx(SkeletonLoader, { className: "h-5 w-12" })
131
136
  ] }),
132
- /* @__PURE__ */ jsx("div", { className: cn(chartCardValueContainerVariants()), children: /* @__PURE__ */ jsx(SkeletonLoader, { className: "h-7 w-32" }) }),
137
+ /* @__PURE__ */ jsx(
138
+ "div",
139
+ {
140
+ className: cn(chartCardValueContainerVariants()),
141
+ "data-slot": "chart-card-value",
142
+ children: /* @__PURE__ */ jsx(SkeletonLoader, { className: "h-7 w-32" })
143
+ }
144
+ ),
133
145
  /* @__PURE__ */ jsx("div", { className: cn(chartCardChartVariants(), chartHeight), children: /* @__PURE__ */ jsx(SkeletonLoader, { className: "h-full w-full" }) })
134
146
  ]
135
147
  }
@@ -143,34 +155,38 @@ function ChartCard({
143
155
  "data-slot": "chart-card",
144
156
  ...props,
145
157
  children: [
146
- /* @__PURE__ */ jsx("div", { className: cn(chartCardHeaderVariants()), children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2", children: [
147
- /* @__PURE__ */ jsx("h3", { className: cn(chartCardTitleVariants()), children: title }),
148
- showComparison && (badge ?? /* @__PURE__ */ jsx(Badge, { color: getBadgeColor(evolution), size: "sm", children: formatPercentage(evolution) }))
149
- ] }) }),
150
- /* @__PURE__ */ jsxs("div", { className: cn(chartCardValueContainerVariants()), children: [
151
- /* @__PURE__ */ jsx("p", { className: cn(chartCardValueVariants()), children: valueFormatter(totalValue) }),
152
- showComparison && /* @__PURE__ */ jsxs("p", { className: cn(chartCardPreviousValueVariants()), children: [
153
- "from ",
154
- valueFormatter(totalPreviousValue)
155
- ] })
158
+ /* @__PURE__ */ jsxs("div", { className: cn(chartCardHeaderVariants()), "data-slot": "chart-card-header", children: [
159
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2", children: [
160
+ featuredIcon && /* @__PURE__ */ jsx("span", { "data-slot": "chart-card-featured-icon", children: featuredIcon }),
161
+ /* @__PURE__ */ jsx("h3", { className: cn(chartCardTitleVariants()), "data-slot": "chart-card-title", children: title }),
162
+ showComparison && (badge ?? /* @__PURE__ */ jsx(Badge, { color: getBadgeColor(evolution), size: "sm", children: formatPercentage(evolution) }))
163
+ ] }),
164
+ headerAction && /* @__PURE__ */ jsx("span", { "data-slot": "chart-card-header-action", children: headerAction })
156
165
  ] }),
157
- !isThumbnail && data.length > 0 && /* @__PURE__ */ jsx(
158
- LineChart,
166
+ /* @__PURE__ */ jsxs(
167
+ "div",
168
+ {
169
+ className: cn(chartCardValueContainerVariants()),
170
+ "data-slot": "chart-card-value",
171
+ children: [
172
+ /* @__PURE__ */ jsx("p", { className: cn(chartCardValueVariants()), children: valueFormatter(totalValue) }),
173
+ showComparison && /* @__PURE__ */ jsxs("p", { className: cn(chartCardPreviousValueVariants()), children: [
174
+ "from ",
175
+ valueFormatter(totalPreviousValue)
176
+ ] })
177
+ ]
178
+ }
179
+ ),
180
+ tabs && /* @__PURE__ */ jsx("div", { className: "mt-[var(--chart-card-gap)]", "data-slot": "chart-card-tabs", children: tabs }),
181
+ !isThumbnail && chart && /* @__PURE__ */ jsx(
182
+ "div",
159
183
  {
160
- autoMinValue: true,
161
- startEndOnly: true,
162
184
  className: cn(chartCardChartVariants(), chartHeight),
163
- config,
164
- data,
165
- series,
166
- showLegend: false,
167
- showTooltip,
168
- showYAxis: false,
169
- xAxisKey,
170
- xAxisTickFormatter: (value) => String(value),
171
- yAxisTickFormatter: (value) => valueFormatter(Number(value))
185
+ "data-slot": "chart-card-chart",
186
+ children: chart
172
187
  }
173
- )
188
+ ),
189
+ footer && /* @__PURE__ */ jsx("div", { className: "mt-[var(--chart-card-gap)]", "data-slot": "chart-card-footer", children: footer })
174
190
  ]
175
191
  }
176
192
  );
@@ -178,5 +194,5 @@ function ChartCard({
178
194
  ChartCard.displayName = "ChartCard";
179
195
 
180
196
  export { ChartCard, chartCardChartVariants, chartCardHeaderVariants, chartCardPreviousValueVariants, chartCardTitleVariants, chartCardValueContainerVariants, chartCardValueVariants, chartCardVariants };
181
- //# sourceMappingURL=chunk-DDR24GOP.js.map
182
- //# sourceMappingURL=chunk-DDR24GOP.js.map
197
+ //# sourceMappingURL=chunk-L3Z5FAJE.js.map
198
+ //# sourceMappingURL=chunk-L3Z5FAJE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/data-display/ChartCard/ChartCard.variants.ts","../src/components/data-display/ChartCard/ChartCard.tsx"],"names":[],"mappings":"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","file":"chunk-L3Z5FAJE.js","sourcesContent":["// ChartCard/ChartCard.variants.ts\nimport { cva } from \"class-variance-authority\"\n\n/**\n * ChartCard container variants.\n *\n * Consumes the `--chart-card-*` component tokens (DES-1253). The Figma container\n * is flat — background + radius + asymmetric padding, no border or shadow — so the\n * base styles render that container and `outlined` / `elevated` are code-only\n * extensions (documented in the README) layered on top.\n */\nexport const chartCardVariants = cva(\n \"rounded-[var(--chart-card-radius)] bg-[color:var(--chart-card-bg)] px-[var(--chart-card-padding-x)] pt-[var(--chart-card-padding-top)] pb-[var(--chart-card-padding-bottom)] text-[color:var(--chart-card-fg)] transition\",\n {\n variants: {\n variant: {\n default: \"\",\n outlined: \"border border-[color:var(--chart-card-border)]\",\n elevated: \"shadow-sm\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\n/**\n * ChartCard header (Title Row) — leading group (featured icon + title + badge)\n * and an optional trailing overflow action.\n */\nexport const chartCardHeaderVariants = cva(\n \"flex items-center justify-between gap-x-2\"\n)\n\n/**\n * ChartCard title — Figma Heading/H5 (18px / 24px / SemiBold), tokenised.\n */\nexport const chartCardTitleVariants = cva(\n \"text-[length:var(--chart-card-title-size)] font-[var(--chart-card-title-weight)] leading-[var(--chart-card-title-line-height)] text-[color:var(--chart-card-title-color)]\"\n)\n\n/**\n * ChartCard value container.\n */\nexport const chartCardValueContainerVariants = cva(\n \"mt-2 flex items-baseline justify-between\"\n)\n\n/**\n * ChartCard KPI value text — tokenised size + color.\n */\nexport const chartCardValueVariants = cva(\n \"text-[length:var(--chart-card-value-size)] text-[color:var(--chart-card-value-color)]\"\n)\n\n/**\n * ChartCard previous-value caption.\n */\nexport const chartCardPreviousValueVariants = cva(\n \"text-sm text-[color:var(--chart-card-previous-color)]\"\n)\n\n/**\n * ChartCard chart-slot wrapper — 24px row gap + tokenised area height\n * (`--chart-card-chart-height`). The injected chart fills the area via\n * `[&>*]:h-full`; the `chartHeight` prop overrides the height.\n */\nexport const chartCardChartVariants = cva(\n \"mt-[var(--chart-card-gap)] h-[var(--chart-card-chart-height)] [&>*]:h-full\"\n)\n","// ChartCard/ChartCard.tsx\n\"use client\"\n\nimport type { ChartCardProps, ChartCardValueFormatter } from \"./ChartCard.types\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"../../../lib/utils\"\nimport { Badge } from \"../../primitives/Badge\"\nimport { SkeletonLoader } from \"../../primitives/SkeletonLoader\"\nimport {\n chartCardChartVariants,\n chartCardHeaderVariants,\n chartCardPreviousValueVariants,\n chartCardTitleVariants,\n chartCardValueContainerVariants,\n chartCardValueVariants,\n chartCardVariants,\n} from \"./ChartCard.variants\"\n\n/**\n * Default value formatter (returns value as string)\n */\nconst defaultFormatter: ChartCardValueFormatter = (value) => String(value)\n\n/**\n * Get badge color based on evolution percentage\n */\nfunction getBadgeColor(value: number): \"destructive\" | \"muted\" | \"success\" | \"warning\" {\n if (value > 0) {\n return \"success\"\n } else if (value < 0) {\n if (value < -50) {\n return \"warning\"\n }\n return \"destructive\"\n }\n return \"muted\"\n}\n\n/**\n * Format percentage for display\n */\nfunction formatPercentage(value: number): string {\n const sign = value > 0 ? \"+\" : \"\"\n return `${sign}${(value * 100).toFixed(1)}%`\n}\n\n/**\n * ChartCard - Dashboard KPI widget with a chart-agnostic slot.\n *\n * Renders a KPI value with an auto evolution badge and optional comparison\n * period. The chart itself is **injected by the consumer** via the `chart`\n * slot — ChartCard ships no default chart (DES-1253). The Title Row exposes\n * `featuredIcon` + `headerAction` (overflow) slots, with optional `tabs` and\n * `footer` composition slots below.\n *\n * @example\n * ```tsx\n * const data = [\n * { formattedDate: \"01/01\", value: 1000, previousValue: 900 },\n * { formattedDate: \"02/01\", value: 1200, previousValue: 1100 },\n * ]\n *\n * <ChartCard\n * title=\"Revenue\"\n * data={data}\n * comparisonPeriod=\"previous-year\"\n * valueFormatter={(v) => `$${v.toLocaleString()}`}\n * chart={\n * <LineChart\n * className=\"h-full\"\n * data={data}\n * config={{ value: { label: \"Current\" } }}\n * series={[\"value\"]}\n * />\n * }\n * />\n * ```\n */\nfunction ChartCard({\n badge,\n chart,\n chartHeight,\n className,\n comparisonPeriod = \"no-comparison\",\n data,\n emptyMessage,\n featuredIcon,\n footer,\n headerAction,\n isThumbnail = false,\n loading = false,\n tabs,\n title,\n valueFormatter = defaultFormatter,\n variant,\n ...props\n}: ChartCardProps) {\n const isEmpty = !loading && data.length === 0\n\n // Calculate totals\n const totalValue = React.useMemo(() => {\n return data.reduce((acc, item) => acc + (item.value ?? 0), 0)\n }, [data])\n\n const totalPreviousValue = React.useMemo(() => {\n return data.reduce((acc, item) => acc + (item.previousValue ?? 0), 0)\n }, [data])\n\n // Calculate evolution percentage\n const evolution = React.useMemo(() => {\n if (comparisonPeriod === \"no-comparison\" || totalPreviousValue === 0) {\n return 0\n }\n return (totalValue - totalPreviousValue) / totalPreviousValue\n }, [comparisonPeriod, totalPreviousValue, totalValue])\n\n // Show comparison UI elements\n const showComparison = comparisonPeriod !== \"no-comparison\"\n\n // Title Row leading slots (featured icon + title), shared across states.\n const titleLead = (\n <div className=\"flex items-center gap-x-2\">\n {featuredIcon && (\n <span data-slot=\"chart-card-featured-icon\">{featuredIcon}</span>\n )}\n <h3 className={cn(chartCardTitleVariants())} data-slot=\"chart-card-title\">\n {title}\n </h3>\n </div>\n )\n\n // Empty state (DES-1254 item 3 — Figma Empty State)\n if (isEmpty) {\n return (\n <article\n aria-label={`${title}: empty`}\n className={cn(chartCardVariants({ variant }), className)}\n data-empty=\"true\"\n data-slot=\"chart-card\"\n {...props}\n >\n <div className={cn(chartCardHeaderVariants())} data-slot=\"chart-card-header\">\n {titleLead}\n {headerAction && (\n <span data-slot=\"chart-card-header-action\">{headerAction}</span>\n )}\n </div>\n <div\n className={cn(\n chartCardChartVariants(),\n chartHeight,\n \"flex items-center justify-center text-[length:var(--chart-card-empty-state-caption-size)] text-[color:var(--chart-card-empty-state-caption-color)]\"\n )}\n data-slot=\"chart-card-empty\"\n >\n {emptyMessage ?? \"No data available\"}\n </div>\n </article>\n )\n }\n\n // Loading state\n if (loading) {\n return (\n <article\n aria-busy=\"true\"\n className={cn(chartCardVariants({ variant }), className)}\n data-slot=\"chart-card\"\n {...props}\n >\n <div className={cn(chartCardHeaderVariants())} data-slot=\"chart-card-header\">\n <SkeletonLoader className=\"h-4 w-24\" />\n <SkeletonLoader className=\"h-5 w-12\" />\n </div>\n <div\n className={cn(chartCardValueContainerVariants())}\n data-slot=\"chart-card-value\"\n >\n <SkeletonLoader className=\"h-7 w-32\" />\n </div>\n <div className={cn(chartCardChartVariants(), chartHeight)}>\n <SkeletonLoader className=\"h-full w-full\" />\n </div>\n </article>\n )\n }\n\n return (\n <article\n aria-label={`${title}: ${valueFormatter(totalValue)}`}\n className={cn(chartCardVariants({ variant }), className)}\n data-slot=\"chart-card\"\n {...props}\n >\n {/* Title Row — featured icon + title + badge / overflow action */}\n <div className={cn(chartCardHeaderVariants())} data-slot=\"chart-card-header\">\n <div className=\"flex items-center gap-x-2\">\n {featuredIcon && (\n <span data-slot=\"chart-card-featured-icon\">{featuredIcon}</span>\n )}\n <h3 className={cn(chartCardTitleVariants())} data-slot=\"chart-card-title\">\n {title}\n </h3>\n {showComparison && (\n badge ?? (\n <Badge color={getBadgeColor(evolution)} size=\"sm\">\n {formatPercentage(evolution)}\n </Badge>\n )\n )}\n </div>\n {headerAction && (\n <span data-slot=\"chart-card-header-action\">{headerAction}</span>\n )}\n </div>\n\n {/* Value display */}\n <div\n className={cn(chartCardValueContainerVariants())}\n data-slot=\"chart-card-value\"\n >\n <p className={cn(chartCardValueVariants())}>\n {valueFormatter(totalValue)}\n </p>\n {showComparison && (\n <p className={cn(chartCardPreviousValueVariants())}>\n from {valueFormatter(totalPreviousValue)}\n </p>\n )}\n </div>\n\n {/* Tabs row slot (Figma showTabs) */}\n {tabs && (\n <div className=\"mt-[var(--chart-card-gap)]\" data-slot=\"chart-card-tabs\">\n {tabs}\n </div>\n )}\n\n {/* Chart slot — injected by the consumer (chart-agnostic) */}\n {!isThumbnail && chart && (\n <div\n className={cn(chartCardChartVariants(), chartHeight)}\n data-slot=\"chart-card-chart\"\n >\n {chart}\n </div>\n )}\n\n {/* Card Footer slot (Figma showCardFooter — trend + total) */}\n {footer && (\n <div className=\"mt-[var(--chart-card-gap)]\" data-slot=\"chart-card-footer\">\n {footer}\n </div>\n )}\n </article>\n )\n}\n\nChartCard.displayName = \"ChartCard\"\n\nexport { ChartCard }\n"]}
@@ -4,7 +4,7 @@ import { Popover, PopoverTrigger, PopoverContent } from './chunk-AFCSDND5.js';
4
4
  import { Button } from './chunk-ONQCNOLU.js';
5
5
  import { cn } from './chunk-HRNDJU7D.js';
6
6
  import { format, startOfDay, isBefore, isAfter, setMinutes, setHours } from 'date-fns';
7
- import { XIcon, CalendarIcon } from 'lucide-react';
7
+ import { CalendarIcon, XIcon } from 'lucide-react';
8
8
  import * as React from 'react';
9
9
  import { cva } from 'class-variance-authority';
10
10
  import { jsxs, jsx } from 'react/jsx-runtime';
@@ -40,6 +40,40 @@ var datePickerTriggerVariants = cva(
40
40
  }
41
41
  }
42
42
  );
43
+ var datePickerClearButtonVariants = cva(
44
+ [
45
+ "absolute top-1/2 inline-flex size-4 -translate-y-1/2 items-center justify-center rounded-sm outline-none",
46
+ "text-muted-foreground opacity-70 transition-opacity",
47
+ "hover:opacity-100 focus-visible:opacity-100",
48
+ "focus-visible:ring-[color:var(--date-picker-trigger-ring-primary)]/50 focus-visible:ring-[length:var(--date-picker-trigger-ring-width)]"
49
+ ],
50
+ {
51
+ variants: {
52
+ size: {
53
+ sm: "",
54
+ md: "",
55
+ lg: ""
56
+ },
57
+ variant: {
58
+ default: "",
59
+ filled: "",
60
+ flushed: ""
61
+ }
62
+ },
63
+ compoundVariants: [
64
+ // Non-flushed variants inset the trailing slot by the trigger's px token
65
+ { variant: ["default", "filled"], size: "sm", className: "right-[var(--date-picker-trigger-padding-x-sm)]" },
66
+ { variant: ["default", "filled"], size: "md", className: "right-[var(--date-picker-trigger-padding-x-md)]" },
67
+ { variant: ["default", "filled"], size: "lg", className: "right-[var(--date-picker-trigger-padding-x-lg)]" },
68
+ // Flushed removes horizontal padding, so the slot sits at the edge
69
+ { variant: "flushed", className: "right-0" }
70
+ ],
71
+ defaultVariants: {
72
+ size: "md",
73
+ variant: "default"
74
+ }
75
+ }
76
+ );
43
77
  function to12Hour(hours) {
44
78
  const period = hours >= 12 ? "PM" : "AM";
45
79
  let hour12 = hours % 12;
@@ -68,6 +102,8 @@ function getMinuteOptions(step) {
68
102
  function DatePicker({
69
103
  ref,
70
104
  className,
105
+ align = "start",
106
+ dialogLabel = "Choose date",
71
107
  value,
72
108
  defaultValue,
73
109
  placeholder = "Select date",
@@ -212,7 +248,8 @@ function DatePicker({
212
248
  const hourOptions = React.useMemo(() => getHourOptions(timeUse12Hour), [timeUse12Hour]);
213
249
  const minuteOptions = React.useMemo(() => getMinuteOptions(timeMinuteStep), [timeMinuteStep]);
214
250
  const displayHour = timeUse12Hour ? to12Hour(currentHours).hour12 : currentHours;
215
- const showClearButton = clearable && selectedDate && !disabled && !readOnly;
251
+ const hasValue = Boolean(selectedDate);
252
+ const showClearButton = clearable && hasValue && !disabled && !readOnly;
216
253
  const isDateDisabled = React.useCallback(
217
254
  (date) => {
218
255
  const normalizedDate = startOfDay(date);
@@ -243,13 +280,14 @@ function DatePicker({
243
280
  !displayValue && "text-muted-foreground"
244
281
  ),
245
282
  "aria-describedby": ariaDescribedby,
283
+ "aria-disabled": readOnly || void 0,
246
284
  "aria-expanded": open,
247
285
  "aria-haspopup": "dialog",
248
286
  "aria-invalid": invalid,
249
287
  "aria-label": ariaLabel,
250
288
  "aria-labelledby": ariaLabelledby,
251
- "aria-readonly": readOnly,
252
289
  "aria-required": required,
290
+ "data-has-value": hasValue,
253
291
  "data-readonly": readOnly || void 0,
254
292
  "data-size": size,
255
293
  "data-slot": "date-picker-trigger",
@@ -257,38 +295,24 @@ function DatePicker({
257
295
  "data-variant": variant,
258
296
  disabled,
259
297
  id,
260
- role: "combobox",
261
298
  type: "button",
262
299
  children: [
263
300
  /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: displayValue ?? placeholder }),
264
- /* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-1", children: [
265
- showClearButton && /* @__PURE__ */ jsx(
266
- "span",
267
- {
268
- "aria-label": "Clear date",
269
- className: "rounded-sm opacity-50 hover:opacity-100 focus:outline-none",
270
- "data-slot": "date-picker-clear",
271
- role: "button",
272
- tabIndex: 0,
273
- onClick: handleClear,
274
- onKeyDown: (e) => {
275
- if (e.key === "Enter" || e.key === " ") {
276
- e.preventDefault();
277
- handleClear(e);
278
- }
279
- },
280
- children: /* @__PURE__ */ jsx(XIcon, { className: "size-4" })
281
- }
282
- ),
283
- /* @__PURE__ */ jsx(CalendarIcon, { className: "size-4 opacity-50" })
284
- ] })
301
+ /* @__PURE__ */ jsx(
302
+ CalendarIcon,
303
+ {
304
+ "aria-hidden": "true",
305
+ className: cn("size-4 shrink-0 opacity-50", showClearButton && "invisible")
306
+ }
307
+ )
285
308
  ]
286
309
  }
287
310
  ) }),
288
311
  /* @__PURE__ */ jsxs(
289
312
  PopoverContent,
290
313
  {
291
- align: "start",
314
+ align,
315
+ "aria-label": dialogLabel,
292
316
  className: "w-auto p-0",
293
317
  "data-slot": "date-picker-calendar",
294
318
  children: [
@@ -444,6 +468,17 @@ function DatePicker({
444
468
  }
445
469
  )
446
470
  ] }),
471
+ showClearButton && /* @__PURE__ */ jsx(
472
+ "button",
473
+ {
474
+ "aria-label": "Clear date",
475
+ className: cn(datePickerClearButtonVariants({ size, variant })),
476
+ "data-slot": "date-picker-clear",
477
+ type: "button",
478
+ onClick: handleClear,
479
+ children: /* @__PURE__ */ jsx(XIcon, { className: "size-4" })
480
+ }
481
+ ),
447
482
  name && /* @__PURE__ */ jsx(
448
483
  "input",
449
484
  {
@@ -456,5 +491,5 @@ function DatePicker({
456
491
  }
457
492
 
458
493
  export { DatePicker, datePickerTriggerVariants };
459
- //# sourceMappingURL=chunk-RVUO7SDG.js.map
460
- //# sourceMappingURL=chunk-RVUO7SDG.js.map
494
+ //# sourceMappingURL=chunk-LS3WD6IZ.js.map
495
+ //# sourceMappingURL=chunk-LS3WD6IZ.js.map