@flikk/ui 1.0.0-beta.11 → 1.0.0-beta.13

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 (220) hide show
  1. package/dist/components/ai/ApprovalCard/ApprovalCard.js +1 -1
  2. package/dist/components/ai/MessageHistory/MessageHistory.js +1 -0
  3. package/dist/components/ai/PromptInput/PromptInput.js +7 -125
  4. package/dist/components/ai/PromptInput/VoiceRecorder.js +0 -77
  5. package/dist/components/ai/StreamingResponse/StreamingResponse.js +1 -0
  6. package/dist/components/ai/StreamingResponse/StreamingResponse.types.d.ts +7 -7
  7. package/dist/components/ai/index.js +1 -0
  8. package/dist/components/core/Accordion/Accordion.d.ts +1 -1
  9. package/dist/components/core/Accordion/Accordion.js +2 -2
  10. package/dist/components/core/Accordion/Accordion.theme.d.ts +2 -2
  11. package/dist/components/core/Accordion/Accordion.theme.js +4 -4
  12. package/dist/components/core/Accordion/Accordion.types.d.ts +19 -20
  13. package/dist/components/core/Accordion/AccordionBody.d.ts +3 -0
  14. package/dist/components/core/Accordion/{AccordionContent.js → AccordionBody.js} +4 -4
  15. package/dist/components/core/Accordion/AccordionItem.js +1 -1
  16. package/dist/components/core/Accordion/AccordionTrigger.js +14 -7
  17. package/dist/components/core/Accordion/index.d.ts +2 -2
  18. package/dist/components/core/Alert/Alert.js +5 -1
  19. package/dist/components/core/Alert/Alert.types.d.ts +4 -4
  20. package/dist/components/core/Avatar/Avatar.js +22 -18
  21. package/dist/components/core/Avatar/Avatar.theme.js +1 -1
  22. package/dist/components/core/Avatar/Avatar.types.d.ts +9 -8
  23. package/dist/components/core/AvatarGroup/AvatarGroup.js +2 -2
  24. package/dist/components/core/Badge/Badge.js +7 -5
  25. package/dist/components/core/Badge/Badge.theme.js +11 -4
  26. package/dist/components/core/Badge/Badge.types.d.ts +2 -2
  27. package/dist/components/core/Breadcrumbs/Breadcrumbs.js +7 -3
  28. package/dist/components/core/Breadcrumbs/Breadcrumbs.types.d.ts +1 -1
  29. package/dist/components/core/Button/Button.js +2 -8
  30. package/dist/components/core/Button/Button.theme.js +7 -7
  31. package/dist/components/core/Calendar/Calendar.js +3 -3
  32. package/dist/components/core/Calendar/CalendarEvent/CalendarEvent.types.d.ts +5 -6
  33. package/dist/components/core/Card/Card.d.ts +2 -2
  34. package/dist/components/core/Card/Card.js +3 -3
  35. package/dist/components/core/Card/Card.theme.js +3 -3
  36. package/dist/components/core/Card/Card.types.d.ts +4 -4
  37. package/dist/components/core/Card/CardBody.d.ts +3 -0
  38. package/dist/components/core/Card/CardBody.js +11 -0
  39. package/dist/components/core/Card/index.d.ts +2 -2
  40. package/dist/components/core/Carousel/Carousel.js +4 -4
  41. package/dist/components/core/Carousel/Carousel.types.d.ts +4 -4
  42. package/dist/components/core/Carousel/CarouselBody.d.ts +4 -0
  43. package/dist/components/core/Carousel/{CarouselContent.js → CarouselBody.js} +3 -3
  44. package/dist/components/core/Carousel/index.d.ts +2 -1
  45. package/dist/components/core/ContextMenu/ContextMenu.d.ts +2 -2
  46. package/dist/components/core/ContextMenu/ContextMenu.js +6 -6
  47. package/dist/components/core/ContextMenu/ContextMenu.types.d.ts +2 -2
  48. package/dist/components/core/ContextMenu/ContextMenuBody.d.ts +6 -0
  49. package/dist/components/core/ContextMenu/{ContextMenuContent.js → ContextMenuBody.js} +4 -4
  50. package/dist/components/core/ContextMenu/ContextMenuSubBody.d.ts +6 -0
  51. package/dist/components/core/ContextMenu/{ContextMenuSubContent.js → ContextMenuSubBody.js} +4 -4
  52. package/dist/components/core/ContextMenu/index.d.ts +1 -1
  53. package/dist/components/core/Drawer/Drawer.d.ts +2 -2
  54. package/dist/components/core/Drawer/Drawer.js +28 -9
  55. package/dist/components/core/Drawer/Drawer.theme.js +1 -1
  56. package/dist/components/core/Drawer/Drawer.types.d.ts +8 -6
  57. package/dist/components/core/Drawer/DrawerBody.d.ts +5 -0
  58. package/dist/components/core/Drawer/DrawerBody.js +11 -0
  59. package/dist/components/core/Drawer/index.d.ts +2 -1
  60. package/dist/components/core/Dropdown/Dropdown.types.d.ts +3 -3
  61. package/dist/components/core/Dropdown/DropdownSection.js +3 -1
  62. package/dist/components/core/FileTypeIcon/FileTypeIcon.d.ts +3 -0
  63. package/dist/components/core/FileTypeIcon/FileTypeIcon.js +33 -0
  64. package/dist/components/core/FileTypeIcon/FileTypeIcon.theme.d.ts +2 -0
  65. package/dist/components/core/FileTypeIcon/FileTypeIcon.theme.js +12 -0
  66. package/dist/components/core/FileTypeIcon/FileTypeIcon.types.d.ts +19 -0
  67. package/dist/components/core/FileTypeIcon/fileTypes.d.ts +7 -0
  68. package/dist/components/core/FileTypeIcon/fileTypes.js +30 -0
  69. package/dist/components/core/FileTypeIcon/index.d.ts +2 -0
  70. package/dist/components/core/MenuItem/MenuItem.js +3 -1
  71. package/dist/components/core/MenuItem/MenuItem.theme.js +1 -1
  72. package/dist/components/core/MenuItem/MenuItem.types.d.ts +1 -1
  73. package/dist/components/core/Message/Message.d.ts +1 -1
  74. package/dist/components/core/Message/Message.js +3 -3
  75. package/dist/components/core/Message/Message.theme.js +2 -2
  76. package/dist/components/core/Message/Message.types.d.ts +7 -7
  77. package/dist/components/core/Message/MessageAvatar.d.ts +2 -2
  78. package/dist/components/core/Message/MessageAvatar.js +3 -3
  79. package/dist/components/core/Message/MessageBody.d.ts +8 -0
  80. package/dist/components/core/Message/{MessageContent.js → MessageBody.js} +3 -3
  81. package/dist/components/core/Message/index.d.ts +2 -0
  82. package/dist/components/core/Modal/Modal.js +5 -1
  83. package/dist/components/core/Modal/Modal.theme.js +1 -1
  84. package/dist/components/core/Modal/Modal.types.d.ts +5 -2
  85. package/dist/components/core/ModalStack/ModalStackModal.js +1 -0
  86. package/dist/components/core/PageHeading/PageHeading.types.d.ts +1 -1
  87. package/dist/components/core/PageHeading/PageHeadingBackButton.js +3 -1
  88. package/dist/components/core/Popover/Popover.d.ts +1 -1
  89. package/dist/components/core/Popover/Popover.js +4 -4
  90. package/dist/components/core/Popover/Popover.theme.d.ts +1 -1
  91. package/dist/components/core/Popover/Popover.theme.js +2 -2
  92. package/dist/components/core/Popover/Popover.types.d.ts +3 -3
  93. package/dist/components/core/Popover/PopoverBody.d.ts +7 -0
  94. package/dist/components/core/Popover/{PopoverContent.js → PopoverBody.js} +24 -13
  95. package/dist/components/core/Popover/index.d.ts +4 -3
  96. package/dist/components/core/Tabs/Tabs.animations.d.ts +2 -2
  97. package/dist/components/core/Tabs/Tabs.animations.js +3 -3
  98. package/dist/components/core/Tabs/Tabs.d.ts +1 -1
  99. package/dist/components/core/Tabs/Tabs.js +3 -3
  100. package/dist/components/core/Tabs/Tabs.theme.d.ts +1 -1
  101. package/dist/components/core/Tabs/Tabs.theme.js +2 -2
  102. package/dist/components/core/Tabs/Tabs.types.d.ts +9 -9
  103. package/dist/components/core/Tabs/TabsBody.d.ts +6 -0
  104. package/dist/components/core/Tabs/{TabsContent.js → TabsBody.js} +8 -8
  105. package/dist/components/core/Tabs/index.d.ts +2 -2
  106. package/dist/components/core/Tag/Tag.d.ts +1 -1
  107. package/dist/components/core/Tag/Tag.js +2 -2
  108. package/dist/components/core/Tag/Tag.types.d.ts +1 -1
  109. package/dist/components/core/Toast/Toast.js +5 -1
  110. package/dist/components/core/Toast/Toast.types.d.ts +9 -9
  111. package/dist/components/core/index.d.ts +1 -1
  112. package/dist/components/core/index.js +7 -3
  113. package/dist/components/data-display/Feed/Feed.animations.d.ts +40 -0
  114. package/dist/components/data-display/Feed/Feed.animations.js +26 -0
  115. package/dist/components/data-display/Feed/Feed.d.ts +5 -1
  116. package/dist/components/data-display/Feed/Feed.js +87 -52
  117. package/dist/components/data-display/Feed/Feed.theme.js +11 -13
  118. package/dist/components/data-display/Feed/Feed.types.d.ts +35 -34
  119. package/dist/components/data-display/Feed/index.d.ts +1 -1
  120. package/dist/components/data-display/GanttChart/GanttTaskBar.js +11 -9
  121. package/dist/components/data-display/GanttChart/GanttTaskContextMenu.js +1 -1
  122. package/dist/components/data-display/KPI/KPI.js +2 -2
  123. package/dist/components/data-display/KPI/KPI.types.d.ts +3 -3
  124. package/dist/components/data-display/Metric/Metric.js +2 -2
  125. package/dist/components/data-display/Metric/Metric.types.d.ts +3 -3
  126. package/dist/components/data-display/Table/TableColumnManager.js +2 -1
  127. package/dist/components/data-display/Table/TableFilter.js +2 -1
  128. package/dist/components/data-display/Timeline/TimelineMarker.js +2 -2
  129. package/dist/components/effects/3d/index.d.ts +1 -1
  130. package/dist/components/effects/AIOrb/AIOrb.d.ts +1 -0
  131. package/dist/components/effects/AIOrb/AIOrb.js +3 -2
  132. package/dist/components/effects/AIOrb/AIOrb.types.d.ts +1 -0
  133. package/dist/components/effects/AIOrb/hooks/index.d.ts +2 -0
  134. package/dist/components/effects/AIOrb/hooks/useOrbState.d.ts +20 -0
  135. package/dist/components/effects/AIOrb/hooks/useOrbState.js +27 -0
  136. package/dist/components/effects/AIOrb/index.d.ts +2 -2
  137. package/dist/components/effects/AIOrb/variants/Aura/Aura.d.ts +3 -0
  138. package/dist/components/effects/AIOrb/variants/Aura/Aura.js +75 -0
  139. package/dist/components/effects/AIOrb/variants/Aura/Aura.shaders.d.ts +28 -0
  140. package/dist/components/effects/AIOrb/variants/Aura/Aura.shaders.js +191 -0
  141. package/dist/components/effects/AIOrb/variants/Aura/Aura.types.d.ts +53 -0
  142. package/dist/components/effects/AIOrb/variants/Aura/ShaderCanvas.d.ts +17 -0
  143. package/dist/components/effects/AIOrb/variants/Aura/ShaderCanvas.js +149 -0
  144. package/dist/components/effects/AIOrb/variants/Aura/index.d.ts +2 -0
  145. package/dist/components/effects/AIOrb/variants/DotSphere/DotSphere.js +38 -7
  146. package/dist/components/effects/AIOrb/variants/DotSphere/DotSphere.types.d.ts +6 -0
  147. package/dist/components/effects/AIOrb/variants/Liquid/Liquid.js +34 -8
  148. package/dist/components/effects/AIOrb/variants/Liquid/Liquid.types.d.ts +6 -0
  149. package/dist/components/effects/AIOrb/variants/index.d.ts +2 -0
  150. package/dist/components/effects/CustomCursor/CustomCursor.d.ts +2 -2
  151. package/dist/components/effects/CustomCursor/CustomCursor.js +50 -47
  152. package/dist/components/effects/GlassSurface/GlassSurface.js +24 -12
  153. package/dist/components/effects/GlassSurface/GlassSurface.types.d.ts +8 -0
  154. package/dist/components/forms/Checkbox/Checkbox.js +1 -1
  155. package/dist/components/forms/Checkbox/Checkbox.types.d.ts +5 -5
  156. package/dist/components/forms/Checkbox/CheckboxGroup.js +2 -2
  157. package/dist/components/forms/ColorPicker/ColorPicker.d.ts +1 -1
  158. package/dist/components/forms/ColorPicker/ColorPicker.js +2 -2
  159. package/dist/components/forms/ColorPicker/ColorPicker.types.d.ts +2 -2
  160. package/dist/components/forms/ColorPicker/ColorPickerBody.d.ts +7 -0
  161. package/dist/components/forms/ColorPicker/{ColorPickerContent.js → ColorPickerBody.js} +5 -5
  162. package/dist/components/forms/ColorPicker/index.d.ts +2 -2
  163. package/dist/components/forms/DatePicker/DatePicker.d.ts +7 -3
  164. package/dist/components/forms/DatePicker/DatePicker.js +6 -5
  165. package/dist/components/forms/DatePicker/DatePicker.theme.js +3 -3
  166. package/dist/components/forms/DatePicker/DatePicker.types.d.ts +9 -4
  167. package/dist/components/forms/DatePicker/DatePickerBody.d.ts +7 -0
  168. package/dist/components/forms/DatePicker/{DatePickerContent.js → DatePickerBody.js} +10 -9
  169. package/dist/components/forms/DatePicker/index.d.ts +2 -2
  170. package/dist/components/forms/FileUpload/FileUpload.js +0 -78
  171. package/dist/components/forms/Input/Input.js +2 -2
  172. package/dist/components/forms/Input/Input.types.d.ts +4 -4
  173. package/dist/components/forms/Mention/Mention.js +2 -2
  174. package/dist/components/forms/Radio/Radio.js +1 -1
  175. package/dist/components/forms/Radio/Radio.types.d.ts +5 -5
  176. package/dist/components/forms/Radio/RadioGroup.js +1 -1
  177. package/dist/components/forms/Select/Select.js +2 -2
  178. package/dist/components/forms/Select/Select.types.d.ts +4 -4
  179. package/dist/components/forms/Switch/Switch.js +1 -1
  180. package/dist/components/forms/Switch/Switch.types.d.ts +4 -4
  181. package/dist/components/forms/Textarea/Textarea.js +2 -2
  182. package/dist/components/forms/Textarea/Textarea.types.d.ts +4 -4
  183. package/dist/components/forms/TimePicker/TimePickerContent.js +1 -78
  184. package/dist/components/forms/index.d.ts +2 -2
  185. package/dist/components/forms/index.js +2 -80
  186. package/dist/components/layout/FormLayout/FormLayout.d.ts +0 -2
  187. package/dist/components/layout/FormLayout/FormLayout.js +12 -6
  188. package/dist/components/layout/FormLayout/FormLayout.theme.js +2 -5
  189. package/dist/components/layout/FormLayout/FormLayout.types.d.ts +8 -26
  190. package/dist/components/layout/FormLayout/FormLayoutSection.js +3 -2
  191. package/dist/components/layout/FormLayout/index.d.ts +1 -1
  192. package/dist/index.js +197 -199
  193. package/dist/styles.css +1 -1
  194. package/dist/utils/index.d.ts +1 -0
  195. package/dist/utils/paletteGenerator.d.ts +46 -0
  196. package/package.json +1 -1
  197. package/src/styles/theme.css +2 -6
  198. package/dist/components/core/Accordion/AccordionContent.d.ts +0 -3
  199. package/dist/components/core/Card/CardContent.d.ts +0 -3
  200. package/dist/components/core/Card/CardContent.js +0 -11
  201. package/dist/components/core/Carousel/CarouselContent.d.ts +0 -4
  202. package/dist/components/core/ContextMenu/ContextMenuContent.d.ts +0 -6
  203. package/dist/components/core/ContextMenu/ContextMenuSubContent.d.ts +0 -6
  204. package/dist/components/core/Drawer/DrawerContent.d.ts +0 -5
  205. package/dist/components/core/Drawer/DrawerContent.js +0 -11
  206. package/dist/components/core/Loader/Loader.d.ts +0 -24
  207. package/dist/components/core/Loader/Loader.js +0 -57
  208. package/dist/components/core/Loader/Loader.theme.d.ts +0 -27
  209. package/dist/components/core/Loader/Loader.theme.js +0 -60
  210. package/dist/components/core/Loader/Loader.types.d.ts +0 -71
  211. package/dist/components/core/Loader/index.d.ts +0 -2
  212. package/dist/components/core/Message/MessageContent.d.ts +0 -8
  213. package/dist/components/core/Popover/PopoverContent.d.ts +0 -7
  214. package/dist/components/core/Tabs/TabsContent.d.ts +0 -6
  215. package/dist/components/forms/ColorPicker/ColorPickerContent.d.ts +0 -7
  216. package/dist/components/forms/DatePicker/DatePickerContent.d.ts +0 -7
  217. package/dist/components/layout/FormLayout/FormLayoutBody.d.ts +0 -3
  218. package/dist/components/layout/FormLayout/FormLayoutBody.js +0 -91
  219. package/dist/components/layout/FormLayout/FormLayoutHeader.d.ts +0 -3
  220. package/dist/components/layout/FormLayout/FormLayoutHeader.js +0 -12
