@flikk/ui 1.0.0-beta.12 → 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 (80) hide show
  1. package/dist/components/ai/StreamingResponse/StreamingResponse.types.d.ts +7 -7
  2. package/dist/components/core/Accordion/Accordion.types.d.ts +1 -7
  3. package/dist/components/core/Accordion/AccordionTrigger.js +4 -6
  4. package/dist/components/core/Alert/Alert.types.d.ts +1 -1
  5. package/dist/components/core/Avatar/Avatar.js +22 -18
  6. package/dist/components/core/Avatar/Avatar.theme.js +1 -1
  7. package/dist/components/core/Avatar/Avatar.types.d.ts +9 -8
  8. package/dist/components/core/AvatarGroup/AvatarGroup.js +2 -2
  9. package/dist/components/core/Badge/Badge.js +7 -5
  10. package/dist/components/core/Badge/Badge.theme.js +11 -4
  11. package/dist/components/core/Badge/Badge.types.d.ts +2 -2
  12. package/dist/components/core/Button/Button.theme.js +2 -2
  13. package/dist/components/core/Calendar/CalendarEvent/CalendarEvent.types.d.ts +5 -6
  14. package/dist/components/core/FileTypeIcon/FileTypeIcon.d.ts +3 -0
  15. package/dist/components/core/FileTypeIcon/FileTypeIcon.js +33 -0
  16. package/dist/components/core/FileTypeIcon/FileTypeIcon.theme.d.ts +2 -0
  17. package/dist/components/core/FileTypeIcon/FileTypeIcon.theme.js +12 -0
  18. package/dist/components/core/FileTypeIcon/FileTypeIcon.types.d.ts +19 -0
  19. package/dist/components/core/FileTypeIcon/fileTypes.d.ts +7 -0
  20. package/dist/components/core/FileTypeIcon/fileTypes.js +30 -0
  21. package/dist/components/core/FileTypeIcon/index.d.ts +2 -0
  22. package/dist/components/core/MenuItem/MenuItem.theme.js +1 -1
  23. package/dist/components/core/Message/Message.js +1 -1
  24. package/dist/components/core/Message/Message.theme.js +2 -2
  25. package/dist/components/core/Message/Message.types.d.ts +6 -6
  26. package/dist/components/core/Message/MessageAvatar.d.ts +2 -2
  27. package/dist/components/core/Message/MessageAvatar.js +3 -3
  28. package/dist/components/core/Popover/PopoverBody.js +19 -8
  29. package/dist/components/core/Tag/Tag.d.ts +1 -1
  30. package/dist/components/core/Tag/Tag.js +2 -2
  31. package/dist/components/core/Tag/Tag.types.d.ts +1 -1
  32. package/dist/components/core/index.d.ts +1 -1
  33. package/dist/components/core/index.js +1 -1
  34. package/dist/components/data-display/Feed/Feed.animations.d.ts +40 -0
  35. package/dist/components/data-display/Feed/Feed.animations.js +26 -0
  36. package/dist/components/data-display/Feed/Feed.d.ts +5 -1
  37. package/dist/components/data-display/Feed/Feed.js +87 -60
  38. package/dist/components/data-display/Feed/Feed.theme.js +11 -13
  39. package/dist/components/data-display/Feed/Feed.types.d.ts +35 -34
  40. package/dist/components/data-display/Feed/index.d.ts +1 -1
  41. package/dist/components/data-display/GanttChart/GanttTaskBar.js +11 -9
  42. package/dist/components/data-display/Timeline/TimelineMarker.js +2 -2
  43. package/dist/components/effects/3d/index.d.ts +1 -1
  44. package/dist/components/effects/AIOrb/AIOrb.d.ts +1 -0
  45. package/dist/components/effects/AIOrb/AIOrb.js +3 -2
  46. package/dist/components/effects/AIOrb/AIOrb.types.d.ts +1 -0
  47. package/dist/components/effects/AIOrb/hooks/index.d.ts +2 -0
  48. package/dist/components/effects/AIOrb/hooks/useOrbState.d.ts +20 -0
  49. package/dist/components/effects/AIOrb/hooks/useOrbState.js +27 -0
  50. package/dist/components/effects/AIOrb/index.d.ts +2 -2
  51. package/dist/components/effects/AIOrb/variants/Aura/Aura.d.ts +3 -0
  52. package/dist/components/effects/AIOrb/variants/Aura/Aura.js +75 -0
  53. package/dist/components/effects/AIOrb/variants/Aura/Aura.shaders.d.ts +28 -0
  54. package/dist/components/effects/AIOrb/variants/Aura/Aura.shaders.js +191 -0
  55. package/dist/components/effects/AIOrb/variants/Aura/Aura.types.d.ts +53 -0
  56. package/dist/components/effects/AIOrb/variants/Aura/ShaderCanvas.d.ts +17 -0
  57. package/dist/components/effects/AIOrb/variants/Aura/ShaderCanvas.js +149 -0
  58. package/dist/components/effects/AIOrb/variants/Aura/index.d.ts +2 -0
  59. package/dist/components/effects/AIOrb/variants/DotSphere/DotSphere.js +38 -7
  60. package/dist/components/effects/AIOrb/variants/DotSphere/DotSphere.types.d.ts +6 -0
  61. package/dist/components/effects/AIOrb/variants/Liquid/Liquid.js +34 -8
  62. package/dist/components/effects/AIOrb/variants/Liquid/Liquid.types.d.ts +6 -0
  63. package/dist/components/effects/AIOrb/variants/index.d.ts +2 -0
  64. package/dist/components/effects/CustomCursor/CustomCursor.d.ts +2 -2
  65. package/dist/components/effects/CustomCursor/CustomCursor.js +50 -47
  66. package/dist/components/effects/GlassSurface/GlassSurface.js +24 -12
  67. package/dist/components/effects/GlassSurface/GlassSurface.types.d.ts +8 -0
  68. package/dist/components/forms/Mention/Mention.js +2 -2
  69. package/dist/index.js +1 -1
  70. package/dist/styles.css +1 -1
  71. package/dist/utils/index.d.ts +1 -0
  72. package/dist/utils/paletteGenerator.d.ts +46 -0
  73. package/package.json +1 -1
  74. package/src/styles/theme.css +2 -6
  75. package/dist/components/core/Loader/Loader.d.ts +0 -24
  76. package/dist/components/core/Loader/Loader.js +0 -57
  77. package/dist/components/core/Loader/Loader.theme.d.ts +0 -27
  78. package/dist/components/core/Loader/Loader.theme.js +0 -60
  79. package/dist/components/core/Loader/Loader.types.d.ts +0 -71
  80. package/dist/components/core/Loader/index.d.ts +0 -2
