@flikk/ui 1.0.0-beta.10 → 1.0.0-beta.11
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 -0
- package/dist/components/ai/PromptInput/PromptInput.js +125 -7
- package/dist/components/ai/PromptInput/VoiceRecorder.js +77 -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.theme.js +3 -3
- package/dist/components/core/Accordion/Accordion.types.d.ts +25 -0
- package/dist/components/core/Accordion/AccordionContent.js +1 -1
- package/dist/components/core/Accordion/AccordionTrigger.js +11 -6
- package/dist/components/core/Badge/Badge.theme.js +2 -2
- package/dist/components/core/Button/Button.js +21 -18
- 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 +6 -6
- package/dist/components/core/Button/index.d.ts +2 -0
- package/dist/components/core/Card/Card.theme.js +6 -6
- package/dist/components/core/Card/Card.types.d.ts +4 -9
- package/dist/components/core/Card/CardSubtitle.d.ts +1 -1
- package/dist/components/core/Card/CardTitle.d.ts +1 -1
- package/dist/components/core/Drawer/Drawer.js +1 -1
- package/dist/components/core/Drawer/Drawer.theme.d.ts +2 -0
- package/dist/components/core/Drawer/Drawer.theme.js +13 -11
- package/dist/components/core/Drawer/Drawer.types.d.ts +5 -5
- package/dist/components/core/Drawer/DrawerContent.js +1 -1
- 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 +1 -1
- package/dist/components/core/Modal/ModalHeader.js +1 -0
- package/dist/components/core/index.js +1 -0
- package/dist/components/data-display/GanttChart/GanttToolbar.js +1 -0
- package/dist/components/data-display/Table/TableColumnManager.js +1 -0
- package/dist/components/data-display/Table/TableSelectionHeader.js +1 -1
- package/dist/components/forms/FileUpload/FileUpload.js +78 -0
- package/dist/components/forms/TimePicker/TimePickerContent.js +78 -1
- package/dist/components/forms/index.js +78 -0
- package/dist/components/layout/FormLayout/FormLayoutBody.js +79 -1
- package/dist/index.js +198 -191
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/global.scss +1 -1
- package/dist/components/core/Button/Button.animations.d.ts +0 -5
|
@@ -4,6 +4,7 @@ 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, }) => {
|
|
@@ -1,14 +1,43 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import React__default, { useState, useRef, useId, useEffect, useCallback } from 'react';
|
|
3
3
|
import { AnimatePresence, motion } from 'motion/react';
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import { VoiceRecorder } from './VoiceRecorder.js';
|
|
9
|
-
import { dropzoneContainerVariants, dropzoneChildVariants, dropzoneActionIconVariants, textareaSwapVariants, iconSwapVariants } from './PromptInput.animations.js';
|
|
4
|
+
import '../../forms/Input/Input.js';
|
|
5
|
+
import '../../forms/Input/Input.theme.js';
|
|
6
|
+
import '../../forms/Select/Select.js';
|
|
7
|
+
import '../../forms/Select/Select.theme.js';
|
|
10
8
|
import { Textarea } from '../../forms/Textarea/Textarea.js';
|
|
11
9
|
import '../../forms/Textarea/Textarea.theme.js';
|
|
10
|
+
import '../../forms/FormLabel/FormLabel.js';
|
|
11
|
+
import '../../forms/Radio/Radio.js';
|
|
12
|
+
import '../../forms/Checkbox/Checkbox.js';
|
|
13
|
+
import '../../forms/Switch/Switch.js';
|
|
14
|
+
import '../../forms/DatePicker/DatePicker.js';
|
|
15
|
+
import '../../forms/DatePicker/DatePicker.theme.js';
|
|
16
|
+
import '../../forms/FileUpload/FileUpload.js';
|
|
17
|
+
import '../../forms/TimePicker/TimePicker.js';
|
|
18
|
+
import { CloudArrowUpIcon, MicrophoneIcon, PaperClipIcon, LinkIcon, DocumentIcon, XMarkIcon, PlusIcon, AdjustmentsHorizontalIcon, ChevronDownIcon, ArrowRightIcon } from '@heroicons/react/24/outline';
|
|
19
|
+
import { cn } from '../../../utils/cn.js';
|
|
20
|
+
import 'react-dom';
|
|
21
|
+
import '../../core/Accordion/Accordion.js';
|
|
22
|
+
import '../../core/AlertDialog/AlertDialog.js';
|
|
23
|
+
import '../../core/AspectRatio/AspectRatio.js';
|
|
24
|
+
import '../../core/Avatar/Avatar.js';
|
|
25
|
+
import '../../core/AvatarGroup/AvatarGroup.js';
|
|
26
|
+
import '../../core/Badge/Badge.js';
|
|
27
|
+
import '../../core/Breadcrumbs/Breadcrumbs.js';
|
|
28
|
+
import '../../core/Breadcrumbs/Breadcrumbs.theme.js';
|
|
29
|
+
import { Button } from '../../core/Button/Button.js';
|
|
30
|
+
import '../../core/ButtonGroup/ButtonGroup.js';
|
|
31
|
+
import '../../core/ButtonGroup/ButtonGroupSeparator.js';
|
|
32
|
+
import '../../core/ButtonGroup/ButtonGroupText.js';
|
|
33
|
+
import '../../core/Calendar/Calendar.js';
|
|
34
|
+
import '../../core/Calendar/CalendarMini/CalendarMini.js';
|
|
35
|
+
import '../../core/Card/Card.js';
|
|
36
|
+
import '../../core/CardStack/CardStack.js';
|
|
37
|
+
import '../../core/Carousel/Carousel.js';
|
|
38
|
+
import '../../core/CommandPalette/CommandPalette.js';
|
|
39
|
+
import '../../core/Separator/Separator.js';
|
|
40
|
+
import '../../core/Drawer/Drawer.js';
|
|
12
41
|
import { Dropdown } from '../../core/Dropdown/Dropdown.js';
|
|
13
42
|
import '../../core/Dropdown/DropdownTrigger.js';
|
|
14
43
|
import '../../core/Dropdown/DropdownMenu.js';
|
|
@@ -16,7 +45,96 @@ import '../../core/Dropdown/DropdownItem.js';
|
|
|
16
45
|
import '../../core/Dropdown/DropdownSection.js';
|
|
17
46
|
import '../../core/Dropdown/DropdownSeparator.js';
|
|
18
47
|
import '../../core/Dropdown/Dropdown.theme.js';
|
|
19
|
-
import
|
|
48
|
+
import '../../core/Kbd/Kbd.js';
|
|
49
|
+
import '../../core/MenuItem/MenuItem.js';
|
|
50
|
+
import '../../core/Link/Link.js';
|
|
51
|
+
import '../../core/Loader/Loader.js';
|
|
52
|
+
import '../../core/Modal/Modal.js';
|
|
53
|
+
import '../../core/ModalStack/ModalStack.js';
|
|
54
|
+
import '../../core/PageHeading/PageHeading.js';
|
|
55
|
+
import '../../core/Pagination/Pagination.js';
|
|
56
|
+
import '../../core/Popover/Popover.js';
|
|
57
|
+
import '../../core/Popover/PopoverContext.js';
|
|
58
|
+
import '../../core/Progress/Progress.js';
|
|
59
|
+
import '../../core/Rating/Rating.js';
|
|
60
|
+
import '../../core/ScrollArea/ScrollArea.js';
|
|
61
|
+
import '../../core/ScrollArea/smooth/SmoothScrollEngine.js';
|
|
62
|
+
import '../../core/Segmented/Segmented.js';
|
|
63
|
+
import '../../core/Skeleton/Skeleton.js';
|
|
64
|
+
import '../../core/SlidingNumber/SlidingNumber.js';
|
|
65
|
+
import '../../core/Tabs/Tabs.js';
|
|
66
|
+
import '../../core/Tabs/TabsList.js';
|
|
67
|
+
import '../../core/Tabs/TabsTrigger.js';
|
|
68
|
+
import '../../core/Tabs/TabsContent.js';
|
|
69
|
+
import '../../core/Tabs/TabsContext.js';
|
|
70
|
+
import '../../core/Tooltip/Tooltip.js';
|
|
71
|
+
import '../../core/Tooltip/Tooltip.animations.js';
|
|
72
|
+
import '../../core/Tree/Tree.js';
|
|
73
|
+
import '../../core/Tag/Tag.js';
|
|
74
|
+
import '../../core/Alert/Alert.js';
|
|
75
|
+
import '../../core/Toast/Toast.js';
|
|
76
|
+
import '../../core/Toast/ToastProvider.js';
|
|
77
|
+
import { StopIcon } from '@heroicons/react/24/solid';
|
|
78
|
+
import '../../core/Spinner/Spinner.js';
|
|
79
|
+
import '../../core/Message/Message.js';
|
|
80
|
+
import '../../core/Message/TypeWriter.js';
|
|
81
|
+
import '../../core/Empty/Empty.js';
|
|
82
|
+
import '../../core/Masonry/Masonry.js';
|
|
83
|
+
import '../../core/DragDrop/DragDrop.js';
|
|
84
|
+
import '../../core/Sortable/Sortable.js';
|
|
85
|
+
import '../../core/NavItem/NavItem.js';
|
|
86
|
+
import '../../core/Sidebar/Sidebar.js';
|
|
87
|
+
import '../../core/Sidebar/SidebarHeader.js';
|
|
88
|
+
import '../../core/Sidebar/SidebarContent.js';
|
|
89
|
+
import '../../core/Sidebar/SidebarFooter.js';
|
|
90
|
+
import '../../core/Sidebar/SidebarNav.js';
|
|
91
|
+
import '../../core/Sidebar/SidebarNavGroup.js';
|
|
92
|
+
import '../../core/Sidebar/SidebarToggle.js';
|
|
93
|
+
import '../../core/Sidebar/SidebarContext.js';
|
|
94
|
+
import '../../core/OfflineIndicator/OfflineIndicator.js';
|
|
95
|
+
import '../../core/ContextMenu/ContextMenu.js';
|
|
96
|
+
import '../../core/ContextMenu/ContextMenu.theme.js';
|
|
97
|
+
import '../../core/Pill/Pill.js';
|
|
98
|
+
import '../../core/SocialIcon/SocialIcon.js';
|
|
99
|
+
import '../../forms/TimePicker/WheelColumn.js';
|
|
100
|
+
import '../../forms/TimePicker/TimePicker.theme.js';
|
|
101
|
+
import '../../forms/Slider/Slider.js';
|
|
102
|
+
import '../../forms/Slider/Slider.theme.js';
|
|
103
|
+
import '../../forms/Signature/Signature.js';
|
|
104
|
+
import '../../forms/Signature/Signature.theme.js';
|
|
105
|
+
import '../../forms/RichTextEditor/RichTextEditor.js';
|
|
106
|
+
import '../../forms/RichTextEditor/RichTextEditor.theme.js';
|
|
107
|
+
import '../../forms/InputOTP/InputOTP.js';
|
|
108
|
+
import '../../forms/InputOTP/InputOTP.theme.js';
|
|
109
|
+
import '../../forms/InputCreditCard/InputCreditCard.js';
|
|
110
|
+
import '../../forms/InputCreditCard/InputCreditCard.theme.js';
|
|
111
|
+
import '../../forms/InputAddress/InputAddress.js';
|
|
112
|
+
import '../../forms/InputAddress/InputAddress.theme.js';
|
|
113
|
+
import '../../forms/InputDate/InputDate.js';
|
|
114
|
+
import '../../forms/InputCounter/InputCounter.js';
|
|
115
|
+
import '../../forms/InputTag/InputTag.js';
|
|
116
|
+
import '../../forms/InputTag/InputTag.theme.js';
|
|
117
|
+
import '../../forms/Combobox/Combobox.js';
|
|
118
|
+
import '../../forms/Combobox/Combobox.theme.js';
|
|
119
|
+
import '../../forms/ColorPicker/ColorPicker.js';
|
|
120
|
+
import '../../forms/ColorPicker/ColorPickerTrigger.js';
|
|
121
|
+
import '../../forms/ColorPicker/ColorPickerContent.js';
|
|
122
|
+
import '../../forms/ColorPicker/ColorPicker2DCanvas.js';
|
|
123
|
+
import '../../forms/ColorPicker/ColorPickerSwatch.js';
|
|
124
|
+
import '../../forms/ColorPicker/ColorPickerSliders.js';
|
|
125
|
+
import '../../forms/ColorPicker/ColorPickerInput.js';
|
|
126
|
+
import '../../forms/ColorPicker/ColorPickerFormatSelector.js';
|
|
127
|
+
import '../../forms/ColorPicker/ColorPickerEyeDropper.js';
|
|
128
|
+
import '../../forms/ColorPicker/ColorPickerPresets.js';
|
|
129
|
+
import '../../forms/SelectableCard/SelectableCard.js';
|
|
130
|
+
import '../../forms/TransferList/TransferList.js';
|
|
131
|
+
import '../../forms/Mention/Mention.js';
|
|
132
|
+
import '../../forms/Mention/Mention.theme.js';
|
|
133
|
+
import '../../forms/CronInput/CronInput.js';
|
|
134
|
+
import '../../forms/CronInput/CronInput.theme.js';
|
|
135
|
+
import { promptInputTheme } from './PromptInput.theme.js';
|
|
136
|
+
import { VoiceRecorder } from './VoiceRecorder.js';
|
|
137
|
+
import { dropzoneContainerVariants, dropzoneChildVariants, dropzoneActionIconVariants, textareaSwapVariants, iconSwapVariants } from './PromptInput.animations.js';
|
|
20
138
|
|
|
21
139
|
/**
|
|
22
140
|
* Default model options for the model selector
|
|
@@ -3,7 +3,84 @@ import { useState, useRef, useCallback, useEffect } from 'react';
|
|
|
3
3
|
import { motion } from 'motion/react';
|
|
4
4
|
import { PlayIcon, PauseIcon, CheckIcon } from '@heroicons/react/24/outline';
|
|
5
5
|
import { cn } from '../../../utils/cn.js';
|
|
6
|
+
import '../../core/Accordion/Accordion.js';
|
|
7
|
+
import '../../core/AlertDialog/AlertDialog.js';
|
|
8
|
+
import '../../core/AspectRatio/AspectRatio.js';
|
|
9
|
+
import '../../core/Avatar/Avatar.js';
|
|
10
|
+
import '../../core/AvatarGroup/AvatarGroup.js';
|
|
11
|
+
import '../../core/Badge/Badge.js';
|
|
12
|
+
import '../../core/Breadcrumbs/Breadcrumbs.js';
|
|
13
|
+
import '../../core/Breadcrumbs/Breadcrumbs.theme.js';
|
|
6
14
|
import { Button } from '../../core/Button/Button.js';
|
|
15
|
+
import '../../core/ButtonGroup/ButtonGroup.js';
|
|
16
|
+
import '../../core/ButtonGroup/ButtonGroupSeparator.js';
|
|
17
|
+
import '../../core/ButtonGroup/ButtonGroupText.js';
|
|
18
|
+
import '../../core/Calendar/Calendar.js';
|
|
19
|
+
import '../../core/Calendar/CalendarMini/CalendarMini.js';
|
|
20
|
+
import '../../core/Card/Card.js';
|
|
21
|
+
import '../../core/CardStack/CardStack.js';
|
|
22
|
+
import '../../core/Carousel/Carousel.js';
|
|
23
|
+
import '../../core/CommandPalette/CommandPalette.js';
|
|
24
|
+
import '../../core/Separator/Separator.js';
|
|
25
|
+
import '../../core/Drawer/Drawer.js';
|
|
26
|
+
import '../../core/Dropdown/Dropdown.js';
|
|
27
|
+
import '../../core/Dropdown/DropdownTrigger.js';
|
|
28
|
+
import '../../core/Dropdown/DropdownMenu.js';
|
|
29
|
+
import '../../core/Dropdown/DropdownItem.js';
|
|
30
|
+
import '../../core/Dropdown/DropdownSection.js';
|
|
31
|
+
import '../../core/Dropdown/DropdownSeparator.js';
|
|
32
|
+
import '../../core/Dropdown/Dropdown.theme.js';
|
|
33
|
+
import '../../core/Kbd/Kbd.js';
|
|
34
|
+
import '../../core/MenuItem/MenuItem.js';
|
|
35
|
+
import '../../core/Link/Link.js';
|
|
36
|
+
import '../../core/Loader/Loader.js';
|
|
37
|
+
import '../../core/Modal/Modal.js';
|
|
38
|
+
import '../../core/ModalStack/ModalStack.js';
|
|
39
|
+
import '../../core/PageHeading/PageHeading.js';
|
|
40
|
+
import '../../core/Pagination/Pagination.js';
|
|
41
|
+
import '../../core/Popover/Popover.js';
|
|
42
|
+
import '../../core/Popover/PopoverContext.js';
|
|
43
|
+
import '../../core/Progress/Progress.js';
|
|
44
|
+
import '../../core/Rating/Rating.js';
|
|
45
|
+
import '../../core/ScrollArea/ScrollArea.js';
|
|
46
|
+
import '../../core/ScrollArea/smooth/SmoothScrollEngine.js';
|
|
47
|
+
import '../../core/Segmented/Segmented.js';
|
|
48
|
+
import '../../core/Skeleton/Skeleton.js';
|
|
49
|
+
import '../../core/SlidingNumber/SlidingNumber.js';
|
|
50
|
+
import '../../core/Tabs/Tabs.js';
|
|
51
|
+
import '../../core/Tabs/TabsList.js';
|
|
52
|
+
import '../../core/Tabs/TabsTrigger.js';
|
|
53
|
+
import '../../core/Tabs/TabsContent.js';
|
|
54
|
+
import '../../core/Tabs/TabsContext.js';
|
|
55
|
+
import '../../core/Tooltip/Tooltip.js';
|
|
56
|
+
import '../../core/Tooltip/Tooltip.animations.js';
|
|
57
|
+
import '../../core/Tree/Tree.js';
|
|
58
|
+
import '../../core/Tag/Tag.js';
|
|
59
|
+
import '../../core/Alert/Alert.js';
|
|
60
|
+
import '../../core/Toast/Toast.js';
|
|
61
|
+
import '../../core/Toast/ToastProvider.js';
|
|
62
|
+
import '@heroicons/react/24/solid';
|
|
63
|
+
import '../../core/Spinner/Spinner.js';
|
|
64
|
+
import '../../core/Message/Message.js';
|
|
65
|
+
import '../../core/Message/TypeWriter.js';
|
|
66
|
+
import '../../core/Empty/Empty.js';
|
|
67
|
+
import '../../core/Masonry/Masonry.js';
|
|
68
|
+
import '../../core/DragDrop/DragDrop.js';
|
|
69
|
+
import '../../core/Sortable/Sortable.js';
|
|
70
|
+
import '../../core/NavItem/NavItem.js';
|
|
71
|
+
import '../../core/Sidebar/Sidebar.js';
|
|
72
|
+
import '../../core/Sidebar/SidebarHeader.js';
|
|
73
|
+
import '../../core/Sidebar/SidebarContent.js';
|
|
74
|
+
import '../../core/Sidebar/SidebarFooter.js';
|
|
75
|
+
import '../../core/Sidebar/SidebarNav.js';
|
|
76
|
+
import '../../core/Sidebar/SidebarNavGroup.js';
|
|
77
|
+
import '../../core/Sidebar/SidebarToggle.js';
|
|
78
|
+
import '../../core/Sidebar/SidebarContext.js';
|
|
79
|
+
import '../../core/OfflineIndicator/OfflineIndicator.js';
|
|
80
|
+
import '../../core/ContextMenu/ContextMenu.js';
|
|
81
|
+
import '../../core/ContextMenu/ContextMenu.theme.js';
|
|
82
|
+
import '../../core/Pill/Pill.js';
|
|
83
|
+
import '../../core/SocialIcon/SocialIcon.js';
|
|
7
84
|
|
|
8
85
|
/**
|
|
9
86
|
* Format seconds into MM:SS display
|
|
@@ -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 };
|
|
@@ -4,13 +4,13 @@ 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
|
|
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
12
|
// Content styles (shared across variants)
|
|
13
|
-
contentStyle: "data-[state=closed]:max-h-0 data-[state=open]:max-h-[
|
|
13
|
+
contentStyle: "data-[state=closed]:max-h-0 data-[state=open]:max-h-[320px] accordion-content overflow-hidden",
|
|
14
14
|
// Content inner wrapper styles
|
|
15
15
|
contentInnerStyle: "p-4 pb-2.5 pt-0",
|
|
16
16
|
};
|
|
@@ -54,6 +54,7 @@ export interface AccordionContextValue {
|
|
|
54
54
|
baseStyle: string;
|
|
55
55
|
triggerStyle: string;
|
|
56
56
|
contentStyle: string;
|
|
57
|
+
contentInnerStyle: string;
|
|
57
58
|
};
|
|
58
59
|
}
|
|
59
60
|
/**
|
|
@@ -89,6 +90,29 @@ export interface AccordionItemContextValue {
|
|
|
89
90
|
export interface AccordionTriggerProps extends React.HTMLAttributes<HTMLButtonElement> {
|
|
90
91
|
children: React.ReactNode;
|
|
91
92
|
className?: string;
|
|
93
|
+
/**
|
|
94
|
+
* Optional leading icon rendered before children
|
|
95
|
+
*/
|
|
96
|
+
iconStart?: React.ReactNode;
|
|
97
|
+
/**
|
|
98
|
+
* Indicator icon rendered after children. Defaults to PlusIcon.
|
|
99
|
+
* Set to `null` to hide the indicator entirely.
|
|
100
|
+
*/
|
|
101
|
+
iconEnd?: React.ReactNode | null;
|
|
102
|
+
/**
|
|
103
|
+
* Rotation degrees applied to iconStart when open.
|
|
104
|
+
* Default: 0 (static, no rotation). Use 45 for a plus-to-X effect.
|
|
105
|
+
*/
|
|
106
|
+
iconStartRotation?: number;
|
|
107
|
+
/**
|
|
108
|
+
* Rotation degrees applied to iconEnd when open.
|
|
109
|
+
* Default: 45 (for PlusIcon). Use 180 for chevrons, 90 for right-arrows, 0 for none.
|
|
110
|
+
*/
|
|
111
|
+
iconEndRotation?: number;
|
|
112
|
+
/**
|
|
113
|
+
* @deprecated Use `iconEndRotation` instead. Alias for `iconEndRotation`.
|
|
114
|
+
*/
|
|
115
|
+
iconRotation?: number;
|
|
92
116
|
}
|
|
93
117
|
/**
|
|
94
118
|
* Content props
|
|
@@ -105,6 +129,7 @@ export interface AccordionThemeOverrides {
|
|
|
105
129
|
baseStyleStacked?: string;
|
|
106
130
|
triggerStyle?: string;
|
|
107
131
|
contentStyle?: string;
|
|
132
|
+
contentInnerStyle?: string;
|
|
108
133
|
itemStyle?: string;
|
|
109
134
|
itemStyleStacked?: string;
|
|
110
135
|
}
|
|
@@ -14,7 +14,7 @@ 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.contentStyle, "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.contentInnerStyle, className), variants: accordionContentAnimations, initial: "collapsed", animate: "open", exit: "collapsed", transition: instantTransition, children: children }) })) }));
|
|
18
18
|
});
|
|
19
19
|
AccordionContent.displayName = "AccordionContent";
|
|
20
20
|
|
|
@@ -1,18 +1,23 @@
|
|
|
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, iconStart, iconEnd, iconStartRotation = 0, iconEndRotation, iconRotation, ...props }, ref) => {
|
|
11
|
+
var _a;
|
|
10
12
|
const { theme } = useAccordionContext();
|
|
11
13
|
const { isOpen, toggle, triggerId, contentId } = useAccordionItemContext();
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
const resolvedEndRotation = (_a = iconEndRotation !== null && iconEndRotation !== void 0 ? iconEndRotation : iconRotation) !== null && _a !== void 0 ? _a : 45;
|
|
15
|
+
const renderIcon = iconEnd === null
|
|
16
|
+
? null
|
|
17
|
+
: iconEnd !== undefined
|
|
18
|
+
? iconEnd
|
|
19
|
+
: jsx(PlusIcon, { className: "size-4", strokeWidth: 2 });
|
|
20
|
+
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: [iconStart && (iconStartRotation !== 0 ? (jsx(motion.div, { initial: false, animate: isOpen ? "open" : "closed", variants: createTriggerIconVariants(iconStartRotation), className: "flex items-center justify-center shrink-0", children: iconStart })) : (jsx("span", { className: "flex items-center justify-center shrink-0", children: iconStart }))), children, renderIcon && (jsx(motion.div, { initial: false, animate: isOpen ? "open" : "closed", variants: createTriggerIconVariants(resolvedEndRotation), className: "flex items-center justify-center shrink-0 ml-auto", children: renderIcon }))] }));
|
|
16
21
|
});
|
|
17
22
|
AccordionTrigger.displayName = "AccordionTrigger";
|
|
18
23
|
|
|
@@ -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: {
|
|
@@ -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) {
|
|
@@ -62,7 +62,6 @@ const Button = React__default.forwardRef(({ children, className = "", iconOnly =
|
|
|
62
62
|
}, [
|
|
63
63
|
onClick,
|
|
64
64
|
isDisabled,
|
|
65
|
-
props.disabled,
|
|
66
65
|
enableRipple,
|
|
67
66
|
shouldReduceMotion,
|
|
68
67
|
createRipple,
|
|
@@ -71,7 +70,7 @@ const Button = React__default.forwardRef(({ children, className = "", iconOnly =
|
|
|
71
70
|
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
71
|
const colorClasses = ((_c = buttonTheme.variantColors[resolvedVariant]) === null || _c === void 0 ? void 0 : _c[resolvedColor]) || "";
|
|
73
72
|
const variantClasses = ((_d = buttonTheme.variantStyles) === null || _d === void 0 ? void 0 : _d[resolvedVariant]) || "";
|
|
74
|
-
const stateClasses =
|
|
73
|
+
const stateClasses = isDisabled
|
|
75
74
|
? ((_e = buttonTheme.states) === null || _e === void 0 ? void 0 : _e.disabled) || ""
|
|
76
75
|
: isError
|
|
77
76
|
? ((_f = buttonTheme.states) === null || _f === void 0 ? void 0 : _f.error) || ""
|
|
@@ -80,7 +79,7 @@ const Button = React__default.forwardRef(({ children, className = "", iconOnly =
|
|
|
80
79
|
: "";
|
|
81
80
|
const blockStyle = block ? buttonTheme.blockStyle : "";
|
|
82
81
|
// Generate default aria-label for icon-only buttons if not provided (fallback only)
|
|
83
|
-
const ariaLabel = iconOnly && !
|
|
82
|
+
const ariaLabel = iconOnly && !ariaLabelProp ? "Button" : ariaLabelProp;
|
|
84
83
|
// Determine animation props (user props will override due to spread order)
|
|
85
84
|
const animationProps = shouldDisableAnimations
|
|
86
85
|
? {}
|
|
@@ -92,26 +91,30 @@ const Button = React__default.forwardRef(({ children, className = "", iconOnly =
|
|
|
92
91
|
const spinnerClassName = resolvedVariant === "filled" && color !== "neutral"
|
|
93
92
|
? "border-t-white border-l-white"
|
|
94
93
|
: "";
|
|
95
|
-
//
|
|
96
|
-
const
|
|
94
|
+
// Track the latest forwarded ref to avoid mergedRef recreation on inline callback refs
|
|
95
|
+
const forwardedRef = useRef(ref);
|
|
96
|
+
forwardedRef.current = ref;
|
|
97
|
+
// Merge refs - stable callback that won't cause DOM detach/attach cycles
|
|
98
|
+
const mergedRef = useCallback((node) => {
|
|
97
99
|
// Set ripple's buttonRef
|
|
98
100
|
if (buttonRef) {
|
|
99
101
|
buttonRef.current = node;
|
|
100
102
|
}
|
|
101
103
|
// Set forwarded ref
|
|
102
|
-
|
|
103
|
-
|
|
104
|
+
const fRef = forwardedRef.current;
|
|
105
|
+
if (typeof fRef === "function") {
|
|
106
|
+
fRef(node);
|
|
104
107
|
}
|
|
105
|
-
else if (
|
|
106
|
-
|
|
108
|
+
else if (fRef) {
|
|
109
|
+
fRef.current =
|
|
107
110
|
node;
|
|
108
111
|
}
|
|
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,
|
|
112
|
+
}, [buttonRef]);
|
|
113
|
+
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
114
|
resolvedVariant !== "link" &&
|
|
112
|
-
resolvedVariant !== "outline" && (jsx("div", { className: "absolute top-0.25 right-0.25 left-0.25 h-3 bg-gradient-to-b
|
|
115
|
+
resolvedVariant !== "outline" && (jsx("div", { className: "absolute top-0.25 right-0.25 left-0.25 h-3 bg-gradient-to-b from-white/25 to-transparent 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
116
|
ripples.map((ripple) => {
|
|
114
|
-
const animation = getRippleAnimation(effect, ripple
|
|
117
|
+
const animation = getRippleAnimation(effect, ripple, rippleScale);
|
|
115
118
|
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
119
|
getRippleColorClass(resolvedVariant, resolvedColor)), style: {
|
|
117
120
|
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;
|