@flikk/ui 1.0.0-beta.30 → 1.0.0-beta.31
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/CHANGELOG.md +97 -0
- package/dist/components/ai/AgentStatus/AgentStatus.d.ts +3 -0
- package/dist/components/ai/AgentStatus/AgentStatus.js +144 -0
- package/dist/components/ai/AgentStatus/AgentStatus.theme.d.ts +2 -0
- package/dist/components/ai/AgentStatus/AgentStatus.theme.js +37 -0
- package/dist/components/ai/AgentStatus/AgentStatus.types.d.ts +116 -0
- package/dist/components/ai/AgentStatus/index.d.ts +3 -0
- package/dist/components/ai/CodeBlock/CodeBlock.js +3 -3
- package/dist/components/ai/CodeBlock/CodeBlock.theme.js +1 -1
- package/dist/components/ai/PromptInput/PromptInput.js +13 -14
- package/dist/components/ai/PromptInput/PromptInput.theme.js +1 -1
- package/dist/components/ai/PromptInput/VoiceRecorder.js +3 -3
- package/dist/components/ai/Reasoning/Reasoning.d.ts +5 -0
- package/dist/components/ai/Reasoning/Reasoning.js +16 -0
- package/dist/components/ai/Reasoning/Reasoning.types.d.ts +20 -0
- package/dist/components/ai/Reasoning/index.d.ts +2 -0
- package/dist/components/ai/SourceCitation/SourceCitation.d.ts +4 -0
- package/dist/components/ai/SourceCitation/SourceCitation.js +29 -0
- package/dist/components/ai/SourceCitation/SourceCitation.theme.d.ts +2 -0
- package/dist/components/ai/SourceCitation/SourceCitation.theme.js +23 -0
- package/dist/components/ai/SourceCitation/SourceCitation.types.d.ts +55 -0
- package/dist/components/ai/SourceCitation/index.d.ts +3 -0
- package/dist/components/ai/StreamingResponse/ErrorDisplay.js +2 -2
- package/dist/components/ai/StreamingResponse/StreamingResponse.js +1 -3
- package/dist/components/ai/StreamingResponse/StreamingResponse.theme.js +3 -1
- package/dist/components/ai/TokenCounter/TokenCounter.js +2 -2
- package/dist/components/ai/index.d.ts +3 -0
- package/dist/components/ai/index.js +6 -3
- package/dist/components/ai/shared/StatusIndicator.d.ts +8 -0
- package/dist/components/ai/shared/StatusIndicator.js +34 -0
- package/dist/components/canvas/CanvasToolbar.js +2 -2
- package/dist/components/canvas/NodeControls.js +2 -2
- package/dist/components/canvas/NodeRenderer.js +2 -2
- package/dist/components/charts/ActivityRings/ActivityRings.js +2 -2
- package/dist/components/charts/AreaChart/AreaChart.js +21 -32
- package/dist/components/charts/AreaChart/AreaChart.theme.d.ts +1 -6
- package/dist/components/charts/AreaChart/AreaChart.theme.js +7 -19
- package/dist/components/charts/AreaChart/AreaChart.types.d.ts +18 -11
- package/dist/components/charts/AreaChart/AreaChart.types.js +10 -3
- package/dist/components/charts/AreaChart/index.d.ts +1 -1
- package/dist/components/charts/BarChart/BarChart.js +9 -28
- package/dist/components/charts/BarChart/BarChart.types.d.ts +20 -16
- package/dist/components/charts/BarChart/BarChart.types.js +11 -4
- package/dist/components/charts/ComboChart/BarRenderer.js +8 -5
- package/dist/components/charts/ComboChart/ComboChart.js +11 -24
- package/dist/components/charts/ComboChart/ComboChart.types.d.ts +15 -13
- package/dist/components/charts/ComboChart/ComboChart.types.js +14 -2
- package/dist/components/charts/ComboChart/LineRenderer.js +15 -10
- package/dist/components/charts/HorizontalBarChart/HorizontalBarChart.d.ts +16 -0
- package/dist/components/charts/HorizontalBarChart/HorizontalBarChart.js +237 -0
- package/dist/components/charts/HorizontalBarChart/HorizontalBarChart.types.d.ts +62 -0
- package/dist/components/charts/HorizontalBarChart/HorizontalBarChart.types.js +21 -0
- package/dist/components/charts/HorizontalBarChart/index.d.ts +3 -0
- package/dist/components/charts/LineChart/LineChart.js +9 -26
- package/dist/components/charts/LineChart/LineChart.types.d.ts +11 -14
- package/dist/components/charts/LineChart/LineChart.types.js +11 -3
- package/dist/components/charts/LollipopChart/LollipopChart.d.ts +3 -0
- package/dist/components/charts/LollipopChart/LollipopChart.js +361 -0
- package/dist/components/charts/LollipopChart/LollipopChart.types.d.ts +42 -0
- package/dist/components/charts/LollipopChart/LollipopChart.types.js +12 -0
- package/dist/components/charts/LollipopChart/index.d.ts +3 -0
- package/dist/components/charts/ScatterPlot/ScatterPlot.js +5 -4
- package/dist/components/charts/ScatterPlot/ScatterPlot.types.d.ts +14 -19
- package/dist/components/charts/ScatterPlot/ScatterPlot.types.js +9 -2
- package/dist/components/charts/StackedBarChart/StackedBarChart.js +150 -132
- package/dist/components/charts/StackedBarChart/StackedBarChart.types.d.ts +20 -18
- package/dist/components/charts/StackedBarChart/StackedBarChart.types.js +10 -4
- package/dist/components/charts/hooks/useChartAccessibility.d.ts +1 -1
- package/dist/components/charts/hooks/useChartAccessibility.js +3 -0
- package/dist/components/charts/hooks/useTooltipPosition.js +18 -6
- package/dist/components/charts/index.d.ts +6 -0
- package/dist/components/charts/index.js +6 -0
- package/dist/components/charts/shared/ChartAxis/CategoryYAxis.d.ts +14 -0
- package/dist/components/charts/shared/ChartAxis/CategoryYAxis.js +35 -0
- package/dist/components/charts/shared/ChartAxis/ChartAxis.types.d.ts +69 -8
- package/dist/components/charts/shared/ChartAxis/ValueXAxis.d.ts +14 -0
- package/dist/components/charts/shared/ChartAxis/ValueXAxis.js +64 -0
- package/dist/components/charts/shared/ChartAxis/XAxis.js +1 -1
- package/dist/components/charts/shared/ChartAxis/YAxis.js +2 -2
- package/dist/components/charts/shared/ChartAxis/index.d.ts +3 -1
- package/dist/components/charts/shared/ChartGrid/HorizontalGrid.d.ts +0 -2
- package/dist/components/charts/shared/ChartGrid/HorizontalGrid.js +1 -1
- package/dist/components/charts/shared/ChartGrid/VerticalGrid.d.ts +29 -0
- package/dist/components/charts/shared/ChartGrid/VerticalGrid.js +26 -0
- package/dist/components/charts/shared/ChartGrid/index.d.ts +2 -0
- package/dist/components/charts/shared/ChartMarker/ChartMarker.js +7 -1
- package/dist/components/charts/theme/chart.theme.js +18 -23
- package/dist/components/charts/types/chart.types.d.ts +9 -5
- package/dist/components/charts/types/chart.types.js +1 -7
- package/dist/components/charts/utils/animation-utils.js +1 -3
- package/dist/components/charts/utils/bar-emphasis.d.ts +32 -3
- package/dist/components/charts/utils/bar-emphasis.js +24 -8
- package/dist/components/charts/utils/index.d.ts +1 -0
- package/dist/components/charts/utils/series-color.d.ts +7 -0
- package/dist/components/charts/utils/series-color.js +20 -0
- package/dist/components/core/Accordion/Accordion.theme.js +2 -2
- package/dist/components/core/Accordion/AccordionTrigger.js +2 -2
- package/dist/components/core/Alert/Alert.animations.d.ts +2 -1
- package/dist/components/core/Alert/Alert.animations.js +21 -6
- package/dist/components/core/Alert/Alert.js +7 -7
- package/dist/components/core/Avatar/Avatar.js +50 -42
- package/dist/components/core/Avatar/Avatar.theme.d.ts +8 -4
- package/dist/components/core/Avatar/Avatar.theme.js +64 -8
- package/dist/components/core/Avatar/Avatar.types.d.ts +13 -2
- package/dist/components/core/Avatar/index.d.ts +1 -1
- package/dist/components/core/AvatarGroup/AvatarGroup.js +6 -8
- package/dist/components/core/AvatarGroup/AvatarGroup.theme.d.ts +1 -2
- package/dist/components/core/AvatarGroup/AvatarGroup.theme.js +2 -6
- package/dist/components/core/AvatarGroup/AvatarGroup.types.d.ts +0 -6
- package/dist/components/core/AvatarGroup/index.d.ts +1 -1
- package/dist/components/core/Badge/Badge.animations.js +4 -2
- package/dist/components/core/Badge/Badge.js +9 -4
- package/dist/components/core/Badge/Badge.theme.js +18 -12
- package/dist/components/core/Breadcrumbs/Breadcrumbs.theme.d.ts +1 -4
- package/dist/components/core/Breadcrumbs/Breadcrumbs.theme.js +2 -2
- package/dist/components/core/Button/Button.js +9 -17
- package/dist/components/core/Button/Button.ripple.js +2 -2
- package/dist/components/core/Button/Button.theme.d.ts +2 -0
- package/dist/components/core/Button/Button.theme.js +34 -21
- package/dist/components/core/Button/Button.types.d.ts +18 -1
- package/dist/components/core/Calendar/Calendar.js +20 -5
- package/dist/components/core/Calendar/Calendar.theme.js +14 -22
- package/dist/components/core/Calendar/Calendar.types.d.ts +0 -1
- package/dist/components/core/Calendar/CalendarMini/CalendarMini.js +3 -3
- package/dist/components/core/Card/Card.theme.js +12 -4
- package/dist/components/core/Card/CardBody.js +1 -1
- package/dist/components/core/Card/CardFooter.js +1 -1
- package/dist/components/core/Card/CardHeader.js +1 -1
- package/dist/components/core/Carousel/CarouselNext.js +2 -2
- package/dist/components/core/Carousel/CarouselPrevious.js +2 -2
- package/dist/components/core/CommandPalette/CommandPalette.js +5 -4
- package/dist/components/core/CommandPalette/CommandPalette.theme.js +3 -7
- package/dist/components/core/CommandPalette/CommandPalette.types.d.ts +2 -0
- package/dist/components/core/ContextMenu/ContextMenuItem.js +2 -2
- package/dist/components/core/ContextMenu/ContextMenuSubTrigger.js +2 -2
- package/dist/components/core/Drawer/Drawer.theme.js +7 -4
- package/dist/components/core/Drawer/DrawerHeader.js +2 -2
- package/dist/components/core/Dropdown/Dropdown.theme.js +3 -1
- package/dist/components/core/Dropdown/DropdownItem.js +2 -2
- package/dist/components/core/Dropdown/DropdownTrigger.js +16 -5
- package/dist/components/core/HeroCard/HeroCard.theme.js +5 -2
- package/dist/components/core/Kbd/Kbd.theme.js +4 -2
- package/dist/components/core/Link/Link.js +6 -4
- package/dist/components/core/Message/Message.js +2 -2
- package/dist/components/core/Message/Message.theme.js +5 -7
- package/dist/components/core/Message/MessageAudio.js +2 -2
- package/dist/components/core/Message/MessageFile.js +2 -2
- package/dist/components/core/Message/MessageLink.js +2 -2
- package/dist/components/core/Message/MessageStatusIndicator.js +5 -5
- package/dist/components/core/Modal/Modal.d.ts +1 -1
- package/dist/components/core/Modal/Modal.js +2 -2
- package/dist/components/core/Modal/Modal.theme.js +9 -4
- package/dist/components/core/Modal/ModalHeader.js +2 -2
- package/dist/components/core/ModalStack/ModalStackModal.js +2 -2
- package/dist/components/core/NavItem/NavItem.js +6 -6
- package/dist/components/core/OfflineIndicator/OfflineIndicator.animations.d.ts +22 -0
- package/dist/components/core/OfflineIndicator/OfflineIndicator.animations.js +54 -0
- package/dist/components/core/OfflineIndicator/OfflineIndicator.js +23 -24
- package/dist/components/core/OfflineIndicator/OfflineIndicator.theme.js +25 -6
- package/dist/components/core/OfflineIndicator/OfflineIndicator.types.d.ts +17 -0
- package/dist/components/core/PageHeading/PageHeading.theme.js +1 -1
- package/dist/components/core/PageHeading/PageHeadingBackButton.js +2 -2
- package/dist/components/core/Pagination/Pagination.js +3 -3
- package/dist/components/core/Pagination/Pagination.theme.js +3 -3
- package/dist/components/core/Pill/Pill.js +4 -2
- package/dist/components/core/Pill/Pill.theme.js +6 -4
- package/dist/components/core/Rating/Rating.js +4 -5
- package/dist/components/core/Rating/Rating.theme.js +1 -1
- package/dist/components/core/Segmented/Segmented.theme.js +9 -6
- package/dist/components/core/Sidebar/Sidebar.types.d.ts +4 -2
- package/dist/components/core/Sidebar/SidebarHeader.js +2 -2
- package/dist/components/core/Sidebar/SidebarMobileTrigger.js +2 -2
- package/dist/components/core/Sidebar/SidebarSearch.js +3 -3
- package/dist/components/core/Sidebar/SidebarToggle.js +3 -3
- package/dist/components/core/Sidebar/SidebarUserProfile.js +2 -2
- package/dist/components/core/Sortable/Sortable.js +2 -2
- package/dist/components/core/Tag/Tag.js +2 -2
- package/dist/components/core/Tag/Tag.theme.js +4 -2
- package/dist/components/core/Toast/Toast.js +3 -3
- package/dist/components/core/Toast/Toast.types.d.ts +1 -1
- package/dist/components/core/Toast/useToast.js +5 -5
- package/dist/components/core/Tooltip/Tooltip.d.ts +1 -1
- package/dist/components/core/Tooltip/Tooltip.js +42 -10
- package/dist/components/core/Tooltip/Tooltip.types.d.ts +25 -0
- package/dist/components/core/Tree/Tree.js +2 -2
- package/dist/components/core/shared/interaction.animations.d.ts +51 -0
- package/dist/components/core/shared/interaction.animations.js +59 -0
- package/dist/components/data-display/Feed/Feed.js +2 -2
- package/dist/components/data-display/GanttChart/GanttChart.theme.js +1 -1
- package/dist/components/data-display/GanttChart/GanttChartPanel.js +2 -2
- package/dist/components/data-display/GanttChart/GanttTableGroupRow.js +3 -3
- package/dist/components/data-display/GanttChart/GanttTaskContextMenu.js +2 -2
- package/dist/components/data-display/GanttChart/GanttToolbar.js +2 -2
- package/dist/components/data-display/KPI/KPI.js +2 -2
- package/dist/components/data-display/KPI/KPI.theme.js +4 -4
- package/dist/components/data-display/Metric/Metric.js +2 -2
- package/dist/components/data-display/Metric/Metric.theme.js +25 -8
- package/dist/components/data-display/Metric/Metric.types.d.ts +1 -1
- package/dist/components/data-display/Table/Table.theme.js +9 -9
- package/dist/components/data-display/Table/TableActions.js +2 -2
- package/dist/components/data-display/Table/TableActionsMenu.js +1 -1
- package/dist/components/data-display/Table/TableColumnManager.js +2 -2
- package/dist/components/data-display/Table/TableDeclarative.js +3 -3
- package/dist/components/data-display/Table/TableFilter.js +4 -4
- package/dist/components/data-display/Table/TableHeader.js +3 -3
- package/dist/components/data-display/Table/TableRow.js +2 -2
- package/dist/components/data-display/Table/TableSelectionHeader.js +3 -3
- package/dist/components/data-display/Timeline/TimelineMarker.js +2 -2
- package/dist/components/effects/CustomCursor/CustomCursor.js +2 -2
- package/dist/components/effects/CustomCursor/CustomCursor.theme.js +2 -2
- package/dist/components/effects/DotPattern/DotPattern.js +6 -0
- package/dist/components/effects/DotPattern/DotPattern.types.d.ts +4 -2
- package/dist/components/effects/MeshGradient/MeshGradient.utils.d.ts +1 -1
- package/dist/components/effects/MeshGradient/MeshGradient.utils.js +1 -1
- package/dist/components/forms/Checkbox/Checkbox.js +2 -1
- package/dist/components/forms/Checkbox/Checkbox.theme.js +2 -2
- package/dist/components/forms/ColorPicker/ColorPickerEyeDropper.js +2 -2
- package/dist/components/forms/ColorPicker/ColorPickerGradient.js +2 -2
- package/dist/components/forms/ColorPicker/ColorPickerHeader.js +2 -2
- package/dist/components/forms/ColorPicker/ColorPickerImage.js +3 -3
- package/dist/components/forms/ColorPicker/ColorPickerInput.js +2 -2
- package/dist/components/forms/ColorPicker/ColorPickerPresets.js +2 -2
- package/dist/components/forms/ColorPicker/ColorPickerSavedColors.js +2 -2
- package/dist/components/forms/Combobox/Combobox.js +3 -3
- package/dist/components/forms/Combobox/Combobox.theme.js +2 -2
- package/dist/components/forms/DatePicker/DatePicker.animations.js +16 -25
- package/dist/components/forms/DatePicker/DatePicker.theme.js +2 -2
- package/dist/components/forms/DatePicker/DatePickerBody.js +1 -1
- package/dist/components/forms/DatePicker/DatePickerTrigger.js +2 -2
- package/dist/components/forms/DateRangePicker/DateRangePicker.theme.js +3 -3
- package/dist/components/forms/DateRangePicker/DateRangePickerBody.js +1 -1
- package/dist/components/forms/DateRangePicker/DateRangePickerPresets.js +2 -2
- package/dist/components/forms/DateRangePicker/DateRangePickerTrigger.js +2 -2
- package/dist/components/forms/FileUpload/FileUpload.js +4 -4
- package/dist/components/forms/FileUpload/FileUpload.theme.js +5 -1
- package/dist/components/forms/FileUpload/FileUploadProgress.js +7 -7
- package/dist/components/forms/Input/Input.js +6 -7
- package/dist/components/forms/Input/Input.theme.js +19 -15
- package/dist/components/forms/InputAddress/InputAddress.js +10 -3
- package/dist/components/forms/InputCounter/InputCounter.js +3 -3
- package/dist/components/forms/InputOTP/InputOTP.d.ts +3 -12
- package/dist/components/forms/InputOTP/InputOTP.js +140 -151
- package/dist/components/forms/InputOTP/InputOTP.theme.d.ts +5 -1
- package/dist/components/forms/InputOTP/InputOTP.theme.js +40 -5
- package/dist/components/forms/InputOTP/InputOTP.types.d.ts +45 -2
- package/dist/components/forms/InputOTP/index.d.ts +1 -1
- package/dist/components/forms/InputTag/InputTag.js +5 -5
- package/dist/components/forms/InputTag/InputTag.theme.js +1 -2
- package/dist/components/forms/Mention/Mention.theme.js +3 -5
- package/dist/components/forms/Radio/Radio.js +3 -2
- package/dist/components/forms/Radio/Radio.theme.js +2 -2
- package/dist/components/forms/RichTextEditor/RichTextEditor.js +22 -23
- package/dist/components/forms/Select/Select.d.ts +5 -1
- package/dist/components/forms/Select/Select.js +12 -11
- package/dist/components/forms/Select/Select.theme.js +4 -4
- package/dist/components/forms/Select/Select.types.d.ts +4 -1
- package/dist/components/forms/SelectableCard/SelectableCard.animations.d.ts +1 -2
- package/dist/components/forms/SelectableCard/SelectableCard.animations.js +6 -7
- package/dist/components/forms/SelectableCard/SelectableCard.js +1 -1
- package/dist/components/forms/Signature/Signature.js +1 -1
- package/dist/components/forms/Slider/Slider.js +24 -11
- package/dist/components/forms/Slider/Slider.theme.js +9 -3
- package/dist/components/forms/Switch/Switch.theme.js +1 -1
- package/dist/components/forms/TimePicker/TimePicker.theme.js +6 -7
- package/dist/components/forms/TimePicker/TimePickerContent.js +1 -1
- package/dist/components/forms/TimePicker/TimePickerTrigger.js +3 -3
- package/dist/components/forms/forms.theme.js +23 -12
- package/dist/components/forms/index.js +1 -1
- package/dist/components/generative/registry.js +195 -2
- package/dist/components/generative/resolvers.js +16 -16
- package/dist/components/generative/schema.generated.js +2687 -379
- package/dist/components/layout/Section/Section.theme.js +1 -1
- package/dist/generative.schema.json +2687 -379
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/useElapsedTime.d.ts +28 -0
- package/dist/hooks/useElapsedTime.js +37 -0
- package/dist/hooks/useSelectPortal.d.ts +10 -2
- package/dist/hooks/useSelectPortal.js +6 -3
- package/dist/index.js +1 -1
- package/dist/registry.json +835 -261
- package/dist/shadcn-compat.css +1 -1
- package/dist/styles.css +1 -1
- package/dist/theme.css +5 -1
- package/dist/themes/ember.css +131 -0
- package/dist/themes/iris.css +94 -0
- package/dist/themes/jade.css +139 -0
- package/dist/tools.json +2705 -361
- package/dist/utils/colorUtils.d.ts +6 -6
- package/dist/utils/colorUtils.js +8 -8
- package/package.json +9 -6
- package/src/global.scss +15 -4
- package/src/styles/theme.css +440 -152
- package/tailwind.preset.cjs +52 -34
- package/dist/components/core/Pill/Pill.animations.d.ts +0 -32
- package/dist/components/core/Pill/Pill.animations.js +0 -16
|
@@ -13,8 +13,7 @@ import '../../core/Dropdown/DropdownSection.js';
|
|
|
13
13
|
import '../../core/Dropdown/DropdownSeparator.js';
|
|
14
14
|
import '../../core/Dropdown/Dropdown.theme.js';
|
|
15
15
|
import { cn } from '../../../utils/cn.js';
|
|
16
|
-
import {
|
|
17
|
-
import { MicrophoneIcon as MicrophoneIcon$1, StopIcon } from '@heroicons/react/24/solid';
|
|
16
|
+
import { CloudArrowUp, Microphone, Paperclip, Link, File as File$1, X, Plus, SlidersHorizontal, CaretDown, ArrowRight, Stop } from '@phosphor-icons/react';
|
|
18
17
|
import { promptInputTheme } from './PromptInput.theme.js';
|
|
19
18
|
import { VoiceRecorder } from './VoiceRecorder.js';
|
|
20
19
|
import { dropzoneContainerVariants, dropzoneChildVariants, dropzoneActionIconVariants, textareaSwapVariants, iconSwapVariants } from './PromptInput.animations.js';
|
|
@@ -70,7 +69,7 @@ attachments: controlledAttachments, onAttachmentsChange, acceptedFileTypes = ["i
|
|
|
70
69
|
// Button visibility
|
|
71
70
|
showAttachmentButton = true, showVoiceButton = true, showSettingsButton = true, showModelSelector = true,
|
|
72
71
|
// Submit button
|
|
73
|
-
submitButtonLabel = "Submit prompt", submitButtonIcon = (jsx(
|
|
72
|
+
submitButtonLabel = "Submit prompt", submitButtonIcon = (jsx(ArrowRight, { className: "size-4", weight: "bold" })), submitShortcut,
|
|
74
73
|
// Variant
|
|
75
74
|
variant = "default",
|
|
76
75
|
// Styling
|
|
@@ -508,7 +507,7 @@ className, textareaClassName, footerClassName, theme = {},
|
|
|
508
507
|
*/
|
|
509
508
|
const renderSubmitButton = (buttonSize, buttonVariant, buttonColor, extraClassName) => {
|
|
510
509
|
if (showStopButton) {
|
|
511
|
-
return (jsx(Button, { iconOnly: true, className: cn(mergedTheme.submitButtonStyle, extraClassName), size: buttonSize, variant: buttonVariant, color: "danger", onClick: onStop, "aria-label": "Stop generation", title: "Stop generation", showReflection: false, children: jsx(AnimatePresence, { mode: "wait", initial: false, children: jsx(motion.span, { variants: iconSwapVariants, initial: "initial", animate: "animate", exit: "exit", className: "flex items-center justify-center", children: jsx(
|
|
510
|
+
return (jsx(Button, { iconOnly: true, className: cn(mergedTheme.submitButtonStyle, extraClassName), size: buttonSize, variant: buttonVariant, color: "danger", onClick: onStop, "aria-label": "Stop generation", title: "Stop generation", showReflection: false, children: jsx(AnimatePresence, { mode: "wait", initial: false, children: jsx(motion.span, { variants: iconSwapVariants, initial: "initial", animate: "animate", exit: "exit", className: "flex items-center justify-center", children: jsx(Stop, { className: "size-4" }) }, "stop") }) }));
|
|
512
511
|
}
|
|
513
512
|
return (jsx(Button, { iconOnly: true, className: cn(mergedTheme.submitButtonStyle, extraClassName), size: buttonSize, variant: buttonVariant, color: buttonColor, onClick: handleSubmit, disabled: !canSubmit, state: isLoading ? "loading" : "default", "aria-label": submitButtonLabel, title: submitShortcut ? `Submit (${submitShortcut})` : undefined, showReflection: buttonVariant === "filled" ? false : undefined, children: jsx(AnimatePresence, { mode: "wait", initial: false, children: jsx(motion.span, { variants: iconSwapVariants, initial: "initial", animate: "animate", exit: "exit", className: "flex items-center justify-center", children: submitButtonIcon }, "submit") }) }));
|
|
514
513
|
};
|
|
@@ -517,24 +516,24 @@ className, textareaClassName, footerClassName, theme = {},
|
|
|
517
516
|
if (e.target.files)
|
|
518
517
|
processFiles(e.target.files);
|
|
519
518
|
e.target.value = "";
|
|
520
|
-
}, className: "sr-only", "aria-label": "Attach files" }), jsxs("div", { className: cn("relative", mergedTheme.baseStyle, mergedTheme.stateStyle, variant === "simple" ? "p-3 rounded-full pl-5" : ""), onDragEnter: handleDragEnter, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, children: [jsx(AnimatePresence, { children: isDragOver && enableDropzone && (jsxs(motion.div, { variants: dropzoneContainerVariants, initial: "initial", animate: "animate", exit: "exit", className: mergedTheme.dropzoneStyle, children: [jsx(motion.div, { variants: dropzoneChildVariants, children: jsx(
|
|
519
|
+
}, className: "sr-only", "aria-label": "Attach files" }), jsxs("div", { className: cn("relative", mergedTheme.baseStyle, mergedTheme.stateStyle, variant === "simple" ? "p-3 rounded-full pl-5" : ""), onDragEnter: handleDragEnter, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, children: [jsx(AnimatePresence, { children: isDragOver && enableDropzone && (jsxs(motion.div, { variants: dropzoneContainerVariants, initial: "initial", animate: "animate", exit: "exit", className: mergedTheme.dropzoneStyle, children: [jsx(motion.div, { variants: dropzoneChildVariants, children: jsx(CloudArrowUp, { className: "size-8 text-[var(--color-primary)] mx-auto" }) }), jsx(motion.p, { variants: dropzoneChildVariants, className: mergedTheme.dropzoneTitleStyle, children: dropzoneTitle ? (
|
|
521
520
|
// Parse **browse** as clickable button
|
|
522
521
|
jsx(Fragment, { children: resolvedDropzoneTitle
|
|
523
522
|
.split(/\*\*(.*?)\*\*/)
|
|
524
523
|
.map((part, i) => i % 2 === 1 ? (jsx("button", { type: "button", onClick: handleDropzoneBrowse, className: "font-bold underline underline-offset-2 cursor-pointer hover:opacity-80", children: part }, i)) : (jsx("span", { children: part }, i))) })) : (resolvedDropzoneTitle) }), dropzoneSubtitle && (jsx(motion.p, { variants: dropzoneChildVariants, className: mergedTheme.dropzoneSubtitleStyle, children: dropzoneSubtitle })), dropzoneTitle && (jsx(motion.div, { variants: dropzoneChildVariants, className: mergedTheme.dropzoneActionsStyle, children: [
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
524
|
+
CloudArrowUp,
|
|
525
|
+
Microphone,
|
|
526
|
+
Paperclip,
|
|
527
|
+
Link,
|
|
529
528
|
].map((Icon, i) => (jsx(motion.div, { variants: dropzoneActionIconVariants, className: "size-8 rounded-full bg-white/30 dark:bg-white/10 flex items-center justify-center", children: jsx(Icon, { className: "size-4 text-[var(--color-primary)]" }) }, i))) }))] })) }), currentAttachments.length > 0 && (jsx("div", { className: "flex flex-wrap gap-2 py-2 px-1", children: currentAttachments.map((attachment) => {
|
|
530
529
|
var _a;
|
|
531
|
-
return (jsxs("div", { className: "relative group rounded-lg border border-[var(--color-border)] bg-white", children: [attachment.type === "image" ? (attachment.isCompressing ? (jsx("div", { className: "size-12 flex items-center justify-center bg-gray-100 rounded-lg", children: jsx("div", { className: "w-4 h-4 border-2 border-gray-300 border-t-[var(--color-primary)] rounded-full animate-spin" }) })) : (jsx("img", { src: attachment.previewUrl, alt: attachment.file.name, className: "size-12 object-cover rounded-lg" }))) : (jsxs("div", { className: "size-12 flex flex-col items-center justify-center text-center p-1 rounded-lg", children: [jsx(
|
|
530
|
+
return (jsxs("div", { className: "relative group rounded-lg border border-[var(--color-border)] bg-white", children: [attachment.type === "image" ? (attachment.isCompressing ? (jsx("div", { className: "size-12 flex items-center justify-center bg-gray-100 rounded-lg", children: jsx("div", { className: "w-4 h-4 border-2 border-gray-300 border-t-[var(--color-primary)] rounded-full animate-spin" }) })) : (jsx("img", { src: attachment.previewUrl, alt: attachment.file.name, className: "size-12 object-cover rounded-lg" }))) : (jsxs("div", { className: "size-12 flex flex-col items-center justify-center text-center p-1 rounded-lg", children: [jsx(File$1, { className: "w-5 h-5 text-[var(--color-text-muted)]" }), jsx("span", { className: "text-[10px] text-[var(--color-text-secondary)] truncate w-full", children: (_a = attachment.file.name.split(".").pop()) === null || _a === void 0 ? void 0 : _a.toUpperCase() })] })), jsx("button", { onClick: () => removeAttachment(attachment.id), className: "absolute -top-1.5 -right-1.5 size-5 rounded-full bg-[var(--color-danger)] text-[var(--color-danger-contrast)] flex items-center justify-center opacity-0 translate-y-1 group-hover:translate-y-0 group-hover:opacity-100 transition-all duration-300 ease-in-out cursor-pointer shadow-md", "aria-label": `Remove ${attachment.file.name}`, children: jsx(X, { className: "size-3", weight: "bold" }) })] }, attachment.id));
|
|
532
531
|
}) })), jsxs("div", { className: cn("flex gap-2", variant === "simple" ? "items-end" : "items-start"), children: [jsx(AnimatePresence, { mode: "wait", initial: false, children: isRecording && enableVoiceRecording ? (jsx(motion.div, { variants: textareaSwapVariants, initial: "initial", animate: "animate", exit: "exit", className: "flex-1 min-w-0", children: jsx("p", { className: "text-center text-sm text-[var(--color-text-placeholder)]", children: placeholder }) }, "voice-recorder")) : (jsx(motion.div, { variants: textareaSwapVariants, initial: "initial", animate: "animate", exit: "exit", className: cn("flex-1 min-w-0", variant === "simple" && "flex items-end"), children: jsx(Textarea, { ref: textareaRef, id: id, unstyled: true, value: currentValue, onChange: handleChange, onKeyDown: handleKeyDown, onPaste: handlePaste, placeholder: placeholder, disabled: isDisabled, maxLength: maxLength, rows: rows, "aria-label": ariaLabel || "Prompt input", "aria-describedby": helperTextId, "aria-invalid": isInvalid, "aria-disabled": isDisabled, className: cn(mergedTheme.textareaStyle, variant === "simple" &&
|
|
533
532
|
"!w-auto flex-1 min-w-0 justify-center", textareaClassName), style: {
|
|
534
533
|
minHeight,
|
|
535
534
|
maxHeight,
|
|
536
535
|
} }) }, "textarea")) }), variant === "simple" &&
|
|
537
|
-
renderSubmitButton("md", "filled", "
|
|
536
|
+
renderSubmitButton("md", "filled", "mono", "shrink-0")] }), variant !== "simple" && (jsx("div", { className: cn(mergedTheme.footerStyle, footerClassName), children: jsx(AnimatePresence, { mode: "wait", initial: false, children: isRecording && enableVoiceRecording ? (jsx(motion.div, { variants: textareaSwapVariants, initial: "initial", animate: "animate", exit: "exit", className: "w-full", children: jsx(VoiceRecorder, { onComplete: handleRecordingComplete, onCancel: handleRecordingCancel, maxDuration: maxRecordingDuration, className: mergedTheme.voiceRecorderStyle }) }, "recorder-controls")) : (jsxs(motion.div, { variants: textareaSwapVariants, initial: "initial", animate: "animate", exit: "exit", className: "flex justify-between items-end w-full", children: [jsxs("div", { className: mergedTheme.actionsStyle, children: [showAttachmentButton && (jsxs(Dropdown, { selectionMode: "none", children: [jsx(Dropdown.Trigger, { children: jsx(Button, { iconOnly: true, variant: "outline", color: "mono", size: "sm", className: "rounded-full !border-0.5", "aria-label": "Add attachment", disabled: isDisabled, children: jsx(Plus, { className: "size-4", weight: "bold" }) }) }), jsxs(Dropdown.Menu, { children: [jsx(Dropdown.Item, { itemKey: "upload-image", onAction: () => {
|
|
538
537
|
// Set accept to images only and trigger file input
|
|
539
538
|
if (fileInputRef.current) {
|
|
540
539
|
fileInputRef.current.accept = "image/*";
|
|
@@ -553,12 +552,12 @@ className, textareaClassName, footerClassName, theme = {},
|
|
|
553
552
|
fileInputRef.current.click();
|
|
554
553
|
}
|
|
555
554
|
onAttachmentClick === null || onAttachmentClick === void 0 ? void 0 : onAttachmentClick();
|
|
556
|
-
}, children: "Upload PDF" }, "upload-pdf")] })] })), showSettingsButton && (jsx(Button, { iconOnly: true, variant: "outline", color: "
|
|
555
|
+
}, children: "Upload PDF" }, "upload-pdf")] })] })), showSettingsButton && (jsx(Button, { iconOnly: true, variant: "outline", color: "mono", size: "sm", className: "rounded-full !border-0.5", onClick: onSettingsClick, "aria-label": "Open settings", disabled: isDisabled, children: jsx(SlidersHorizontal, { className: "size-4 text-[var(--color-text-muted)]", weight: "bold" }) })), showVoiceButton && (jsxs(Button, { variant: "outline", color: "mono", size: "sm", className: "rounded-full border-0 hover:bg-[var(--color-surface-hover)] dark:hover:bg-[var(--color-surface-hover)] text-[var(--color-text-secondary)]", onClick: handleVoiceClick, "aria-label": "Voice input", disabled: isDisabled || isRecording, children: [jsx(Microphone, { className: "size-4" }), "Voice"] })), showModelSelector && (jsxs(Dropdown, { selectionMode: "single", selectedKeys: isModelControlled
|
|
557
556
|
? [controlledModel]
|
|
558
|
-
: internalModel, onSelectionChange: handleModelChange, children: [jsx(Dropdown.Trigger, { children: jsxs(Button, { variant: "outline", color: "
|
|
557
|
+
: internalModel, onSelectionChange: handleModelChange, children: [jsx(Dropdown.Trigger, { children: jsxs(Button, { variant: "outline", color: "mono", size: "sm",
|
|
559
558
|
// Hover + open active state now come from Dropdown.Trigger
|
|
560
559
|
// (unified surface-hover tint). `group` stays for the chevron flip.
|
|
561
|
-
className: "group bg-transparent rounded-full border-0 font-medium text-[var(--color-text-secondary)]", "aria-label": "Select AI model", disabled: isDisabled, children: [modelMap[currentModel] || "Select Model", jsx(
|
|
560
|
+
className: "group bg-transparent rounded-full border-0 font-medium text-[var(--color-text-secondary)]", "aria-label": "Select AI model", disabled: isDisabled, children: [modelMap[currentModel] || "Select Model", jsx(CaretDown, { className: "size-3 opacity-80 transition-transform duration-200 group-aria-[expanded=true]:rotate-180", weight: "bold" })] }) }), jsx(Dropdown.Menu, { children: models.map((model) => (jsx(Dropdown.Item, { itemKey: model.key, startContent: model.icon, children: model.label }, model.key))) })] }))] }), jsx("div", { children: renderSubmitButton("sm", "outline", "mono") })] }, "footer-controls")) }) }))] }), displayHelperText && (jsx("div", { id: helperTextId, className: cn("mt-1 text-sm", isInvalid
|
|
562
561
|
? "text-[var(--color-danger)]"
|
|
563
562
|
: "text-[var(--color-text-muted)]"), role: isInvalid ? "alert" : undefined, "aria-live": isInvalid ? "polite" : undefined, children: displayHelperText }))] }));
|
|
564
563
|
});
|
|
@@ -26,7 +26,7 @@ const promptInputTheme = {
|
|
|
26
26
|
// Inset danger edge + fill (mirrors the resting/focus border model above) so invalid
|
|
27
27
|
// composes over baseStyle instead of stacking a second real border on the hairline.
|
|
28
28
|
invalid: "shadow-[inset_0_0_0_1px_var(--color-danger)] bg-[var(--color-danger-50)] " +
|
|
29
|
-
"focus-within:shadow-[inset_0_0_0_1px_var(--color-danger)] focus-within:ring-[var(--color-danger
|
|
29
|
+
"focus-within:shadow-[inset_0_0_0_1px_var(--color-danger)] focus-within:ring-[var(--color-danger)]/10 " +
|
|
30
30
|
"not-focus-within:hover:shadow-[inset_0_0_0_1px_var(--color-danger)] " +
|
|
31
31
|
"dark:bg-[var(--color-danger-950)]/30 dark:shadow-[inset_0_0_0_1px_var(--color-danger-500)] " +
|
|
32
32
|
"dark:focus-within:ring-[var(--color-danger-500)]/20",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
3
|
import { useState, useRef, useEffect, useCallback } from 'react';
|
|
4
4
|
import { motion } from 'motion/react';
|
|
5
|
-
import {
|
|
5
|
+
import { Play, Pause, Check } from '@phosphor-icons/react';
|
|
6
6
|
import { cn } from '../../../utils/cn.js';
|
|
7
7
|
import { Button } from '../../core/Button/Button.js';
|
|
8
8
|
|
|
@@ -315,13 +315,13 @@ const VoiceRecorder = ({ onComplete, onCancel, maxDuration, className, }) => {
|
|
|
315
315
|
}
|
|
316
316
|
}
|
|
317
317
|
}, [recordingState, clearTimer, startTimer]);
|
|
318
|
-
return (jsxs("div", { className: cn("flex items-center justify-between w-full", className), children: [jsx(Button, { variant: "soft", color: "
|
|
318
|
+
return (jsxs("div", { className: cn("flex items-center justify-between w-full", className), children: [jsx(Button, { variant: "soft", color: "mono", size: "sm", className: "rounded-full", onClick: handleCancel, "aria-label": "Cancel recording", children: "Cancel" }), jsxs("div", { className: "flex items-center gap-4", children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx(motion.div, { className: "size-2 rounded-full bg-[var(--color-danger)]", animate: recordingState === "recording"
|
|
319
319
|
? { scale: [1, 1.4, 1] }
|
|
320
320
|
: undefined, transition: {
|
|
321
321
|
duration: 1.5,
|
|
322
322
|
repeat: Infinity,
|
|
323
323
|
ease: "easeInOut",
|
|
324
|
-
} }), jsx("span", { className: "text-sm font-medium tabular-nums text-[var(--color-text-primary)] min-w-[2.5rem] text-center", children: formatTime(elapsed) })] }), jsx("canvas", { ref: canvasRef, width: 128, height: 32, className: "w-32 h-8 bg-transparent" })] }), jsxs("div", { className: "flex items-center gap-2", children: [jsx(Button, { iconOnly: true, variant: "outline", color: "
|
|
324
|
+
} }), jsx("span", { className: "text-sm font-medium tabular-nums text-[var(--color-text-primary)] min-w-[2.5rem] text-center", children: formatTime(elapsed) })] }), jsx("canvas", { ref: canvasRef, width: 128, height: 32, className: "w-32 h-8 bg-transparent" })] }), jsxs("div", { className: "flex items-center gap-2", children: [jsx(Button, { iconOnly: true, variant: "outline", color: "mono", size: "sm", className: "rounded-full", onClick: handleTogglePause, "aria-label": recordingState === "paused" ? "Resume recording" : "Pause recording", children: recordingState === "paused" ? (jsx(Play, { className: "size-4", weight: "bold" })) : (jsx(Pause, { className: "size-4", weight: "bold" })) }), jsx(Button, { iconOnly: true, variant: "filled", color: "primary", size: "sm", className: "rounded-full", onClick: handleConfirm, "aria-label": "Confirm recording", children: jsx(Check, { className: "size-4", weight: "bold" }) })] })] }));
|
|
325
325
|
};
|
|
326
326
|
VoiceRecorder.displayName = "VoiceRecorder";
|
|
327
327
|
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { ReasoningProps, ReasoningStepProps } from "./Reasoning.types";
|
|
3
|
+
export declare const Reasoning: React.ForwardRefExoticComponent<ReasoningProps & React.RefAttributes<HTMLDivElement>> & {
|
|
4
|
+
Step: React.ForwardRefExoticComponent<ReasoningStepProps & React.RefAttributes<HTMLDivElement>>;
|
|
5
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import React__default from 'react';
|
|
4
|
+
import { AgentStatus } from '../AgentStatus/AgentStatus.js';
|
|
5
|
+
|
|
6
|
+
// Reasoning is AgentStatus in its reasoning mode, with a discoverable name.
|
|
7
|
+
const ReasoningRoot = React__default.forwardRef((props, ref) => jsx(AgentStatus, { ref: ref, mode: "reasoning", ...props }));
|
|
8
|
+
ReasoningRoot.displayName = "Reasoning";
|
|
9
|
+
// A step is just a status row; children carry its text.
|
|
10
|
+
const ReasoningStep = React__default.forwardRef(({ children, status = "complete", ...rest }, ref) => (jsx(AgentStatus, { ref: ref, mode: "status", status: status, label: children, wrap: true, live: "off", ...rest })));
|
|
11
|
+
ReasoningStep.displayName = "Reasoning.Step";
|
|
12
|
+
const Reasoning = Object.assign(ReasoningRoot, {
|
|
13
|
+
Step: ReasoningStep,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export { Reasoning };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { AgentStatusProps, AgentStatusState, AgentStatusStepData, AgentStatusThemeOverrides } from "../AgentStatus";
|
|
3
|
+
/**
|
|
4
|
+
* Reasoning is a preset of AgentStatus fixed to `mode="reasoning"` — the
|
|
5
|
+
* collapsible "show the AI's thinking" disclosure. Every AgentStatus prop
|
|
6
|
+
* except `mode` applies.
|
|
7
|
+
*/
|
|
8
|
+
export type ReasoningProps = Omit<AgentStatusProps, "mode">;
|
|
9
|
+
/** A structured reasoning step (an AgentStatus row). */
|
|
10
|
+
export type ReasoningStepData = AgentStatusStepData;
|
|
11
|
+
export type ReasoningThemeOverrides = AgentStatusThemeOverrides;
|
|
12
|
+
export interface ReasoningStepProps {
|
|
13
|
+
/** Step state — drives the indicator glyph. @default "complete" */
|
|
14
|
+
status?: AgentStatusState;
|
|
15
|
+
/** Step text. */
|
|
16
|
+
children: React.ReactNode;
|
|
17
|
+
/** Elapsed or final step duration in seconds. */
|
|
18
|
+
duration?: number;
|
|
19
|
+
className?: string;
|
|
20
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { SourceCitationGroupProps, SourceCitationProps } from "./SourceCitation.types";
|
|
3
|
+
export declare const SourceCitation: React.ForwardRefExoticComponent<SourceCitationProps & React.RefAttributes<HTMLButtonElement>>;
|
|
4
|
+
export declare const SourceCitationGroup: React.ForwardRefExoticComponent<SourceCitationGroupProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
3
|
+
import React__default, { useMemo } from 'react';
|
|
4
|
+
import { Link, ArrowSquareOut } from '@phosphor-icons/react';
|
|
5
|
+
import { cn } from '../../../utils/cn.js';
|
|
6
|
+
import { Link as Link$1 } from '../../core/Link/Link.js';
|
|
7
|
+
import { Popover } from '../../core/Popover/Popover.js';
|
|
8
|
+
import '../../core/Popover/PopoverContext.js';
|
|
9
|
+
import '../../core/Popover/PopoverBody.js';
|
|
10
|
+
import { sourceCitationTheme } from './SourceCitation.theme.js';
|
|
11
|
+
|
|
12
|
+
const SourceCitation = React__default.forwardRef(({ index, title, domain, excerpt, href, icon, preview, placement = "top-start", open, defaultOpen, onOpenChange, openInNewTab = true, linkLabel = "Open source", className, theme: themeOverrides, disabled, ...props }, ref) => {
|
|
13
|
+
const theme = useMemo(() => ({ ...sourceCitationTheme, ...themeOverrides }), [themeOverrides]);
|
|
14
|
+
// `title` and `domain` are both ReactNode, so neither is guaranteed to yield a
|
|
15
|
+
// usable name. Fall back through the domain (already the visible chip text) before
|
|
16
|
+
// the generic word, so rich-titled citations stay distinguishable by ear.
|
|
17
|
+
const label = (typeof title === "string" && title) ||
|
|
18
|
+
(typeof domain === "string" && domain) ||
|
|
19
|
+
"source";
|
|
20
|
+
return (jsxs(Popover, { placement: placement, isOpen: open, defaultIsOpen: defaultOpen, onOpenChange: onOpenChange, children: [jsx(Popover.Trigger, { children: jsxs("button", { ref: ref, type: "button", className: cn(theme.triggerStyle, className), "aria-label": `View source: ${label}`, disabled: disabled, ...props, children: [icon ? (jsx("span", { className: theme.faviconStyle, "aria-hidden": "true", children: icon })) : (index !== undefined && (jsx("span", { className: theme.indexStyle, children: index }))), jsx("span", { className: theme.domainStyle, children: domain !== null && domain !== void 0 ? domain : title })] }) }), jsx(Popover.Body, { className: theme.popoverStyle, children: preview !== null && preview !== void 0 ? preview : (jsxs(Fragment, { children: [jsxs("div", { className: theme.previewHeaderStyle, children: [jsx("span", { className: theme.previewIconStyle, "aria-hidden": "true", children: icon !== null && icon !== void 0 ? icon : jsx(Link, { className: "size-4" }) }), jsxs("div", { className: "min-w-0", children: [jsx("div", { className: theme.previewTitleStyle, children: title }), domain && (jsx("div", { className: theme.previewDomainStyle, children: domain }))] })] }), excerpt && jsx("div", { className: theme.excerptStyle, children: excerpt }), href && (jsxs(Link$1, { href: href, target: openInNewTab ? "_blank" : undefined, rel: openInNewTab ? "noopener noreferrer" : undefined, className: theme.linkStyle, children: [linkLabel, jsx(ArrowSquareOut, { className: "size-3.5", "aria-hidden": "true", weight: "bold" })] }))] })) })] }));
|
|
21
|
+
});
|
|
22
|
+
SourceCitation.displayName = "SourceCitation";
|
|
23
|
+
const SourceCitationGroup = React__default.forwardRef(({ children, className, theme: themeOverrides, ...props }, ref) => {
|
|
24
|
+
var _a;
|
|
25
|
+
return (jsx("div", { ref: ref, role: "group", "aria-label": "Sources", className: cn((_a = themeOverrides === null || themeOverrides === void 0 ? void 0 : themeOverrides.groupStyle) !== null && _a !== void 0 ? _a : sourceCitationTheme.groupStyle, className), ...props, children: children }));
|
|
26
|
+
});
|
|
27
|
+
SourceCitationGroup.displayName = "SourceCitation.Group";
|
|
28
|
+
|
|
29
|
+
export { SourceCitation, SourceCitationGroup };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const sourceCitationTheme = {
|
|
2
|
+
// Asymmetric padding: the round leading token provides its own visual inset,
|
|
3
|
+
// so the left padding is tighter than the right where the domain text sits.
|
|
4
|
+
triggerStyle: "inline-flex max-w-52 cursor-pointer items-center gap-1.5 rounded-full border border-[var(--color-border)] bg-[var(--color-surface)] py-0.5 pl-0.5 pr-2.5 text-xs font-medium text-[var(--color-text-secondary)] transition-colors hover:border-[var(--color-border-hover)] hover:bg-[var(--color-surface-hover)] hover:text-[var(--color-text-primary)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-primary)]",
|
|
5
|
+
// Quiet numbered token — a recessed well with a hairline, not a loud filled disc.
|
|
6
|
+
indexStyle: "flex size-[1.125rem] shrink-0 items-center justify-center rounded-full bg-[var(--color-surface-sunken)] text-[10px] font-semibold tabular-nums text-[var(--color-text-secondary)] ring-1 ring-inset ring-[var(--color-border)]",
|
|
7
|
+
// Favicon well (shown instead of the number when an icon is supplied).
|
|
8
|
+
faviconStyle: "flex size-[1.125rem] shrink-0 items-center justify-center overflow-hidden rounded-full bg-[var(--color-surface-sunken)] ring-1 ring-inset ring-[var(--color-border)] [&>img]:size-full [&>img]:object-cover [&>svg]:size-3",
|
|
9
|
+
domainStyle: "truncate",
|
|
10
|
+
popoverStyle: "w-80 space-y-3",
|
|
11
|
+
previewHeaderStyle: "flex items-start gap-2.5",
|
|
12
|
+
previewIconStyle: "flex size-10 shrink-0 items-center justify-center rounded-lg bg-[var(--color-surface-sunken)] text-[var(--color-text-muted)]",
|
|
13
|
+
previewTitleStyle: "line-clamp-2 text-sm font-semibold text-[var(--color-text-primary)]",
|
|
14
|
+
previewDomainStyle: "mt-0.5 truncate text-xs text-[var(--color-text-muted)]",
|
|
15
|
+
excerptStyle: "line-clamp-4 text-sm leading-5 text-[var(--color-text-secondary)]",
|
|
16
|
+
// Link's own base already provides layout (inline-flex/items-center/gap),
|
|
17
|
+
// color, hover underline, and focus-visible ring — only the size-specific
|
|
18
|
+
// bits need overriding here.
|
|
19
|
+
linkStyle: "text-xs font-medium",
|
|
20
|
+
groupStyle: "inline-flex flex-wrap items-center gap-1.5",
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export { sourceCitationTheme };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { PopoverPlacement } from "../../core/Popover";
|
|
3
|
+
export interface SourceCitationTheme {
|
|
4
|
+
triggerStyle: string;
|
|
5
|
+
indexStyle: string;
|
|
6
|
+
faviconStyle: string;
|
|
7
|
+
domainStyle: string;
|
|
8
|
+
popoverStyle: string;
|
|
9
|
+
previewHeaderStyle: string;
|
|
10
|
+
previewIconStyle: string;
|
|
11
|
+
previewTitleStyle: string;
|
|
12
|
+
previewDomainStyle: string;
|
|
13
|
+
excerptStyle: string;
|
|
14
|
+
linkStyle: string;
|
|
15
|
+
groupStyle: string;
|
|
16
|
+
}
|
|
17
|
+
export type SourceCitationThemeOverrides = Partial<SourceCitationTheme>;
|
|
18
|
+
export interface SourceCitationProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "children" | "title"> {
|
|
19
|
+
/** Citation number or compact identifier displayed in the chip. */
|
|
20
|
+
index?: React.ReactNode;
|
|
21
|
+
/** Source title displayed in the preview. */
|
|
22
|
+
title: React.ReactNode;
|
|
23
|
+
/** Source domain displayed in both the chip and preview. */
|
|
24
|
+
domain?: React.ReactNode;
|
|
25
|
+
/** Supporting source excerpt. */
|
|
26
|
+
excerpt?: React.ReactNode;
|
|
27
|
+
/** Destination URL. */
|
|
28
|
+
href?: string;
|
|
29
|
+
/** Optional source or favicon icon. */
|
|
30
|
+
icon?: React.ReactNode;
|
|
31
|
+
/** Fully custom preview content. */
|
|
32
|
+
preview?: React.ReactNode;
|
|
33
|
+
/** Popover placement relative to the citation chip. */
|
|
34
|
+
placement?: PopoverPlacement;
|
|
35
|
+
/** Controlled popover state. */
|
|
36
|
+
open?: boolean;
|
|
37
|
+
/** Initial popover state for uncontrolled usage. */
|
|
38
|
+
defaultOpen?: boolean;
|
|
39
|
+
onOpenChange?: (open: boolean) => void;
|
|
40
|
+
/** Open the source link in a new tab. @default true */
|
|
41
|
+
openInNewTab?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Label for the link at the foot of the preview. Overridable so the string is
|
|
44
|
+
* not trapped in English.
|
|
45
|
+
* @default "Open source"
|
|
46
|
+
*/
|
|
47
|
+
linkLabel?: React.ReactNode;
|
|
48
|
+
className?: string;
|
|
49
|
+
theme?: SourceCitationThemeOverrides;
|
|
50
|
+
}
|
|
51
|
+
export interface SourceCitationGroupProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
52
|
+
children: React.ReactNode;
|
|
53
|
+
className?: string;
|
|
54
|
+
theme?: Pick<SourceCitationThemeOverrides, "groupStyle">;
|
|
55
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { SourceCitation, SourceCitationGroup } from "./SourceCitation";
|
|
2
|
+
export { sourceCitationTheme } from "./SourceCitation.theme";
|
|
3
|
+
export type { SourceCitationProps, SourceCitationGroupProps, SourceCitationTheme, SourceCitationThemeOverrides, } from "./SourceCitation.types";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import {
|
|
3
|
+
import { WarningCircle } from '@phosphor-icons/react';
|
|
4
4
|
import { cn } from '../../../utils/cn.js';
|
|
5
5
|
import { streamingResponseTheme } from './StreamingResponse.theme.js';
|
|
6
6
|
|
|
@@ -29,7 +29,7 @@ const getErrorTitle = (type) => {
|
|
|
29
29
|
*/
|
|
30
30
|
const ErrorDisplay = ({ error, onRetry, retryAttempt, maxAttempts, className, }) => {
|
|
31
31
|
const canRetry = error.retryable && retryAttempt < maxAttempts;
|
|
32
|
-
return (jsxs("div", { className: cn(streamingResponseTheme.errorContainerStyle, className), role: "alert", "aria-live": "assertive", children: [jsx(
|
|
32
|
+
return (jsxs("div", { className: cn(streamingResponseTheme.errorContainerStyle, className), role: "alert", "aria-live": "assertive", children: [jsx(WarningCircle, { className: "size-5 text-[var(--color-danger)] flex-shrink-0" }), jsxs("div", { className: "flex-1", children: [jsx("p", { className: cn(streamingResponseTheme.errorTitleStyle), children: getErrorTitle(error.type) }), jsx("p", { className: cn(streamingResponseTheme.errorMessageStyle), children: error.message }), canRetry && (jsxs("button", { onClick: onRetry, className: cn(streamingResponseTheme.errorRetryButtonStyle), type: "button", children: ["Retry (", retryAttempt + 1, "/", maxAttempts, ")"] }))] })] }));
|
|
33
33
|
};
|
|
34
34
|
ErrorDisplay.displayName = 'ErrorDisplay';
|
|
35
35
|
|
|
@@ -7,9 +7,7 @@ import { TypeWriter } from '../../core/Message/TypeWriter.js';
|
|
|
7
7
|
import '../../core/Message/MessageBody.js';
|
|
8
8
|
import '../../../utils/cn.js';
|
|
9
9
|
import '../../core/Link/Link.js';
|
|
10
|
-
import '@
|
|
11
|
-
import '@heroicons/react/24/outline';
|
|
12
|
-
import '@heroicons/react/24/solid';
|
|
10
|
+
import '@phosphor-icons/react';
|
|
13
11
|
import { ErrorDisplay } from './ErrorDisplay.js';
|
|
14
12
|
import { MarkdownRenderer } from './MarkdownRenderer.js';
|
|
15
13
|
import { AnimatedText } from './AnimatedText.js';
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
const streamingResponseTheme = {
|
|
2
|
-
|
|
2
|
+
// Danger banner — same role as Alert, so it reuses --alert-radius rather
|
|
3
|
+
// than the bare --radius-base (which would be uncapped at extreme themes).
|
|
4
|
+
errorContainerStyle: "flex items-start gap-3 rounded-[var(--alert-radius)] border border-[var(--color-danger-200)] bg-[var(--color-danger-50)] px-4 py-3",
|
|
3
5
|
errorTitleStyle: "text-sm font-medium text-[var(--color-danger)]",
|
|
4
6
|
errorMessageStyle: "text-sm text-[var(--color-text-secondary)] mt-1",
|
|
5
7
|
errorRetryButtonStyle: "mt-2 text-sm font-medium text-[var(--color-danger)] hover:text-[var(--color-danger-700)] transition-colors",
|
|
@@ -4,7 +4,7 @@ import React__default, { useMemo } from 'react';
|
|
|
4
4
|
import { tokenCounterTheme } from './TokenCounter.theme.js';
|
|
5
5
|
import { MODEL_CONFIGS, estimateTokens, calculateCost, formatTokenCount, formatCost } from './tokenUtils.js';
|
|
6
6
|
import { cn } from '../../../utils/cn.js';
|
|
7
|
-
import {
|
|
7
|
+
import { Database } from '@phosphor-icons/react';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* TokenCounter - Real-time token usage display with cost estimation
|
|
@@ -55,7 +55,7 @@ const TokenCounter = React__default.forwardRef(({ text = "", tokens: providedTok
|
|
|
55
55
|
const costStyle = customTheme.costStyle || tokenCounterTheme.costStyle;
|
|
56
56
|
const progressStyle = customTheme.progressStyle || tokenCounterTheme.progressStyle;
|
|
57
57
|
const progressBarStyle = customTheme.progressBarStyle || tokenCounterTheme.progressBarStyle;
|
|
58
|
-
return (jsxs("div", { ref: ref, className: cn(baseStyle, sizeConfig.container, className), ...props, children: [icon || jsx(
|
|
58
|
+
return (jsxs("div", { ref: ref, className: cn(baseStyle, sizeConfig.container, className), ...props, children: [icon || jsx(Database, { className: cn(iconStyle, sizeConfig.icon) }), jsx("span", { className: cn(countStyle, sizeConfig.text, isOverLimit && "text-[var(--color-danger)]"), children: formatTokenCount(tokenCount) }), maxTokens && format === "detailed" && (jsxs("span", { className: cn(labelStyle, sizeConfig.text), children: ["/ ", formatTokenCount(effectiveMaxTokens)] })), jsx("span", { className: cn(labelStyle, sizeConfig.text), children: "tokens" }), showCost && (jsxs("span", { className: cn(costStyle, sizeConfig.text), children: ["(", formatCost(cost), ")"] })), format === "detailed" && maxTokens && (jsx("div", { className: cn(progressStyle, "w-16 ml-2"), children: jsx("div", { className: cn(progressBarStyle, isOverLimit && "bg-[var(--color-danger)]"), style: { width: `${progressPercent}%` } }) }))] }));
|
|
59
59
|
});
|
|
60
60
|
TokenCounter.displayName = "TokenCounter";
|
|
61
61
|
|
|
@@ -10,3 +10,6 @@ export { StreamingResponse, ErrorDisplay, MarkdownRenderer, AnimatedText, Stream
|
|
|
10
10
|
export type { StreamingResponseProps, StreamingResponseTheme, MarkdownOptions, AnimatedTextProps, StreamingCursorProps, MarkdownRendererProps, } from "./StreamingResponse";
|
|
11
11
|
export { CodeBlock, codeBlockTheme } from "./CodeBlock";
|
|
12
12
|
export type { CodeBlockProps, CodeBlockLanguage, CodeBlockTheme, CodeBlockThemeOverrides, } from "./CodeBlock";
|
|
13
|
+
export * from "./AgentStatus";
|
|
14
|
+
export * from "./Reasoning";
|
|
15
|
+
export * from "./SourceCitation";
|
|
@@ -6,9 +6,7 @@ import 'react/jsx-runtime';
|
|
|
6
6
|
import '../../utils/cn.js';
|
|
7
7
|
import 'react';
|
|
8
8
|
import '../core/Link/Link.js';
|
|
9
|
-
import '@
|
|
10
|
-
import '@heroicons/react/24/outline';
|
|
11
|
-
import '@heroicons/react/24/solid';
|
|
9
|
+
import '@phosphor-icons/react';
|
|
12
10
|
export { PromptInput } from './PromptInput/PromptInput.js';
|
|
13
11
|
export { promptInputTheme } from './PromptInput/PromptInput.theme.js';
|
|
14
12
|
export { TokenCounter } from './TokenCounter/TokenCounter.js';
|
|
@@ -26,3 +24,8 @@ export { streamingResponseTheme } from './StreamingResponse/StreamingResponse.th
|
|
|
26
24
|
export { blockSlideIn, blockTransition, cursorPulse, staggerContainer, tokenFadeIn, tokenTransition } from './StreamingResponse/StreamingResponse.animations.js';
|
|
27
25
|
export { CodeBlock } from './CodeBlock/CodeBlock.js';
|
|
28
26
|
export { codeBlockTheme } from './CodeBlock/CodeBlock.theme.js';
|
|
27
|
+
export { AgentStatus } from './AgentStatus/AgentStatus.js';
|
|
28
|
+
export { agentStatusTheme } from './AgentStatus/AgentStatus.theme.js';
|
|
29
|
+
export { Reasoning } from './Reasoning/Reasoning.js';
|
|
30
|
+
export { SourceCitation, SourceCitationGroup } from './SourceCitation/SourceCitation.js';
|
|
31
|
+
export { sourceCitationTheme } from './SourceCitation/SourceCitation.theme.js';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export type AIStatusIndicatorState = "idle" | "active" | "complete" | "pending" | "error";
|
|
3
|
+
export interface AIStatusIndicatorProps extends Omit<React.SVGAttributes<SVGSVGElement>, "children"> {
|
|
4
|
+
state: AIStatusIndicatorState;
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
/** A rotating open arc that settles into a drawn semantic status glyph. */
|
|
8
|
+
export declare const AIStatusIndicator: React.ForwardRefExoticComponent<AIStatusIndicatorProps & React.RefAttributes<SVGSVGElement>>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
|
+
import React__default from 'react';
|
|
4
|
+
import { useReducedMotion, AnimatePresence, motion } from 'motion/react';
|
|
5
|
+
import { cn } from '../../../utils/cn.js';
|
|
6
|
+
|
|
7
|
+
/** A rotating open arc that settles into a drawn semantic status glyph. */
|
|
8
|
+
const AIStatusIndicator = React__default.forwardRef(({ state, className, ...props }, ref) => {
|
|
9
|
+
const shouldReduceMotion = useReducedMotion();
|
|
10
|
+
const instant = shouldReduceMotion ? { duration: 0 } : undefined;
|
|
11
|
+
// Unique per instance: SVG gradient ids are document-global, so a shared id
|
|
12
|
+
// would let the first-mounted indicator's def win for every spinner on the page.
|
|
13
|
+
const gradientId = `${React__default.useId()}-arc`;
|
|
14
|
+
return (jsx("svg", { ref: ref, viewBox: "0 0 16 16", fill: "none", className: cn("size-4 overflow-visible", className), "data-ai-status-indicator": state, "aria-hidden": "true", ...props, children: jsxs(AnimatePresence, { initial: false, mode: "sync", children: [state === "active" && (jsx(motion.g, { initial: shouldReduceMotion ? false : { opacity: 0, scale: 0.7 }, animate: { opacity: 1, scale: 1 }, exit: shouldReduceMotion
|
|
15
|
+
? { opacity: 0, transition: { duration: 0 } }
|
|
16
|
+
: {
|
|
17
|
+
opacity: 0,
|
|
18
|
+
scale: 0.55,
|
|
19
|
+
transition: { duration: 0.18, ease: "easeOut" },
|
|
20
|
+
}, transition: {
|
|
21
|
+
opacity: { duration: 0.16 },
|
|
22
|
+
scale: { duration: 0.2, ease: "easeOut" },
|
|
23
|
+
}, style: { transformBox: "view-box", transformOrigin: "8px 8px" }, children: jsxs("g", { className: "animate-spin motion-reduce:animate-none [transform-box:view-box] [transform-origin:center]", children: [jsx("defs", { children: jsxs("linearGradient", { id: gradientId, gradientUnits: "userSpaceOnUse", x1: "2.5", y1: "8", x2: "13.5", y2: "8", children: [jsx("stop", { offset: "0%", stopColor: "currentColor", stopOpacity: "1" }), jsx("stop", { offset: "55%", stopColor: "currentColor", stopOpacity: "1" }), jsx("stop", { offset: "100%", stopColor: "currentColor", stopOpacity: "0" })] }) }), jsx("circle", { cx: "8", cy: "8", r: "5.5", stroke: `url(#${gradientId})`, strokeWidth: "1.75", strokeLinecap: "round", strokeDasharray: "17.3 34.6" })] }) }, "active")), state === "complete" && (jsx(motion.path, { d: "M3.5 8.25 6.65 11.2 12.6 4.9", stroke: "currentColor", strokeWidth: "1.9", strokeLinecap: "round", strokeLinejoin: "round", initial: shouldReduceMotion
|
|
24
|
+
? false
|
|
25
|
+
: { opacity: 0, pathLength: 0, scale: 0.7, rotate: -18 }, animate: { opacity: 1, pathLength: 1, scale: 1, rotate: 0 }, exit: { opacity: 0, scale: 0.7 }, transition: instant !== null && instant !== void 0 ? instant : {
|
|
26
|
+
opacity: { duration: 0.12 },
|
|
27
|
+
pathLength: { duration: 0.32, delay: 0.08, ease: "easeOut" },
|
|
28
|
+
scale: { type: "spring", stiffness: 420, damping: 24 },
|
|
29
|
+
rotate: { type: "spring", stiffness: 360, damping: 22 },
|
|
30
|
+
}, style: { transformOrigin: "8px 8px" } }, "complete")), state === "pending" && (jsx(motion.circle, { cx: "8", cy: "8", r: "4.5", stroke: "currentColor", strokeWidth: "1.4", initial: shouldReduceMotion ? false : { opacity: 0, scale: 0.7 }, animate: { opacity: 0.55, scale: 1 }, exit: { opacity: 0, scale: 0.7 }, transition: instant !== null && instant !== void 0 ? instant : { duration: 0.2 }, style: { transformOrigin: "8px 8px" } }, "pending")), state === "error" && (jsx(motion.path, { d: "M4.5 4.5 11.5 11.5 M11.5 4.5 4.5 11.5", stroke: "currentColor", strokeWidth: "1.7", strokeLinecap: "round", initial: shouldReduceMotion ? false : { opacity: 0, pathLength: 0 }, animate: { opacity: 1, pathLength: 1 }, exit: { opacity: 0, scale: 0.7 }, transition: instant !== null && instant !== void 0 ? instant : { duration: 0.24 } }, "error")), state === "idle" && (jsx(motion.circle, { cx: "8", cy: "8", r: "2.25", fill: "currentColor", initial: shouldReduceMotion ? false : { opacity: 0, scale: 0.6 }, animate: { opacity: 0.7, scale: 1 }, exit: { opacity: 0, scale: 0.6 }, transition: instant !== null && instant !== void 0 ? instant : { duration: 0.18 }, style: { transformOrigin: "8px 8px" } }, "idle"))] }) }));
|
|
31
|
+
});
|
|
32
|
+
AIStatusIndicator.displayName = "AIStatusIndicator";
|
|
33
|
+
|
|
34
|
+
export { AIStatusIndicator };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import {
|
|
3
|
+
import { CursorClick, Hand, Plus } from '@phosphor-icons/react';
|
|
4
4
|
import { cn } from '../../utils/cn.js';
|
|
5
5
|
import { Button } from '../core/Button/Button.js';
|
|
6
6
|
import 'react';
|
|
@@ -28,7 +28,7 @@ const Divider = () => (jsx("span", { className: "mx-0.5 h-6 w-px bg-[var(--color
|
|
|
28
28
|
function CanvasToolbar({ nodeOptions, onAddNode, showTools = true, position = "bottom", className, children, }) {
|
|
29
29
|
const { tool, setTool } = useCanvasApi();
|
|
30
30
|
const hasNodes = !!(nodeOptions === null || nodeOptions === void 0 ? void 0 : nodeOptions.length);
|
|
31
|
-
return (jsxs("div", { "data-flikkui-nopan": "", className: cn("absolute z-30 flex items-center gap-1 rounded-full border border-[var(--color-border)] bg-[var(--color-surface-overlay)]/60 backdrop-blur-lg p-1 shadow-real-lg", POSITIONS[position], className), children: [showTools && (jsxs(Fragment, { children: [jsx(Button, { variant: tool === "select" ? "soft" : "ghost", color: "
|
|
31
|
+
return (jsxs("div", { "data-flikkui-nopan": "", className: cn("absolute z-30 flex items-center gap-1 rounded-full border border-[var(--color-border)] bg-[var(--color-surface-overlay)]/60 backdrop-blur-lg p-1 shadow-real-lg", POSITIONS[position], className), children: [showTools && (jsxs(Fragment, { children: [jsx(Button, { variant: tool === "select" ? "soft" : "ghost", color: "mono", size: "sm", iconOnly: true, onClick: () => setTool("select"), "aria-label": "Select tool", "aria-pressed": tool === "select", className: cn("rounded-full", tool === "select" && "shadow-inner"), children: jsx(CursorClick, { className: "size-4" }) }), jsx(Button, { variant: tool === "pan" ? "soft" : "ghost", color: "mono", size: "sm", iconOnly: true, onClick: () => setTool("pan"), "aria-label": "Hand (pan) tool", "aria-pressed": tool === "pan", className: cn("rounded-full", tool === "pan" && "shadow-inner"), children: jsx(Hand, { className: "size-4" }) })] })), showTools && hasNodes && jsx(Divider, {}), hasNodes && (jsxs(Dropdown, { placement: "top", offset: 10, onAction: (type) => onAddNode === null || onAddNode === void 0 ? void 0 : onAddNode(type), children: [jsx(Dropdown.Trigger, { children: jsxs(Button, { variant: "ghost", color: "mono", size: "sm", className: "rounded-full gap-1.5", children: [jsx(Plus, { className: "size-4" }), "Add node"] }) }), jsx(Dropdown.Menu, { "aria-label": "Add node", children: nodeOptions === null || nodeOptions === void 0 ? void 0 : nodeOptions.map((opt) => (jsx(Dropdown.Item, { itemKey: opt.type, startContent: opt.icon && (jsx("span", { className: "size-4 grid place-items-center text-[var(--color-text-muted)]", children: opt.icon })), children: opt.label }, opt.type))) })] })), children && (jsxs(Fragment, { children: [(showTools || hasNodes) && jsx(Divider, {}), children] }))] }));
|
|
32
32
|
}
|
|
33
33
|
CanvasToolbar.displayName = "CanvasToolbar";
|
|
34
34
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import {
|
|
3
|
+
import { Plus, Minus, ArrowsOutSimple, Lock, LockOpen } from '@phosphor-icons/react';
|
|
4
4
|
import { cn } from '../../utils/cn.js';
|
|
5
5
|
import { Button } from '../core/Button/Button.js';
|
|
6
6
|
import 'react';
|
|
@@ -34,7 +34,7 @@ function NodeControls({ position = "bottom-right", showZoom = true, showFitView
|
|
|
34
34
|
});
|
|
35
35
|
};
|
|
36
36
|
const ctrlBtn = "size-8 rounded-none";
|
|
37
|
-
return (jsxs("div", { "data-flikkui-controls": "", className: cn("absolute z-20 flex flex-col overflow-hidden rounded-lg border border-[var(--color-border)] divide-y divide-[var(--color-border)] bg-[var(--color-surface-overlay)]/60 backdrop-blur-lg shadow-real-lg", POSITIONS[position], className), children: [showZoom && (jsxs(Fragment, { children: [jsx(Button, { variant: "ghost", color: "
|
|
37
|
+
return (jsxs("div", { "data-flikkui-controls": "", className: cn("absolute z-20 flex flex-col overflow-hidden rounded-lg border border-[var(--color-border)] divide-y divide-[var(--color-border)] bg-[var(--color-surface-overlay)]/60 backdrop-blur-lg shadow-real-lg", POSITIONS[position], className), children: [showZoom && (jsxs(Fragment, { children: [jsx(Button, { variant: "ghost", color: "mono", size: "sm", iconOnly: true, className: ctrlBtn, onClick: () => zoomBy(zoomStep), "aria-label": "Zoom in", children: jsx(Plus, { className: "size-4" }) }), jsx(Button, { variant: "ghost", color: "mono", size: "sm", iconOnly: true, className: ctrlBtn, onClick: () => zoomBy(1 / zoomStep), "aria-label": "Zoom out", children: jsx(Minus, { className: "size-4" }) })] })), showFitView && (jsx(Button, { variant: "ghost", color: "mono", size: "sm", iconOnly: true, className: ctrlBtn, onClick: () => fitView(), "aria-label": "Fit view", children: jsx(ArrowsOutSimple, { className: "size-4" }) })), showLock && (jsx(Button, { variant: locked ? "soft" : "ghost", color: locked ? "primary" : "mono", size: "sm", iconOnly: true, className: ctrlBtn, onClick: () => setLocked(!locked), "aria-label": locked ? "Unlock canvas" : "Lock canvas", "aria-pressed": locked, children: locked ? jsx(Lock, { className: "size-4" }) : jsx(LockOpen, { className: "size-4" }) }))] }));
|
|
38
38
|
}
|
|
39
39
|
NodeControls.displayName = "NodeControls";
|
|
40
40
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
3
3
|
import React__default, { useCallback, useRef, useEffect } from 'react';
|
|
4
|
-
import {
|
|
4
|
+
import { Plus } from '@phosphor-icons/react';
|
|
5
5
|
import { cn } from '../../utils/cn.js';
|
|
6
6
|
import { NodeIdProvider } from './context/NodeIdContext.js';
|
|
7
7
|
import { useCanvasApi } from './context/CanvasContext.js';
|
|
@@ -79,7 +79,7 @@ function AutoHandle({ nodeId, position }) {
|
|
|
79
79
|
};
|
|
80
80
|
}, [nodeId, handleId, position, register, unregister, viewportRef]);
|
|
81
81
|
return (jsx("button", { ref: ref, type: "button", "data-flikkui-handle": "", "data-node-id": nodeId, "data-handle-type": "source", "data-handle-id": handleId, "data-handle-kind": "auto", "aria-label": `Connect from ${position}`, className: cn("nodrag absolute z-20 grid place-items-center size-4 rounded-full", "bg-[var(--color-primary)] text-[var(--color-primary-contrast)] shadow-md ring-2 ring-[var(--color-surface)] cursor-crosshair", "opacity-0 scale-75 pointer-events-none transition-[opacity,transform,box-shadow] duration-150 ease-out", "hover:scale-110 hover:shadow-lg hover:ring-4 active:scale-95", !disabled &&
|
|
82
|
-
"group-hover:opacity-100 group-hover:scale-100 group-hover:pointer-events-auto group-focus-within:opacity-100 group-focus-within:scale-100 group-focus-within:pointer-events-auto", AUTO_SIDE_CLASSES[position]), onPointerDown: disabled ? undefined : onPointerDown, children: jsx(
|
|
82
|
+
"group-hover:opacity-100 group-hover:scale-100 group-hover:pointer-events-auto group-focus-within:opacity-100 group-focus-within:scale-100 group-focus-within:pointer-events-auto", AUTO_SIDE_CLASSES[position]), onPointerDown: disabled ? undefined : onPointerDown, children: jsx(Plus, { className: "size-2.5" }) }));
|
|
83
83
|
}
|
|
84
84
|
// Memoized so unrelated graph updates (another node's data/position, selection
|
|
85
85
|
// elsewhere) skip this node: `node` identity is preserved by applyNodeChanges,
|
|
@@ -5,7 +5,7 @@ import { motion, useReducedMotion } from 'motion/react';
|
|
|
5
5
|
import { cn } from '../../../utils/cn.js';
|
|
6
6
|
import { activityRingsTheme } from './ActivityRings.theme.js';
|
|
7
7
|
import { ACTIVITY_RINGS_DEFAULTS } from './ActivityRings.types.js';
|
|
8
|
-
import {
|
|
8
|
+
import { Warning } from '@phosphor-icons/react';
|
|
9
9
|
import { useTooltipPosition } from '../hooks/useTooltipPosition.js';
|
|
10
10
|
import { ChartTooltip } from '../shared/ChartTooltip/ChartTooltip.js';
|
|
11
11
|
import { getSpringAnimation, CIRCULAR_CHART_ANIMATIONS, getStaggerDelay } from '../utils/animation-utils.js';
|
|
@@ -127,7 +127,7 @@ const ActivityRings = ({ rings, centerLabel, centerSuffix, size = ACTIVITY_RINGS
|
|
|
127
127
|
// BarChart.tsx.
|
|
128
128
|
// Early return for invalid configuration
|
|
129
129
|
if (!Array.isArray(rings) || rings.length === 0) {
|
|
130
|
-
return (jsxs("div", { className: cn("flex items-center justify-center p-6 border border-[var(--color-border)] rounded-lg", className), role: "alert", ...props, children: [jsx(
|
|
130
|
+
return (jsxs("div", { className: cn("flex items-center justify-center p-6 border border-[var(--color-border)] rounded-lg", className), role: "alert", ...props, children: [jsx(Warning, { className: "size-5 text-[var(--color-danger)] mr-2" }), jsx("span", { className: "text-base text-[var(--color-text-secondary)]", children: "Invalid ActivityRings: rings array is required" })] }));
|
|
131
131
|
}
|
|
132
132
|
// Get color for a ring by index
|
|
133
133
|
// Priority: ring.color > colors prop > theme colors > fallback
|