@@ -2,16 +2,16 @@
2
2
  * StreamingResponse Component Types
3
3
  * Type definitions for the StreamingResponse component
4
4
  */
5
- import type { ReactNode } from 'react';
6
- import type { SSEFormat, SSEParser } from '../../../utils/sseFormatParsers';
7
- import type { StreamingError, RetryConfig } from '../../../utils';
8
- import type { MessageRole } from '../../core/Message';
5
+ import type { ReactNode } from "react";
6
+ import type { SSEFormat, SSEParser } from "../../../utils/sseFormatParsers";
7
+ import type { StreamingError, RetryConfig } from "../../../utils";
8
+ import type { MessageRole } from "../../core/Message";
9
9
  /**
10
10
  * Avatar configuration for Message component
11
11
  */
12
12
  export interface MessageAvatarProps {
13
13
  src?: string;
14
- alt: string;
14
+ name: string;
15
15
  fallback?: ReactNode;
16
16
  }
17
17
  /**
@@ -21,7 +21,7 @@ export interface MarkdownOptions {
21
21
  /** Allow HTML in markdown (default: false) */
22
22
  allowHtml?: boolean;
23
23
  /** Syntax highlighting theme (default: 'light') */
24
- syntaxTheme?: 'light' | 'dark';
24
+ syntaxTheme?: "light" | "dark";
25
25
  /** Custom code block renderer */
26
26
  renderCodeBlock?: (code: string, language: string) => ReactNode;
27
27
  }
