@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.
- package/dist/components/ai/ApprovalCard/ApprovalCard.js +1 -1
- package/dist/components/ai/MessageHistory/MessageHistory.js +1 -0
- package/dist/components/ai/PromptInput/PromptInput.js +7 -125
- package/dist/components/ai/PromptInput/VoiceRecorder.js +0 -77
- package/dist/components/ai/StreamingResponse/StreamingResponse.js +1 -0
- package/dist/components/ai/StreamingResponse/StreamingResponse.types.d.ts +7 -7
- package/dist/components/ai/index.js +1 -0
- package/dist/components/core/Accordion/Accordion.d.ts +1 -1
- package/dist/components/core/Accordion/Accordion.js +2 -2
- package/dist/components/core/Accordion/Accordion.theme.d.ts +2 -2
- package/dist/components/core/Accordion/Accordion.theme.js +4 -4
- package/dist/components/core/Accordion/Accordion.types.d.ts +19 -20
- package/dist/components/core/Accordion/AccordionBody.d.ts +3 -0
- package/dist/components/core/Accordion/{AccordionContent.js → AccordionBody.js} +4 -4
- package/dist/components/core/Accordion/AccordionItem.js +1 -1
- package/dist/components/core/Accordion/AccordionTrigger.js +14 -7
- package/dist/components/core/Accordion/index.d.ts +2 -2
- package/dist/components/core/Alert/Alert.js +5 -1
- package/dist/components/core/Alert/Alert.types.d.ts +4 -4
- 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/Breadcrumbs/Breadcrumbs.js +7 -3
- package/dist/components/core/Breadcrumbs/Breadcrumbs.types.d.ts +1 -1
- package/dist/components/core/Button/Button.js +2 -8
- package/dist/components/core/Button/Button.theme.js +7 -7
- package/dist/components/core/Calendar/Calendar.js +3 -3
- package/dist/components/core/Calendar/CalendarEvent/CalendarEvent.types.d.ts +5 -6
- package/dist/components/core/Card/Card.d.ts +2 -2
- package/dist/components/core/Card/Card.js +3 -3
- package/dist/components/core/Card/Card.theme.js +3 -3
- package/dist/components/core/Card/Card.types.d.ts +4 -4
- package/dist/components/core/Card/CardBody.d.ts +3 -0
- package/dist/components/core/Card/CardBody.js +11 -0
- package/dist/components/core/Card/index.d.ts +2 -2
- package/dist/components/core/Carousel/Carousel.js +4 -4
- package/dist/components/core/Carousel/Carousel.types.d.ts +4 -4
- package/dist/components/core/Carousel/CarouselBody.d.ts +4 -0
- package/dist/components/core/Carousel/{CarouselContent.js → CarouselBody.js} +3 -3
- package/dist/components/core/Carousel/index.d.ts +2 -1
- package/dist/components/core/ContextMenu/ContextMenu.d.ts +2 -2
- package/dist/components/core/ContextMenu/ContextMenu.js +6 -6
- package/dist/components/core/ContextMenu/ContextMenu.types.d.ts +2 -2
- package/dist/components/core/ContextMenu/ContextMenuBody.d.ts +6 -0
- package/dist/components/core/ContextMenu/{ContextMenuContent.js → ContextMenuBody.js} +4 -4
- package/dist/components/core/ContextMenu/ContextMenuSubBody.d.ts +6 -0
- package/dist/components/core/ContextMenu/{ContextMenuSubContent.js → ContextMenuSubBody.js} +4 -4
- package/dist/components/core/ContextMenu/index.d.ts +1 -1
- package/dist/components/core/Drawer/Drawer.d.ts +2 -2
- package/dist/components/core/Drawer/Drawer.js +28 -9
- package/dist/components/core/Drawer/Drawer.theme.js +1 -1
- package/dist/components/core/Drawer/Drawer.types.d.ts +8 -6
- package/dist/components/core/Drawer/DrawerBody.d.ts +5 -0
- package/dist/components/core/Drawer/DrawerBody.js +11 -0
- package/dist/components/core/Drawer/index.d.ts +2 -1
- package/dist/components/core/Dropdown/Dropdown.types.d.ts +3 -3
- package/dist/components/core/Dropdown/DropdownSection.js +3 -1
- 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.js +3 -1
- package/dist/components/core/MenuItem/MenuItem.theme.js +1 -1
- package/dist/components/core/MenuItem/MenuItem.types.d.ts +1 -1
- package/dist/components/core/Message/Message.d.ts +1 -1
- package/dist/components/core/Message/Message.js +3 -3
- package/dist/components/core/Message/Message.theme.js +2 -2
- package/dist/components/core/Message/Message.types.d.ts +7 -7
- package/dist/components/core/Message/MessageAvatar.d.ts +2 -2
- package/dist/components/core/Message/MessageAvatar.js +3 -3
- package/dist/components/core/Message/MessageBody.d.ts +8 -0
- package/dist/components/core/Message/{MessageContent.js → MessageBody.js} +3 -3
- package/dist/components/core/Message/index.d.ts +2 -0
- package/dist/components/core/Modal/Modal.js +5 -1
- package/dist/components/core/Modal/Modal.theme.js +1 -1
- package/dist/components/core/Modal/Modal.types.d.ts +5 -2
- package/dist/components/core/ModalStack/ModalStackModal.js +1 -0
- package/dist/components/core/PageHeading/PageHeading.types.d.ts +1 -1
- package/dist/components/core/PageHeading/PageHeadingBackButton.js +3 -1
- package/dist/components/core/Popover/Popover.d.ts +1 -1
- package/dist/components/core/Popover/Popover.js +4 -4
- package/dist/components/core/Popover/Popover.theme.d.ts +1 -1
- package/dist/components/core/Popover/Popover.theme.js +2 -2
- package/dist/components/core/Popover/Popover.types.d.ts +3 -3
- package/dist/components/core/Popover/PopoverBody.d.ts +7 -0
- package/dist/components/core/Popover/{PopoverContent.js → PopoverBody.js} +24 -13
- package/dist/components/core/Popover/index.d.ts +4 -3
- package/dist/components/core/Tabs/Tabs.animations.d.ts +2 -2
- package/dist/components/core/Tabs/Tabs.animations.js +3 -3
- package/dist/components/core/Tabs/Tabs.d.ts +1 -1
- package/dist/components/core/Tabs/Tabs.js +3 -3
- package/dist/components/core/Tabs/Tabs.theme.d.ts +1 -1
- package/dist/components/core/Tabs/Tabs.theme.js +2 -2
- package/dist/components/core/Tabs/Tabs.types.d.ts +9 -9
- package/dist/components/core/Tabs/TabsBody.d.ts +6 -0
- package/dist/components/core/Tabs/{TabsContent.js → TabsBody.js} +8 -8
- package/dist/components/core/Tabs/index.d.ts +2 -2
- 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/Toast/Toast.js +5 -1
- package/dist/components/core/Toast/Toast.types.d.ts +9 -9
- package/dist/components/core/index.d.ts +1 -1
- package/dist/components/core/index.js +7 -3
- 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 -52
- 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/GanttChart/GanttTaskContextMenu.js +1 -1
- package/dist/components/data-display/KPI/KPI.js +2 -2
- package/dist/components/data-display/KPI/KPI.types.d.ts +3 -3
- package/dist/components/data-display/Metric/Metric.js +2 -2
- package/dist/components/data-display/Metric/Metric.types.d.ts +3 -3
- package/dist/components/data-display/Table/TableColumnManager.js +2 -1
- package/dist/components/data-display/Table/TableFilter.js +2 -1
- 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/Checkbox/Checkbox.js +1 -1
- package/dist/components/forms/Checkbox/Checkbox.types.d.ts +5 -5
- package/dist/components/forms/Checkbox/CheckboxGroup.js +2 -2
- package/dist/components/forms/ColorPicker/ColorPicker.d.ts +1 -1
- package/dist/components/forms/ColorPicker/ColorPicker.js +2 -2
- package/dist/components/forms/ColorPicker/ColorPicker.types.d.ts +2 -2
- package/dist/components/forms/ColorPicker/ColorPickerBody.d.ts +7 -0
- package/dist/components/forms/ColorPicker/{ColorPickerContent.js → ColorPickerBody.js} +5 -5
- package/dist/components/forms/ColorPicker/index.d.ts +2 -2
- package/dist/components/forms/DatePicker/DatePicker.d.ts +7 -3
- package/dist/components/forms/DatePicker/DatePicker.js +6 -5
- package/dist/components/forms/DatePicker/DatePicker.theme.js +3 -3
- package/dist/components/forms/DatePicker/DatePicker.types.d.ts +9 -4
- package/dist/components/forms/DatePicker/DatePickerBody.d.ts +7 -0
- package/dist/components/forms/DatePicker/{DatePickerContent.js → DatePickerBody.js} +10 -9
- package/dist/components/forms/DatePicker/index.d.ts +2 -2
- package/dist/components/forms/FileUpload/FileUpload.js +0 -78
- package/dist/components/forms/Input/Input.js +2 -2
- package/dist/components/forms/Input/Input.types.d.ts +4 -4
- package/dist/components/forms/Mention/Mention.js +2 -2
- package/dist/components/forms/Radio/Radio.js +1 -1
- package/dist/components/forms/Radio/Radio.types.d.ts +5 -5
- package/dist/components/forms/Radio/RadioGroup.js +1 -1
- package/dist/components/forms/Select/Select.js +2 -2
- package/dist/components/forms/Select/Select.types.d.ts +4 -4
- package/dist/components/forms/Switch/Switch.js +1 -1
- package/dist/components/forms/Switch/Switch.types.d.ts +4 -4
- package/dist/components/forms/Textarea/Textarea.js +2 -2
- package/dist/components/forms/Textarea/Textarea.types.d.ts +4 -4
- package/dist/components/forms/TimePicker/TimePickerContent.js +1 -78
- package/dist/components/forms/index.d.ts +2 -2
- package/dist/components/forms/index.js +2 -80
- package/dist/components/layout/FormLayout/FormLayout.d.ts +0 -2
- package/dist/components/layout/FormLayout/FormLayout.js +12 -6
- package/dist/components/layout/FormLayout/FormLayout.theme.js +2 -5
- package/dist/components/layout/FormLayout/FormLayout.types.d.ts +8 -26
- package/dist/components/layout/FormLayout/FormLayoutSection.js +3 -2
- package/dist/components/layout/FormLayout/index.d.ts +1 -1
- package/dist/index.js +197 -199
- 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/Accordion/AccordionContent.d.ts +0 -3
- package/dist/components/core/Card/CardContent.d.ts +0 -3
- package/dist/components/core/Card/CardContent.js +0 -11
- package/dist/components/core/Carousel/CarouselContent.d.ts +0 -4
- package/dist/components/core/ContextMenu/ContextMenuContent.d.ts +0 -6
- package/dist/components/core/ContextMenu/ContextMenuSubContent.d.ts +0 -6
- package/dist/components/core/Drawer/DrawerContent.d.ts +0 -5
- package/dist/components/core/Drawer/DrawerContent.js +0 -11
- 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
- package/dist/components/core/Message/MessageContent.d.ts +0 -8
- package/dist/components/core/Popover/PopoverContent.d.ts +0 -7
- package/dist/components/core/Tabs/TabsContent.d.ts +0 -6
- package/dist/components/forms/ColorPicker/ColorPickerContent.d.ts +0 -7
- package/dist/components/forms/DatePicker/DatePickerContent.d.ts +0 -7
- package/dist/components/layout/FormLayout/FormLayoutBody.d.ts +0 -3
- package/dist/components/layout/FormLayout/FormLayoutBody.js +0 -91
- package/dist/components/layout/FormLayout/FormLayoutHeader.d.ts +0 -3
- package/dist/components/layout/FormLayout/FormLayoutHeader.js +0 -12
|
@@ -38,7 +38,7 @@ export interface KPIProps extends Omit<HTMLAttributes<HTMLDivElement>, "title">
|
|
|
38
38
|
/**
|
|
39
39
|
* Label describing the metric (e.g. "Fund raised", "Total Revenue")
|
|
40
40
|
*/
|
|
41
|
-
label?:
|
|
41
|
+
label?: ReactNode;
|
|
42
42
|
/**
|
|
43
43
|
* Percentage change value (e.g. 20, -5.3). Determines trend direction & color.
|
|
44
44
|
*/
|
|
@@ -46,7 +46,7 @@ export interface KPIProps extends Omit<HTMLAttributes<HTMLDivElement>, "title">
|
|
|
46
46
|
/**
|
|
47
47
|
* Custom trend label override (default: auto-formats as "+20%" or "-5.3%")
|
|
48
48
|
*/
|
|
49
|
-
trendLabel?:
|
|
49
|
+
trendLabel?: ReactNode;
|
|
50
50
|
/**
|
|
51
51
|
* Progress value from 0-100. Controls how many bars are filled.
|
|
52
52
|
*/
|
|
@@ -59,7 +59,7 @@ export interface KPIProps extends Omit<HTMLAttributes<HTMLDivElement>, "title">
|
|
|
59
59
|
/**
|
|
60
60
|
* Subtitle text below the bars (e.g. "Compared to last month")
|
|
61
61
|
*/
|
|
62
|
-
subtitle?:
|
|
62
|
+
subtitle?: ReactNode;
|
|
63
63
|
/**
|
|
64
64
|
* Icon to display before the label.
|
|
65
65
|
*/
|
|
@@ -11,9 +11,9 @@ const Metric = React__default.forwardRef(({ value, label, subtitle, trendValue,
|
|
|
11
11
|
const variantStyles = metricTheme.variants[variant];
|
|
12
12
|
const variantColorStyles = metricTheme.variantColors[variant] || "";
|
|
13
13
|
const iconStyles = ((_a = metricTheme.iconContainerVariantColors[variant]) === null || _a === void 0 ? void 0 : _a[color]) || "";
|
|
14
|
-
return (jsx("div", { ref: ref, className: cn(metricTheme.baseStyle, variantStyles, variantColorStyles, sizeStyles.container, className), "data-size": size, ...props, children: jsxs("div", { className: "flex flex-col gap-3 ", children: [jsxs("div", { className: cn("flex items-start gap-3", sizeStyles.contentPadding), children: [icon && (jsx("div", { className: cn(metricTheme.iconContainerStyle, iconStyles, sizeStyles.iconContainer), children: icon })), jsxs("div", { className: "flex flex-col flex-1", children: [jsx("div", { className: cn(metricTheme.labelStyle, sizeStyles.label), children: label }), jsxs("div", { className: "flex items-center gap-2", children: [jsx("div", { className: cn(metricTheme.valueStyle, sizeStyles.value), children: value }), trendValue && (jsxs("div", { className: cn("flex items-center w-fit gap-1 text-base font-medium", trendDirection === "up"
|
|
14
|
+
return (jsx("div", { ref: ref, className: cn(metricTheme.baseStyle, variantStyles, variantColorStyles, sizeStyles.container, className), "data-size": size, ...props, children: jsxs("div", { className: "flex flex-col gap-3 ", children: [jsxs("div", { className: cn("flex items-start gap-3", sizeStyles.contentPadding), children: [icon && (jsx("div", { className: cn(metricTheme.iconContainerStyle, iconStyles, sizeStyles.iconContainer), children: icon })), jsxs("div", { className: "flex flex-col flex-1", children: [typeof label === 'string' ? (jsx("div", { className: cn(metricTheme.labelStyle, sizeStyles.label), children: label })) : label, jsxs("div", { className: "flex items-center gap-2", children: [jsx("div", { className: cn(metricTheme.valueStyle, sizeStyles.value), children: value }), trendValue && (typeof trendValue === 'string' ? (jsxs("div", { className: cn("flex items-center w-fit gap-1 text-base font-medium", trendDirection === "up"
|
|
15
15
|
? "text-[var(--color-success)]"
|
|
16
|
-
: "text-[var(--color-danger)]"), children: [trendIcon, " ", trendValue] }))] }), subtitle && (jsx("div", { className: cn(metricTheme.subtitleStyle, sizeStyles.subtitle), children: subtitle }))] })] }), trendChart && (jsx("div", { className: "w-full h-12 flex-shrink-0 -mt-4", children: trendChart }))] }) }));
|
|
16
|
+
: "text-[var(--color-danger)]"), children: [trendIcon, " ", trendValue] })) : trendValue)] }), subtitle && (typeof subtitle === 'string' ? (jsx("div", { className: cn(metricTheme.subtitleStyle, sizeStyles.subtitle), children: subtitle })) : subtitle)] })] }), trendChart && (jsx("div", { className: "w-full h-12 flex-shrink-0 -mt-4", children: trendChart }))] }) }));
|
|
17
17
|
});
|
|
18
18
|
Metric.displayName = "Metric";
|
|
19
19
|
|
|
@@ -12,16 +12,16 @@ export interface MetricProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
12
12
|
/**
|
|
13
13
|
* Label describing the metric
|
|
14
14
|
*/
|
|
15
|
-
label:
|
|
15
|
+
label: React.ReactNode;
|
|
16
16
|
/**
|
|
17
17
|
* Optional subtitle or secondary text
|
|
18
18
|
*/
|
|
19
|
-
subtitle?:
|
|
19
|
+
subtitle?: React.ReactNode;
|
|
20
20
|
/**
|
|
21
21
|
* Trend value to display (e.g., "+10.34%", "-5.2%")
|
|
22
22
|
* Also acts as boolean - if provided, trend badge is shown
|
|
23
23
|
*/
|
|
24
|
-
trendValue?:
|
|
24
|
+
trendValue?: React.ReactNode;
|
|
25
25
|
/**
|
|
26
26
|
* Trend direction - determines icon and color
|
|
27
27
|
* @default 'up'
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { Popover } from '../../core/Popover/Popover.js';
|
|
3
3
|
import '../../core/Popover/PopoverContext.js';
|
|
4
|
+
import '../../core/Popover/PopoverBody.js';
|
|
4
5
|
import { Cog6ToothIcon } from '@heroicons/react/24/outline';
|
|
5
6
|
import { Button } from '../../core/Button/Button.js';
|
|
6
7
|
import 'react';
|
|
@@ -17,7 +18,7 @@ function TableColumnManagerComponent({ columns, visibleColumns, columnOrder, onT
|
|
|
17
18
|
const displayName = typeof column.header === 'string' ? column.header : column.id;
|
|
18
19
|
return (jsx(Checkbox, { id: `column-checkbox-${column.id}`, name: `column-${column.id}`, value: column.id, checked: isVisible, onChange: () => onToggleColumn(column.id), "aria-label": `Toggle visibility for ${displayName} column`, label: displayName, state: isLocked ? 'disabled' : 'default' }));
|
|
19
20
|
};
|
|
20
|
-
return (jsxs(Popover, { placement: "bottom-end", offset: 8, children: [jsx(Popover.Trigger, { children: jsxs(Button, { color: "neutral", variant: "filled", "aria-label": "Manage column visibility", children: [jsx(Cog6ToothIcon, { className: "size-5", "aria-hidden": "true" }), "Manage Columns"] }) }), jsx(Popover.
|
|
21
|
+
return (jsxs(Popover, { placement: "bottom-end", offset: 8, children: [jsx(Popover.Trigger, { children: jsxs(Button, { color: "neutral", variant: "filled", "aria-label": "Manage column visibility", children: [jsx(Cog6ToothIcon, { className: "size-5", "aria-hidden": "true" }), "Manage Columns"] }) }), jsx(Popover.Body, { className: "p-0", children: jsxs("div", { className: "w-64 p-3 overflow-hidden", role: "dialog", "aria-labelledby": "column-manager-title", "aria-describedby": "column-manager-description", "aria-modal": "true", children: [jsx("div", { id: "column-manager-title", className: "text-sm uppercase font-bold mb-3 text-[var(--color-text-placeholder)]", children: "Manage Columns" }), jsx("div", { id: "column-manager-description", className: "sr-only", children: "Use checkboxes to control which columns are visible in the table. Locked columns cannot be hidden." }), jsx("div", { className: "space-y-0.5", role: "group", "aria-label": "Column visibility options", children: onColumnReorder ? (jsx(Sortable, { onReorder: onColumnReorder, showDragHandle: true, className: "space-y-0.5", children: orderedColumns.map((column) => (jsx(SortableItem, { id: column.id, disabled: column.locked === true, className: `hover:bg-[var(--color-background-tertiary)] rounded-lg p-1.5 transition-colors ${column.locked ? 'bg-[var(--color-background-secondary)]' : ''}`, children: renderColumnItem(column) }, column.id))) })) : (orderedColumns.map((column) => (jsx("div", { className: `hover:bg-[var(--color-background-tertiary)] rounded-lg p-1.5 transition-colors ${column.locked ? 'bg-[var(--color-background-secondary)]' : ''}`, children: renderColumnItem(column) }, column.id)))) }), jsx("div", { className: "mt-3 flex justify-end", children: jsx(Button, { color: "neutral", variant: "filled", className: "w-full", onClick: onResetToDefault, children: "Reset to Default" }) })] }) })] }));
|
|
21
22
|
}
|
|
22
23
|
const TableColumnManager = TableColumnManagerComponent;
|
|
23
24
|
|
|
@@ -8,6 +8,7 @@ import { Select } from '../../forms/Select/Select.js';
|
|
|
8
8
|
import '../../forms/Select/Select.theme.js';
|
|
9
9
|
import { Popover } from '../../core/Popover/Popover.js';
|
|
10
10
|
import '../../core/Popover/PopoverContext.js';
|
|
11
|
+
import '../../core/Popover/PopoverBody.js';
|
|
11
12
|
import { FunnelIcon, XMarkIcon, PlusIcon } from '@heroicons/react/24/outline';
|
|
12
13
|
import { cn } from '../../../utils/cn.js';
|
|
13
14
|
|
|
@@ -206,7 +207,7 @@ function TableFilter({ columns, filterConfig, onFilterChange, filterLogic: contr
|
|
|
206
207
|
return true;
|
|
207
208
|
return f.value != null && f.value !== "";
|
|
208
209
|
}).length;
|
|
209
|
-
return (jsxs(Popover, { placement: "bottom-end", offset: 8, closeOnClickOutside: false, children: [jsx(Popover.Trigger, { children: jsxs(Button, { color: "neutral", variant: "outline", "aria-label": "Filter table data", size: "sm", children: [jsx(FunnelIcon, { className: "size-4", "aria-hidden": "true" }), "Filters", appliedFilterCount > 0 && (jsx("span", { className: "ml-1 inline-flex items-center justify-center size-5 rounded-full bg-[var(--color-primary)] text-[var(--color-primary-contrast)] text-sm font-medium", children: appliedFilterCount }))] }) }), jsx(Popover.
|
|
210
|
+
return (jsxs(Popover, { placement: "bottom-end", offset: 8, closeOnClickOutside: false, children: [jsx(Popover.Trigger, { children: jsxs(Button, { color: "neutral", variant: "outline", "aria-label": "Filter table data", size: "sm", children: [jsx(FunnelIcon, { className: "size-4", "aria-hidden": "true" }), "Filters", appliedFilterCount > 0 && (jsx("span", { className: "ml-1 inline-flex items-center justify-center size-5 rounded-full bg-[var(--color-primary)] text-[var(--color-primary-contrast)] text-sm font-medium", children: appliedFilterCount }))] }) }), jsx(Popover.Body, { className: "p-0 max-w-none", children: jsxs("div", { className: cn("w-[500px] p-3", className), role: "dialog", "aria-labelledby": "table-filter-title", "aria-modal": "true", children: [jsxs("div", { className: "flex items-center justify-between mb-3", children: [jsx("div", { id: "table-filter-title", className: "text-sm uppercase font-bold text-[var(--color-text-placeholder)]", children: "Filters" }), activeFilters.length > 1 && (jsxs("div", { className: "flex items-center gap-0.5 rounded-md bg-[var(--color-background-secondary)] p-0.5", children: [jsx("button", { type: "button", className: cn("px-2.5 py-0.5 text-sm font-medium rounded transition-colors", filterLogic === "and"
|
|
210
211
|
? "bg-[var(--color-background)] text-[var(--color-text-primary)] shadow-sm"
|
|
211
212
|
: "text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]"), onClick: () => handleSetLogic("and"), children: "AND" }), jsx("button", { type: "button", className: cn("px-2.5 py-0.5 text-sm font-medium rounded transition-colors", filterLogic === "or"
|
|
212
213
|
? "bg-[var(--color-background)] text-[var(--color-text-primary)] shadow-sm"
|
|
@@ -28,9 +28,9 @@ const TimelineMarker = React__default.forwardRef(({ icon, className, ...props },
|
|
|
28
28
|
const variants = shouldReduceMotion ? undefined : timelineMarkerVariants;
|
|
29
29
|
// Filter out conflicting motion props
|
|
30
30
|
const { onDrag, onDragEnd, onDragStart, onAnimationStart, onAnimationEnd, ...safeProps } = props;
|
|
31
|
-
return (jsxs("div", { className: cn("relative flex flex-col items-center", isHorizontal && "
|
|
31
|
+
return (jsxs("div", { className: cn("relative flex flex-col items-center", isHorizontal && "w-full"), children: [jsx(motion.div, { ref: ref, className: cn(theme.markerStyle, theme.markerStatuses[status], className), "data-status": status, "aria-label": `${status} step`, initial: variants ? "hidden" : undefined, animate: variants ? "visible" : undefined, variants: variants, ...safeProps, children: renderIcon() }), !isLast && !isHorizontal && (jsx("div", { className: cn("w-0.5 flex-1 min-h-4", status === "completed"
|
|
32
32
|
? "bg-[var(--color-success)]"
|
|
33
|
-
: "bg-[var(--color-border)]"), "aria-hidden": "true" })), !isLast && isHorizontal && (jsx("div", { className: cn("h-0.5
|
|
33
|
+
: "bg-[var(--color-border)]"), "aria-hidden": "true" })), !isLast && isHorizontal && (jsx("div", { className: cn("absolute top-1/2 -translate-y-1/2 left-1/2 h-0.5 w-full", status === "completed"
|
|
34
34
|
? "bg-[var(--color-success)]"
|
|
35
35
|
: "bg-[var(--color-border)]"), "aria-hidden": "true" }))] }));
|
|
36
36
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { AIOrb } from "../AIOrb";
|
|
2
|
-
export type { AIOrbProps, DotSphereProps, LiquidProps } from "../AIOrb";
|
|
2
|
+
export type { AIOrbProps, OrbState, DotSphereProps, LiquidProps, AuraProps } from "../AIOrb";
|
|
3
3
|
export { Particles } from "../Particles";
|
|
4
4
|
export type { ParticlesProps } from "../Particles";
|
|
5
5
|
export { SpotlightBorder } from "../SpotlightBorder";
|
|
@@ -2,6 +2,7 @@ import { jsx } from 'react/jsx-runtime';
|
|
|
2
2
|
import { cn } from '../../../utils/cn.js';
|
|
3
3
|
import { DotSphere } from './variants/DotSphere/DotSphere.js';
|
|
4
4
|
import { Liquid } from './variants/Liquid/Liquid.js';
|
|
5
|
+
import { Aura } from './variants/Aura/Aura.js';
|
|
5
6
|
|
|
6
7
|
const AIOrbRoot = ({ size, backgroundColor = "#000", className, style, children, ...props }) => {
|
|
7
8
|
const containerStyle = {
|
|
@@ -9,8 +10,8 @@ const AIOrbRoot = ({ size, backgroundColor = "#000", className, style, children,
|
|
|
9
10
|
...(size ? { width: size, height: size } : {}),
|
|
10
11
|
...style,
|
|
11
12
|
};
|
|
12
|
-
return (jsx("div", { className: cn("relative overflow-
|
|
13
|
+
return (jsx("div", { className: cn("relative overflow-visible", !size && "w-full h-full", className), style: containerStyle, ...props, children: children }));
|
|
13
14
|
};
|
|
14
|
-
const AIOrb = Object.assign(AIOrbRoot, { DotSphere, Liquid });
|
|
15
|
+
const AIOrb = Object.assign(AIOrbRoot, { DotSphere, Liquid, Aura });
|
|
15
16
|
|
|
16
17
|
export { AIOrb };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { OrbState } from "../AIOrb.types";
|
|
2
|
+
/**
|
|
3
|
+
* State-to-parameter configuration. Maps each OrbState to a set of numeric
|
|
4
|
+
* target values that will be smoothly interpolated.
|
|
5
|
+
*/
|
|
6
|
+
export type StateParamConfig<T extends Record<string, number>> = Record<OrbState, T>;
|
|
7
|
+
/**
|
|
8
|
+
* Generic ref-based interpolation hook for orb state-driven animation.
|
|
9
|
+
*
|
|
10
|
+
* - When `state` is defined, target values come from the config map.
|
|
11
|
+
* - When `state` is undefined, target values come from the `propValues` fallback
|
|
12
|
+
* (backwards-compatible — orb behaves exactly as if no state was set).
|
|
13
|
+
* - Returns a mutable `valuesRef` read inside animation loops, and a `tick(dt)`
|
|
14
|
+
* function that advances the interpolation by `dt` seconds.
|
|
15
|
+
* - Zero React re-renders — all mutation is ref-based.
|
|
16
|
+
*/
|
|
17
|
+
export declare function useOrbState<T extends Record<string, number>>(state: OrbState | undefined, config: StateParamConfig<T>, propValues: T, damping?: number): {
|
|
18
|
+
readonly valuesRef: import("react").RefObject<T>;
|
|
19
|
+
readonly tick: (dt: number) => void;
|
|
20
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { useRef, useCallback } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Generic ref-based interpolation hook for orb state-driven animation.
|
|
5
|
+
*
|
|
6
|
+
* - When `state` is defined, target values come from the config map.
|
|
7
|
+
* - When `state` is undefined, target values come from the `propValues` fallback
|
|
8
|
+
* (backwards-compatible — orb behaves exactly as if no state was set).
|
|
9
|
+
* - Returns a mutable `valuesRef` read inside animation loops, and a `tick(dt)`
|
|
10
|
+
* function that advances the interpolation by `dt` seconds.
|
|
11
|
+
* - Zero React re-renders — all mutation is ref-based.
|
|
12
|
+
*/
|
|
13
|
+
function useOrbState(state, config, propValues, damping = 4) {
|
|
14
|
+
const valuesRef = useRef({ ...propValues });
|
|
15
|
+
const tick = useCallback((dt) => {
|
|
16
|
+
const target = state ? config[state] : propValues;
|
|
17
|
+
const current = valuesRef.current;
|
|
18
|
+
const factor = 1 - Math.exp(-damping * dt);
|
|
19
|
+
for (const key in target) {
|
|
20
|
+
current[key] = (current[key] +
|
|
21
|
+
(target[key] - current[key]) * factor);
|
|
22
|
+
}
|
|
23
|
+
}, [state, config, propValues, damping]);
|
|
24
|
+
return { valuesRef, tick };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export { useOrbState };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { AIOrb } from "./AIOrb";
|
|
2
|
-
export type { AIOrbProps } from "./AIOrb.types";
|
|
3
|
-
export type { DotSphereProps, LiquidProps } from "./variants";
|
|
2
|
+
export type { AIOrbProps, OrbState } from "./AIOrb.types";
|
|
3
|
+
export type { DotSphereProps, LiquidProps, AuraProps } from "./variants";
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { useOrbState } from '../../hooks/useOrbState.js';
|
|
4
|
+
import { ShaderCanvas } from './ShaderCanvas.js';
|
|
5
|
+
import { auraFragmentShader } from './Aura.shaders.js';
|
|
6
|
+
|
|
7
|
+
const STATE_CONFIG = {
|
|
8
|
+
idle: { speed: 10, amplitude: 1.2, frequency: 0.4, brightness: 1.0, scale: 0.2 },
|
|
9
|
+
listening: { speed: 20, amplitude: 1.0, frequency: 0.7, brightness: 1.75, scale: 0.3 },
|
|
10
|
+
thinking: { speed: 30, amplitude: 0.5, frequency: 1.0, brightness: 1.5, scale: 0.3 },
|
|
11
|
+
speaking: { speed: 70, amplitude: 0.75, frequency: 1.25, brightness: 1.5, scale: 0.3 },
|
|
12
|
+
};
|
|
13
|
+
// ── Hex → RGB helper ─────────────────────────────────────────────────────────
|
|
14
|
+
function hexToRgb(hex) {
|
|
15
|
+
const h = hex.replace("#", "");
|
|
16
|
+
const num = parseInt(h.length === 3 ? h.split("").map((c) => c + c).join("") : h, 16);
|
|
17
|
+
return [(num >> 16) / 255, ((num >> 8) & 0xff) / 255, (num & 0xff) / 255];
|
|
18
|
+
}
|
|
19
|
+
// ── Aura component ───────────────────────────────────────────────────────────
|
|
20
|
+
const Aura = ({ color = "#1FD5F9", colorShift = 0.3, speed = 10, amplitude = 2.0, frequency = 0.5, scale = 0.2, blur = 1.0, brightness = 1.5, themeMode = "dark", state, }) => {
|
|
21
|
+
const rgb = useMemo(() => hexToRgb(color), [color]);
|
|
22
|
+
const propValues = useMemo(() => ({ speed, amplitude, frequency, brightness, scale }), [speed, amplitude, frequency, brightness, scale]);
|
|
23
|
+
const { valuesRef, tick } = useOrbState(state, STATE_CONFIG, propValues);
|
|
24
|
+
// Stable uniform object — mutated in-place each frame via the getter ref
|
|
25
|
+
const uniforms = useMemo(() => ({
|
|
26
|
+
u_color: rgb,
|
|
27
|
+
u_colorShift: colorShift,
|
|
28
|
+
u_speed: speed,
|
|
29
|
+
u_amplitude: amplitude,
|
|
30
|
+
u_frequency: frequency,
|
|
31
|
+
u_scale: scale,
|
|
32
|
+
u_blur: blur,
|
|
33
|
+
u_brightness: brightness,
|
|
34
|
+
u_bloom: 0.4,
|
|
35
|
+
u_spacing: 0.5,
|
|
36
|
+
u_variance: 0.1,
|
|
37
|
+
u_smoothing: 1.0,
|
|
38
|
+
u_lightMode: themeMode === "light" ? 1.0 : 0.0,
|
|
39
|
+
}),
|
|
40
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
41
|
+
[]);
|
|
42
|
+
// Sync non-interpolated props every render
|
|
43
|
+
uniforms.u_color = rgb;
|
|
44
|
+
uniforms.u_colorShift = colorShift;
|
|
45
|
+
uniforms.u_blur = blur;
|
|
46
|
+
uniforms.u_lightMode = themeMode === "light" ? 1.0 : 0.0;
|
|
47
|
+
// Custom ref whose getter ticks interpolation + writes interpolated values
|
|
48
|
+
// into the uniform object right before ShaderCanvas reads it each frame.
|
|
49
|
+
const tickingRef = useMemo(() => {
|
|
50
|
+
let lastT = 0;
|
|
51
|
+
return {
|
|
52
|
+
get current() {
|
|
53
|
+
const now = performance.now() / 1000;
|
|
54
|
+
if (lastT > 0) {
|
|
55
|
+
tick(Math.min(now - lastT, 0.1));
|
|
56
|
+
}
|
|
57
|
+
lastT = now;
|
|
58
|
+
const v = valuesRef.current;
|
|
59
|
+
uniforms.u_speed = v.speed;
|
|
60
|
+
uniforms.u_amplitude = v.amplitude;
|
|
61
|
+
uniforms.u_frequency = v.frequency;
|
|
62
|
+
uniforms.u_brightness = v.brightness;
|
|
63
|
+
uniforms.u_scale = v.scale;
|
|
64
|
+
return uniforms;
|
|
65
|
+
},
|
|
66
|
+
set current(_v) {
|
|
67
|
+
// no-op — ShaderCanvas never writes to this ref
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
71
|
+
}, [tick]);
|
|
72
|
+
return (jsx("div", { className: "absolute inset-0", children: jsx(ShaderCanvas, { fragmentShader: auraFragmentShader, uniformsRef: tickingRef }) }));
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export { Aura };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Aura fragment shader — faithful port of LiveKit's AgentAudioVisualizerAura.
|
|
3
|
+
*
|
|
4
|
+
* Uses 36 iterations of turbulence-warped SDF evaluation to produce a
|
|
5
|
+
* luminous ring through accumulation. The ring shape emerges naturally
|
|
6
|
+
* from the turbulence + circle SDF interaction — not from drawing a
|
|
7
|
+
* ring directly.
|
|
8
|
+
*
|
|
9
|
+
* Uniforms (all from Aura component):
|
|
10
|
+
* u_color vec3 Base RGB colour (0-1)
|
|
11
|
+
* u_colorShift float HSV hue shift range across iterations (0-1)
|
|
12
|
+
* u_speed float Animation speed multiplier
|
|
13
|
+
* u_amplitude float Turbulence displacement strength
|
|
14
|
+
* u_frequency float Wave complexity (remapped to 2.0-15.0)
|
|
15
|
+
* u_scale float Circle SDF radius
|
|
16
|
+
* u_blur float Edge softness
|
|
17
|
+
* u_brightness float Overall brightness/opacity
|
|
18
|
+
* u_bloom float Glow intensity (dark mode only)
|
|
19
|
+
* u_spacing float Iteration spacing (remapped to 1.0-TAU)
|
|
20
|
+
* u_variance float Amplitude variance per turbulence layer
|
|
21
|
+
* u_smoothing float Dynamic blur smoothing factor
|
|
22
|
+
* u_lightMode float 0.0 = dark mode, 1.0 = light mode
|
|
23
|
+
*
|
|
24
|
+
* Built-in from ShaderCanvas:
|
|
25
|
+
* iTime float Elapsed seconds
|
|
26
|
+
* iResolution vec2 Viewport pixel dimensions
|
|
27
|
+
*/
|
|
28
|
+
export declare const auraFragmentShader = "#version 300 es\nprecision highp float;\n\nuniform float iTime;\nuniform vec2 iResolution;\n\nuniform vec3 u_color;\nuniform float u_colorShift;\nuniform float u_speed;\nuniform float u_amplitude;\nuniform float u_frequency;\nuniform float u_scale;\nuniform float u_blur;\nuniform float u_brightness;\nuniform float u_bloom;\nuniform float u_spacing;\nuniform float u_variance;\nuniform float u_smoothing;\nuniform float u_lightMode;\n\nout vec4 fragColor;\n\n/* \u2500\u2500 Constants \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\nconst float TAU = 6.283185;\n\n/* \u2500\u2500 Utilities \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\nvec2 randFibo(vec2 p) {\n p = fract(p * vec2(443.897, 441.423));\n p += dot(p, p.yx + 19.19);\n return fract((p.xx + p.yx) * p.xy);\n}\n\nvec3 Tonemap(vec3 x) {\n x *= 4.0;\n return x / (1.0 + x);\n}\n\nfloat luma(vec3 color) {\n return dot(color, vec3(0.299, 0.587, 0.114));\n}\n\nvec3 rgb2hsv(vec3 c) {\n vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));\n vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));\n float d = q.x - min(q.w, q.y);\n float e = 1.0e-10;\n return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n}\n\nvec3 hsv2rgb(vec3 c) {\n vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n}\n\n/* \u2500\u2500 SDF \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\nfloat sdCircle(vec2 st, float r) {\n return length(st) - r;\n}\n\n/* \u2500\u2500 Turbulence \u2014 4 layers of sinusoidal displacement with rotation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\nvec2 turb(vec2 pos, float t, float it) {\n mat2 rotation = mat2(0.6, -0.25, 0.25, 0.9);\n mat2 layerRotation = mat2(0.6, -0.8, 0.8, 0.6);\n\n float frequency = mix(2.0, 15.0, u_frequency);\n float amplitude = u_amplitude;\n float frequencyGrowth = 1.4;\n float animTime = t * 0.1 * u_speed;\n\n const int LAYERS = 4;\n for (int i = 0; i < LAYERS; i++) {\n vec2 rotatedPos = pos * rotation;\n vec2 wave = sin(frequency * rotatedPos + float(i) * animTime + it);\n\n pos += (amplitude / frequency) * rotation[0] * wave;\n\n rotation *= layerRotation;\n amplitude *= mix(1.0, max(wave.x, wave.y), u_variance);\n frequency *= frequencyGrowth;\n }\n\n return pos;\n}\n\n/* \u2500\u2500 Main \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\nconst float ITERATIONS = 36.0;\n\nvoid main() {\n vec2 uv = gl_FragCoord.xy / iResolution.xy;\n\n vec3 pp = vec3(0.0);\n vec3 bloom = vec3(0.0);\n float t = iTime * 0.5;\n vec2 pos = uv - 0.5;\n\n vec2 prevPos = turb(pos, t, 0.0 - 1.0 / ITERATIONS);\n float spacing = mix(1.0, TAU, u_spacing);\n\n for (float i = 1.0; i < ITERATIONS + 1.0; i++) {\n float iter = i / ITERATIONS;\n vec2 st = turb(pos, t, iter * spacing);\n float d = abs(sdCircle(st, u_scale));\n float pd = distance(st, prevPos);\n prevPos = st;\n float dynamicBlur = exp2(pd * 2.0 * 1.4426950408889634) - 1.0;\n float ds = smoothstep(0.0, u_blur * 0.05 + max(dynamicBlur * u_smoothing, 0.001), d);\n\n vec3 col = u_color;\n if (u_colorShift > 0.01) {\n vec3 hsv = rgb2hsv(col);\n hsv.x = fract(hsv.x + (1.0 - iter) * u_colorShift * 0.3);\n col = hsv2rgb(hsv);\n }\n\n float invd = 1.0 / max(d + dynamicBlur, 0.001);\n pp += (ds - 1.0) * col;\n bloom += clamp(invd, 0.0, 250.0) * col;\n }\n\n pp *= 1.0 / ITERATIONS;\n\n vec3 color;\n\n // Dark mode (default)\n if (u_lightMode < 0.5) {\n bloom = bloom / (bloom + 2e4);\n color = (-pp + bloom * 3.0 * u_bloom) * 1.2;\n color += (randFibo(gl_FragCoord.xy).x - 0.5) / 255.0;\n color = Tonemap(color);\n float alpha = luma(color) * u_brightness;\n fragColor = vec4(color * u_brightness, alpha);\n }\n // Light mode\n else {\n color = -pp;\n color += (randFibo(gl_FragCoord.xy).x - 0.5) / 255.0;\n\n float brightness = length(color);\n vec3 direction = brightness > 0.0 ? color / brightness : color;\n\n float factor = 2.0;\n float mappedBrightness = (brightness * factor) / (1.0 + brightness * factor);\n color = direction * mappedBrightness;\n\n float gray = dot(color, vec3(0.2, 0.5, 0.1));\n float saturationBoost = 3.0;\n color = mix(vec3(gray), color, saturationBoost);\n\n color = clamp(color, 0.0, 1.0);\n\n float alpha = mappedBrightness * clamp(u_brightness, 1.0, 2.0);\n fragColor = vec4(color, alpha);\n }\n}\n";
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Aura fragment shader — faithful port of LiveKit's AgentAudioVisualizerAura.
|
|
3
|
+
*
|
|
4
|
+
* Uses 36 iterations of turbulence-warped SDF evaluation to produce a
|
|
5
|
+
* luminous ring through accumulation. The ring shape emerges naturally
|
|
6
|
+
* from the turbulence + circle SDF interaction — not from drawing a
|
|
7
|
+
* ring directly.
|
|
8
|
+
*
|
|
9
|
+
* Uniforms (all from Aura component):
|
|
10
|
+
* u_color vec3 Base RGB colour (0-1)
|
|
11
|
+
* u_colorShift float HSV hue shift range across iterations (0-1)
|
|
12
|
+
* u_speed float Animation speed multiplier
|
|
13
|
+
* u_amplitude float Turbulence displacement strength
|
|
14
|
+
* u_frequency float Wave complexity (remapped to 2.0-15.0)
|
|
15
|
+
* u_scale float Circle SDF radius
|
|
16
|
+
* u_blur float Edge softness
|
|
17
|
+
* u_brightness float Overall brightness/opacity
|
|
18
|
+
* u_bloom float Glow intensity (dark mode only)
|
|
19
|
+
* u_spacing float Iteration spacing (remapped to 1.0-TAU)
|
|
20
|
+
* u_variance float Amplitude variance per turbulence layer
|
|
21
|
+
* u_smoothing float Dynamic blur smoothing factor
|
|
22
|
+
* u_lightMode float 0.0 = dark mode, 1.0 = light mode
|
|
23
|
+
*
|
|
24
|
+
* Built-in from ShaderCanvas:
|
|
25
|
+
* iTime float Elapsed seconds
|
|
26
|
+
* iResolution vec2 Viewport pixel dimensions
|
|
27
|
+
*/
|
|
28
|
+
const auraFragmentShader = `#version 300 es
|
|
29
|
+
precision highp float;
|
|
30
|
+
|
|
31
|
+
uniform float iTime;
|
|
32
|
+
uniform vec2 iResolution;
|
|
33
|
+
|
|
34
|
+
uniform vec3 u_color;
|
|
35
|
+
uniform float u_colorShift;
|
|
36
|
+
uniform float u_speed;
|
|
37
|
+
uniform float u_amplitude;
|
|
38
|
+
uniform float u_frequency;
|
|
39
|
+
uniform float u_scale;
|
|
40
|
+
uniform float u_blur;
|
|
41
|
+
uniform float u_brightness;
|
|
42
|
+
uniform float u_bloom;
|
|
43
|
+
uniform float u_spacing;
|
|
44
|
+
uniform float u_variance;
|
|
45
|
+
uniform float u_smoothing;
|
|
46
|
+
uniform float u_lightMode;
|
|
47
|
+
|
|
48
|
+
out vec4 fragColor;
|
|
49
|
+
|
|
50
|
+
/* ── Constants ─────────────────────────────────────────────────────────────── */
|
|
51
|
+
|
|
52
|
+
const float TAU = 6.283185;
|
|
53
|
+
|
|
54
|
+
/* ── Utilities ─────────────────────────────────────────────────────────────── */
|
|
55
|
+
|
|
56
|
+
vec2 randFibo(vec2 p) {
|
|
57
|
+
p = fract(p * vec2(443.897, 441.423));
|
|
58
|
+
p += dot(p, p.yx + 19.19);
|
|
59
|
+
return fract((p.xx + p.yx) * p.xy);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
vec3 Tonemap(vec3 x) {
|
|
63
|
+
x *= 4.0;
|
|
64
|
+
return x / (1.0 + x);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
float luma(vec3 color) {
|
|
68
|
+
return dot(color, vec3(0.299, 0.587, 0.114));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
vec3 rgb2hsv(vec3 c) {
|
|
72
|
+
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
|
73
|
+
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
|
74
|
+
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
|
75
|
+
float d = q.x - min(q.w, q.y);
|
|
76
|
+
float e = 1.0e-10;
|
|
77
|
+
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
vec3 hsv2rgb(vec3 c) {
|
|
81
|
+
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
|
82
|
+
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
|
83
|
+
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* ── SDF ───────────────────────────────────────────────────────────────────── */
|
|
87
|
+
|
|
88
|
+
float sdCircle(vec2 st, float r) {
|
|
89
|
+
return length(st) - r;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/* ── Turbulence — 4 layers of sinusoidal displacement with rotation ────────── */
|
|
93
|
+
|
|
94
|
+
vec2 turb(vec2 pos, float t, float it) {
|
|
95
|
+
mat2 rotation = mat2(0.6, -0.25, 0.25, 0.9);
|
|
96
|
+
mat2 layerRotation = mat2(0.6, -0.8, 0.8, 0.6);
|
|
97
|
+
|
|
98
|
+
float frequency = mix(2.0, 15.0, u_frequency);
|
|
99
|
+
float amplitude = u_amplitude;
|
|
100
|
+
float frequencyGrowth = 1.4;
|
|
101
|
+
float animTime = t * 0.1 * u_speed;
|
|
102
|
+
|
|
103
|
+
const int LAYERS = 4;
|
|
104
|
+
for (int i = 0; i < LAYERS; i++) {
|
|
105
|
+
vec2 rotatedPos = pos * rotation;
|
|
106
|
+
vec2 wave = sin(frequency * rotatedPos + float(i) * animTime + it);
|
|
107
|
+
|
|
108
|
+
pos += (amplitude / frequency) * rotation[0] * wave;
|
|
109
|
+
|
|
110
|
+
rotation *= layerRotation;
|
|
111
|
+
amplitude *= mix(1.0, max(wave.x, wave.y), u_variance);
|
|
112
|
+
frequency *= frequencyGrowth;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return pos;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/* ── Main ──────────────────────────────────────────────────────────────────── */
|
|
119
|
+
|
|
120
|
+
const float ITERATIONS = 36.0;
|
|
121
|
+
|
|
122
|
+
void main() {
|
|
123
|
+
vec2 uv = gl_FragCoord.xy / iResolution.xy;
|
|
124
|
+
|
|
125
|
+
vec3 pp = vec3(0.0);
|
|
126
|
+
vec3 bloom = vec3(0.0);
|
|
127
|
+
float t = iTime * 0.5;
|
|
128
|
+
vec2 pos = uv - 0.5;
|
|
129
|
+
|
|
130
|
+
vec2 prevPos = turb(pos, t, 0.0 - 1.0 / ITERATIONS);
|
|
131
|
+
float spacing = mix(1.0, TAU, u_spacing);
|
|
132
|
+
|
|
133
|
+
for (float i = 1.0; i < ITERATIONS + 1.0; i++) {
|
|
134
|
+
float iter = i / ITERATIONS;
|
|
135
|
+
vec2 st = turb(pos, t, iter * spacing);
|
|
136
|
+
float d = abs(sdCircle(st, u_scale));
|
|
137
|
+
float pd = distance(st, prevPos);
|
|
138
|
+
prevPos = st;
|
|
139
|
+
float dynamicBlur = exp2(pd * 2.0 * 1.4426950408889634) - 1.0;
|
|
140
|
+
float ds = smoothstep(0.0, u_blur * 0.05 + max(dynamicBlur * u_smoothing, 0.001), d);
|
|
141
|
+
|
|
142
|
+
vec3 col = u_color;
|
|
143
|
+
if (u_colorShift > 0.01) {
|
|
144
|
+
vec3 hsv = rgb2hsv(col);
|
|
145
|
+
hsv.x = fract(hsv.x + (1.0 - iter) * u_colorShift * 0.3);
|
|
146
|
+
col = hsv2rgb(hsv);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
float invd = 1.0 / max(d + dynamicBlur, 0.001);
|
|
150
|
+
pp += (ds - 1.0) * col;
|
|
151
|
+
bloom += clamp(invd, 0.0, 250.0) * col;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
pp *= 1.0 / ITERATIONS;
|
|
155
|
+
|
|
156
|
+
vec3 color;
|
|
157
|
+
|
|
158
|
+
// Dark mode (default)
|
|
159
|
+
if (u_lightMode < 0.5) {
|
|
160
|
+
bloom = bloom / (bloom + 2e4);
|
|
161
|
+
color = (-pp + bloom * 3.0 * u_bloom) * 1.2;
|
|
162
|
+
color += (randFibo(gl_FragCoord.xy).x - 0.5) / 255.0;
|
|
163
|
+
color = Tonemap(color);
|
|
164
|
+
float alpha = luma(color) * u_brightness;
|
|
165
|
+
fragColor = vec4(color * u_brightness, alpha);
|
|
166
|
+
}
|
|
167
|
+
// Light mode
|
|
168
|
+
else {
|
|
169
|
+
color = -pp;
|
|
170
|
+
color += (randFibo(gl_FragCoord.xy).x - 0.5) / 255.0;
|
|
171
|
+
|
|
172
|
+
float brightness = length(color);
|
|
173
|
+
vec3 direction = brightness > 0.0 ? color / brightness : color;
|
|
174
|
+
|
|
175
|
+
float factor = 2.0;
|
|
176
|
+
float mappedBrightness = (brightness * factor) / (1.0 + brightness * factor);
|
|
177
|
+
color = direction * mappedBrightness;
|
|
178
|
+
|
|
179
|
+
float gray = dot(color, vec3(0.2, 0.5, 0.1));
|
|
180
|
+
float saturationBoost = 3.0;
|
|
181
|
+
color = mix(vec3(gray), color, saturationBoost);
|
|
182
|
+
|
|
183
|
+
color = clamp(color, 0.0, 1.0);
|
|
184
|
+
|
|
185
|
+
float alpha = mappedBrightness * clamp(u_brightness, 1.0, 2.0);
|
|
186
|
+
fragColor = vec4(color, alpha);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
`;
|
|
190
|
+
|
|
191
|
+
export { auraFragmentShader };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { OrbState } from "../../AIOrb.types";
|
|
2
|
+
export interface AuraProps {
|
|
3
|
+
/**
|
|
4
|
+
* Base colour as a hex string.
|
|
5
|
+
* @default '#1FD5F9'
|
|
6
|
+
*/
|
|
7
|
+
color?: string;
|
|
8
|
+
/**
|
|
9
|
+
* HSV hue shift for iridescence (0-1).
|
|
10
|
+
* @default 0.3
|
|
11
|
+
*/
|
|
12
|
+
colorShift?: number;
|
|
13
|
+
/**
|
|
14
|
+
* Animation speed multiplier.
|
|
15
|
+
* @default 10
|
|
16
|
+
*/
|
|
17
|
+
speed?: number;
|
|
18
|
+
/**
|
|
19
|
+
* Wave displacement strength.
|
|
20
|
+
* @default 2.0
|
|
21
|
+
*/
|
|
22
|
+
amplitude?: number;
|
|
23
|
+
/**
|
|
24
|
+
* Wave complexity.
|
|
25
|
+
* @default 0.5
|
|
26
|
+
*/
|
|
27
|
+
frequency?: number;
|
|
28
|
+
/**
|
|
29
|
+
* Circle SDF radius in normalized coordinates.
|
|
30
|
+
* @default 0.2
|
|
31
|
+
*/
|
|
32
|
+
scale?: number;
|
|
33
|
+
/**
|
|
34
|
+
* Edge softness.
|
|
35
|
+
* @default 1.0
|
|
36
|
+
*/
|
|
37
|
+
blur?: number;
|
|
38
|
+
/**
|
|
39
|
+
* Overall brightness/opacity.
|
|
40
|
+
* @default 1.5
|
|
41
|
+
*/
|
|
42
|
+
brightness?: number;
|
|
43
|
+
/**
|
|
44
|
+
* Rendering mode — affects colour inversion for light backgrounds.
|
|
45
|
+
* @default 'dark'
|
|
46
|
+
*/
|
|
47
|
+
themeMode?: "dark" | "light";
|
|
48
|
+
/**
|
|
49
|
+
* State-driven animation. When set, overrides speed/amplitude/frequency/
|
|
50
|
+
* brightness/scale with smooth interpolation towards state targets.
|
|
51
|
+
*/
|
|
52
|
+
state?: OrbState;
|
|
53
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface ShaderCanvasProps {
|
|
3
|
+
fragmentShader: string;
|
|
4
|
+
uniformsRef: React.MutableRefObject<Record<string, number | number[]>>;
|
|
5
|
+
maxDpr?: number;
|
|
6
|
+
className?: string;
|
|
7
|
+
style?: React.CSSProperties;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Minimal raw WebGL2 canvas renderer for fullscreen fragment shaders.
|
|
11
|
+
* - Built-in uniforms: iTime (float), iResolution (vec2)
|
|
12
|
+
* - Custom uniforms read from `uniformsRef` each frame (no stale closures)
|
|
13
|
+
* - ResizeObserver for responsive canvas sizing
|
|
14
|
+
* - rAF animation loop with cleanup on unmount
|
|
15
|
+
* - Graceful degradation: renders nothing if WebGL2 unavailable
|
|
16
|
+
*/
|
|
17
|
+
export declare const ShaderCanvas: React.FC<ShaderCanvasProps>;
|