@@ -1,13 +1,13 @@
1
- import { HTMLAttributes, ReactNode } from 'react';
1
+ import { HTMLAttributes, ReactNode } from "react";
2
2
  /**
3
3
  * Toast visual variant
4
4
  */
5
- export type ToastVariant = 'default' | 'glass';
5
+ export type ToastVariant = "default" | "glass";
6
6
  /**
7
7
  * Toast state (e.g., loading indicator)
8
8
  */
9
- export type ToastState = 'default' | 'loading';
10
- export type ToastPosition = 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
9
+ export type ToastState = "default" | "loading";
10
+ export type ToastPosition = "top-left" | "top-center" | "top-right" | "bottom-left" | "bottom-center" | "bottom-right";
11
11
  export interface ToastAction {
12
12
  label: string;
13
13
  onClick: () => void;
@@ -42,15 +42,15 @@ export interface ToastData {
42
42
  id: string;
43
43
  variant?: ToastVariant;
44
44
  state?: ToastState;
45
- title?: string;
46
- subtitle?: string;
45
+ title?: ReactNode;
46
+ subtitle?: ReactNode;
47
47
  icon?: ReactNode;
48
48
  action?: ToastAction;
49
49
  duration?: number;
50
50
  dismissible?: boolean;
51
51
  onDismiss?: () => void;
52
52
  }
53
- export interface ToastProps extends HTMLAttributes<HTMLDivElement> {
53
+ export interface ToastProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
54
54
  /** Toast data */
55
55
  toast: ToastData;
56
56
  /** Custom class name */
@@ -93,7 +93,7 @@ export interface ToastProviderProps {
93
93
  }
94
94
  export interface ToastContextValue {
95
95
  toasts: ToastData[];
96
- addToast: (toast: Omit<ToastData, 'id'>) => string;
96
+ addToast: (toast: Omit<ToastData, "id">) => string;
97
97
  removeToast: (id: string) => void;
98
98
  removeAllToasts: () => void;
99
99
  }
@@ -121,7 +121,7 @@ export interface UseToastReturn {
121
121
  info: (title: string, options?: UseToastOptions & {
122
122
  subtitle?: string;
123
123
  }) => string;
124
- loading: (title: string, options?: Omit<UseToastOptions, 'state'> & {
124
+ loading: (title: string, options?: Omit<UseToastOptions, "state"> & {
125
125
  subtitle?: string;
126
126
  }) => string;
127
127
  dismiss: (id: string) => void;
@@ -18,7 +18,6 @@ export * from "./Dropdown";
18
18
  export * from "./Kbd";
19
19
  export * from "./MenuItem";
20
20
  export * from "./Link";
21
- export * from "./Loader";
22
21
  export * from "./Modal";
23
22
  export * from "./ModalStack";
24
23
  export * from "./PageHeading";
@@ -48,3 +47,4 @@ export * from "./OfflineIndicator";
48
47
  export * from "./ContextMenu";
49
48
  export * from "./Pill";
50
49
  export * from "./SocialIcon";
50
+ export * from "./FileTypeIcon";
@@ -18,11 +18,13 @@ export { CalendarMini } from './Calendar/CalendarMini/CalendarMini.js';
18
18
  export { Card } from './Card/Card.js';
19
19
  export { CardStack } from './CardStack/CardStack.js';
20
20
  export { Carousel } from './Carousel/Carousel.js';
21
+ export { CarouselBody } from './Carousel/CarouselBody.js';
21
22
  export { CommandPalette } from './CommandPalette/CommandPalette.js';
22
23
  export { commandPaletteTheme } from './CommandPalette/CommandPalette.theme.js';
23
24
  export { Separator } from './Separator/Separator.js';
24
25
  export { separatorTheme } from './Separator/Separator.theme.js';
25
26
  export { Drawer } from './Drawer/Drawer.js';
27
+ export { DrawerBody } from './Drawer/DrawerBody.js';
26
28
  export { Dropdown } from './Dropdown/Dropdown.js';
27
29
  export { DropdownTrigger } from './Dropdown/DropdownTrigger.js';
28
30
  export { DropdownMenu } from './Dropdown/DropdownMenu.js';
@@ -34,13 +36,13 @@ export { Kbd } from './Kbd/Kbd.js';
34
36
  export { MenuItem } from './MenuItem/MenuItem.js';
35
37
  export { menuItemTheme } from './MenuItem/MenuItem.theme.js';
36
38
  export { Link } from './Link/Link.js';
37
- export { Loader } from './Loader/Loader.js';
38
39
  export { Modal } from './Modal/Modal.js';
39
40
  export { ModalStack } from './ModalStack/ModalStack.js';
40
41
  export { PageHeading } from './PageHeading/PageHeading.js';
41
42
  export { Pagination } from './Pagination/Pagination.js';
42
43
  export { Popover } from './Popover/Popover.js';
43
44
  export { PopoverContext, usePopoverContext } from './Popover/PopoverContext.js';
45
+ export { PopoverBody } from './Popover/PopoverBody.js';
44
46
  export { Progress } from './Progress/Progress.js';
45
47
  export { Rating } from './Rating/Rating.js';
46
48
  export { ScrollArea } from './ScrollArea/ScrollArea.js';
@@ -52,7 +54,7 @@ export { SlidingNumber } from './SlidingNumber/SlidingNumber.js';
52
54
  export { Tabs } from './Tabs/Tabs.js';
53
55
  export { TabsList } from './Tabs/TabsList.js';
54
56
  export { TabsTrigger } from './Tabs/TabsTrigger.js';
55
- export { TabsContent } from './Tabs/TabsContent.js';
57
+ export { TabsBody } from './Tabs/TabsBody.js';
56
58
  export { TabsContext, useTabsContext } from './Tabs/TabsContext.js';
57
59
  export { Tooltip } from './Tooltip/Tooltip.js';
58
60
  export { baseTooltipVariants, getTooltipVariants, tooltipSpringConfig } from './Tooltip/Tooltip.animations.js';
@@ -71,6 +73,7 @@ export { Message } from './Message/Message.js';
71
73
  export { messageTheme } from './Message/Message.theme.js';
72
74
  export { messageListTheme } from './Message/MessageList.theme.js';
73
75
  export { TypeWriter } from './Message/TypeWriter.js';
76
+ export { MessageBody } from './Message/MessageBody.js';
74
77
  export { Empty } from './Empty/Empty.js';
75
78
  export { emptyTheme } from './Empty/Empty.theme.js';
76
79
  export { Masonry } from './Masonry/Masonry.js';
@@ -94,8 +97,9 @@ export { contextMenuTheme } from './ContextMenu/ContextMenu.theme.js';
94
97
  export { Pill } from './Pill/Pill.js';
95
98
  export { pillTheme } from './Pill/Pill.theme.js';
96
99
  export { SocialIcon } from './SocialIcon/SocialIcon.js';
100
+ export { FileTypeIcon } from './FileTypeIcon/FileTypeIcon.js';
97
101
  export { AnimatePresence } from 'motion/react';
98
- export { CardContent } from './Card/CardContent.js';
102
+ export { CardBody } from './Card/CardBody.js';
99
103
  export { CardFooter } from './Card/CardFooter.js';
100
104
  export { CardHeader } from './Card/CardHeader.js';
101
105
  export { CardSubtitle } from './Card/CardSubtitle.js';
@@ -0,0 +1,40 @@
1
+ export declare const EASE: readonly [0.04, 0.62, 0.23, 0.98];
2
+ export declare const STAGGER_IN = 0.05;
3
+ export declare const STAGGER_OUT = 0.04;
4
+ export declare const STAGGER_BASE_DELAY = 0.15;
5
+ export declare const collapseLayerExitTiming: {
6
+ height: {
7
+ duration: number;
8
+ delay: number;
9
+ ease: readonly [0.04, 0.62, 0.23, 0.98];
10
+ };
11
+ opacity: {
12
+ duration: number;
13
+ delay: number;
14
+ };
15
+ };
16
+ export declare const collapseLayerEnterTiming: {
17
+ height: {
18
+ duration: number;
19
+ delay: number;
20
+ ease: readonly [0.04, 0.62, 0.23, 0.98];
21
+ };
22
+ opacity: {
23
+ duration: number;
24
+ delay: number;
25
+ };
26
+ };
27
+ export declare const expandLayerEnterTiming: {
28
+ height: {
29
+ duration: number;
30
+ delay: number;
31
+ ease: readonly [0.04, 0.62, 0.23, 0.98];
32
+ };
33
+ };
34
+ export declare const expandLayerExitTiming: {
35
+ height: {
36
+ duration: number;
37
+ delay: number;
38
+ ease: readonly [0.04, 0.62, 0.23, 0.98];
39
+ };
40
+ };
@@ -0,0 +1,26 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Feed.Collapse — multi-stage animation timing
3
+ // ---------------------------------------------------------------------------
4
+ const EASE = [0.04, 0.62, 0.23, 0.98];
5
+ // Stagger timing
6
+ const STAGGER_IN = 0.05; // 50ms between each item entering
7
+ const STAGGER_OUT = 0.04; // 40ms between each item exiting (slightly faster)
8
+ const STAGGER_BASE_DELAY = 0.15; // items start shortly after height begins expanding
9
+ // Collapsed layer (curve + label) — exit = collapsing away, enter = reappearing
10
+ const collapseLayerExitTiming = {
11
+ height: { duration: 0.3, delay: 0, ease: EASE },
12
+ opacity: { duration: 0.2, delay: 0 },
13
+ };
14
+ const collapseLayerEnterTiming = {
15
+ height: { duration: 0.35, delay: 0.05, ease: EASE },
16
+ opacity: { duration: 0.25, delay: 0.15 },
17
+ };
18
+ // Expanded layer (children container) — enter = growing, exit = shrinking
19
+ const expandLayerEnterTiming = {
20
+ height: { duration: 0.4, delay: 0, ease: EASE },
21
+ };
22
+ const expandLayerExitTiming = {
23
+ height: { duration: 0.35, delay: 0.05, ease: EASE },
24
+ };
25
+
26
+ export { EASE, STAGGER_BASE_DELAY, STAGGER_IN, STAGGER_OUT, collapseLayerEnterTiming, collapseLayerExitTiming, expandLayerEnterTiming, expandLayerExitTiming };
@@ -1,5 +1,9 @@
1
1
  import React from "react";
2
- import type { FeedProps, FeedItemProps } from "./Feed.types";
2
+ import type { FeedProps, FeedItemProps, FeedCollapseProps, FeedTheme } from "./Feed.types";
3
+ export declare const useFeedContext: () => {
4
+ theme: FeedTheme;
5
+ };
3
6
  export declare const Feed: React.ForwardRefExoticComponent<FeedProps & React.RefAttributes<HTMLDivElement>> & {
4
7
  Item: React.ForwardRefExoticComponent<FeedItemProps & React.RefAttributes<HTMLLIElement>>;
8
+ Collapse: React.FC<FeedCollapseProps>;
5
9
  };
@@ -1,11 +1,10 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
- import React__default, { createContext, useMemo, useState, useContext } from 'react';
2
+ import React__default, { createContext, useMemo, useState, useCallback, useContext } from 'react';
3
+ import { useReducedMotion, motion } from 'motion/react';
4
+ import { ChevronUpDownIcon } from '@heroicons/react/16/solid';
3
5
  import { cn } from '../../../utils/cn.js';
4
6
  import { feedTheme } from './Feed.theme.js';
5
- import { Avatar } from '../../core/Avatar/Avatar.js';
6
- import { Button } from '../../core/Button/Button.js';
7
- import { Textarea } from '../../forms/Textarea/Textarea.js';
8
- import '../../forms/Textarea/Textarea.theme.js';
7
+ import { collapseLayerExitTiming, collapseLayerEnterTiming, EASE, expandLayerEnterTiming, expandLayerExitTiming, STAGGER_BASE_DELAY, STAGGER_IN, STAGGER_OUT } from './Feed.animations.js';
9
8
 
10
9
  // ---------------------------------------------------------------------------
11
10
  // Context
@@ -29,60 +28,96 @@ FeedRoot.displayName = "Feed";
29
28
  // ---------------------------------------------------------------------------
30
29
  // Feed.Item
31
30
  // ---------------------------------------------------------------------------
32
- const FeedItem = React__default.forwardRef(({ variant = "default", title, timestamp, icon, avatar, children, placeholder = "Add your comment...", submitLabel = "Comment", onSubmit, className, ...props }, ref) => {
31
+ const FeedItemInner = ({ icon, indicatorClassName, timestamp, children }) => {
33
32
  const { theme } = useFeedContext();
34
- // Always call useState (rules of hooks) only used for comment-input
35
- const [inputValue, setInputValue] = useState("");
36
- // ------- Indicator rendering -------
37
- const renderIndicator = () => {
38
- var _a;
39
- switch (variant) {
40
- case "icon":
41
- return jsx("div", { className: theme.iconIndicatorStyle, children: icon });
42
- case "avatar":
43
- case "comment-input":
44
- return (jsx("div", { className: theme.avatarIndicatorStyle, children: jsx(Avatar, { src: avatar === null || avatar === void 0 ? void 0 : avatar.src, alt: (_a = avatar === null || avatar === void 0 ? void 0 : avatar.alt) !== null && _a !== void 0 ? _a : "", className: "size-10 ring-8 ring-[var(--color-background)]" }) }));
45
- case "default":
46
- default:
47
- return (jsx("div", { className: theme.dotIndicatorStyle, children: jsx("span", { className: "size-1.5 rounded-full bg-[var(--color-text-muted)]" }) }));
48
- }
49
- };
50
- // ------- Content rendering -------
51
- const renderContent = () => {
52
- switch (variant) {
53
- case "default":
54
- case "icon":
55
- return (jsxs("div", { className: cn(theme.contentStyle, "py-1.5"), children: [jsxs("p", { className: theme.actionTextStyle, children: [title && jsxs("span", { className: theme.titleStyle, children: [title, " "] }), children] }), timestamp && jsx("p", { className: theme.timestampStyle, children: timestamp })] }));
56
- case "avatar":
57
- return (jsxs("div", { className: theme.contentStyle, children: [title && (jsx("p", { className: cn(theme.titleStyle, "text-base"), children: title })), jsx("p", { className: cn(theme.actionTextStyle, "mt-0.5"), children: children }), timestamp && jsx("p", { className: theme.timestampStyle, children: timestamp })] }));
58
- case "comment-input": {
59
- const handleSubmit = () => {
60
- const trimmed = inputValue.trim();
61
- if (trimmed && onSubmit) {
62
- onSubmit(trimmed);
63
- setInputValue("");
64
- }
65
- };
66
- const handleKeyDown = (e) => {
67
- if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
68
- e.preventDefault();
69
- handleSubmit();
70
- }
71
- };
72
- return (jsxs("div", { className: theme.commentInputWrapperStyle, children: [jsx(Textarea, { size: "sm", rows: 3, placeholder: placeholder, value: inputValue, onChange: (e) => setInputValue(e.target.value), onKeyDown: handleKeyDown }), jsx("div", { className: theme.commentInputFooterStyle, children: jsx(Button, { size: "sm", onClick: handleSubmit, children: submitLabel }) })] }));
73
- }
74
- default:
75
- return null;
76
- }
77
- };
78
- return (jsx("li", { ref: ref, className: className, ...props, children: jsxs("div", { className: theme.itemInnerStyle, children: [jsx("span", { "aria-hidden": "true", className: theme.connectorStyle }), jsxs("div", { className: theme.itemContentStyle, children: [renderIndicator(), renderContent()] })] }) }));
33
+ return (jsxs("div", { className: theme.itemInnerStyle, children: [jsx("span", { "aria-hidden": "true", className: theme.connectorStyle }), jsxs("div", { className: theme.itemContentStyle, children: [icon ? (jsx("div", { className: cn(theme.indicatorStyle, indicatorClassName), children: icon })) : (jsx("div", { className: cn(theme.dotIndicatorStyle, indicatorClassName), children: jsx("span", { className: "size-1.5 rounded-full bg-[var(--color-text-muted)]" }) })), jsxs("div", { className: theme.contentStyle, children: [children, timestamp && jsx("p", { className: theme.timestampStyle, children: timestamp })] })] })] }));
34
+ };
35
+ const FeedItem = React__default.forwardRef(({ icon, indicatorClassName, timestamp, children, className, _as = "li", ...props }, ref) => {
36
+ const inner = (jsx(FeedItemInner, { icon: icon, indicatorClassName: indicatorClassName, timestamp: timestamp, children: children }));
37
+ if (_as === "div") {
38
+ return (jsx("div", { className: className, ...props, children: inner }));
39
+ }
40
+ return (jsx("li", { ref: ref, className: className, ...props, children: inner }));
79
41
  });
80
42
  FeedItem.displayName = "Feed.Item";
81
43
  // ---------------------------------------------------------------------------
44
+ // Feed.Collapse
45
+ // ---------------------------------------------------------------------------
46
+ /**
47
+ * SVG curved connector for the collapsed state.
48
+ * Draws a smooth parenthesis ) shape from (1,0) → (APEX,MID) → (1,H).
49
+ * Cubic beziers with vertical tangents at every junction so the curve
50
+ * connects seamlessly to the straight Feed connector above/below.
51
+ *
52
+ * Both CURVE_PATH and STRAIGHT_PATH use identical command structure
53
+ * (M, C, C) so framer-motion interpolates all numeric values smoothly.
54
+ */
55
+ const COLLAPSED_HEIGHT = 72;
56
+ const CURVE_APEX_X = 24;
57
+ const STROKE_WIDTH = 2;
58
+ const SVG_WIDTH = CURVE_APEX_X + STROKE_WIDTH;
59
+ const MID_Y = COLLAPSED_HEIGHT / 2;
60
+ const CURVE_PATH = `M 1 0 C 1 20, ${CURVE_APEX_X} 16, ${CURVE_APEX_X} ${MID_Y} C ${CURVE_APEX_X} 56, 1 52, 1 ${COLLAPSED_HEIGHT}`;
61
+ const STRAIGHT_PATH = `M 1 0 C 1 12, 1 24, 1 ${MID_Y} C 1 48, 1 60, 1 ${COLLAPSED_HEIGHT}`;
62
+ const FeedCollapse = ({ label = "Show {count} more", icon, defaultExpanded = false, expanded: controlledExpanded, onToggle, children, className, }) => {
63
+ const { theme } = useFeedContext();
64
+ const shouldReduceMotion = useReducedMotion();
65
+ const [internalExpanded, setInternalExpanded] = useState(defaultExpanded);
66
+ const isControlled = controlledExpanded !== undefined;
67
+ const expanded = isControlled ? controlledExpanded : internalExpanded;
68
+ const count = React__default.Children.count(children);
69
+ const resolvedLabel = label.replace("{count}", String(count));
70
+ const handleToggle = useCallback(() => {
71
+ const next = !expanded;
72
+ if (!isControlled)
73
+ setInternalExpanded(next);
74
+ onToggle === null || onToggle === void 0 ? void 0 : onToggle(next);
75
+ }, [expanded, isControlled, onToggle]);
76
+ // Clone children with _as="div" to avoid nested <li>
77
+ const clonedChildren = React__default.Children.map(children, (child) => {
78
+ if (React__default.isValidElement(child)) {
79
+ return React__default.cloneElement(child, {
80
+ _as: "div",
81
+ });
82
+ }
83
+ return child;
84
+ });
85
+ const collapseIcon = icon !== null && icon !== void 0 ? icon : (jsx(ChevronUpDownIcon, { className: "size-4 text-[var(--color-primary)]" }));
86
+ /* ---- Reduced motion: instant toggle, no staged animations ---- */
87
+ if (shouldReduceMotion) {
88
+ return (jsxs("li", { className: cn(theme.collapseStyle, className), children: [expanded && (jsx("span", { "aria-hidden": "true", className: "absolute left-5 -translate-x-1/2 top-0 h-full w-0.5 bg-[var(--color-border)]/60" })), !expanded ? (jsxs("div", { className: "relative", style: { height: COLLAPSED_HEIGHT }, children: [jsx("svg", { "aria-hidden": "true", className: theme.collapseSvgStyle, style: { left: "calc(1.25rem - 1px)" }, width: SVG_WIDTH, height: COLLAPSED_HEIGHT, fill: "none", children: jsx("path", { d: CURVE_PATH, stroke: "var(--color-border)", strokeOpacity: "0.6", strokeWidth: STROKE_WIDTH }) }), jsxs("button", { type: "button", className: "absolute top-1/2 -translate-y-1/2 flex items-center gap-2.5 cursor-pointer bg-transparent border-none p-0", style: {
89
+ left: `calc(1.25rem - 1px + ${CURVE_APEX_X + 12}px)`,
90
+ }, onClick: handleToggle, "aria-expanded": false, children: [jsx("div", { className: "flex size-5 shrink-0 items-center justify-center rounded-full bg-[var(--color-surface)] ", children: collapseIcon }), jsx("span", { className: theme.collapseButtonStyle, children: resolvedLabel })] })] })) : (jsxs("div", { children: [clonedChildren, jsx("div", { className: "relative pb-8", children: jsxs("div", { className: theme.itemContentStyle, children: [jsx("div", { className: "flex size-8 ml-1 shrink-0 items-center justify-center rounded-full bg-[var(--color-background-secondary)] ring-2 ring-[var(--color-background)]/50", children: collapseIcon }), jsx("div", { className: theme.contentStyle, children: jsx("button", { type: "button", className: theme.collapseButtonStyle, onClick: handleToggle, "aria-expanded": true, children: "Show less" }) })] }) })] }))] }));
91
+ }
92
+ /* ---- Full multi-stage animation ---- */
93
+ return (jsxs("li", { className: cn(theme.collapseStyle, className), children: [jsx(motion.span, { "aria-hidden": "true", className: "absolute left-5 -translate-x-1/2 top-0 h-full w-0.5 bg-[var(--color-border)]/60", animate: { opacity: expanded ? 1 : 0 }, transition: { duration: 0.2 } }), jsx(motion.div, { animate: {
94
+ height: expanded ? 0 : COLLAPSED_HEIGHT,
95
+ opacity: expanded ? 0 : 1,
96
+ }, transition: expanded ? collapseLayerExitTiming : collapseLayerEnterTiming, style: { overflow: "hidden", position: "relative" }, children: jsxs("div", { className: "relative", style: { height: COLLAPSED_HEIGHT }, children: [jsx("svg", { "aria-hidden": "true", className: theme.collapseSvgStyle, style: { left: "calc(1.25rem - 1px)" }, width: SVG_WIDTH, height: COLLAPSED_HEIGHT, fill: "none", children: jsx(motion.path, { animate: { d: expanded ? STRAIGHT_PATH : CURVE_PATH }, transition: { duration: 0.3, ease: EASE }, stroke: "var(--color-border)", strokeOpacity: "0.6", strokeWidth: STROKE_WIDTH }) }), jsxs(motion.button, { type: "button", className: "absolute top-1/2 -translate-y-1/2 flex items-center gap-2.5 cursor-pointer bg-transparent border-none p-0", style: {
97
+ left: `calc(1.25rem - 1px + ${CURVE_APEX_X + 12}px)`,
98
+ }, animate: { opacity: expanded ? 0 : 1 }, transition: { duration: 0.2, delay: expanded ? 0 : 0.2 }, onClick: handleToggle, "aria-expanded": false, children: [jsx("div", { className: "flex size-5 shrink-0 items-center justify-center rounded-full bg-[var(--color-surface)] border border-[var(--color-border)] shadow-sm", children: collapseIcon }), jsx("span", { className: theme.collapseButtonStyle, children: resolvedLabel })] })] }) }), jsxs(motion.div, { animate: { height: expanded ? "auto" : 0 }, transition: expanded ? expandLayerEnterTiming : expandLayerExitTiming, style: { overflow: "hidden" }, children: [React__default.Children.map(clonedChildren, (child, i) => (jsx(motion.div, { animate: {
99
+ opacity: expanded ? 1 : 0,
100
+ y: expanded ? 0 : 8,
101
+ }, transition: {
102
+ duration: 0.25,
103
+ delay: expanded
104
+ ? STAGGER_BASE_DELAY + i * STAGGER_IN
105
+ : (count - i) * STAGGER_OUT,
106
+ }, children: child }, i))), jsx(motion.div, { animate: {
107
+ opacity: expanded ? 1 : 0,
108
+ y: expanded ? 0 : 8,
109
+ }, transition: {
110
+ duration: 0.25,
111
+ delay: expanded ? STAGGER_BASE_DELAY + count * STAGGER_IN : 0,
112
+ }, children: jsx("div", { className: "relative pb-8", children: jsxs("div", { className: theme.itemContentStyle, children: [jsx("div", { className: "flex size-8 ml-1 shrink-0 items-center justify-center rounded-full bg-[var(--color-background-secondary)] ring-2 ring-[var(--color-background)]/50", children: collapseIcon }), jsx("div", { className: theme.contentStyle, children: jsx("button", { type: "button", className: theme.collapseButtonStyle, onClick: handleToggle, "aria-expanded": true, children: "Show less" }) })] }) }) })] })] }));
113
+ };
114
+ FeedCollapse.displayName = "Feed.Collapse";
115
+ // ---------------------------------------------------------------------------
82
116
  // Compound export
83
117
  // ---------------------------------------------------------------------------
84
118
  const Feed = Object.assign(FeedRoot, {
85
119
  Item: FeedItem,
120
+ Collapse: FeedCollapse,
86
121
  });
87
122
 
88
- export { Feed };
123
+ export { Feed, useFeedContext };
@@ -1,22 +1,20 @@
1
1
  const feedTheme = {
2
2
  // Structural
3
3
  baseStyle: "flow-root",
4
- listStyle: "-mb-8 [&>li:last-child_.feed-connector]:hidden",
4
+ listStyle: "-mb-8 [&>li:last-child>div>.feed-connector]:hidden",
5
5
  itemInnerStyle: "relative pb-8",
6
- itemContentStyle: "relative flex items-start space-x-3",
7
- connectorStyle: "feed-connector absolute top-5 left-[18px] h-full w-0.5 bg-[var(--color-border)]",
6
+ itemContentStyle: "relative flex items-start space-x-4",
7
+ connectorStyle: "feed-connector absolute top-5 left-5 -translate-x-1/2 h-full w-0.5 bg-[var(--color-border)]",
8
8
  // Indicators
9
- dotIndicatorStyle: "relative flex size-9 items-center justify-center",
10
- iconIndicatorStyle: "flex size-9 items-center justify-center rounded-full bg-[var(--color-background-tertiary)] ring-8 ring-[var(--color-background)]",
11
- avatarIndicatorStyle: "relative flex-shrink-0",
9
+ indicatorStyle: "relative flex size-8 ml-1 shrink-0 items-center justify-center bg-[var(--color-background-secondary)] rounded-full ring-2 ring-[var(--color-background)]/50",
10
+ dotIndicatorStyle: "relative flex size-10 items-center justify-center",
12
11
  // Content
13
- contentStyle: "min-w-0 flex-1",
14
- titleStyle: "font-medium text-[var(--color-text-primary)]",
15
- actionTextStyle: "text-base text-[var(--color-text-secondary)]",
16
- timestampStyle: "mt-1 text-sm text-[var(--color-text-muted)]/80 whitespace-nowrap font-medium",
17
- // Comment input
18
- commentInputWrapperStyle: "min-w-0 flex-1 space-y-2",
19
- commentInputFooterStyle: "flex justify-end",
12
+ contentStyle: "min-w-0 flex-1 pt-1",
13
+ timestampStyle: "mt-1 text-xs text-[var(--color-text-muted)]/80 whitespace-nowrap",
14
+ // Collapse
15
+ collapseStyle: "relative",
16
+ collapseButtonStyle: "flex items-center gap-1.5 text-sm font-medium text-[var(--color-primary)] hover:text-[var(--color-primary-700)] transition-colors cursor-pointer bg-transparent border-none p-0",
17
+ collapseSvgStyle: "absolute top-0",
20
18
  };
21
19
 
22
20
  export { feedTheme };
@@ -1,24 +1,17 @@
1
1
  import { ReactNode } from "react";
2
- export type FeedItemVariant = "default" | "icon" | "avatar" | "comment-input";
3
- export interface FeedAvatarConfig {
4
- src?: string;
5
- alt: string;
6
- }
7
2
  export interface FeedTheme {
8
3
  baseStyle: string;
9
4
  listStyle: string;
10
5
  itemInnerStyle: string;
11
6
  itemContentStyle: string;
12
7
  connectorStyle: string;
8
+ indicatorStyle: string;
13
9
  dotIndicatorStyle: string;
14
- iconIndicatorStyle: string;
15
- avatarIndicatorStyle: string;
16
10
  contentStyle: string;
17
- titleStyle: string;
18
- actionTextStyle: string;
19
11
  timestampStyle: string;
20
- commentInputWrapperStyle: string;
21
- commentInputFooterStyle: string;
12
+ collapseStyle: string;
13
+ collapseButtonStyle: string;
14
+ collapseSvgStyle: string;
22
15
  }
23
16
  export interface FeedThemeOverrides {
24
17
  baseStyle?: string;
@@ -26,39 +19,47 @@ export interface FeedThemeOverrides {
26
19
  itemInnerStyle?: string;
27
20
  itemContentStyle?: string;
28
21
  connectorStyle?: string;
22
+ indicatorStyle?: string;
29
23
  dotIndicatorStyle?: string;
30
- iconIndicatorStyle?: string;
31
- avatarIndicatorStyle?: string;
32
24
  contentStyle?: string;
33
- titleStyle?: string;
34
- actionTextStyle?: string;
35
25
  timestampStyle?: string;
36
- commentInputWrapperStyle?: string;
37
- commentInputFooterStyle?: string;
26
+ collapseStyle?: string;
27
+ collapseButtonStyle?: string;
28
+ collapseSvgStyle?: string;
38
29
  }
39
30
  export interface FeedProps extends React.HTMLAttributes<HTMLDivElement> {
40
31
  children: ReactNode;
41
32
  theme?: FeedThemeOverrides;
42
33
  className?: string;
43
34
  }
44
- export interface FeedItemProps extends Omit<React.HTMLAttributes<HTMLLIElement>, "onSubmit"> {
45
- /** Visual variant of the feed item */
46
- variant?: FeedItemVariant;
47
- /** Name/label of the entity that performed the action */
48
- title?: string;
49
- /** Timestamp label (e.g. "6d ago") */
50
- timestamp?: string;
51
- /** Icon element for the "icon" variant indicator */
35
+ /** @internal Injected by Feed.Collapse via cloneElement */
36
+ export interface FeedItemInternalProps {
37
+ _as?: "li" | "div";
38
+ }
39
+ export interface FeedItemProps extends React.HTMLAttributes<HTMLLIElement>, FeedItemInternalProps {
40
+ /** Icon or avatar element rendered as the indicator */
52
41
  icon?: ReactNode;
53
- /** Avatar configuration for avatar/comment-input variants */
54
- avatar?: FeedAvatarConfig;
55
- /** Body content (action description, comment text, etc.) */
42
+ /** Custom className for the indicator wrapper (icon background circle) */
43
+ indicatorClassName?: string;
44
+ /** Timestamp label (e.g. "6d ago") */
45
+ timestamp?: ReactNode;
46
+ /** Body content */
56
47
  children?: ReactNode;
57
- /** Placeholder text for the comment-input textarea */
58
- placeholder?: string;
59
- /** Label for the comment-input submit button */
60
- submitLabel?: string;
61
- /** Callback when the comment-input form is submitted */
62
- onSubmit?: (text: string) => void;
48
+ className?: string;
49
+ }
50
+ export interface FeedCollapseProps {
51
+ /** Template string with `{count}` placeholder for the number of hidden items */
52
+ label?: string;
53
+ /** Icon rendered next to the label */
54
+ icon?: ReactNode;
55
+ /** Uncontrolled initial expanded state */
56
+ defaultExpanded?: boolean;
57
+ /** Controlled expanded state */
58
+ expanded?: boolean;
59
+ /** Callback fired when the toggle is clicked */
60
+ onToggle?: (expanded: boolean) => void;
61
+ /** Feed.Item children to hide/reveal */
62
+ children: ReactNode;
63
+ /** Override className on the wrapper <li> */
63
64
  className?: string;
64
65
  }
@@ -1,2 +1,2 @@
1
1
  export { Feed } from "./Feed";
2
- export type { FeedProps, FeedItemProps, FeedItemVariant, FeedAvatarConfig, FeedTheme, FeedThemeOverrides, } from "./Feed.types";
2
+ export type { FeedProps, FeedItemProps, FeedCollapseProps, FeedItemInternalProps, FeedTheme, FeedThemeOverrides, } from "./Feed.types";
@@ -11,10 +11,10 @@ import { taskBarVariants } from './GanttChart.animations.js';
11
11
  import { useGanttDrag } from './hooks/useGanttDrag.js';
12
12
  import { getDaysBetween, addDays, toDate } from '../../../utils/dateUtils.js';
13
13
 
14
- const GanttTaskBar = React__default.memo(({ task, group, top, }) => {
14
+ const GanttTaskBar = React__default.memo(({ task, group, top }) => {
15
15
  var _a;
16
16
  const { theme, dayWidth, rangeStart, rowHeight, readonly, readonlyDates, readonlyProgress, onTaskUpdate, onTaskClick, tasks, } = useGanttContext();
17
- const { hoveredTaskId, setHoveredTaskId, focusedTaskId, setActiveDrag, } = useGanttInteraction();
17
+ const { hoveredTaskId, setHoveredTaskId, focusedTaskId, setActiveDrag } = useGanttInteraction();
18
18
  const [tooltipPos, setTooltipPos] = useState(null);
19
19
  const offset = getDayOffset(task.startDate, rangeStart);
20
20
  const span = getDaysBetween(task.startDate, task.endDate);
@@ -66,7 +66,9 @@ const GanttTaskBar = React__default.memo(({ task, group, top, }) => {
66
66
  disabled: !canDragDates,
67
67
  onDragEnd: handleResizeLeftEnd,
68
68
  onDragStateChange: useCallback((isDragging, deltaX) => {
69
- setActiveDrag(isDragging ? { taskId: task.id, mode: "resize-left", deltaX } : null);
69
+ setActiveDrag(isDragging
70
+ ? { taskId: task.id, mode: "resize-left", deltaX }
71
+ : null);
70
72
  }, [setActiveDrag, task.id]),
71
73
  });
72
74
  // ----- Drag: Resize right -----
@@ -87,7 +89,9 @@ const GanttTaskBar = React__default.memo(({ task, group, top, }) => {
87
89
  disabled: !canDragDates,
88
90
  onDragEnd: handleResizeRightEnd,
89
91
  onDragStateChange: useCallback((isDragging, deltaX) => {
90
- setActiveDrag(isDragging ? { taskId: task.id, mode: "resize-right", deltaX } : null);
92
+ setActiveDrag(isDragging
93
+ ? { taskId: task.id, mode: "resize-right", deltaX }
94
+ : null);
91
95
  }, [setActiveDrag, task.id]),
92
96
  });
93
97
  // ----- Drag: Progress -----
@@ -151,9 +155,7 @@ const GanttTaskBar = React__default.memo(({ task, group, top, }) => {
151
155
  const hoveredTask = tasks.find((t) => t.id === hoveredTaskId);
152
156
  return (_c = (_b = hoveredTask === null || hoveredTask === void 0 ? void 0 : hoveredTask.dependencies) === null || _b === void 0 ? void 0 : _b.includes(task.id)) !== null && _c !== void 0 ? _c : false;
153
157
  }, [hoveredTaskId, task.id, task.dependencies, tasks]);
154
- const isFaded = hoveredTaskId !== null &&
155
- hoveredTaskId !== task.id &&
156
- !isHighlighted;
158
+ const isFaded = hoveredTaskId !== null && hoveredTaskId !== task.id && !isHighlighted;
157
159
  const isFocused = focusedTaskId === task.id;
158
160
  // ----- Click handler -----
159
161
  const handleClick = (e) => {
@@ -165,7 +167,7 @@ const GanttTaskBar = React__default.memo(({ task, group, top, }) => {
165
167
  const tooltipContent = (jsxs("div", { className: "text-sm space-y-2 min-w-[180px]", children: [jsx("div", { className: "font-semibold text-base", children: task.title }), jsxs("div", { className: "flex items-center gap-1.5 opacity-70", children: [jsx("span", { className: "inline-block size-2 rounded-full shrink-0", style: { backgroundColor: group.color } }), group.title] }), jsxs("div", { className: "space-y-0.5", children: [jsxs("div", { children: [formatDateShort(task.startDate), " \u2014 ", formatDateShort(task.endDate)] }), jsx("div", { className: "opacity-70", children: formatDuration(task.startDate, task.endDate) })] }), jsxs("div", { children: [jsxs("div", { className: "flex justify-between mb-1", children: [jsx("span", { children: "Progress" }), jsxs("span", { className: "font-medium", children: [task.progress, "%"] })] }), jsx("div", { className: "h-1.5 rounded-full bg-white/20 overflow-hidden", children: jsx("div", { className: "h-full rounded-full", style: {
166
168
  width: `${task.progress}%`,
167
169
  backgroundColor: barColor,
168
- } }) })] }), task.assignee && (jsxs("div", { className: "flex items-center gap-1.5 pt-0.5", children: [jsx(Avatar, { src: task.assignee.avatar, alt: task.assignee.name, size: "xs" }), jsx("span", { children: task.assignee.name })] })), isBehindSchedule && (jsxs("div", { className: "text-[var(--color-warning)] text-[10px]", children: ["Behind schedule (expected ", expectedProgress, "%)"] }))] }));
170
+ } }) })] }), task.assignee && (jsxs("div", { className: "flex items-center gap-1.5 pt-0.5", children: [jsx(Avatar, { src: task.assignee.avatar, name: task.assignee.name, size: "xs" }), jsx("span", { children: task.assignee.name })] })), isBehindSchedule && (jsxs("div", { className: "text-[var(--color-warning)] text-[10px]", children: ["Behind schedule (expected ", expectedProgress, "%)"] }))] }));
169
171
  return (jsxs(Fragment, { children: [jsx(GanttTaskContextMenu, { task: task, children: jsxs("div", { className: "absolute", style: {
170
172
  left: visualLeft,
171
173
  top: top + (rowHeight - barHeight) / 2,
@@ -195,7 +197,7 @@ const GanttTaskBar = React__default.memo(({ task, group, top, }) => {
195
197
  } }), isBehindSchedule && (jsx("div", { className: "absolute top-0 bottom-0 w-px", style: {
196
198
  left: `${expectedProgress}%`,
197
199
  borderLeft: "2px dashed rgba(255,255,255,0.5)",
198
- } })), task.completed && (jsx("div", { className: "absolute top-1/2 left-2 right-2 h-px bg-white/60", style: { transform: "translateY(-0.5px)" } })), canDragDates && (jsx("div", { className: "absolute left-0 top-0 bottom-0 w-2 cursor-ew-resize z-20 rounded-l-full opacity-0 group-hover:opacity-100 transition-opacity hover:bg-black/10", onPointerDown: resizeLeftDrag.handlePointerDown })), canDragDates && (jsx("div", { className: "absolute right-0 top-0 bottom-0 w-2 cursor-ew-resize z-20 rounded-r-full opacity-0 group-hover:opacity-100 transition-opacity hover:bg-black/10", onPointerDown: resizeRightDrag.handlePointerDown })), canDragProgress && !isNarrow && (jsx("div", { className: "absolute top-0 bottom-0 w-3 cursor-ew-resize z-20 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity", style: { left: `calc(${displayProgress}% - 6px)` }, onPointerDown: progressDrag.handlePointerDown, children: jsx("div", { className: "w-0.5 h-3 rounded-full bg-white/80 shadow" }) })), !isNarrow && (jsxs("div", { className: "relative flex items-center gap-1.5 px-1 z-10 min-w-0 pointer-events-none", children: [task.assignee && (jsx(Avatar, { src: task.assignee.avatar, alt: task.assignee.name, size: "xs" })), jsx("span", { className: "truncate text-sm text-[var(--color-text-inverse)] font-medium", children: task.title })] }))] }), isNarrow && (jsx("span", { className: "absolute text-sm font-medium whitespace-nowrap pointer-events-none", style: {
200
+ } })), task.completed && (jsx("div", { className: "absolute top-1/2 left-2 right-2 h-px bg-white/60", style: { transform: "translateY(-0.5px)" } })), canDragDates && (jsx("div", { className: "absolute left-0 top-0 bottom-0 w-2 cursor-ew-resize z-20 rounded-l-full opacity-0 group-hover:opacity-100 transition-opacity hover:bg-black/10", onPointerDown: resizeLeftDrag.handlePointerDown })), canDragDates && (jsx("div", { className: "absolute right-0 top-0 bottom-0 w-2 cursor-ew-resize z-20 rounded-r-full opacity-0 group-hover:opacity-100 transition-opacity hover:bg-black/10", onPointerDown: resizeRightDrag.handlePointerDown })), canDragProgress && !isNarrow && (jsx("div", { className: "absolute top-0 bottom-0 w-3 cursor-ew-resize z-20 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity", style: { left: `calc(${displayProgress}% - 6px)` }, onPointerDown: progressDrag.handlePointerDown, children: jsx("div", { className: "w-0.5 h-3 rounded-full bg-white/80 shadow" }) })), !isNarrow && (jsxs("div", { className: "relative flex items-center gap-1.5 px-1 z-10 min-w-0 pointer-events-none", children: [task.assignee && (jsx(Avatar, { src: task.assignee.avatar, name: task.assignee.name, size: "xs" })), jsx("span", { className: "truncate text-sm text-[var(--color-text-inverse)] font-medium", children: task.title })] }))] }), isNarrow && (jsx("span", { className: "absolute text-sm font-medium whitespace-nowrap pointer-events-none", style: {
199
201
  left: visualWidth + 6,
200
202
  top: barHeight / 2,
201
203
  transform: "translateY(-50%)",
@@ -11,7 +11,7 @@ const GanttTaskContextMenu = ({ task, children, }) => {
11
11
  if (readonly || (!onTaskUpdate && !onTaskDuplicate && !onTaskDelete)) {
12
12
  return jsx(Fragment, { children: children });
13
13
  }
14
- return (jsxs(ContextMenu, { children: [jsx(ContextMenu.Trigger, { children: children }), jsxs(ContextMenu.Content, { children: [onTaskUpdate && (jsxs(ContextMenu.Item, { onSelect: () => onTaskUpdate(task.id, { completed: !task.completed, progress: task.completed ? 0 : 100 }), children: [jsx(CheckCircleIcon, { className: "size-4 mr-2" }), task.completed ? "Mark as incomplete" : "Mark as done"] })), onTaskUpdate && (jsxs(ContextMenu.Sub, { children: [jsx(ContextMenu.SubTrigger, { children: "Progress" }), jsx(ContextMenu.SubContent, { children: PROGRESS_STEPS.map((val) => (jsxs(ContextMenu.Item, { onSelect: () => onTaskUpdate(task.id, { progress: val, completed: val === 100 }), children: [val, "%"] }, val))) })] })), (onTaskDuplicate || onTaskDelete) && jsx(ContextMenu.Separator, {}), onTaskDuplicate && (jsxs(ContextMenu.Item, { onSelect: () => onTaskDuplicate(task.id), children: [jsx(DocumentDuplicateIcon, { className: "size-4 mr-2" }), "Duplicate"] })), onTaskDelete && (jsxs(ContextMenu.Item, { onSelect: () => onTaskDelete(task.id), className: "text-[var(--color-danger)]", children: [jsx(TrashIcon, { className: "size-4 mr-2" }), "Delete"] }))] })] }));
14
+ return (jsxs(ContextMenu, { children: [jsx(ContextMenu.Trigger, { children: children }), jsxs(ContextMenu.Body, { children: [onTaskUpdate && (jsxs(ContextMenu.Item, { onSelect: () => onTaskUpdate(task.id, { completed: !task.completed, progress: task.completed ? 0 : 100 }), children: [jsx(CheckCircleIcon, { className: "size-4 mr-2" }), task.completed ? "Mark as incomplete" : "Mark as done"] })), onTaskUpdate && (jsxs(ContextMenu.Sub, { children: [jsx(ContextMenu.SubTrigger, { children: "Progress" }), jsx(ContextMenu.SubBody, { children: PROGRESS_STEPS.map((val) => (jsxs(ContextMenu.Item, { onSelect: () => onTaskUpdate(task.id, { progress: val, completed: val === 100 }), children: [val, "%"] }, val))) })] })), (onTaskDuplicate || onTaskDelete) && jsx(ContextMenu.Separator, {}), onTaskDuplicate && (jsxs(ContextMenu.Item, { onSelect: () => onTaskDuplicate(task.id), children: [jsx(DocumentDuplicateIcon, { className: "size-4 mr-2" }), "Duplicate"] })), onTaskDelete && (jsxs(ContextMenu.Item, { onSelect: () => onTaskDelete(task.id), className: "text-[var(--color-danger)]", children: [jsx(TrashIcon, { className: "size-4 mr-2" }), "Delete"] }))] })] }));
15
15
  };
16
16
 
17
17
  export { GanttTaskContextMenu };
@@ -32,7 +32,7 @@ const KPI = React__default.forwardRef(({ value, label, trend, trendLabel, progre
32
32
  return Math.round((Math.min(Math.max(progress, 0), 100) / 100) * barCount);
33
33
  }, [progress, barCount]);
34
34
  const barSize = kpiTheme.barSizes[size];
35
- return (jsxs("div", { ref: ref, className: cn(theme.baseStyle, className), ...props, children: [jsxs("div", { className: "flex items-start justify-between", children: [jsxs("div", { className: "flex items-baseline gap-2", children: [jsx("span", { className: cn(theme.valueSizes[size]), children: value }), label && (jsxs("span", { className: cn(theme.labelStyle, theme.labelSizes[size]), children: [icon && (jsx("span", { className: "inline-flex items-center mr-1", children: icon })), label] }))] }), formattedTrend && trendDirection && (jsxs("span", { className: cn("inline-flex items-center gap-0.5 font-medium", theme.trendSizes[size], trendDirection === "up" && theme.trendPositive, trendDirection === "down" && theme.trendNegative, trendDirection === "neutral" && theme.trendNeutral), children: [formattedTrend, trendDirection === "up" && jsx(ArrowUpRightIcon, { className: "size-4" }), trendDirection === "down" && jsx(ArrowDownRightIcon, { className: "size-4" })] }))] }), progress !== undefined && (jsx("div", { className: cn("flex items-end", barSize.gap), role: "img", "aria-label": `Progress: ${progress}%`, children: Array.from({ length: barCount }, (_, i) => {
35
+ return (jsxs("div", { ref: ref, className: cn(theme.baseStyle, className), ...props, children: [jsxs("div", { className: "flex items-start justify-between", children: [jsxs("div", { className: "flex items-baseline gap-2", children: [jsx("span", { className: cn(theme.valueSizes[size]), children: value }), label && (typeof label === 'string' ? (jsxs("span", { className: cn(theme.labelStyle, theme.labelSizes[size]), children: [icon && (jsx("span", { className: "inline-flex items-center mr-1", children: icon })), label] })) : label)] }), formattedTrend && trendDirection && (typeof formattedTrend === 'string' ? (jsxs("span", { className: cn("inline-flex items-center gap-0.5 font-medium", theme.trendSizes[size], trendDirection === "up" && theme.trendPositive, trendDirection === "down" && theme.trendNegative, trendDirection === "neutral" && theme.trendNeutral), children: [formattedTrend, trendDirection === "up" && jsx(ArrowUpRightIcon, { className: "size-4" }), trendDirection === "down" && jsx(ArrowDownRightIcon, { className: "size-4" })] })) : formattedTrend)] }), progress !== undefined && (jsx("div", { className: cn("flex items-end", barSize.gap), role: "img", "aria-label": `Progress: ${progress}%`, children: Array.from({ length: barCount }, (_, i) => {
36
36
  const isFilled = i < filledBars;
37
37
  const fadeDistance = filledBars - i;
38
38
  const fillOpacity = isFilled && fadeDistance <= 3
@@ -43,7 +43,7 @@ const KPI = React__default.forwardRef(({ value, label, trend, trendLabel, progre
43
43
  ease: "easeOut",
44
44
  delay: i * 0.03,
45
45
  } })) }, i));
46
- }) })), subtitle && (jsx("span", { className: cn(theme.subtitleStyle, size === "sm" ? "text-sm" : "text-base"), children: subtitle }))] }));
46
+ }) })), subtitle && (typeof subtitle === 'string' ? (jsx("span", { className: cn(theme.subtitleStyle, size === "sm" ? "text-sm" : "text-base"), children: subtitle })) : subtitle)] }));
47
47
  });
48
48
  KPI.displayName = "KPI";
49
49