@@ -32,7 +32,7 @@ export interface StreamingResponseProps {
32
32
  /** The SSE endpoint URL */
33
33
  url: string;
34
34
  /** HTTP method (default: 'POST') */
35
- method?: 'GET' | 'POST';
35
+ method?: "GET" | "POST";
36
36
  /** Request headers */
37
37
  headers?: Record<string, string>;
38
38
  /** Request body (for POST requests) */
@@ -92,7 +92,7 @@ export interface AccordionTriggerProps extends React.HTMLAttributes<HTMLButtonEl
92
92
  className?: string;
93
93
  /**
94
94
  * Override the default indicator (chevron) icon.
95
- * Set to `null` to hide it entirely — equivalent to `showChevron={false}`.
95
+ * Set to `null` to hide it entirely.
96
96
  */
97
97
  chevron?: React.ReactNode | null;
98
98
  /**
@@ -108,12 +108,6 @@ export interface AccordionTriggerProps extends React.HTMLAttributes<HTMLButtonEl
108
108
  * @default "right"
109
109
  */
110
110
  chevronPosition?: "left" | "right";
111
- /**
112
- * Set to `false` to hide the chevron icon entirely.
113
- * Equivalent to passing `chevron={null}`.
114
- * @default true
115
- */
116
- showChevron?: boolean;
117
111
  /**
118
112
  * @deprecated Use `chevronRotation` instead.
119
113
  */
@@ -7,14 +7,14 @@ import { motion } from 'motion/react';
7
7
  import { PlusIcon } from '@heroicons/react/24/outline';
8
8
  import { createTriggerIconVariants } from './Accordion.animations.js';
9
9
 
10
- const AccordionTrigger = React__default.forwardRef(({ children, className, chevron, chevronRotation, iconRotation, chevronPosition = "right", showChevron = true, ...props }, ref) => {
10
+ const AccordionTrigger = React__default.forwardRef(({ children, className, chevron, chevronRotation, iconRotation, chevronPosition = "right", ...props }, ref) => {
11
11
  var _a;
12
12
  const { theme } = useAccordionContext();
13
13
  const { isOpen, toggle, triggerId, contentId } = useAccordionItemContext();
14
14
  const resolvedChevronRotation = (_a = chevronRotation !== null && chevronRotation !== void 0 ? chevronRotation : iconRotation) !== null && _a !== void 0 ? _a : 45;
15
- // Resolve the indicator icon, respecting showChevron and chevron overrides
15
+ // Resolve the indicator icon
16
16
  const defaultChevronIcon = jsx(PlusIcon, { className: "size-4", strokeWidth: 2 });
17
- const resolvedChevron = !showChevron || chevron === null
17
+ const resolvedChevron = chevron === null
18
18
  ? null
19
19
  : chevron !== undefined
20
20
  ? chevron
@@ -22,9 +22,7 @@ const AccordionTrigger = React__default.forwardRef(({ children, className, chevr
22
22
  ? null // rendered in the left slot instead
23
23
  : defaultChevronIcon;
24
24
  // When chevronPosition="left", render the default animated chevron before children
25
- const useDefaultOnLeft = showChevron && chevron === null
26
- ? false
27
- : showChevron && chevronPosition === "left" && chevron === undefined;
25
+ const useDefaultOnLeft = chevron !== null && chevronPosition === "left" && chevron === undefined;
28
26
  const animatedChevron = (rotation, extraClass) => (jsx(motion.div, { initial: false, animate: isOpen ? "open" : "closed", variants: createTriggerIconVariants(rotation), className: cn("flex items-center justify-center shrink-0", extraClass), children: defaultChevronIcon }));
29
27
  return (jsxs("button", { ref: ref, type: "button", id: triggerId, className: cn(theme === null || theme === void 0 ? void 0 : theme.triggerStyle, className), "aria-expanded": isOpen, "aria-controls": contentId, "data-state": isOpen ? "open" : "closed", onClick: toggle, ...props, children: [useDefaultOnLeft && animatedChevron(resolvedChevronRotation), children, resolvedChevron && (jsx(motion.div, { initial: false, animate: isOpen ? "open" : "closed", variants: createTriggerIconVariants(resolvedChevronRotation), className: "flex items-center justify-center shrink-0 ml-auto", children: resolvedChevron }))] }));
30
28
  });
@@ -45,7 +45,7 @@ export interface AlertProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"
45
45
  showIcon?: boolean;
46
46
  /**
47
47
  * Avatar to display (takes precedence over icons)
48
- * Example: avatar={<Avatar src="..." alt="User name" size="md" />}
48
+ * Example: avatar={<Avatar src="..." name="User name" size="md" />}
49
49
  */
50
50
  avatar?: ReactNode;
51
51
  /**
@@ -4,12 +4,14 @@ import { cn } from '../../../utils/cn.js';
4
4
  import { avatarTheme } from './Avatar.theme.js';
5
5
  import { Tooltip } from '../Tooltip/Tooltip.js';
6
6
  import '../Tooltip/Tooltip.animations.js';
7
+ import { UserIcon } from '@heroicons/react/24/solid';
7
8
 
8
- const Avatar = React__default.forwardRef(({ src, alt = "Avatar", // Default alt text for better accessibility
9
- size = "md", status = "none", fallback, className, role, lazyLoad = true, retryCount = 0, retryDelay = 1000, contextualLabel, groupPosition, showTooltip = false, ...props }, ref) => {
9
+ const Avatar = React__default.forwardRef(({ src, name, size = "md", status = "none", fallback, className, role, lazyLoad = true, retryCount = 0, retryDelay = 1000, contextualLabel, groupPosition, showTooltip = false, initialsCount = 2, ...props }, ref) => {
10
10
  const [imageError, setImageError] = useState(false);
11
11
  const [retries, setRetries] = useState(0);
12
12
  const retryTimerRef = useRef(null);
13
+ // Normalize null to undefined for internal use
14
+ const resolvedName = name !== null && name !== void 0 ? name : undefined;
13
15
  // Clear timeout on unmount to prevent memory leaks
14
16
  useEffect(() => {
15
17
  return () => {
@@ -43,21 +45,23 @@ size = "md", status = "none", fallback, className, role, lazyLoad = true, retryC
43
45
  }, [retries, retryCount, retryDelay]);
44
46
  // Handle fallback content
45
47
  const getFallbackContent = () => {
48
+ // 1. Explicit fallback always wins
46
49
  if (fallback) {
47
50
  return fallback;
48
51
  }
49
- // If no fallback provided and no alt text, use placeholder
50
- if (alt === "Avatar") {
51
- return jsx("span", { "aria-hidden": "true", children: "?" });
52
+ // 2. Generate initials from name
53
+ if (resolvedName) {
54
+ const maxInitials = size === "xs" ? 1 : initialsCount;
55
+ const initials = resolvedName
56
+ .split(" ")
57
+ .map((part) => part[0])
58
+ .slice(0, maxInitials)
59
+ .join("")
60
+ .toUpperCase();
61
+ return jsx("span", { "aria-hidden": "true", children: initials });
52
62
  }
53
- // Use initials from alt text
54
- const initials = alt
55
- .split(" ")
56
- .map((part) => part[0])
57
- .slice(0, 1)
58
- .join("")
59
- .toUpperCase();
60
- return jsx("span", { "aria-hidden": "true", children: initials });
63
+ // 3. Default placeholder icon
64
+ return jsx(UserIcon, { className: "w-1/2 h-1/2" });
61
65
  };
62
66
  // Determine status indicator size based on avatar size
63
67
  const getStatusSize = () => {
@@ -78,15 +82,15 @@ size = "md", status = "none", fallback, className, role, lazyLoad = true, retryC
78
82
  };
79
83
  // Create full accessibility label including context if provided
80
84
  const accessibilityLabel = contextualLabel
81
- ? `${alt}${contextualLabel}`
82
- : alt;
85
+ ? `${resolvedName !== null && resolvedName !== void 0 ? resolvedName : "Avatar"}${contextualLabel}`
86
+ : (resolvedName !== null && resolvedName !== void 0 ? resolvedName : "Avatar");
83
87
  // Determine appropriate ARIA role
84
88
  const ariaRole = role || (src ? undefined : "img");
85
89
  // Avatar content to potentially wrap in tooltip
86
- const avatarContent = (jsxs("div", { ref: ref, className: cn("relative inline-flex avatar-wrapper", groupPosition), role: ariaRole === "presentation" ? "presentation" : undefined, "aria-label": ariaRole === "presentation" ? undefined : accessibilityLabel, "data-size": size, "data-status": status, "data-error": imageError ? "true" : "false", ...props, children: [jsx("div", { className: cn(avatarTheme.baseStyle, avatarTheme.sizes[size], className), "aria-hidden": ariaRole === "presentation" ? "true" : undefined, "data-size": size, children: src && !imageError ? (jsx("img", { src: src, alt: alt, className: "size-full object-cover object-top", onError: handleImageError, loading: lazyLoad ? "lazy" : undefined, "aria-hidden": ariaRole === "presentation" ? "true" : undefined, "data-loaded": "true" })) : (jsx("div", { className: "avatar-fallback", children: getFallbackContent() })) }), status !== "none" && (jsx("span", { className: cn("absolute rounded-full ring-2 ring-[var(--color-background)]", getStatusSize(), avatarTheme.statuses[status]), "aria-label": `Status: ${status}`, role: "status", "data-status": status }))] }));
90
+ const avatarContent = (jsxs("div", { ref: ref, className: cn("relative inline-flex avatar-wrapper", groupPosition), role: ariaRole === "presentation" ? "presentation" : undefined, "aria-label": ariaRole === "presentation" ? undefined : accessibilityLabel, "data-size": size, "data-status": status, "data-error": imageError ? "true" : "false", ...props, children: [jsx("div", { className: cn(avatarTheme.baseStyle, avatarTheme.sizes[size], className), "aria-hidden": ariaRole === "presentation" ? "true" : undefined, "data-size": size, children: src && !imageError ? (jsx("img", { src: src, alt: resolvedName !== null && resolvedName !== void 0 ? resolvedName : "Avatar", className: "size-full object-cover object-top", onError: handleImageError, loading: lazyLoad ? "lazy" : undefined, "aria-hidden": ariaRole === "presentation" ? "true" : undefined, "data-loaded": "true" })) : (jsx("div", { className: "avatar-fallback", children: getFallbackContent() })) }), status !== "none" && (jsx("span", { className: cn("absolute rounded-full ring-2 ring-[var(--color-background)]", getStatusSize(), avatarTheme.statuses[status]), "aria-label": `Status: ${status}`, role: "status", "data-status": status }))] }));
87
91
  // Conditionally wrap in tooltip
88
- if (showTooltip && alt && alt !== "Avatar") {
89
- return (jsx(Tooltip, { content: alt, placement: "top", children: avatarContent }));
92
+ if (showTooltip && resolvedName) {
93
+ return (jsx(Tooltip, { content: resolvedName, placement: "top", children: avatarContent }));
90
94
  }
91
95
  return avatarContent;
92
96
  });
@@ -3,7 +3,7 @@
3
3
  */
4
4
  const avatarTheme = {
5
5
  // Base styles for the avatar element
6
- baseStyle: "relative inline-flex items-center justify-center overflow-hidden bg-neutral-200 text-[var(--color-text-primary)] font-semibold tracking-tighter rounded-[var(--avatar-radius)] ring-2 ring-[var(--color-primary)]/10 border border-[var(--border)] transition-all duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-primary)] focus-visible:ring-offset-2 glass-effect",
6
+ baseStyle: "relative inline-flex items-center justify-center overflow-hidden bg-neutral-200 text-[var(--color-text-primary)] font-bold tracking-tighter rounded-[var(--avatar-radius)] border border-[var(--color-border)] transition-all duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-primary)] focus-visible:ring-offset-2",
7
7
  // Size variants using CSS variables
8
8
  sizes: {
9
9
  xs: "size-[var(--avatar-size-xs)] text-xs",
@@ -1,17 +1,17 @@
1
- import { ReactNode } from 'react';
2
- export type AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
3
- export type AvatarStatus = 'online' | 'offline' | 'busy' | 'away' | 'none';
1
+ import { ReactNode } from "react";
2
+ export type AvatarSize = "xs" | "sm" | "md" | "lg" | "xl";
3
+ export type AvatarStatus = "online" | "offline" | "busy" | "away" | "none";
4
4
  export interface AvatarProps extends React.HTMLAttributes<HTMLDivElement> {
5
5
  /**
6
6
  * The source URL for the avatar image
7
7
  */
8
8
  src?: string;
9
9
  /**
10
- * Alternative text for the avatar image.
11
- * Should describe the person or entity represented by the avatar.
12
- * @default "Avatar"
10
+ * The name of the person or entity represented by the avatar.
11
+ * Used to generate initials for the fallback and as alt text for the image.
12
+ * Accepts `null` for compatibility with nullable data sources.
13
13
  */
14
- alt?: string;
14
+ name?: string | null;
15
15
  /**
16
16
  * The size of the avatar
17
17
  * @default "md"
@@ -23,7 +23,8 @@ export interface AvatarProps extends React.HTMLAttributes<HTMLDivElement> {
23
23
  */
24
24
  status?: AvatarStatus;
25
25
  /**
26
- * Fallback content to display when image fails to load or no src is provided
26
+ * Fallback content to display when image fails to load or no src is provided.
27
+ * Overrides the default placeholder icon and auto-generated initials.
27
28
  */
28
29
  fallback?: ReactNode;
29
30
  /**
@@ -18,7 +18,7 @@ const AvatarGroup = React__default.forwardRef(({ avatars = [], max = 5, size = "
18
18
  const directionClass = direction === "row-reverse" ? "flex-row-reverse" : "flex-row";
19
19
  const totalPeople = avatars.length;
20
20
  const groupDescription = avatars
21
- .map((avatar) => avatar.alt || "User")
21
+ .map((avatar) => avatar.name || "User")
22
22
  .join(", ");
23
23
  return {
24
24
  visibleAvatars,
@@ -49,7 +49,7 @@ const AvatarGroup = React__default.forwardRef(({ avatars = [], max = 5, size = "
49
49
  // Ensure that groupPosition is not passed to avoid conflicts
50
50
  groupPosition: undefined }) }, index));
51
51
  }), overflowCount > 0 && (jsx("div", { className: cn(spacingClass, enableAnimations &&
52
- "transition-transform duration-200 hover:scale-110"), "data-overflow-count": overflowCount, children: overflowIndicator ? (overflowIndicator(overflowCount)) : (jsx(Avatar, { size: size, alt: `+${overflowCount} more`, fallback: jsxs("span", { children: ["+", overflowCount] }), className: avatarGroupTheme.overflowAvatarStyle, role: "img", "aria-label": `+ ${overflowCount} more users` })) }))] }));
52
+ "transition-transform duration-200 hover:scale-110"), "data-overflow-count": overflowCount, children: overflowIndicator ? (overflowIndicator(overflowCount)) : (jsx(Avatar, { size: size, name: `+${overflowCount} more`, fallback: jsxs("span", { children: ["+", overflowCount] }), className: avatarGroupTheme.overflowAvatarStyle, role: "img", "aria-label": `+ ${overflowCount} more users` })) }))] }));
53
53
  });
54
54
  // Set display name for dev tools and Storybook
55
55
  AvatarGroup.displayName = "AvatarGroup";
@@ -164,14 +164,16 @@ const Badge = React__default.memo(React__default.forwardRef(({ children, variant
164
164
  // Apply negative margin for overlap effect (scales with badge size)
165
165
  const avatarMargin = pill
166
166
  ? {
167
- sm: "-ml-1.5", // Small pill: minimal overlap
168
- md: "-ml-1.5", // Medium pill: moderate overlap
167
+ xs: "-ml-1",
168
+ sm: "-ml-1.5",
169
+ md: "-ml-1.5",
169
170
  }[size]
170
171
  : {
171
- sm: "-ml-1.5", // Small default: minimal overlap
172
- md: "-ml-1", // Medium default: less overlap (has border ring)
172
+ xs: "-ml-1",
173
+ sm: "-ml-1.5",
174
+ md: "-ml-1",
173
175
  }[size];
174
- return (jsx(Avatar, { src: avatar.src, alt: avatar.alt, fallback: avatar.fallback, initialsCount: avatar.initialsCount, className: cn((_a = theme.avatarSizes) === null || _a === void 0 ? void 0 : _a[size], avatarMargin, "border-0", pill ? "rounded-full" : "rounded-md ring-0") }));
176
+ return (jsx(Avatar, { src: avatar.src, name: avatar.name, fallback: avatar.fallback, initialsCount: avatar.initialsCount, className: cn((_a = theme.avatarSizes) === null || _a === void 0 ? void 0 : _a[size], avatarMargin, "border-0", pill ? "rounded-full" : "rounded-md ring-0") }));
175
177
  }
176
178
  if (iconStart) {
177
179
  return (jsx("span", { className: cn("inline-flex items-center justify-center flex-shrink-0", (_b = theme.iconSizes) === null || _b === void 0 ? void 0 : _b[size]), "aria-hidden": "true", children: iconStart }));
@@ -6,7 +6,7 @@ import { semanticBgColors } from '../../../utils/colorUtils.js';
6
6
  */
7
7
  const badgeTheme = {
8
8
  // Base styles applied to all badges
9
- baseStyle: "inline-flex items-center font-semibold select-none whitespace-nowrap transition-all duration-300 h-fit",
9
+ baseStyle: "inline-flex items-center align-middle select-none whitespace-nowrap transition-all duration-300 h-fit",
10
10
  // Visual style variants (structure only, no colors)
11
11
  variants: {
12
12
  filled: "",
@@ -47,7 +47,7 @@ const badgeTheme = {
47
47
  },
48
48
  // Ghost variant - subtle background tints
49
49
  ghost: {
50
- neutral: "bg-[var(--color-neutral-200)] text-[var(--color-text-secondary)] " +
50
+ neutral: "bg-[var(--color-neutral-200)] text-[var(--color-text-primary)] " +
51
51
  "dark:bg-[var(--color-neutral-900)] ",
52
52
  primary: "bg-[var(--color-primary-100)] text-[var(--color-primary-700)] " +
53
53
  "dark:bg-[var(--color-primary-600)]/30 dark:text-[var(--color-primary-400)]",
@@ -63,36 +63,43 @@ const badgeTheme = {
63
63
  },
64
64
  // Flat size structure (no nested objects)
65
65
  sizes: {
66
- sm: "text-sm px-1.5 py-0.5 gap-1",
67
- md: "text-base px-2 py-0.5 gap-1",
66
+ xs: "text-xs px-1 py-0 gap-1 font-medium",
67
+ sm: "text-sm px-1.5 py-0 gap-1 font-medium",
68
+ md: "text-sm px-2 py-0.25 gap-1 font-semibold",
68
69
  },
69
70
  // Border radius per size (using CSS variable)
70
71
  radiusSizes: {
72
+ xs: "rounded-[calc(var(--badge-radius)*0.5)]",
71
73
  sm: "rounded-[calc(var(--badge-radius)*0.75)]",
72
74
  md: "rounded-[var(--badge-radius)]",
73
75
  },
74
76
  // Additional padding for pill shape
75
77
  pillSizes: {
78
+ xs: "px-1.5",
76
79
  sm: "px-2",
77
80
  md: "px-2.5",
78
81
  },
79
82
  // Icon sizes
80
83
  iconSizes: {
84
+ xs: "size-2.5",
81
85
  sm: "size-3",
82
86
  md: "size-3.5",
83
87
  },
84
88
  // Avatar sizes (base sizes without negative margin)
85
89
  avatarSizes: {
90
+ xs: "size-3.5",
86
91
  sm: "size-4",
87
92
  md: "size-4",
88
93
  },
89
94
  // Dismiss button container sizes
90
95
  dismissButtonSizes: {
96
+ xs: "size-3",
91
97
  sm: "size-3.5",
92
98
  md: "size-4",
93
99
  },
94
100
  // Dismiss icon sizes (inside button)
95
101
  dismissIconSizes: {
102
+ xs: "size-2",
96
103
  sm: "size-2.5",
97
104
  md: "size-3",
98
105
  },
@@ -2,7 +2,7 @@ import React, { ReactNode, MouseEvent } from "react";
2
2
  import { SemanticColor } from "../../../utils/colorUtils";
3
3
  export type BadgeVariant = "filled" | "outline" | "ghost";
4
4
  export type BadgeColor = SemanticColor;
5
- export type BadgeSize = "sm" | "md";
5
+ export type BadgeSize = "xs" | "sm" | "md";
6
6
  /**
7
7
  * Theme configuration for Badge component
8
8
  */
@@ -122,7 +122,7 @@ export interface BadgeProps extends Omit<React.HTMLAttributes<HTMLSpanElement>,
122
122
  */
123
123
  avatar?: {
124
124
  src?: string;
125
- alt: string;
125
+ name: string;
126
126
  fallback?: ReactNode;
127
127
  initialsCount?: number;
128
128
  };
@@ -124,9 +124,9 @@ const buttonTheme = {
124
124
  // Size variants
125
125
  sizes: {
126
126
  sm: {
127
- default: "font-semibold min-h-[var(--button-min-h-sm)] px-[var(--button-px-sm)] py-[var(--button-py-sm)] text-base",
127
+ default: "font-semibold min-h-[var(--button-min-h-sm)] px-[var(--button-px-sm)] py-[var(--button-py-sm)] text-sm",
128
128
  iconOnly: "size-[var(--button-icon-size-sm)] p-[var(--button-icon-p-sm)]",
129
- link: "font-semibold p-0 text-base h-fit",
129
+ link: "font-semibold p-0 text-sm h-fit",
130
130
  },
131
131
  md: {
132
132
  default: "font-semibold min-h-[var(--button-min-h-md)] px-[var(--button-px-md)] py-[var(--button-py-md)] text-base",
@@ -1,7 +1,7 @@
1
- import { HTMLAttributes } from 'react';
2
- import { CalendarEventThemeOverrides } from './CalendarEvent.theme';
3
- import { CalendarEvent as CalendarEventType, GridConfig, EventPosition } from '../../../../utils';
4
- export type CalendarEventVariant = 'daily' | 'weekly' | 'monthly';
1
+ import { HTMLAttributes } from "react";
2
+ import { CalendarEventThemeOverrides } from "./CalendarEvent.theme";
3
+ import { CalendarEvent as CalendarEventType, GridConfig, EventPosition } from "../../../../utils";
4
+ export type CalendarEventVariant = "daily" | "weekly" | "monthly";
5
5
  export interface CalendarEventProps extends HTMLAttributes<HTMLDivElement> {
6
6
  variant?: CalendarEventVariant;
7
7
  event: CalendarEventType & {
@@ -9,7 +9,6 @@ export interface CalendarEventProps extends HTMLAttributes<HTMLDivElement> {
9
9
  attendees?: Array<{
10
10
  name: string;
11
11
  src: string;
12
- alt: string;
13
12
  showTooltip?: boolean;
14
13
  }>;
15
14
  };
@@ -20,5 +19,5 @@ export interface CalendarEventProps extends HTMLAttributes<HTMLDivElement> {
20
19
  gridInterval?: number;
21
20
  startOffset?: number;
22
21
  theme?: CalendarEventThemeOverrides;
23
- onEventClick?: (eventData: CalendarEventProps['event']) => void;
22
+ onEventClick?: (eventData: CalendarEventProps["event"]) => void;
24
23
  }
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { FileTypeIconProps } from './FileTypeIcon.types';
3
+ export declare const FileTypeIcon: React.ForwardRefExoticComponent<Omit<FileTypeIconProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
@@ -0,0 +1,33 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import React__default from 'react';
3
+ import { cn } from '../../../utils/cn.js';
4
+ import { fileTypeIconTheme } from './FileTypeIcon.theme.js';
5
+ import { fileTypes } from './fileTypes.js';
6
+
7
+ const FileTypeIcon = React__default.forwardRef(({ type, size = 'md', colorMode = 'color', className, theme: customTheme, ...props }, ref) => {
8
+ var _a;
9
+ const fileType = fileTypes[type];
10
+ if (!fileType) {
11
+ if (process.env.NODE_ENV !== 'production') {
12
+ console.warn(`[FileTypeIcon]: Unknown type "${type}". Available types: ${Object.keys(fileTypes).join(', ')}`);
13
+ }
14
+ return null;
15
+ }
16
+ const theme = {
17
+ ...fileTypeIconTheme,
18
+ ...customTheme,
19
+ sizes: { ...fileTypeIconTheme.sizes, ...customTheme === null || customTheme === void 0 ? void 0 : customTheme.sizes },
20
+ };
21
+ const resolvedSize = typeof size === 'number' ? size : (_a = theme.sizes[size]) !== null && _a !== void 0 ? _a : 24;
22
+ const strokeColor = colorMode === 'color' ? '#D5D7DA' : 'currentColor';
23
+ const strokeOpacity = colorMode === 'color' ? 1 : 0.3;
24
+ const badgeColor = colorMode === 'color' ? fileType.color : 'currentColor';
25
+ const labelText = fileType.label;
26
+ const badgeWidth = Math.round(labelText.length * 6 + 8);
27
+ const badgeX = 1;
28
+ const textX = badgeX + badgeWidth / 2;
29
+ return (jsxs("svg", { ref: ref, xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 40 40", width: resolvedSize, height: resolvedSize, fill: "none", role: "img", "aria-label": `${fileType.label} file`, "data-type": type, "data-color-mode": colorMode, "data-size": size, className: cn(theme.baseStyle, className), ...props, children: [jsx("path", { d: "M11 0.75H27C27.1212 0.75 27.2375 0.798088 27.3232 0.883789L38.1162 11.6768C38.2019 11.7625 38.25 11.8788 38.25 12V36C38.25 37.7949 36.7949 39.25 35 39.25H11C9.20507 39.25 7.75 37.7949 7.75 36V4C7.75 2.20507 9.20508 0.75 11 0.75Z", stroke: strokeColor, strokeWidth: "1.5", opacity: strokeOpacity }), jsx("path", { d: "M27 0.5V8C27 10.2091 28.7909 12 31 12H38.5", stroke: strokeColor, strokeWidth: "1.5", opacity: strokeOpacity }), jsx("rect", { x: badgeX, y: 18, width: badgeWidth, height: 16, rx: 2, fill: badgeColor, opacity: colorMode === 'color' ? 1 : 0.15 }), jsx("text", { x: textX, y: 26, textAnchor: "middle", dominantBaseline: "central", fill: colorMode === 'color' ? 'white' : 'currentColor', fontSize: 9.5, fontWeight: 700, fontFamily: "Arial, Helvetica, sans-serif", letterSpacing: 0.3, children: labelText })] }));
30
+ });
31
+ FileTypeIcon.displayName = 'FileTypeIcon';
32
+
33
+ export { FileTypeIcon };
@@ -0,0 +1,2 @@
1
+ import { FileTypeIconTheme } from './FileTypeIcon.types';
2
+ export declare const fileTypeIconTheme: FileTypeIconTheme;
@@ -0,0 +1,12 @@
1
+ const fileTypeIconTheme = {
2
+ baseStyle: 'inline-block shrink-0',
3
+ sizes: {
4
+ xs: 16,
5
+ sm: 20,
6
+ md: 24,
7
+ lg: 32,
8
+ xl: 40,
9
+ },
10
+ };
11
+
12
+ export { fileTypeIconTheme };
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ export type FileTypeName = 'pdf' | 'doc' | 'docx' | 'txt' | 'xls' | 'xlsx' | 'csv' | 'ppt' | 'mp3' | 'wav' | 'mp4' | 'mov' | 'jpg' | 'png' | 'svg' | 'gif' | 'zip' | 'rar';
3
+ export type FileTypeIconSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
4
+ export type FileTypeIconColorMode = 'color' | 'mono';
5
+ export interface FileTypeIconTheme {
6
+ baseStyle: string;
7
+ sizes: Record<FileTypeIconSize, number>;
8
+ }
9
+ export interface FileTypeIconThemeOverrides {
10
+ baseStyle?: string;
11
+ sizes?: Partial<Record<FileTypeIconSize, number>>;
12
+ }
13
+ export interface FileTypeIconProps extends React.SVGProps<SVGSVGElement> {
14
+ type: FileTypeName;
15
+ size?: FileTypeIconSize | number;
16
+ colorMode?: FileTypeIconColorMode;
17
+ className?: string;
18
+ theme?: FileTypeIconThemeOverrides;
19
+ }
@@ -0,0 +1,7 @@
1
+ import { FileTypeName } from './FileTypeIcon.types';
2
+ export interface FileTypeData {
3
+ label: string;
4
+ color: string;
5
+ category: string;
6
+ }
7
+ export declare const fileTypes: Record<FileTypeName, FileTypeData>;
@@ -0,0 +1,30 @@
1
+ const fileTypes = {
2
+ // PDF
3
+ pdf: { label: 'PDF', color: '#E5252A', category: 'pdf' },
4
+ // Documents
5
+ doc: { label: 'DOC', color: '#2B7CD3', category: 'document' },
6
+ docx: { label: 'DOCX', color: '#2B7CD3', category: 'document' },
7
+ txt: { label: 'TXT', color: '#4B5563', category: 'document' },
8
+ // Spreadsheets
9
+ xls: { label: 'XLS', color: '#1D6F42', category: 'spreadsheet' },
10
+ xlsx: { label: 'XLSX', color: '#1D6F42', category: 'spreadsheet' },
11
+ csv: { label: 'CSV', color: '#1D6F42', category: 'spreadsheet' },
12
+ // Presentations
13
+ ppt: { label: 'PPT', color: '#D04423', category: 'presentation' },
14
+ // Audio
15
+ mp3: { label: 'MP3', color: '#8B5CF6', category: 'audio' },
16
+ wav: { label: 'WAV', color: '#8B5CF6', category: 'audio' },
17
+ // Video
18
+ mp4: { label: 'MP4', color: '#7C3AED', category: 'video' },
19
+ mov: { label: 'MOV', color: '#7C3AED', category: 'video' },
20
+ // Images
21
+ jpg: { label: 'JPG', color: '#F59E0B', category: 'image' },
22
+ png: { label: 'PNG', color: '#F59E0B', category: 'image' },
23
+ svg: { label: 'SVG', color: '#F59E0B', category: 'image' },
24
+ gif: { label: 'GIF', color: '#F59E0B', category: 'image' },
25
+ // Archives
26
+ zip: { label: 'ZIP', color: '#CA8A04', category: 'archive' },
27
+ rar: { label: 'RAR', color: '#CA8A04', category: 'archive' },
28
+ };
29
+
30
+ export { fileTypes };
@@ -0,0 +1,2 @@
1
+ export { FileTypeIcon } from './FileTypeIcon';
2
+ export type { FileTypeIconProps, FileTypeName, FileTypeIconSize, FileTypeIconColorMode, FileTypeIconTheme, FileTypeIconThemeOverrides, } from './FileTypeIcon.types';
@@ -1,6 +1,6 @@
1
1
  const menuItemTheme = {
2
2
  // Base item styling with hover, focus, and disabled states
3
- baseStyle: "relative flex items-center gap-2 px-2.5 py-1.5 text-base font-[500] text-[var(--color-text-primary)] cursor-pointer outline-none select-none rounded-[var(--radius-base)] transition-colors duration-300 " +
3
+ baseStyle: "relative flex items-center gap-2 px-3 py-1.5 text-base font-[500] text-[var(--color-text-primary)] cursor-pointer outline-none select-none rounded-[var(--radius-base)] transition-colors duration-300 " +
4
4
  "hover:bg-[var(--color-background-secondary)] focus:bg-[var(--color-background-secondary)] " +
5
5
  "data-[focused=true]:bg-[var(--color-background-secondary)] " +
6
6
  "data-[selected=true]:bg-[var(--color-primary)]/5 data-[selected=true]:text-[var(--color-primary)] " +
@@ -100,7 +100,7 @@ const MessageRoot = React__default.forwardRef(({ role, variant: variantProp, con
100
100
  if (variant === "system") {
101
101
  return (jsx("div", { ref: ref, className: cn("w-full max-w-full", className), "data-variant": "system", "data-role": role, ...props, children: jsxs("div", { className: containerStyle, children: [jsx("div", { className: bubbleStyle, children: typeof renderedContent === "string" ? (jsx("p", { className: "text-base", children: renderedContent })) : (renderedContent) }), jsx(MessageFooter, { isStreaming: isStreaming, streamingIndicator: streamingIndicator, showTimestamp: showTimestamp, timestamp: timestamp, actions: undefined, timestampStyle: timestampStyle, streamingIndicatorStyle: cn(messageTheme.streamingIndicatorStyle, customTheme.streamingIndicatorStyle), actionsContainerStyle: undefined, variant: "system" })] }) }));
102
102
  }
103
- return (jsx("div", { ref: ref, className: cn("w-full max-w-full group", className), "data-variant": variant, "data-role": role, ...props, children: jsxs("div", { className: containerStyle, children: [avatar && (jsx("div", { className: "flex-shrink-0", children: jsx(Avatar, { src: avatar.src, alt: avatar.alt, fallback: avatar.fallback, size: "xs" }) })), jsxs("div", { className: cn("flex flex-col", variant === "sender" ? "items-end" : "items-start"), children: [jsx("div", { className: bubbleStyle, children: typeof renderedContent === "string" ? (jsx("p", { className: "break-words", children: renderedContent })) : (renderedContent) }), jsx(MessageFooter, { isStreaming: isStreaming, streamingIndicator: streamingIndicator, showTimestamp: showTimestamp, timestamp: timestamp, actions: finalActions, timestampStyle: timestampStyle, streamingIndicatorStyle: cn(messageTheme.streamingIndicatorStyle, customTheme.streamingIndicatorStyle), actionsContainerStyle: cn(messageTheme.actionsContainerStyle, customTheme.actionsContainerStyle), variant: variant })] })] }) }));
103
+ return (jsx("div", { ref: ref, className: cn("w-full max-w-full group", className), "data-variant": variant, "data-role": role, ...props, children: jsxs("div", { className: containerStyle, children: [avatar && (jsx("div", { className: "flex-shrink-0", children: jsx(Avatar, { src: avatar.src, name: avatar.name, fallback: avatar.fallback, size: "xs" }) })), jsxs("div", { className: cn("flex flex-col", variant === "sender" ? "items-end" : "items-start"), children: [jsx("div", { className: bubbleStyle, children: typeof renderedContent === "string" ? (jsx("p", { className: "break-words", children: renderedContent })) : (renderedContent) }), jsx(MessageFooter, { isStreaming: isStreaming, streamingIndicator: streamingIndicator, showTimestamp: showTimestamp, timestamp: timestamp, actions: finalActions, timestampStyle: timestampStyle, streamingIndicatorStyle: cn(messageTheme.streamingIndicatorStyle, customTheme.streamingIndicatorStyle), actionsContainerStyle: cn(messageTheme.actionsContainerStyle, customTheme.actionsContainerStyle), variant: variant })] })] }) }));
104
104
  });
105
105
  MessageRoot.displayName = "Message";
106
106
  // Attach compound components
@@ -6,12 +6,12 @@ const messageTheme = {
6
6
  // Shared base styles (apply to all variants)
7
7
  bubbleBaseStyle: "max-w-[80%] sm:max-w-[85%] rounded-[calc(var(--radius-base)*1.5)] px-3 py-2 w-fit min-w-fit h-fit",
8
8
  containerBaseStyle: "flex items-start gap-3 h-fit text-base",
9
- timestampStyle: "text-sm text-[var(--color-text-placeholder)] dark:text-[var(--color-neutral-500)]",
9
+ timestampStyle: "text-xs text-[var(--color-text-placeholder)] dark:text-[var(--color-neutral-500)]",
10
10
  // Variant-specific modifiers (only differences)
11
11
  variants: {
12
12
  sender: {
13
13
  containerModifier: "flex-row-reverse", // Reverse direction for right alignment
14
- bubbleStyle: "bg-[var(--color-background-secondary)] text-[var(--color-text-secondary)] " +
14
+ bubbleStyle: "bg-[var(--color-neutral-900)] text-[var(--color-neutral-100)] " +
15
15
  "rounded-tr-xs " +
16
16
  // Dark mode - slightly darker gradient for better contrast
17
17
  " ",
@@ -1,12 +1,12 @@
1
- import { ReactNode } from 'react';
1
+ import { ReactNode } from "react";
2
2
  /**
3
3
  * Message role types for AI conversations
4
4
  */
5
- export type MessageRole = 'user' | 'assistant' | 'system';
5
+ export type MessageRole = "user" | "assistant" | "system";
6
6
  /**
7
7
  * Message variant types for chat UI
8
8
  */
9
- export type MessageVariant = 'sender' | 'receiver' | 'system';
9
+ export type MessageVariant = "sender" | "receiver" | "system";
10
10
  /**
11
11
  * Avatar configuration for message sender
12
12
  */
@@ -16,9 +16,9 @@ export interface MessageAvatarProps {
16
16
  */
17
17
  src?: string;
18
18
  /**
19
- * Alternative text for the avatar image
19
+ * The name for the avatar (used for initials and alt text)
20
20
  */
21
- alt: string;
21
+ name: string;
22
22
  /**
23
23
  * Fallback content to display when image fails to load
24
24
  */
@@ -28,7 +28,7 @@ export interface MessageAvatarProps {
28
28
  * Message component props
29
29
  * Supports both props-based API and compound component API
30
30
  */
31
- export interface MessageProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'content'> {
31
+ export interface MessageProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "content"> {
32
32
  /**
33
33
  * The role of the message sender (AI semantic naming)
34
34
  * Takes precedence over variant if both are provided
@@ -1,11 +1,11 @@
1
- import React from 'react';
1
+ import React from "react";
2
2
  export interface MessageAvatarComponentProps extends React.HTMLAttributes<HTMLDivElement> {
3
3
  /**
4
4
  * The source URL for the avatar image
5
5
  */
6
6
  src?: string;
7
7
  /**
8
- * The name or alt text for the avatar
8
+ * The name for the avatar
9
9
  */
10
10
  name: string;
11
11
  /**