@flikk/ui 1.0.0-beta.10 → 1.0.0-beta.12
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 +2 -1
- package/dist/components/ai/MessageHistory/MessageHistory.js +1 -0
- package/dist/components/ai/StreamingResponse/StreamingResponse.js +1 -0
- package/dist/components/ai/index.js +1 -0
- package/dist/components/core/Accordion/Accordion.animations.d.ts +6 -1
- package/dist/components/core/Accordion/Accordion.animations.js +15 -1
- 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 +6 -6
- package/dist/components/core/Accordion/Accordion.types.d.ts +34 -4
- 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 +20 -6
- 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 +3 -3
- package/dist/components/core/Badge/Badge.theme.js +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 +22 -25
- package/dist/components/core/Button/Button.ripple.d.ts +5 -1
- package/dist/components/core/Button/Button.ripple.js +27 -17
- package/dist/components/core/Button/Button.theme.d.ts +1 -2
- package/dist/components/core/Button/Button.theme.js +7 -7
- package/dist/components/core/Button/index.d.ts +2 -0
- package/dist/components/core/Calendar/Calendar.js +3 -3
- 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 +6 -6
- package/dist/components/core/Card/Card.types.d.ts +8 -13
- package/dist/components/core/Card/CardBody.d.ts +3 -0
- package/dist/components/core/Card/CardBody.js +11 -0
- package/dist/components/core/Card/CardSubtitle.d.ts +1 -1
- package/dist/components/core/Card/CardTitle.d.ts +1 -1
- 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.d.ts +2 -0
- package/dist/components/core/Drawer/Drawer.theme.js +12 -10
- 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/{DrawerContent.js → DrawerBody.js} +3 -3
- package/dist/components/core/Drawer/DrawerHeader.js +1 -0
- package/dist/components/core/Drawer/DrawerTitle.js +1 -1
- 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/MenuItem/MenuItem.js +3 -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 +2 -2
- package/dist/components/core/Message/Message.types.d.ts +1 -1
- 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/Modal/ModalHeader.js +1 -0
- 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} +5 -5
- 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/Toast/Toast.js +5 -1
- package/dist/components/core/Toast/Toast.types.d.ts +9 -9
- package/dist/components/core/index.js +7 -2
- package/dist/components/data-display/Feed/Feed.js +10 -2
- package/dist/components/data-display/Feed/Feed.types.d.ts +4 -4
- package/dist/components/data-display/GanttChart/GanttTaskContextMenu.js +1 -1
- package/dist/components/data-display/GanttChart/GanttToolbar.js +1 -0
- 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 +3 -1
- package/dist/components/data-display/Table/TableFilter.js +2 -1
- package/dist/components/data-display/Table/TableSelectionHeader.js +1 -1
- 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/Input/Input.js +2 -2
- package/dist/components/forms/Input/Input.types.d.ts +4 -4
- 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/index.d.ts +2 -2
- package/dist/components/forms/index.js +2 -2
- 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 +9 -4
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/global.scss +1 -1
- package/dist/components/core/Accordion/AccordionContent.d.ts +0 -3
- package/dist/components/core/Button/Button.animations.d.ts +0 -5
- 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/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 -13
- package/dist/components/layout/FormLayout/FormLayoutHeader.d.ts +0 -3
- package/dist/components/layout/FormLayout/FormLayoutHeader.js +0 -12
|
@@ -4,12 +4,13 @@ import { approvalCardTheme } from './ApprovalCard.theme.js';
|
|
|
4
4
|
import { Card } from '../../core/Card/Card.js';
|
|
5
5
|
import { Badge } from '../../core/Badge/Badge.js';
|
|
6
6
|
import { Button } from '../../core/Button/Button.js';
|
|
7
|
+
import 'react';
|
|
7
8
|
import { cn } from '../../../utils/cn.js';
|
|
8
9
|
|
|
9
10
|
const ApprovalCard = ({ title, subtitle, variant = "default", riskLevel = "medium", onApprove, onDeny, children, isApproving = false, className, }) => {
|
|
10
11
|
const riskColor = approvalCardTheme.badgeColors[riskLevel];
|
|
11
12
|
const riskIcon = riskLevel === "critical" || riskLevel === "high" ? (jsx(ExclamationTriangleIcon, { className: "" })) : (jsx(CheckCircleIcon, { className: "" }));
|
|
12
|
-
return (jsxs(Card, { className: cn(approvalCardTheme.baseStyle, approvalCardTheme.variants[variant], className), children: [jsx(Card.Header, { children: jsx("div", { className: "flex flex-col items-start", children: jsxs(Badge, { variant: "outline", color: riskColor, size: "sm", iconStart: riskIcon, className: "font-semibold shadow", children: [riskLevel.toUpperCase(), " RISK"] }) }) }), jsxs(Card.
|
|
13
|
+
return (jsxs(Card, { className: cn(approvalCardTheme.baseStyle, approvalCardTheme.variants[variant], className), children: [jsx(Card.Header, { children: jsx("div", { className: "flex flex-col items-start", children: jsxs(Badge, { variant: "outline", color: riskColor, size: "sm", iconStart: riskIcon, className: "font-semibold shadow", children: [riskLevel.toUpperCase(), " RISK"] }) }) }), jsxs(Card.Body, { className: "space-y-3", children: [jsxs("div", { className: "space-y-1", children: [jsx(Card.Title, { className: "", children: title }), subtitle && (jsx("p", { className: "text-sm md:text-base text-[var(--color-text-secondary)]/80", children: subtitle }))] }), children && (jsx("div", { className: "bg-[var(--color-background-secondary)] rounded-md p-3 text-sm font-mono border border-[var(--color-border)] overflow-x-auto", children: children }))] }), jsxs(Card.Footer, { className: "justify-end gap-2 mt-3", children: [jsx(Button, { variant: "outline", color: "neutral", size: "sm", onClick: onDeny, children: "Deny" }), jsx(Button, { color: riskColor, size: "sm", state: isApproving ? "loading" : "default", onClick: onApprove, children: "Approve" })] })] }));
|
|
13
14
|
};
|
|
14
15
|
|
|
15
16
|
export { ApprovalCard };
|
|
@@ -3,6 +3,7 @@ import React__default, { useRef, useCallback, useEffect, useMemo } from 'react';
|
|
|
3
3
|
import { messageHistoryTheme } from './MessageHistory.theme.js';
|
|
4
4
|
import { Message } from '../../core/Message/Message.js';
|
|
5
5
|
import '../../core/Message/TypeWriter.js';
|
|
6
|
+
import '../../core/Message/MessageBody.js';
|
|
6
7
|
import { cn } from '../../../utils/cn.js';
|
|
7
8
|
|
|
8
9
|
/**
|
|
@@ -3,6 +3,7 @@ import { useRef, useEffect } from 'react';
|
|
|
3
3
|
import { useStreamingSSE } from '../../../hooks/useStreamingSSE.js';
|
|
4
4
|
import { Message } from '../../core/Message/Message.js';
|
|
5
5
|
import { TypeWriter } from '../../core/Message/TypeWriter.js';
|
|
6
|
+
import '../../core/Message/MessageBody.js';
|
|
6
7
|
import { ErrorDisplay } from './ErrorDisplay.js';
|
|
7
8
|
import { MarkdownRenderer } from './MarkdownRenderer.js';
|
|
8
9
|
import { AnimatedText } from './AnimatedText.js';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { Message } from '../core/Message/Message.js';
|
|
2
2
|
export { messageTheme } from '../core/Message/Message.theme.js';
|
|
3
3
|
import '../core/Message/TypeWriter.js';
|
|
4
|
+
import '../core/Message/MessageBody.js';
|
|
4
5
|
export { MessageHistory } from './MessageHistory/MessageHistory.js';
|
|
5
6
|
export { messageHistoryTheme } from './MessageHistory/MessageHistory.theme.js';
|
|
6
7
|
export { PromptInput } from './PromptInput/PromptInput.js';
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
import { Variants } from 'motion/react';
|
|
1
|
+
import type { Variants } from 'motion/react';
|
|
2
2
|
/**
|
|
3
3
|
* Accordion animation variants for smooth, staggered open/close transitions
|
|
4
4
|
*/
|
|
5
5
|
export declare const accordionAnimations: Variants;
|
|
6
|
+
/**
|
|
7
|
+
* Factory for trigger icon rotation variants.
|
|
8
|
+
* @param rotation - Degrees to rotate when open (e.g. 45 for PlusIcon, 180 for chevron)
|
|
9
|
+
*/
|
|
10
|
+
export declare const createTriggerIconVariants: (rotation: number) => Variants;
|
|
6
11
|
/**
|
|
7
12
|
* Content animation variants for subtle slide-in effect after container expands
|
|
8
13
|
*/
|
|
@@ -19,6 +19,20 @@ const accordionAnimations = {
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
};
|
|
22
|
+
/**
|
|
23
|
+
* Factory for trigger icon rotation variants.
|
|
24
|
+
* @param rotation - Degrees to rotate when open (e.g. 45 for PlusIcon, 180 for chevron)
|
|
25
|
+
*/
|
|
26
|
+
const createTriggerIconVariants = (rotation) => ({
|
|
27
|
+
closed: {
|
|
28
|
+
rotate: 0,
|
|
29
|
+
transition: { duration: 0.2, ease: [0.4, 0.0, 0.2, 1] },
|
|
30
|
+
},
|
|
31
|
+
open: {
|
|
32
|
+
rotate: rotation,
|
|
33
|
+
transition: { duration: 0.2, ease: [0.4, 0.0, 0.2, 1] },
|
|
34
|
+
},
|
|
35
|
+
});
|
|
22
36
|
/**
|
|
23
37
|
* Content animation variants for subtle slide-in effect after container expands
|
|
24
38
|
*/
|
|
@@ -42,4 +56,4 @@ const accordionContentAnimations = {
|
|
|
42
56
|
}
|
|
43
57
|
};
|
|
44
58
|
|
|
45
|
-
export { accordionAnimations, accordionContentAnimations };
|
|
59
|
+
export { accordionAnimations, accordionContentAnimations, createTriggerIconVariants };
|
|
@@ -7,5 +7,5 @@ export declare const Accordion: {
|
|
|
7
7
|
} & {
|
|
8
8
|
Item: React.ForwardRefExoticComponent<import("./Accordion.types").AccordionItemProps & React.RefAttributes<HTMLDivElement>>;
|
|
9
9
|
Trigger: React.ForwardRefExoticComponent<import("./Accordion.types").AccordionTriggerProps & React.RefAttributes<HTMLButtonElement>>;
|
|
10
|
-
|
|
10
|
+
Body: React.ForwardRefExoticComponent<import("./Accordion.types").AccordionBodyProps & React.RefAttributes<HTMLDivElement>>;
|
|
11
11
|
};
|
|
@@ -3,7 +3,7 @@ import { useContext, createContext, useState, useCallback } from 'react';
|
|
|
3
3
|
import { cn } from '../../../utils/cn.js';
|
|
4
4
|
import { accordionTheme } from './Accordion.theme.js';
|
|
5
5
|
import { AccordionTrigger } from './AccordionTrigger.js';
|
|
6
|
-
import {
|
|
6
|
+
import { AccordionBody } from './AccordionBody.js';
|
|
7
7
|
import { AccordionItem } from './AccordionItem.js';
|
|
8
8
|
|
|
9
9
|
// Create context for the main Accordion component
|
|
@@ -50,7 +50,7 @@ AccordionRoot.displayName = "Accordion";
|
|
|
50
50
|
const Accordion = Object.assign(AccordionRoot, {
|
|
51
51
|
Item: AccordionItem,
|
|
52
52
|
Trigger: AccordionTrigger,
|
|
53
|
-
|
|
53
|
+
Body: AccordionBody,
|
|
54
54
|
});
|
|
55
55
|
|
|
56
56
|
export { Accordion, useAccordionContext };
|
|
@@ -4,15 +4,15 @@ const accordionTheme = {
|
|
|
4
4
|
// Base container styles for stacked variant (unified card)
|
|
5
5
|
baseStyleStacked: "w-full border border-[var(--color-border)] rounded-[var(--form-radius)] overflow-hidden",
|
|
6
6
|
// Item styles for separated variant (individual cards with spacing)
|
|
7
|
-
itemStyle: "border border-[var(--color-border)] rounded-[var(--form-radius)] bg-white dark:bg-[var(--color-background-secondary)] overflow-hidden mb-2 last-of-type:mb-0
|
|
7
|
+
itemStyle: "border border-[var(--color-border)] rounded-[var(--form-radius)] bg-white dark:bg-[var(--color-background-secondary)] overflow-hidden mb-2 last-of-type:mb-0",
|
|
8
8
|
// Item styles for stacked variant (shared borders, no spacing)
|
|
9
9
|
itemStyleStacked: "bg-white border-t border-[var(--color-border)] first-of-type:border-t-0",
|
|
10
10
|
// Trigger styles (shared across variants)
|
|
11
|
-
triggerStyle: "flex w-full gap-3 items-center
|
|
12
|
-
//
|
|
13
|
-
|
|
14
|
-
//
|
|
15
|
-
|
|
11
|
+
triggerStyle: "flex w-full gap-3 items-center px-4 py-2.5 text-left font-medium transition-all duration-200 cursor-pointer focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-primary)] focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 text-[var(--color-text-primary)]",
|
|
12
|
+
// Body styles (shared across variants)
|
|
13
|
+
bodyStyle: "data-[state=closed]:max-h-0 data-[state=open]:max-h-[320px] accordion-content overflow-hidden",
|
|
14
|
+
// Body inner wrapper styles
|
|
15
|
+
bodyInnerStyle: "p-4 pb-2.5 pt-0",
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
export { accordionTheme };
|
|
@@ -53,7 +53,8 @@ export interface AccordionContextValue {
|
|
|
53
53
|
theme: AccordionThemeOverrides & {
|
|
54
54
|
baseStyle: string;
|
|
55
55
|
triggerStyle: string;
|
|
56
|
-
|
|
56
|
+
bodyStyle: string;
|
|
57
|
+
bodyInnerStyle: string;
|
|
57
58
|
};
|
|
58
59
|
}
|
|
59
60
|
/**
|
|
@@ -89,11 +90,39 @@ export interface AccordionItemContextValue {
|
|
|
89
90
|
export interface AccordionTriggerProps extends React.HTMLAttributes<HTMLButtonElement> {
|
|
90
91
|
children: React.ReactNode;
|
|
91
92
|
className?: string;
|
|
93
|
+
/**
|
|
94
|
+
* Override the default indicator (chevron) icon.
|
|
95
|
+
* Set to `null` to hide it entirely — equivalent to `showChevron={false}`.
|
|
96
|
+
*/
|
|
97
|
+
chevron?: React.ReactNode | null;
|
|
98
|
+
/**
|
|
99
|
+
* Rotation degrees applied to the chevron icon when open.
|
|
100
|
+
* Default: 45 (for PlusIcon). Use 180 for a chevron-down, 90 for a right-arrow, 0 for none.
|
|
101
|
+
*/
|
|
102
|
+
chevronRotation?: number;
|
|
103
|
+
/**
|
|
104
|
+
* Position of the chevron icon.
|
|
105
|
+
* - `"right"` (default): pushed to the far right after children.
|
|
106
|
+
* - `"left"`: appears before children.
|
|
107
|
+
* No effect when `chevron` is explicitly provided.
|
|
108
|
+
* @default "right"
|
|
109
|
+
*/
|
|
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
|
+
/**
|
|
118
|
+
* @deprecated Use `chevronRotation` instead.
|
|
119
|
+
*/
|
|
120
|
+
iconRotation?: number;
|
|
92
121
|
}
|
|
93
122
|
/**
|
|
94
|
-
*
|
|
123
|
+
* Body props
|
|
95
124
|
*/
|
|
96
|
-
export interface
|
|
125
|
+
export interface AccordionBodyProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
97
126
|
children: React.ReactNode;
|
|
98
127
|
className?: string;
|
|
99
128
|
}
|
|
@@ -104,7 +133,8 @@ export interface AccordionThemeOverrides {
|
|
|
104
133
|
baseStyle?: string;
|
|
105
134
|
baseStyleStacked?: string;
|
|
106
135
|
triggerStyle?: string;
|
|
107
|
-
|
|
136
|
+
bodyStyle?: string;
|
|
137
|
+
bodyInnerStyle?: string;
|
|
108
138
|
itemStyle?: string;
|
|
109
139
|
itemStyleStacked?: string;
|
|
110
140
|
}
|
|
@@ -6,7 +6,7 @@ import { useAccordionItemContext } from './AccordionItem.js';
|
|
|
6
6
|
import { useReducedMotion, AnimatePresence, motion } from 'motion/react';
|
|
7
7
|
import { accordionAnimations, accordionContentAnimations } from './Accordion.animations.js';
|
|
8
8
|
|
|
9
|
-
const
|
|
9
|
+
const AccordionBody = React__default.forwardRef(({ children, className, ...rest }, ref) => {
|
|
10
10
|
const { theme } = useAccordionContext();
|
|
11
11
|
const { isOpen, contentId, triggerId } = useAccordionItemContext();
|
|
12
12
|
const shouldReduceMotion = useReducedMotion();
|
|
@@ -14,8 +14,8 @@ const AccordionContent = React__default.forwardRef(({ children, className, ...re
|
|
|
14
14
|
const instantTransition = shouldReduceMotion ? { duration: 0 } : undefined;
|
|
15
15
|
// Filter out conflicting props to avoid type issues
|
|
16
16
|
const { onDrag, onDragEnd, onDragStart, onAnimationStart, onAnimationEnd, onTransitionEnd, onTransitionStart, ...safeProps } = rest;
|
|
17
|
-
return (jsx(AnimatePresence, { initial: false, children: isOpen && (jsx(motion.div, { ref: ref, id: contentId, role: "region", "aria-labelledby": triggerId, className:
|
|
17
|
+
return (jsx(AnimatePresence, { initial: false, children: isOpen && (jsx(motion.div, { ref: ref, id: contentId, role: "region", "aria-labelledby": triggerId, className: theme === null || theme === void 0 ? void 0 : theme.bodyStyle, "data-state": isOpen ? "open" : "closed", "aria-hidden": !isOpen, initial: "collapsed", animate: "open", exit: "collapsed", variants: accordionAnimations, transition: instantTransition, ...safeProps, children: jsx(motion.div, { className: cn(theme === null || theme === void 0 ? void 0 : theme.bodyInnerStyle, className), variants: accordionContentAnimations, initial: "collapsed", animate: "open", exit: "collapsed", transition: instantTransition, children: children }) })) }));
|
|
18
18
|
});
|
|
19
|
-
|
|
19
|
+
AccordionBody.displayName = "Accordion.Body";
|
|
20
20
|
|
|
21
|
-
export {
|
|
21
|
+
export { AccordionBody };
|
|
@@ -9,7 +9,7 @@ const AccordionItemContext = createContext(undefined);
|
|
|
9
9
|
const useAccordionItemContext = () => {
|
|
10
10
|
const ctx = useContext(AccordionItemContext);
|
|
11
11
|
if (!ctx)
|
|
12
|
-
throw new Error("Accordion.Trigger and Accordion.
|
|
12
|
+
throw new Error("Accordion.Trigger and Accordion.Body must be used within Accordion.Item");
|
|
13
13
|
return ctx;
|
|
14
14
|
};
|
|
15
15
|
const AccordionItem = React__default.forwardRef(({ children, className, value, ...props }, ref) => {
|
|
@@ -1,18 +1,32 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import React__default from 'react';
|
|
3
3
|
import { cn } from '../../../utils/cn.js';
|
|
4
4
|
import { useAccordionContext } from './Accordion.js';
|
|
5
5
|
import { useAccordionItemContext } from './AccordionItem.js';
|
|
6
6
|
import { motion } from 'motion/react';
|
|
7
7
|
import { PlusIcon } from '@heroicons/react/24/outline';
|
|
8
|
+
import { createTriggerIconVariants } from './Accordion.animations.js';
|
|
8
9
|
|
|
9
|
-
const AccordionTrigger = React__default.forwardRef(({ children, className, ...props }, ref) => {
|
|
10
|
+
const AccordionTrigger = React__default.forwardRef(({ children, className, chevron, chevronRotation, iconRotation, chevronPosition = "right", showChevron = true, ...props }, ref) => {
|
|
11
|
+
var _a;
|
|
10
12
|
const { theme } = useAccordionContext();
|
|
11
13
|
const { isOpen, toggle, triggerId, contentId } = useAccordionItemContext();
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
|
16
|
+
const defaultChevronIcon = jsx(PlusIcon, { className: "size-4", strokeWidth: 2 });
|
|
17
|
+
const resolvedChevron = !showChevron || chevron === null
|
|
18
|
+
? null
|
|
19
|
+
: chevron !== undefined
|
|
20
|
+
? chevron
|
|
21
|
+
: chevronPosition === "left"
|
|
22
|
+
? null // rendered in the left slot instead
|
|
23
|
+
: defaultChevronIcon;
|
|
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;
|
|
28
|
+
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
|
+
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 }))] }));
|
|
16
30
|
});
|
|
17
31
|
AccordionTrigger.displayName = "AccordionTrigger";
|
|
18
32
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Accordion } from "./Accordion";
|
|
2
|
-
import { AccordionProps, AccordionTriggerProps,
|
|
2
|
+
import { AccordionProps, AccordionTriggerProps, AccordionBodyProps, AccordionItemProps, AccordionContextValue, AccordionItemContextValue, AccordionThemeOverrides } from "./Accordion.types";
|
|
3
3
|
export { Accordion };
|
|
4
|
-
export type { AccordionProps, AccordionItemProps, AccordionTriggerProps,
|
|
4
|
+
export type { AccordionProps, AccordionItemProps, AccordionTriggerProps, AccordionBodyProps, AccordionContextValue, AccordionItemContextValue, AccordionThemeOverrides, };
|
|
@@ -33,7 +33,11 @@ const Alert = React__default.forwardRef(({ variant = "default", color = "primary
|
|
|
33
33
|
const IconComponent = defaultIcons[color];
|
|
34
34
|
return (jsx("div", { className: "flex-shrink-0 w-6 h-6 mt-1", "aria-hidden": "true", children: jsx(IconComponent, { className: cn("w-6 h-6", iconColor) }) }));
|
|
35
35
|
};
|
|
36
|
-
const alertNode = (jsxs("div", { ref: ref, className: cn(alertTheme.baseStyle, alertTheme.variants[variant], className), role: "alert", "aria-live": "assertive", "aria-atomic": "true", ...props, children: [renderIconOrAvatar(), jsxs("div", { className: `flex-1 min-w-0 ${showDismiss ? "mr-5" : ""}`, children: [title && (
|
|
36
|
+
const alertNode = (jsxs("div", { ref: ref, className: cn(alertTheme.baseStyle, alertTheme.variants[variant], className), role: "alert", "aria-live": "assertive", "aria-atomic": "true", ...props, children: [renderIconOrAvatar(), jsxs("div", { className: `flex-1 min-w-0 ${showDismiss ? "mr-5" : ""}`, children: [title && (typeof title === 'string'
|
|
37
|
+
? jsx("div", { className: cn("font-semibold text-[var(--color-text-primary)]"), children: title })
|
|
38
|
+
: title), subtitle && (typeof subtitle === 'string'
|
|
39
|
+
? jsx("div", { className: "text-[var(--color-text-secondary)]/90 mt-1", children: subtitle })
|
|
40
|
+
: subtitle), children && jsx("div", { className: "mt-2", children: children }), actions && (jsx("div", { className: "flex items-center gap-2 mt-6", children: actions }))] }), showDismiss && (jsx(Button, { variant: "link", color: "neutral", size: "sm", iconOnly: true, onClick: handleDismiss, "aria-label": "Dismiss alert", className: "rounded-full absolute top-2 right-2 flex-shrink-0", children: jsx(XMarkIcon, { className: "size-4", strokeWidth: 2 }) }))] }));
|
|
37
41
|
if (darkMode) {
|
|
38
42
|
return jsx("div", { className: "dark", children: alertNode });
|
|
39
43
|
}
|
|
@@ -23,15 +23,15 @@ export interface AlertTheme {
|
|
|
23
23
|
dismissible: string;
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
|
-
export interface AlertProps extends HTMLAttributes<HTMLDivElement> {
|
|
26
|
+
export interface AlertProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
|
|
27
27
|
/** Visual variant */
|
|
28
28
|
variant?: AlertVariant;
|
|
29
29
|
/** Semantic color */
|
|
30
30
|
color?: AlertColor;
|
|
31
31
|
/** The main title/message of the alert */
|
|
32
|
-
title?:
|
|
32
|
+
title?: ReactNode;
|
|
33
33
|
/** Additional subtitle text */
|
|
34
|
-
subtitle?:
|
|
34
|
+
subtitle?: ReactNode;
|
|
35
35
|
/** Whether the alert can be dismissed */
|
|
36
36
|
dismissible?: boolean;
|
|
37
37
|
/**
|
|
@@ -63,8 +63,8 @@ const badgeTheme = {
|
|
|
63
63
|
},
|
|
64
64
|
// Flat size structure (no nested objects)
|
|
65
65
|
sizes: {
|
|
66
|
-
sm: "text-
|
|
67
|
-
md: "text-
|
|
66
|
+
sm: "text-sm px-1.5 py-0.5 gap-1",
|
|
67
|
+
md: "text-base px-2 py-0.5 gap-1",
|
|
68
68
|
},
|
|
69
69
|
// Border radius per size (using CSS variable)
|
|
70
70
|
radiusSizes: {
|
|
@@ -42,8 +42,10 @@ const Breadcrumbs = ({ items, separator, maxItems = 4, variant = "default", clas
|
|
|
42
42
|
// Render individual breadcrumb item
|
|
43
43
|
const renderItem = (item, index, isLast) => {
|
|
44
44
|
const isCurrentPage = isLast || !item.href;
|
|
45
|
-
const itemContent = (jsxs(Fragment, { children: [showIcons && item.iconStart && (jsx("span", { className: "mr-1.5 flex-shrink-0", children: item.iconStart })), item.label
|
|
46
|
-
|
|
45
|
+
const itemContent = (jsxs(Fragment, { children: [showIcons && item.iconStart && (jsx("span", { className: "mr-1.5 flex-shrink-0", children: item.iconStart })), typeof item.label === 'string'
|
|
46
|
+
? jsx("span", { children: item.label })
|
|
47
|
+
: item.label] }));
|
|
48
|
+
return (jsx("span", { className: "flex items-center text-base", children: isCurrentPage ? (jsx("span", { className: cn("flex items-center", theme.current), "aria-current": "page", children: itemContent })) : (jsx("a", { href: item.href, className: cn("flex items-center", theme.link), "aria-label": typeof item.label === 'string' ? `Navigate to ${item.label}` : undefined, children: itemContent })) }, `breadcrumb-${index}`));
|
|
47
49
|
};
|
|
48
50
|
// Render separator
|
|
49
51
|
const renderSeparator = (index) => {
|
|
@@ -60,7 +62,9 @@ const Breadcrumbs = ({ items, separator, maxItems = 4, variant = "default", clas
|
|
|
60
62
|
window.location.href = selectedItem.href;
|
|
61
63
|
}
|
|
62
64
|
};
|
|
63
|
-
return (jsxs(Dropdown, { isOpen: isEllipsisOpen, onOpenChange: setIsEllipsisOpen, onAction: handleEllipsisAction, placement: "bottom-start", offset: 8, children: [jsx(Dropdown.Trigger, { children: jsx("button", { type: "button", className: cn(theme.ellipsis), "aria-label": `Navigate to one of ${hiddenItems.length} hidden breadcrumbs`, children: "..." }) }), jsx(Dropdown.Menu, { "aria-label": "Hidden breadcrumb items", children: hiddenItems.map((item, index) => (jsx(Dropdown.Item, { itemKey: `hidden-${index}`, startContent: showIcons && item.iconStart, children: item.label
|
|
65
|
+
return (jsxs(Dropdown, { isOpen: isEllipsisOpen, onOpenChange: setIsEllipsisOpen, onAction: handleEllipsisAction, placement: "bottom-start", offset: 8, children: [jsx(Dropdown.Trigger, { children: jsx("button", { type: "button", className: cn(theme.ellipsis), "aria-label": `Navigate to one of ${hiddenItems.length} hidden breadcrumbs`, children: "..." }) }), jsx(Dropdown.Menu, { "aria-label": "Hidden breadcrumb items", children: hiddenItems.map((item, index) => (jsx(Dropdown.Item, { itemKey: `hidden-${index}`, startContent: showIcons && item.iconStart, children: typeof item.label === 'string'
|
|
66
|
+
? jsx("span", { children: item.label })
|
|
67
|
+
: item.label }, `hidden-${index}`))) })] }, "ellipsis"));
|
|
64
68
|
};
|
|
65
69
|
// Build the breadcrumb elements
|
|
66
70
|
const breadcrumbElements = [];
|
|
@@ -4,7 +4,7 @@ import React from "react";
|
|
|
4
4
|
*/
|
|
5
5
|
export interface BreadcrumbItem {
|
|
6
6
|
/** The display text for the breadcrumb item */
|
|
7
|
-
label:
|
|
7
|
+
label: React.ReactNode;
|
|
8
8
|
/** Optional href for navigation. If not provided, item is treated as current page */
|
|
9
9
|
href?: string;
|
|
10
10
|
/** Optional icon to display at the start (before the label) */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
-
import React__default, { useCallback } from 'react';
|
|
2
|
+
import React__default, { useCallback, useRef } from 'react';
|
|
3
3
|
import { useReducedMotion, motion } from 'motion/react';
|
|
4
4
|
import { buttonTheme } from './Button.theme.js';
|
|
5
5
|
import { cn } from '../../../utils/cn.js';
|
|
@@ -18,7 +18,7 @@ const BUTTON_TAP_ANIMATION = {
|
|
|
18
18
|
},
|
|
19
19
|
},
|
|
20
20
|
};
|
|
21
|
-
const Button = React__default.forwardRef(({ children, className = "", iconOnly = false, state = "default", size = "md", color, variant, block = false, onClick, enableRipple = true, rippleEffect = "default", rippleClassName, rippleScale = 10, showReflection = true, darkMode = false, ...
|
|
21
|
+
const Button = React__default.forwardRef(({ children, className = "", iconOnly = false, state = "default", size = "md", color, variant, block = false, onClick, enableRipple = true, rippleEffect = "default", rippleClassName, rippleScale = 10, showReflection = true, darkMode = false, disabled: disabledProp, "aria-label": ariaLabelProp, ...restProps }, ref) => {
|
|
22
22
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
23
23
|
const shouldReduceMotion = useReducedMotion();
|
|
24
24
|
const shouldDisableAnimations = !!shouldReduceMotion;
|
|
@@ -33,18 +33,18 @@ const Button = React__default.forwardRef(({ children, className = "", iconOnly =
|
|
|
33
33
|
const resolvedVariant = variant || "filled";
|
|
34
34
|
// Derived state flags (direct computation - faster than useMemo)
|
|
35
35
|
const isLoading = state === "loading";
|
|
36
|
-
const isDisabled = state === "disabled" || state === "loading";
|
|
36
|
+
const isDisabled = state === "disabled" || state === "loading" || !!disabledProp;
|
|
37
37
|
const isError = state === "error";
|
|
38
38
|
// Dev-time a11y warning for iconOnly buttons without aria-label
|
|
39
39
|
if (process.env.NODE_ENV !== "production") {
|
|
40
|
-
if (iconOnly && !
|
|
40
|
+
if (iconOnly && !ariaLabelProp) {
|
|
41
41
|
// eslint-disable-next-line no-console
|
|
42
42
|
console.warn("Button(iconOnly) requires 'aria-label' for accessibility.");
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
// Safe onClick handler - respect both state="disabled" and disabled={true}
|
|
46
46
|
const handleClick = useCallback((event) => {
|
|
47
|
-
if (isDisabled
|
|
47
|
+
if (isDisabled)
|
|
48
48
|
return;
|
|
49
49
|
// Create ripple effect if enabled
|
|
50
50
|
if (enableRipple && !shouldReduceMotion) {
|
|
@@ -59,19 +59,12 @@ const Button = React__default.forwardRef(({ children, className = "", iconOnly =
|
|
|
59
59
|
console.error("Error in button click handler:", error);
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
|
-
}, [
|
|
63
|
-
onClick,
|
|
64
|
-
isDisabled,
|
|
65
|
-
props.disabled,
|
|
66
|
-
enableRipple,
|
|
67
|
-
shouldReduceMotion,
|
|
68
|
-
createRipple,
|
|
69
|
-
]);
|
|
62
|
+
}, [onClick, isDisabled, enableRipple, shouldReduceMotion, createRipple]);
|
|
70
63
|
// Compute theme classes (direct computation - faster than useMemo)
|
|
71
64
|
const sizeClasses = ((_b = (_a = buttonTheme.sizes) === null || _a === void 0 ? void 0 : _a[size]) === null || _b === void 0 ? void 0 : _b[iconOnly ? "iconOnly" : resolvedVariant === "link" ? "link" : "default"]) || "";
|
|
72
65
|
const colorClasses = ((_c = buttonTheme.variantColors[resolvedVariant]) === null || _c === void 0 ? void 0 : _c[resolvedColor]) || "";
|
|
73
66
|
const variantClasses = ((_d = buttonTheme.variantStyles) === null || _d === void 0 ? void 0 : _d[resolvedVariant]) || "";
|
|
74
|
-
const stateClasses =
|
|
67
|
+
const stateClasses = isDisabled
|
|
75
68
|
? ((_e = buttonTheme.states) === null || _e === void 0 ? void 0 : _e.disabled) || ""
|
|
76
69
|
: isError
|
|
77
70
|
? ((_f = buttonTheme.states) === null || _f === void 0 ? void 0 : _f.error) || ""
|
|
@@ -80,7 +73,7 @@ const Button = React__default.forwardRef(({ children, className = "", iconOnly =
|
|
|
80
73
|
: "";
|
|
81
74
|
const blockStyle = block ? buttonTheme.blockStyle : "";
|
|
82
75
|
// Generate default aria-label for icon-only buttons if not provided (fallback only)
|
|
83
|
-
const ariaLabel = iconOnly && !
|
|
76
|
+
const ariaLabel = iconOnly && !ariaLabelProp ? "Button" : ariaLabelProp;
|
|
84
77
|
// Determine animation props (user props will override due to spread order)
|
|
85
78
|
const animationProps = shouldDisableAnimations
|
|
86
79
|
? {}
|
|
@@ -92,26 +85,30 @@ const Button = React__default.forwardRef(({ children, className = "", iconOnly =
|
|
|
92
85
|
const spinnerClassName = resolvedVariant === "filled" && color !== "neutral"
|
|
93
86
|
? "border-t-white border-l-white"
|
|
94
87
|
: "";
|
|
95
|
-
//
|
|
96
|
-
const
|
|
88
|
+
// Track the latest forwarded ref to avoid mergedRef recreation on inline callback refs
|
|
89
|
+
const forwardedRef = useRef(ref);
|
|
90
|
+
forwardedRef.current = ref;
|
|
91
|
+
// Merge refs - stable callback that won't cause DOM detach/attach cycles
|
|
92
|
+
const mergedRef = useCallback((node) => {
|
|
97
93
|
// Set ripple's buttonRef
|
|
98
94
|
if (buttonRef) {
|
|
99
95
|
buttonRef.current = node;
|
|
100
96
|
}
|
|
101
97
|
// Set forwarded ref
|
|
102
|
-
|
|
103
|
-
|
|
98
|
+
const fRef = forwardedRef.current;
|
|
99
|
+
if (typeof fRef === "function") {
|
|
100
|
+
fRef(node);
|
|
104
101
|
}
|
|
105
|
-
else if (
|
|
106
|
-
|
|
102
|
+
else if (fRef) {
|
|
103
|
+
fRef.current =
|
|
107
104
|
node;
|
|
108
105
|
}
|
|
109
|
-
}, [
|
|
110
|
-
return (jsxs(motion.button, { ref: mergedRef, type: "button", className: cn(buttonTheme.baseStyle, colorClasses, variantClasses, sizeClasses, blockStyle, stateClasses, darkMode && "dark", className), disabled: isDisabled, "data-state": state, "data-color": resolvedColor, "data-variant": resolvedVariant, "data-size": size, "data-icon-only": iconOnly ? "true" : "false", "data-block": block ? "true" : "false", "aria-disabled": isDisabled || undefined, "aria-invalid": isError || undefined, "aria-label": ariaLabel,
|
|
106
|
+
}, [buttonRef]);
|
|
107
|
+
return (jsxs(motion.button, { ...restProps /* React drag events conflict with motion drag events */, ...animationProps, ref: mergedRef, type: "button", className: cn(buttonTheme.baseStyle, colorClasses, variantClasses, sizeClasses, blockStyle, stateClasses, darkMode && "dark", className), disabled: isDisabled, "data-state": state, "data-color": resolvedColor, "data-variant": resolvedVariant, "data-size": size, "data-icon-only": iconOnly ? "true" : "false", "data-block": block ? "true" : "false", "aria-disabled": isDisabled || undefined, "aria-invalid": isError || undefined, "aria-label": ariaLabel, onClick: handleClick, children: [showReflection &&
|
|
111
108
|
resolvedVariant !== "link" &&
|
|
112
|
-
resolvedVariant !== "outline" && (jsx("div", { className: "absolute top-0.25 right-0.25 left-0.25 h-3
|
|
109
|
+
resolvedVariant !== "outline" && (jsx("div", { className: "absolute top-0.25 right-0.25 left-0.25 h-3 border-t-[0.5px] border-white/40 rounded-t-[calc(var(--button-radius)-1.25px)] opacity-60" })), isLoading && (jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: jsx(Spinner, { size: "sm", color: color, className: spinnerClassName }) })), jsx("span", { className: cn("inline-flex items-center gap-2 whitespace-nowrap", isLoading && "opacity-0"), children: children }), enableRipple &&
|
|
113
110
|
ripples.map((ripple) => {
|
|
114
|
-
const animation = getRippleAnimation(effect, ripple
|
|
111
|
+
const animation = getRippleAnimation(effect, ripple, rippleScale);
|
|
115
112
|
return (jsx(motion.span, { initial: animation.initial, animate: animation.animate, transition: animation.transition, className: cn("absolute rounded-full size-5 pointer-events-none ", animation.className, rippleClassName ||
|
|
116
113
|
getRippleColorClass(resolvedVariant, resolvedColor)), style: {
|
|
117
114
|
top: ripple.y - 10,
|
|
@@ -12,6 +12,10 @@ export interface Ripple {
|
|
|
12
12
|
x: number;
|
|
13
13
|
y: number;
|
|
14
14
|
layer?: number;
|
|
15
|
+
/** Pre-computed random scale factor for particle effect (0-1 range) */
|
|
16
|
+
randomScale?: number;
|
|
17
|
+
/** Pre-computed random duration offset for particle effect (0-1 range) */
|
|
18
|
+
randomDuration?: number;
|
|
15
19
|
}
|
|
16
20
|
export interface RippleConfig {
|
|
17
21
|
/** Scale multiplier for ripple expansion (default: 10) */
|
|
@@ -53,7 +57,7 @@ export declare function getRippleColorClass(variant?: string, color?: string): s
|
|
|
53
57
|
/**
|
|
54
58
|
* Get animation properties for specific ripple effect and layer
|
|
55
59
|
*/
|
|
56
|
-
export declare function getRippleAnimation(effect: RippleEffectType,
|
|
60
|
+
export declare function getRippleAnimation(effect: RippleEffectType, ripple: Ripple, baseScale: number): {
|
|
57
61
|
initial: {
|
|
58
62
|
scale: number;
|
|
59
63
|
opacity: number;
|