@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.
- package/dist/components/ai/StreamingResponse/StreamingResponse.types.d.ts +7 -7
- package/dist/components/core/Accordion/Accordion.types.d.ts +1 -7
- package/dist/components/core/Accordion/AccordionTrigger.js +4 -6
- package/dist/components/core/Alert/Alert.types.d.ts +1 -1
- package/dist/components/core/Avatar/Avatar.js +22 -18
- package/dist/components/core/Avatar/Avatar.theme.js +1 -1
- package/dist/components/core/Avatar/Avatar.types.d.ts +9 -8
- package/dist/components/core/AvatarGroup/AvatarGroup.js +2 -2
- package/dist/components/core/Badge/Badge.js +7 -5
- package/dist/components/core/Badge/Badge.theme.js +11 -4
- package/dist/components/core/Badge/Badge.types.d.ts +2 -2
- package/dist/components/core/Button/Button.theme.js +2 -2
- package/dist/components/core/Calendar/CalendarEvent/CalendarEvent.types.d.ts +5 -6
- package/dist/components/core/FileTypeIcon/FileTypeIcon.d.ts +3 -0
- package/dist/components/core/FileTypeIcon/FileTypeIcon.js +33 -0
- package/dist/components/core/FileTypeIcon/FileTypeIcon.theme.d.ts +2 -0
- package/dist/components/core/FileTypeIcon/FileTypeIcon.theme.js +12 -0
- package/dist/components/core/FileTypeIcon/FileTypeIcon.types.d.ts +19 -0
- package/dist/components/core/FileTypeIcon/fileTypes.d.ts +7 -0
- package/dist/components/core/FileTypeIcon/fileTypes.js +30 -0
- package/dist/components/core/FileTypeIcon/index.d.ts +2 -0
- package/dist/components/core/MenuItem/MenuItem.theme.js +1 -1
- package/dist/components/core/Message/Message.js +1 -1
- package/dist/components/core/Message/Message.theme.js +2 -2
- package/dist/components/core/Message/Message.types.d.ts +6 -6
- package/dist/components/core/Message/MessageAvatar.d.ts +2 -2
- package/dist/components/core/Message/MessageAvatar.js +3 -3
- package/dist/components/core/Popover/PopoverBody.js +19 -8
- package/dist/components/core/Tag/Tag.d.ts +1 -1
- package/dist/components/core/Tag/Tag.js +2 -2
- package/dist/components/core/Tag/Tag.types.d.ts +1 -1
- package/dist/components/core/index.d.ts +1 -1
- package/dist/components/core/index.js +1 -1
- package/dist/components/data-display/Feed/Feed.animations.d.ts +40 -0
- package/dist/components/data-display/Feed/Feed.animations.js +26 -0
- package/dist/components/data-display/Feed/Feed.d.ts +5 -1
- package/dist/components/data-display/Feed/Feed.js +87 -60
- package/dist/components/data-display/Feed/Feed.theme.js +11 -13
- package/dist/components/data-display/Feed/Feed.types.d.ts +35 -34
- package/dist/components/data-display/Feed/index.d.ts +1 -1
- package/dist/components/data-display/GanttChart/GanttTaskBar.js +11 -9
- package/dist/components/data-display/Timeline/TimelineMarker.js +2 -2
- package/dist/components/effects/3d/index.d.ts +1 -1
- package/dist/components/effects/AIOrb/AIOrb.d.ts +1 -0
- package/dist/components/effects/AIOrb/AIOrb.js +3 -2
- package/dist/components/effects/AIOrb/AIOrb.types.d.ts +1 -0
- package/dist/components/effects/AIOrb/hooks/index.d.ts +2 -0
- package/dist/components/effects/AIOrb/hooks/useOrbState.d.ts +20 -0
- package/dist/components/effects/AIOrb/hooks/useOrbState.js +27 -0
- package/dist/components/effects/AIOrb/index.d.ts +2 -2
- package/dist/components/effects/AIOrb/variants/Aura/Aura.d.ts +3 -0
- package/dist/components/effects/AIOrb/variants/Aura/Aura.js +75 -0
- package/dist/components/effects/AIOrb/variants/Aura/Aura.shaders.d.ts +28 -0
- package/dist/components/effects/AIOrb/variants/Aura/Aura.shaders.js +191 -0
- package/dist/components/effects/AIOrb/variants/Aura/Aura.types.d.ts +53 -0
- package/dist/components/effects/AIOrb/variants/Aura/ShaderCanvas.d.ts +17 -0
- package/dist/components/effects/AIOrb/variants/Aura/ShaderCanvas.js +149 -0
- package/dist/components/effects/AIOrb/variants/Aura/index.d.ts +2 -0
- package/dist/components/effects/AIOrb/variants/DotSphere/DotSphere.js +38 -7
- package/dist/components/effects/AIOrb/variants/DotSphere/DotSphere.types.d.ts +6 -0
- package/dist/components/effects/AIOrb/variants/Liquid/Liquid.js +34 -8
- package/dist/components/effects/AIOrb/variants/Liquid/Liquid.types.d.ts +6 -0
- package/dist/components/effects/AIOrb/variants/index.d.ts +2 -0
- package/dist/components/effects/CustomCursor/CustomCursor.d.ts +2 -2
- package/dist/components/effects/CustomCursor/CustomCursor.js +50 -47
- package/dist/components/effects/GlassSurface/GlassSurface.js +24 -12
- package/dist/components/effects/GlassSurface/GlassSurface.types.d.ts +8 -0
- package/dist/components/forms/Mention/Mention.js +2 -2
- package/dist/index.js +1 -1
- package/dist/styles.css +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/paletteGenerator.d.ts +46 -0
- package/package.json +1 -1
- package/src/styles/theme.css +2 -6
- package/dist/components/core/Loader/Loader.d.ts +0 -24
- package/dist/components/core/Loader/Loader.js +0 -57
- package/dist/components/core/Loader/Loader.theme.d.ts +0 -27
- package/dist/components/core/Loader/Loader.theme.js +0 -60
- package/dist/components/core/Loader/Loader.types.d.ts +0 -71
- 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
|
|
6
|
-
import type { SSEFormat, SSEParser } from
|
|
7
|
-
import type { StreamingError, RetryConfig } from
|
|
8
|
-
import type { MessageRole } from
|
|
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
|
-
|
|
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?:
|
|
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?:
|
|
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
|
|
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",
|
|
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
|
|
15
|
+
// Resolve the indicator icon
|
|
16
16
|
const defaultChevronIcon = jsx(PlusIcon, { className: "size-4", strokeWidth: 2 });
|
|
17
|
-
const resolvedChevron =
|
|
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 =
|
|
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="..."
|
|
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,
|
|
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
|
-
//
|
|
50
|
-
if (
|
|
51
|
-
|
|
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
|
-
//
|
|
54
|
-
|
|
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
|
-
? `${
|
|
82
|
-
:
|
|
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:
|
|
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 &&
|
|
89
|
-
return (jsx(Tooltip, { content:
|
|
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-
|
|
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
|
|
2
|
-
export type AvatarSize =
|
|
3
|
-
export type AvatarStatus =
|
|
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
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
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
|
-
|
|
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.
|
|
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,
|
|
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
|
-
|
|
168
|
-
|
|
167
|
+
xs: "-ml-1",
|
|
168
|
+
sm: "-ml-1.5",
|
|
169
|
+
md: "-ml-1.5",
|
|
169
170
|
}[size]
|
|
170
171
|
: {
|
|
171
|
-
|
|
172
|
-
|
|
172
|
+
xs: "-ml-1",
|
|
173
|
+
sm: "-ml-1.5",
|
|
174
|
+
md: "-ml-1",
|
|
173
175
|
}[size];
|
|
174
|
-
return (jsx(Avatar, { src: avatar.src,
|
|
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
|
|
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-
|
|
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
|
-
|
|
67
|
-
|
|
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
|
-
|
|
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-
|
|
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-
|
|
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
|
|
2
|
-
import { CalendarEventThemeOverrides } from
|
|
3
|
-
import { CalendarEvent as CalendarEventType, GridConfig, EventPosition } from
|
|
4
|
-
export type CalendarEventVariant =
|
|
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[
|
|
22
|
+
onEventClick?: (eventData: CalendarEventProps["event"]) => void;
|
|
24
23
|
}
|
|
@@ -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,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,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 };
|
|
@@ -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-
|
|
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,
|
|
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-
|
|
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-
|
|
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
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
2
|
/**
|
|
3
3
|
* Message role types for AI conversations
|
|
4
4
|
*/
|
|
5
|
-
export type MessageRole =
|
|
5
|
+
export type MessageRole = "user" | "assistant" | "system";
|
|
6
6
|
/**
|
|
7
7
|
* Message variant types for chat UI
|
|
8
8
|
*/
|
|
9
|
-
export type MessageVariant =
|
|
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
|
-
*
|
|
19
|
+
* The name for the avatar (used for initials and alt text)
|
|
20
20
|
*/
|
|
21
|
-
|
|
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>,
|
|
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
|
|
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
|
|
8
|
+
* The name for the avatar
|
|
9
9
|
*/
|
|
10
10
|
name: string;
|
|
11
11
|
/**
|