@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
|
@@ -10,9 +10,8 @@ import { cn } from '../../../utils/cn.js';
|
|
|
10
10
|
import { Button } from '../../core/Button/Button.js';
|
|
11
11
|
import { ScrollArea } from '../../core/ScrollArea/ScrollArea.js';
|
|
12
12
|
import '../../core/ScrollArea/smooth/SmoothScrollEngine.js';
|
|
13
|
-
import {
|
|
13
|
+
import { ArrowUUpRight, ArrowUUpLeft, TextAlignRight, List, TextAlignLeft, PaintBrush, ArrowsLeftRight, ArrowsDownUp, TextB, TextUnderline, TextItalic } from '@phosphor-icons/react';
|
|
14
14
|
import { useSelectPortal } from '../../../hooks/useSelectPortal.js';
|
|
15
|
-
import { PaintBrushIcon } from '@heroicons/react/24/solid';
|
|
16
15
|
import { createDropdownAnimations } from '../Select/Select.animations.js';
|
|
17
16
|
import { useIsClient } from '../../../hooks/useIsClient.js';
|
|
18
17
|
import { useSurfaceElevation, SurfaceProvider, surfaceClasses } from '../../../theme/SurfaceContext.js';
|
|
@@ -1447,11 +1446,11 @@ const RichTextEditor = React__default.forwardRef(({ size = "md", state = "defaul
|
|
|
1447
1446
|
: false;
|
|
1448
1447
|
switch (tool) {
|
|
1449
1448
|
case "bold":
|
|
1450
|
-
return (jsx(Button, { size: "sm", color: "
|
|
1449
|
+
return (jsx(Button, { size: "sm", color: "mono", variant: "soft", iconOnly: true, className: cn(themeStyles.toolbarButtonStyle), "data-state": isActive ? "active" : "inactive", onMouseDown: handleMouseDown, onClick: handleBold, disabled: isDisabled, "aria-label": "Bold", "aria-pressed": isActive ? "true" : "false", children: jsx(TextB, { className: "size-4" }) }, toolKey));
|
|
1451
1450
|
case "italic":
|
|
1452
|
-
return (jsx(Button, { size: "sm", color: "
|
|
1451
|
+
return (jsx(Button, { size: "sm", color: "mono", variant: "soft", iconOnly: true, className: cn(themeStyles.toolbarButtonStyle), "data-state": isActive ? "active" : "inactive", onMouseDown: handleMouseDown, onClick: handleItalic, disabled: isDisabled, "aria-label": "Italic", "aria-pressed": isActive ? "true" : "false", children: jsx(TextItalic, { className: "size-4" }) }, toolKey));
|
|
1453
1452
|
case "underline":
|
|
1454
|
-
return (jsx(Button, { size: "sm", color: "
|
|
1453
|
+
return (jsx(Button, { size: "sm", color: "mono", variant: "soft", iconOnly: true, className: cn(themeStyles.toolbarButtonStyle), "data-state": isActive ? "active" : "inactive", onMouseDown: handleMouseDown, onClick: handleUnderline, disabled: isDisabled, "aria-label": "Underline", "aria-pressed": isActive ? "true" : "false", children: jsx(TextUnderline, { className: "size-4" }) }, toolKey));
|
|
1455
1454
|
case "fontFamily": {
|
|
1456
1455
|
// The `fontFamily` tool is opt-in via toolbar config, but
|
|
1457
1456
|
// `fontFamilies` is also a public prop — if a consumer passes an
|
|
@@ -1487,7 +1486,7 @@ const RichTextEditor = React__default.forwardRef(({ size = "md", state = "defaul
|
|
|
1487
1486
|
}, role: "option", "aria-selected": selected, children: jsxs("span", { className: "flex items-center justify-between gap-3", children: [jsx("span", { className: "text-sm", style: { fontFamily: option.stack || undefined }, children: option.label }), option.family && (jsx("span", { className: "text-xs text-[var(--color-text-muted)]", children: "Google" }))] }) }, option.key));
|
|
1488
1487
|
}) }) })) }), document.body)
|
|
1489
1488
|
: null;
|
|
1490
|
-
return (jsxs("div", { className: "relative", "data-tool": "fontFamily", children: [jsx(Button, { ref: fontFamilyTriggerRef, size: "sm", color: "
|
|
1489
|
+
return (jsxs("div", { className: "relative", "data-tool": "fontFamily", children: [jsx(Button, { ref: fontFamilyTriggerRef, size: "sm", color: "mono", variant: "soft", className: cn(themeStyles.toolbarButtonStyle, "!justify-start !w-auto px-2 min-w-[4rem] gap-1"), "data-state": isActive ? "active" : "inactive", onMouseDown: handleMouseDown, onClick: (event) => {
|
|
1491
1490
|
event.preventDefault();
|
|
1492
1491
|
event.stopPropagation();
|
|
1493
1492
|
focusEditor();
|
|
@@ -1518,12 +1517,12 @@ const RichTextEditor = React__default.forwardRef(({ size = "md", state = "defaul
|
|
|
1518
1517
|
}, role: "option", "aria-selected": selected, children: jsxs("span", { className: "flex items-center justify-between gap-3", children: [jsx("span", { className: "text-sm", style: { fontWeight: option.value }, children: option.label }), jsx("span", { className: "text-sm text-[var(--color-text-muted)]", children: option.value })] }) }, option.key));
|
|
1519
1518
|
}) }) })) }), document.body)
|
|
1520
1519
|
: null;
|
|
1521
|
-
return (jsxs("div", { className: "relative", "data-tool": "fontWeight", children: [jsx(Button, { ref: fontWeightTriggerRef, size: "sm", color: "
|
|
1520
|
+
return (jsxs("div", { className: "relative", "data-tool": "fontWeight", children: [jsx(Button, { ref: fontWeightTriggerRef, size: "sm", color: "mono", variant: "soft", iconOnly: true, className: cn(themeStyles.toolbarButtonStyle), "data-state": isActive ? "active" : "inactive", onMouseDown: handleMouseDown, onClick: (event) => {
|
|
1522
1521
|
event.preventDefault();
|
|
1523
1522
|
event.stopPropagation();
|
|
1524
1523
|
focusEditor();
|
|
1525
1524
|
togglePicker("fontWeight");
|
|
1526
|
-
}, disabled: isDisabled, "aria-label": `Font weight (${currentOption.label})`, "aria-expanded": showFontWeightPicker, "aria-haspopup": "listbox", children: jsx(
|
|
1525
|
+
}, disabled: isDisabled, "aria-label": `Font weight (${currentOption.label})`, "aria-expanded": showFontWeightPicker, "aria-haspopup": "listbox", children: jsx(TextB, { className: "w-4 h-4" }) }), renderedDropdown] }, toolKey));
|
|
1527
1526
|
}
|
|
1528
1527
|
case "fontSize": {
|
|
1529
1528
|
const currentOption = getFontSizeOption(formattingState.fontSize);
|
|
@@ -1549,7 +1548,7 @@ const RichTextEditor = React__default.forwardRef(({ size = "md", state = "defaul
|
|
|
1549
1548
|
}, role: "option", "aria-selected": selected, children: jsxs("span", { className: "flex items-center justify-between gap-3", children: [jsx("span", { className: "uppercase text-sm font-medium", children: option.label }), jsxs("span", { className: "text-sm text-[var(--color-text-muted)]", children: [option.px, "px"] })] }) }, option.key));
|
|
1550
1549
|
}) }) })) }), document.body)
|
|
1551
1550
|
: null;
|
|
1552
|
-
return (jsxs("div", { className: "relative", "data-tool": "fontSize", children: [jsx(Button, { ref: fontSizeTriggerRef, size: "sm", color: "
|
|
1551
|
+
return (jsxs("div", { className: "relative", "data-tool": "fontSize", children: [jsx(Button, { ref: fontSizeTriggerRef, size: "sm", color: "mono", variant: "soft", className: cn(themeStyles.toolbarButtonStyle, "px-2 min-w-[3rem] gap-1"), "data-state": isActive ? "active" : "inactive", onMouseDown: handleMouseDown, onClick: (event) => {
|
|
1553
1552
|
event.preventDefault();
|
|
1554
1553
|
event.stopPropagation();
|
|
1555
1554
|
focusEditor();
|
|
@@ -1580,12 +1579,12 @@ const RichTextEditor = React__default.forwardRef(({ size = "md", state = "defaul
|
|
|
1580
1579
|
}, role: "option", "aria-selected": selected, children: jsxs("span", { className: "flex items-center justify-between gap-3", children: [jsx("span", { className: "text-sm font-medium", children: option.label }), jsx("span", { className: "text-sm text-[var(--color-text-muted)]", children: option.value })] }) }, option.key));
|
|
1581
1580
|
}) }) })) }), document.body)
|
|
1582
1581
|
: null;
|
|
1583
|
-
return (jsxs("div", { className: "relative", "data-tool": "lineHeight", children: [jsx(Button, { ref: lineHeightTriggerRef, size: "sm", color: "
|
|
1582
|
+
return (jsxs("div", { className: "relative", "data-tool": "lineHeight", children: [jsx(Button, { ref: lineHeightTriggerRef, size: "sm", color: "mono", variant: "soft", iconOnly: true, className: cn(themeStyles.toolbarButtonStyle), "data-state": isActive ? "active" : "inactive", onMouseDown: handleMouseDown, onClick: (event) => {
|
|
1584
1583
|
event.preventDefault();
|
|
1585
1584
|
event.stopPropagation();
|
|
1586
1585
|
focusEditor();
|
|
1587
1586
|
togglePicker("lineHeight");
|
|
1588
|
-
}, disabled: isDisabled, "aria-label": `Line height (${currentOption.label})`, "aria-expanded": showLineHeightPicker, "aria-haspopup": "listbox", children: jsx(
|
|
1587
|
+
}, disabled: isDisabled, "aria-label": `Line height (${currentOption.label})`, "aria-expanded": showLineHeightPicker, "aria-haspopup": "listbox", children: jsx(ArrowsDownUp, { className: "w-4 h-4" }) }), renderedDropdown] }, toolKey));
|
|
1589
1588
|
}
|
|
1590
1589
|
case "letterSpacing": {
|
|
1591
1590
|
const currentOption = getLetterSpacingOption(formattingState.letterSpacing);
|
|
@@ -1611,12 +1610,12 @@ const RichTextEditor = React__default.forwardRef(({ size = "md", state = "defaul
|
|
|
1611
1610
|
}, role: "option", "aria-selected": selected, children: jsxs("span", { className: "flex items-center justify-between gap-3", children: [jsx("span", { className: "text-sm font-medium", children: option.label }), jsx("span", { className: "text-sm text-[var(--color-text-muted)]", children: option.value })] }) }, option.key));
|
|
1612
1611
|
}) }) })) }), document.body)
|
|
1613
1612
|
: null;
|
|
1614
|
-
return (jsxs("div", { className: "relative", "data-tool": "letterSpacing", children: [jsx(Button, { ref: letterSpacingTriggerRef, size: "sm", color: "
|
|
1613
|
+
return (jsxs("div", { className: "relative", "data-tool": "letterSpacing", children: [jsx(Button, { ref: letterSpacingTriggerRef, size: "sm", color: "mono", variant: "soft", iconOnly: true, className: cn(themeStyles.toolbarButtonStyle), "data-state": isActive ? "active" : "inactive", onMouseDown: handleMouseDown, onClick: (event) => {
|
|
1615
1614
|
event.preventDefault();
|
|
1616
1615
|
event.stopPropagation();
|
|
1617
1616
|
focusEditor();
|
|
1618
1617
|
togglePicker("letterSpacing");
|
|
1619
|
-
}, disabled: isDisabled, "aria-label": `Letter spacing (${currentOption.label})`, "aria-expanded": showLetterSpacingPicker, "aria-haspopup": "listbox", children: jsx(
|
|
1618
|
+
}, disabled: isDisabled, "aria-label": `Letter spacing (${currentOption.label})`, "aria-expanded": showLetterSpacingPicker, "aria-haspopup": "listbox", children: jsx(ArrowsLeftRight, { className: "w-4 h-4" }) }), renderedDropdown] }, toolKey));
|
|
1620
1619
|
}
|
|
1621
1620
|
case "textColor": {
|
|
1622
1621
|
const portalStyle = {
|
|
@@ -1646,35 +1645,35 @@ const RichTextEditor = React__default.forwardRef(({ size = "md", state = "defaul
|
|
|
1646
1645
|
colorPortalContentRef.current = el;
|
|
1647
1646
|
}, "data-flikkui-portal": "", className: cn(surfaceClasses(surfaceLevel, { translucent: true, shadow: false }), themeStyles.dropdownStyle, "!max-h-none !overflow-visible"), style: portalStyle, variants: shouldReduceMotion ? undefined : colorAnimations, initial: "initial", animate: colorPortalReady ? "visible" : "initial", exit: "exit", children: jsx(SurfaceProvider, { level: surfaceLevel, children: jsx(ScrollArea, { type: "none", className: "max-h-[20rem]", children: jsxs("div", { className: themeStyles.colorPickerStyle, children: [recentColors.length > 0 && (jsxs("div", { className: "flex flex-col gap-1 pb-2 mb-1 border-b border-[var(--color-border)]", children: [jsx("span", { className: "text-[11px] font-medium uppercase tracking-wide text-[var(--color-text-muted)]", children: "Recent" }), jsx("div", { className: "flex gap-0.5", children: recentColors.map((token) => renderSwatch(resolveTailwindColor(token), token, `recent ${token}`)) })] })), jsxs("div", { className: "flex flex-col gap-1", children: [jsx("span", { className: "text-[11px] font-medium uppercase tracking-wide text-[var(--color-text-muted)]", children: "Mono" }), jsx("div", { className: "flex gap-0.5", children: MONO_COLORS.map((color) => renderSwatch(color.value, color.token, color.name)) }), jsx("span", { className: "mt-2 text-[11px] font-medium uppercase tracking-wide text-[var(--color-text-muted)]", children: "Spectrum" }), TAILWIND_COLOR_FAMILIES.map((family) => (jsx("div", { className: "flex gap-0.5", children: getTailwindShadeTokens(family).map((token) => renderSwatch(resolveTailwindColor(token), token, token)) }, family)))] })] }) }) }) })) }), document.body)
|
|
1648
1647
|
: null;
|
|
1649
|
-
return (jsxs("div", { className: "relative", "data-tool": "textColor", children: [jsx(Button, { ref: colorTriggerRef, size: "sm", color: "
|
|
1648
|
+
return (jsxs("div", { className: "relative", "data-tool": "textColor", children: [jsx(Button, { ref: colorTriggerRef, size: "sm", color: "mono", variant: "soft", iconOnly: true, className: cn(themeStyles.toolbarButtonStyle), onMouseDown: handleMouseDown, onClick: (event) => {
|
|
1650
1649
|
event.preventDefault();
|
|
1651
1650
|
event.stopPropagation();
|
|
1652
1651
|
focusEditor();
|
|
1653
1652
|
togglePicker("color");
|
|
1654
|
-
}, disabled: isDisabled, "aria-label": "Text Color", "aria-expanded": showColorPicker, children: jsx(
|
|
1653
|
+
}, disabled: isDisabled, "aria-label": "Text Color", "aria-expanded": showColorPicker, children: jsx(PaintBrush, { className: "w-4 h-4" }) }), renderedColorDropdown] }, toolKey));
|
|
1655
1654
|
}
|
|
1656
1655
|
case "alignLeft":
|
|
1657
|
-
return (jsx(Button, { size: "sm", color: "
|
|
1656
|
+
return (jsx(Button, { size: "sm", color: "mono", variant: "soft", iconOnly: true, className: cn(themeStyles.toolbarButtonStyle), "data-state": isActive ? "active" : "inactive", onMouseDown: handleMouseDown, onClick: (event) => {
|
|
1658
1657
|
event.preventDefault();
|
|
1659
1658
|
event.stopPropagation();
|
|
1660
1659
|
handleAlign("left");
|
|
1661
|
-
}, disabled: isDisabled, "aria-label": "Align Left", "aria-pressed": isActive ? "true" : "false", children: jsx(
|
|
1660
|
+
}, disabled: isDisabled, "aria-label": "Align Left", "aria-pressed": isActive ? "true" : "false", children: jsx(TextAlignLeft, { className: "w-4 h-4" }) }, toolKey));
|
|
1662
1661
|
case "alignCenter":
|
|
1663
|
-
return (jsx(Button, { size: "sm", color: "
|
|
1662
|
+
return (jsx(Button, { size: "sm", color: "mono", variant: "soft", iconOnly: true, className: cn(themeStyles.toolbarButtonStyle), "data-state": isActive ? "active" : "inactive", onMouseDown: handleMouseDown, onClick: (event) => {
|
|
1664
1663
|
event.preventDefault();
|
|
1665
1664
|
event.stopPropagation();
|
|
1666
1665
|
handleAlign("center");
|
|
1667
|
-
}, disabled: isDisabled, "aria-label": "Align Center", "aria-pressed": isActive ? "true" : "false", children: jsx(
|
|
1666
|
+
}, disabled: isDisabled, "aria-label": "Align Center", "aria-pressed": isActive ? "true" : "false", children: jsx(List, { className: "w-4 h-4" }) }, toolKey));
|
|
1668
1667
|
case "alignRight":
|
|
1669
|
-
return (jsx(Button, { size: "sm", color: "
|
|
1668
|
+
return (jsx(Button, { size: "sm", color: "mono", variant: "soft", iconOnly: true, className: cn(themeStyles.toolbarButtonStyle), "data-state": isActive ? "active" : "inactive", onMouseDown: handleMouseDown, onClick: (event) => {
|
|
1670
1669
|
event.preventDefault();
|
|
1671
1670
|
event.stopPropagation();
|
|
1672
1671
|
handleAlign("right");
|
|
1673
|
-
}, disabled: isDisabled, "aria-label": "Align Right", "aria-pressed": isActive ? "true" : "false", children: jsx(
|
|
1672
|
+
}, disabled: isDisabled, "aria-label": "Align Right", "aria-pressed": isActive ? "true" : "false", children: jsx(TextAlignRight, { className: "w-4 h-4" }) }, toolKey));
|
|
1674
1673
|
case "undo":
|
|
1675
|
-
return (jsx(Button, { size: "sm", color: "
|
|
1674
|
+
return (jsx(Button, { size: "sm", color: "mono", variant: "soft", iconOnly: true, className: cn(themeStyles.toolbarButtonStyle), onMouseDown: handleMouseDown, onClick: handleUndo, disabled: isDisabled, "aria-label": "Undo", children: jsx(ArrowUUpLeft, { className: "w-4 h-4" }) }, toolKey));
|
|
1676
1675
|
case "redo":
|
|
1677
|
-
return (jsx(Button, { size: "sm", color: "
|
|
1676
|
+
return (jsx(Button, { size: "sm", color: "mono", variant: "soft", iconOnly: true, className: cn(themeStyles.toolbarButtonStyle), onMouseDown: handleMouseDown, onClick: handleRedo, disabled: isDisabled, "aria-label": "Redo", children: jsx(ArrowUUpRight, { className: "w-4 h-4" }) }, toolKey));
|
|
1678
1677
|
case "separator":
|
|
1679
1678
|
return jsx("div", { className: themeStyles.separatorStyle }, toolKey);
|
|
1680
1679
|
default:
|
|
@@ -14,6 +14,8 @@ export interface SelectContextValue<T = any> extends UseSelectStateReturn<T> {
|
|
|
14
14
|
theme: SelectThemeOverrides;
|
|
15
15
|
/** Whether search is enabled */
|
|
16
16
|
searchable: boolean;
|
|
17
|
+
/** Placeholder text for the search input */
|
|
18
|
+
searchPlaceholder: string;
|
|
17
19
|
/** Whether typeahead is enabled */
|
|
18
20
|
enableTypeahead: boolean;
|
|
19
21
|
/** Button ref (alias for triggerRef for backward compatibility) */
|
|
@@ -44,6 +46,8 @@ export interface SelectProviderProps<T = any> {
|
|
|
44
46
|
theme?: SelectThemeOverrides;
|
|
45
47
|
/** Whether search is enabled */
|
|
46
48
|
searchable?: boolean;
|
|
49
|
+
/** Placeholder text for the search input */
|
|
50
|
+
searchPlaceholder?: string;
|
|
47
51
|
/** Whether typeahead is enabled */
|
|
48
52
|
enableTypeahead?: boolean;
|
|
49
53
|
}
|
|
@@ -68,7 +72,7 @@ export interface SelectProviderProps<T = any> {
|
|
|
68
72
|
* </SelectProvider>
|
|
69
73
|
* ```
|
|
70
74
|
*/
|
|
71
|
-
export declare function SelectProvider<T = any>({ children, selectState, size, componentState, theme: themeOverrides, searchable, enableTypeahead, }: SelectProviderProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
75
|
+
export declare function SelectProvider<T = any>({ children, selectState, size, componentState, theme: themeOverrides, searchable, searchPlaceholder, enableTypeahead, }: SelectProviderProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
72
76
|
/**
|
|
73
77
|
* Select Button Component
|
|
74
78
|
*/
|
|
@@ -8,7 +8,7 @@ import { FormLabel } from '../FormLabel/FormLabel.js';
|
|
|
8
8
|
import { Input } from '../Input/Input.js';
|
|
9
9
|
import '../Input/Input.theme.js';
|
|
10
10
|
import { createDropdownAnimations } from './Select.animations.js';
|
|
11
|
-
import {
|
|
11
|
+
import { CaretUpDown, Plus, MagnifyingGlass, Check } from '@phosphor-icons/react';
|
|
12
12
|
import { useSelectPortal } from '../../../hooks/useSelectPortal.js';
|
|
13
13
|
import { cn } from '../../../utils/cn.js';
|
|
14
14
|
import { isValidTypeaheadChar, findNextMatchingOption, TYPEAHEAD_TIMEOUT_MS } from '../../../utils/typeaheadUtils.js';
|
|
@@ -54,7 +54,7 @@ const useSelectContext = () => {
|
|
|
54
54
|
* </SelectProvider>
|
|
55
55
|
* ```
|
|
56
56
|
*/
|
|
57
|
-
function SelectProvider({ children, selectState, size = "md", componentState = "default", theme: themeOverrides, searchable = false, enableTypeahead = true, }) {
|
|
57
|
+
function SelectProvider({ children, selectState, size = "md", componentState = "default", theme: themeOverrides, searchable = false, searchPlaceholder = "Search...", enableTypeahead = true, }) {
|
|
58
58
|
const theme = useMemo(() => ({ ...selectTheme, ...(themeOverrides || {}) }), [themeOverrides]);
|
|
59
59
|
// Cast triggerRef to buttonRef for backward compatibility
|
|
60
60
|
const buttonRef = selectState.triggerRef;
|
|
@@ -64,9 +64,10 @@ function SelectProvider({ children, selectState, size = "md", componentState = "
|
|
|
64
64
|
state: componentState,
|
|
65
65
|
theme,
|
|
66
66
|
searchable,
|
|
67
|
+
searchPlaceholder,
|
|
67
68
|
enableTypeahead,
|
|
68
69
|
buttonRef,
|
|
69
|
-
}), [selectState, size, componentState, theme, searchable, enableTypeahead, buttonRef]);
|
|
70
|
+
}), [selectState, size, componentState, theme, searchable, searchPlaceholder, enableTypeahead, buttonRef]);
|
|
70
71
|
return (jsx(SelectContext.Provider, { value: contextValue, children: children }));
|
|
71
72
|
}
|
|
72
73
|
// ============================================================================
|
|
@@ -94,7 +95,7 @@ const SelectButton = ({ id, disabled, isOpen, state = "default", size = "md", ic
|
|
|
94
95
|
? "text-sm"
|
|
95
96
|
: size === "lg"
|
|
96
97
|
? "text-base"
|
|
97
|
-
: "text-sm"} text-[var(--color-text-muted)] shrink-0
|
|
98
|
+
: "text-sm"} text-[var(--color-text-muted)] shrink-0`;
|
|
98
99
|
// Use either the themed focus state or directly apply the focus classes if the theme is not working
|
|
99
100
|
const activeFocusState = isOpen
|
|
100
101
|
? focusStateStyle ||
|
|
@@ -111,7 +112,7 @@ const SelectOptions = ({ isOpen, maxHeight = "15rem", className = "", onClose, c
|
|
|
111
112
|
// so a Select inside a Popover/Modal still reads as a higher plane.
|
|
112
113
|
const surfaceLevel = useSurfaceElevation({ baseRung: 5, offset: 2, elevation, lift });
|
|
113
114
|
const context = useSelectContext();
|
|
114
|
-
const { optionsRef, buttonRef, highlightedIndex, setHighlightedIndex, filteredOptions, searchable, searchValue, setSearchValue, enableTypeahead, typeaheadValue, setTypeaheadValue, typeaheadTimeoutRef, theme, selectOption, } = context;
|
|
115
|
+
const { optionsRef, buttonRef, highlightedIndex, setHighlightedIndex, filteredOptions, searchable, searchPlaceholder, searchValue, setSearchValue, enableTypeahead, typeaheadValue, setTypeaheadValue, typeaheadTimeoutRef, theme, selectOption, } = context;
|
|
115
116
|
// Use custom triggerRef if provided, otherwise fall back to buttonRef
|
|
116
117
|
const effectiveTriggerRef = customTriggerRef || buttonRef;
|
|
117
118
|
// Detect dark mode for portal content
|
|
@@ -283,7 +284,7 @@ const SelectOptions = ({ isOpen, maxHeight = "15rem", className = "", onClose, c
|
|
|
283
284
|
: {
|
|
284
285
|
maxHeight: searchable ? "none" : maxHeightValue,
|
|
285
286
|
}),
|
|
286
|
-
}, role: "listbox", "aria-labelledby": ariaLabelledby, tabIndex: -1, variants: animations, initial: "initial", animate: "visible", exit: "exit", children: jsxs(SurfaceProvider, { level: surfaceLevel, children: [searchable && (jsx(Input, { placeholder:
|
|
287
|
+
}, role: "listbox", "aria-labelledby": ariaLabelledby, tabIndex: -1, variants: animations, initial: "initial", animate: "visible", exit: "exit", children: jsxs(SurfaceProvider, { level: surfaceLevel, children: [searchable && (jsx(Input, { placeholder: searchPlaceholder, "aria-label": "Search options", value: searchValue, onChange: handleSearchChange, type: "search", ref: searchInputRef, iconStart: jsx(MagnifyingGlass, { weight: "bold", className: cn("size-4 text-[var(--color-text-secodary)] transition-opacity",
|
|
287
288
|
// Focus can't drive this — the search autofocuses on open, so it's
|
|
288
289
|
// always focused while visible. Emphasize on "actively searching" instead.
|
|
289
290
|
searchValue ? "opacity-100" : "opacity-70") }),
|
|
@@ -337,7 +338,7 @@ const SelectOption = ({ value, isSelected, disabled, className = "", onSelect, c
|
|
|
337
338
|
const createOptionStyle = isCreateOption ? createOptionStyleTheme : "";
|
|
338
339
|
return (jsxs("div", { className: cn(optionStyle, isSelected && selectedOptionStyle,
|
|
339
340
|
// Reserve room on the right so a long, truncated label never runs under the check.
|
|
340
|
-
isSelected && !isCreateOption && "pr-9", disabled && disabledOptionStyle, keyboardHighlightStyle, createOptionStyle, className), role: "option", "aria-selected": isSelected, "aria-disabled": disabled, "data-option-index": optionIndex, onMouseEnter: () => !disabled && setHighlightedIndex(optionIndex), onClick: handleClick, children: [children, isSelected && !isCreateOption && (jsx("span", { className: theme.checkIconStyle, children: jsx(
|
|
341
|
+
isSelected && !isCreateOption && "pr-9", disabled && disabledOptionStyle, keyboardHighlightStyle, createOptionStyle, className), role: "option", "aria-selected": isSelected, "aria-disabled": disabled, "data-option-index": optionIndex, onMouseEnter: () => !disabled && setHighlightedIndex(optionIndex), onClick: handleClick, children: [children, isSelected && !isCreateOption && (jsx("span", { className: theme.checkIconStyle, children: jsx(Check, { className: "size-4", weight: "bold" }) }))] }));
|
|
341
342
|
};
|
|
342
343
|
// ============================================================================
|
|
343
344
|
// Main Select Component
|
|
@@ -366,7 +367,7 @@ const SelectOption = ({ value, isSelected, disabled, className = "", onSelect, c
|
|
|
366
367
|
* />
|
|
367
368
|
* ```
|
|
368
369
|
*/
|
|
369
|
-
const SelectInner = ({ id, name, size = "md", state = "default", value, displayValue, placeholder = "Select an option", disabled = false, required = false, options = [], label, helperText, onChange, onFocus, onBlur, iconStart, iconEnd, contentStart, contentEnd, theme: themeOverrides, className = "", wrapperClassName = "", searchable = false, searchPlaceholder = "Search
|
|
370
|
+
const SelectInner = ({ id, name, size = "md", state = "default", value, displayValue, placeholder = "Select an option", disabled = false, required = false, options = [], label, helperText, onChange, onFocus, onBlur, iconStart, iconEnd, contentStart, contentEnd, theme: themeOverrides, className = "", wrapperClassName = "", searchable = false, searchPlaceholder = "Search...", portal = true, placement = "bottom-start", offset = 8, enableTypeahead = true, creatable = false, onCreateOption, createLabel, multiple = false, maxDisplayedChips = 3, elevation, lift, children, }, ref) => {
|
|
370
371
|
var _a;
|
|
371
372
|
// Merge theme with overrides
|
|
372
373
|
const theme = useMemo(() => ({ ...selectTheme, ...(themeOverrides || {}) }), [themeOverrides]);
|
|
@@ -426,7 +427,7 @@ const SelectInner = ({ id, name, size = "md", state = "default", value, displayV
|
|
|
426
427
|
// Container style
|
|
427
428
|
const containerStyle = theme.containerStyle || "";
|
|
428
429
|
// Default chevron icon if no iconEnd provided
|
|
429
|
-
const defaultChevronIcon = jsx(
|
|
430
|
+
const defaultChevronIcon = jsx(CaretUpDown, { className: "size-4" });
|
|
430
431
|
// Generate a unique ID if not provided
|
|
431
432
|
const generatedId = React__default.useId();
|
|
432
433
|
const selectId = id || generatedId;
|
|
@@ -434,7 +435,7 @@ const SelectInner = ({ id, name, size = "md", state = "default", value, displayV
|
|
|
434
435
|
// FormLabel id through to both so screen readers announce what the
|
|
435
436
|
// listbox (role="listbox") is for, not just the trigger button.
|
|
436
437
|
const labelId = label && typeof label === 'string' ? `${selectId}-label` : undefined;
|
|
437
|
-
return (jsx(SelectProvider, { selectState: selectState, size: size, componentState: state, theme: themeOverrides, searchable: searchable, enableTypeahead: enableTypeahead, children: jsxs("div", { ref: ref, className: cn("relative", containerStyle, wrapperClassName), children: [label && (typeof label === 'string' ? (jsx(FormLabel, { id: `${selectId}-label`, htmlFor: selectId, required: required, state: state, children: label })) : (label)), jsx(SelectButton, { id: selectId, disabled: disabled, isOpen: isOpen, state: state, size: size, iconStart: iconStart, iconEnd: iconEnd || defaultChevronIcon, contentStart: contentStart, contentEnd: contentEnd, onClick: handleButtonClick, onFocus: onFocus, onBlur: onBlur, onKeyDown: handleButtonKeyDown, className: className, "aria-labelledby": labelId, "aria-invalid": state === "invalid" || undefined, "aria-describedby": helperText ? `${selectId}-helper` : undefined, children: jsx("span", { className: cn(multiple && selectedValues.length > 0
|
|
438
|
+
return (jsx(SelectProvider, { selectState: selectState, size: size, componentState: state, theme: themeOverrides, searchable: searchable, searchPlaceholder: searchPlaceholder, enableTypeahead: enableTypeahead, children: jsxs("div", { ref: ref, className: cn("relative", containerStyle, wrapperClassName), children: [label && (typeof label === 'string' ? (jsx(FormLabel, { id: `${selectId}-label`, htmlFor: selectId, required: required, state: state, children: label })) : (label)), jsx(SelectButton, { id: selectId, disabled: disabled, isOpen: isOpen, state: state, size: size, iconStart: iconStart, iconEnd: iconEnd || defaultChevronIcon, contentStart: contentStart, contentEnd: contentEnd, onClick: handleButtonClick, onFocus: onFocus, onBlur: onBlur, onKeyDown: handleButtonKeyDown, className: className, "aria-labelledby": labelId, "aria-invalid": state === "invalid" || undefined, "aria-describedby": helperText ? `${selectId}-helper` : undefined, children: jsx("span", { className: cn(multiple && selectedValues.length > 0
|
|
438
439
|
? "flex min-w-0"
|
|
439
440
|
: "block truncate", (multiple ? selectedValues.length > 0 : selectedOption)
|
|
440
441
|
? theme.valueTextStyle
|
|
@@ -448,7 +449,7 @@ const SelectInner = ({ id, name, size = "md", state = "default", value, displayV
|
|
|
448
449
|
const isSelected = multiple
|
|
449
450
|
? isValueSelected(option.value)
|
|
450
451
|
: option.value === selectedValue;
|
|
451
|
-
return (jsx(SelectOption, { value: option.value, isSelected: isSelected, disabled: option.disabled || false, children: isCreateOption ? (jsxs("span", { className: "flex items-center gap-2", children: [jsx(
|
|
452
|
+
return (jsx(SelectOption, { value: option.value, isSelected: isSelected, disabled: option.disabled || false, children: isCreateOption ? (jsxs("span", { className: "flex items-center gap-2", children: [jsx(Plus, { className: "size-4 shrink-0" }), jsx("span", { className: "block truncate", children: option.label })] })) : (
|
|
452
453
|
// The selected check is rendered by SelectOption itself (single +
|
|
453
454
|
// multiple), so the call site only supplies the label.
|
|
454
455
|
jsx("span", { className: "block truncate", children: option.label })) }, option.id));
|
|
@@ -30,13 +30,13 @@ const selectTheme = {
|
|
|
30
30
|
// Hover state variants - inherited from common form theme
|
|
31
31
|
hoverStates: formsBaseTheme.hoverStates,
|
|
32
32
|
// Options container style - Uses position: fixed for proper scroll behavior with standardized z-index
|
|
33
|
-
// Width is controlled by trigger size via estimatedWidth parameter
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
// Width is controlled by trigger size via estimatedWidth parameter.
|
|
34
|
+
// Padding, radius and border all come from the shared base — only the min-width is Select's own.
|
|
35
|
+
optionsContainerStyle: formsBaseTheme.dropdownStyles.container + " min-w-[8rem]",
|
|
36
36
|
// Search input style
|
|
37
37
|
searchInputStyle: "group",
|
|
38
38
|
// Individual option style
|
|
39
|
-
optionStyle: formsBaseTheme.dropdownStyles.option
|
|
39
|
+
optionStyle: formsBaseTheme.dropdownStyles.option,
|
|
40
40
|
// Selected option style
|
|
41
41
|
selectedOptionStyle: formsBaseTheme.dropdownStyles.optionSelected,
|
|
42
42
|
// Highlighted option style (keyboard navigation)
|
|
@@ -75,7 +75,10 @@ export interface SelectProps<T = unknown> extends SelectBaseProps {
|
|
|
75
75
|
theme?: SelectThemeOverrides;
|
|
76
76
|
/** Whether the select is searchable */
|
|
77
77
|
searchable?: boolean;
|
|
78
|
-
/**
|
|
78
|
+
/**
|
|
79
|
+
* Placeholder text for the search input shown when `searchable` is true.
|
|
80
|
+
* @default "Search..."
|
|
81
|
+
*/
|
|
79
82
|
searchPlaceholder?: string;
|
|
80
83
|
/**
|
|
81
84
|
* Whether to render the dropdown in a portal to `document.body` (default: true).
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export declare const cardVariants: Variants;
|
|
1
|
+
export declare const cardVariants: import("motion-dom").Variants;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
};
|
|
1
|
+
import { createPressVariants } from '../../core/shared/interaction.animations.js';
|
|
2
|
+
|
|
3
|
+
// Shared press physics (fast tween in, stiff spring out) — see
|
|
4
|
+
// core/shared/interaction.animations.ts. Wire as `animate="rest"` +
|
|
5
|
+
// `whileTap="press"`.
|
|
6
|
+
const cardVariants = createPressVariants(0.98);
|
|
8
7
|
|
|
9
8
|
export { cardVariants };
|
|
@@ -60,7 +60,7 @@ const SelectableCardRoot = React__default.forwardRef(({ value, disabled: cardDis
|
|
|
60
60
|
: "checkbox";
|
|
61
61
|
const animated = !shouldReduceMotion && !isDisabled;
|
|
62
62
|
const motionProps = animated
|
|
63
|
-
? { variants: cardVariants,
|
|
63
|
+
? { variants: cardVariants, animate: "rest", whileTap: "press" }
|
|
64
64
|
: {};
|
|
65
65
|
const indicatorNode = resolvedIndicator !== "none" && (jsx("div", { className: cn(theme.indicator, "pointer-events-none"), "aria-hidden": "true", children: resolvedIndicator === "radio" ? (jsx(Radio, { value: value, checked: isSelected, onChange: () => { }, state: isDisabled ? "disabled" : "default", size: indicatorSize })) : (jsx(Checkbox, { value: value, checked: isSelected, onChange: () => { }, state: isDisabled ? "disabled" : "default", size: indicatorSize })) }));
|
|
66
66
|
return (jsxs(motion.div, { ref: ref, role: role, "aria-checked": isSelected, "aria-disabled": isDisabled || undefined, tabIndex: isDisabled ? -1 : 0, "data-selected": isSelected, "data-disabled": isDisabled || undefined, className: cn(theme.card, (_a = theme.cardSizes) === null || _a === void 0 ? void 0 : _a[resolvedSize], isSelected && theme.selectedCard, isDisabled && theme.disabledCard, className), onClick: handleClick, onKeyDown: handleKeyDown, ...motionProps, ...props, children: [jsx("input", { type: inputType, id: inputId, name: isStandalone ? undefined : ctx === null || ctx === void 0 ? void 0 : ctx.name, value: value, checked: isSelected, disabled: isDisabled, onChange: () => { }, className: "sr-only", tabIndex: -1, "aria-hidden": true }), resolvedIndicatorPosition === "start" && indicatorNode, jsx("div", { className: theme.contentWrapper, children: children }), resolvedIndicatorPosition === "end" && indicatorNode] }));
|
|
@@ -155,7 +155,7 @@ const Signature = React__default.forwardRef(({ id, label, labelClassName, helper
|
|
|
155
155
|
// behavior is unchanged otherwise.
|
|
156
156
|
const displayedMessage = isInvalid && errorMessage ? errorMessage : helperText;
|
|
157
157
|
const messageId = `${signatureId}-message`;
|
|
158
|
-
return (jsxs("div", { className: cn(wrapperClasses, stateClass, wrapperClassName), children: [label && (typeof label === 'string' ? (jsx("div", { className: "mb-1", children: jsx(FormLabel, { htmlFor: signatureId, className: labelClassName, state: state, required: required, children: label }) })) : (label)), jsx("div", { className: cn(inputGroupClasses, sizeClasses, stateClasses, className), style: { width, height }, children: jsxs("div", { ref: ref, className: baseClasses, ...props, children: [jsx("canvas", { ref: canvasRef, id: signatureId, className: cn(theme.canvasStyle, customTheme.canvasStyle), tabIndex: isDisabled ? -1 : 0, onMouseDown: startDrawing, onMouseMove: draw, onMouseUp: stopDrawing, onMouseLeave: stopDrawing, onTouchStart: startDrawing, onTouchMove: draw, onTouchEnd: stopDrawing, "aria-label": typeof label === 'string' ? label : 'Signature canvas', "aria-required": required, "aria-invalid": isInvalid, "aria-disabled": isDisabled, "aria-describedby": displayedMessage ? messageId : undefined }), isEmpty && placeholder && !isDisabled && (jsx("div", { className: cn(theme.placeholderStyle, customTheme.placeholderStyle), children: placeholder })), showControls && !isDisabled && (jsxs("div", { className: cn(theme.controlsStyle, customTheme.controlsStyle), children: [jsx(Button, { size: "sm", variant: "outline", color: '
|
|
158
|
+
return (jsxs("div", { className: cn(wrapperClasses, stateClass, wrapperClassName), children: [label && (typeof label === 'string' ? (jsx("div", { className: "mb-1", children: jsx(FormLabel, { htmlFor: signatureId, className: labelClassName, state: state, required: required, children: label }) })) : (label)), jsx("div", { className: cn(inputGroupClasses, sizeClasses, stateClasses, className), style: { width, height }, children: jsxs("div", { ref: ref, className: baseClasses, ...props, children: [jsx("canvas", { ref: canvasRef, id: signatureId, className: cn(theme.canvasStyle, customTheme.canvasStyle), tabIndex: isDisabled ? -1 : 0, onMouseDown: startDrawing, onMouseMove: draw, onMouseUp: stopDrawing, onMouseLeave: stopDrawing, onTouchStart: startDrawing, onTouchMove: draw, onTouchEnd: stopDrawing, "aria-label": typeof label === 'string' ? label : 'Signature canvas', "aria-required": required, "aria-invalid": isInvalid, "aria-disabled": isDisabled, "aria-describedby": displayedMessage ? messageId : undefined }), isEmpty && placeholder && !isDisabled && (jsx("div", { className: cn(theme.placeholderStyle, customTheme.placeholderStyle), children: placeholder })), showControls && !isDisabled && (jsxs("div", { className: cn(theme.controlsStyle, customTheme.controlsStyle), children: [jsx(Button, { size: "sm", variant: "outline", color: 'mono', onClick: clear, type: "button", children: "Clear" }), jsx(Button, { size: "sm", variant: "filled", onClick: save, disabled: isEmpty, type: "button", children: "Save" })] }))] }) }), displayedMessage && (typeof displayedMessage === 'string' ? (jsx("div", { id: messageId, role: isInvalid ? 'alert' : undefined, className: cn(helperTextClasses, helperTextClassName), children: displayedMessage })) : (displayedMessage))] }));
|
|
159
159
|
});
|
|
160
160
|
Signature.displayName = 'Signature';
|
|
161
161
|
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
3
|
import React__default, { useRef, useEffect, useState, useCallback, useMemo } from 'react';
|
|
4
|
+
import { useReducedMotion, motion } from 'motion/react';
|
|
5
|
+
import { createPressVariants } from '../../core/shared/interaction.animations.js';
|
|
4
6
|
import { FormLabel } from '../FormLabel/FormLabel.js';
|
|
7
|
+
import { Tooltip } from '../../core/Tooltip/Tooltip.js';
|
|
8
|
+
import '../../core/Tooltip/Tooltip.animations.js';
|
|
5
9
|
import { sliderTheme } from './Slider.theme.js';
|
|
6
10
|
import { cn } from '../../../utils/cn.js';
|
|
7
11
|
|
|
12
|
+
// Shared press physics (fast tween in, stiff spring out) with a hover lift,
|
|
13
|
+
// wired as `animate="rest"` + `whileTap="press"` + `whileHover="hover"`.
|
|
14
|
+
const thumbPressVariants = createPressVariants(0.95, 1.12);
|
|
8
15
|
const Slider = React__default.forwardRef(({ state = "default", className = "", label, labelClassName = "", helperText, helperTextClassName = "", wrapperClassName = "", min = 0, max = 100, step = 1, value, defaultValue, onChange, onChangeCommitted, showValue = false, unit = "", showMinMax = false, showTicks = false, tickStep, range = false, iconStart, iconEnd, theme = {}, required = false, name, id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, "aria-describedby": ariaDescribedby, ...props }, ref) => {
|
|
9
16
|
var _a;
|
|
10
17
|
const trackRef = useRef(null);
|
|
@@ -22,6 +29,7 @@ const Slider = React__default.forwardRef(({ state = "default", className = "", l
|
|
|
22
29
|
}, []);
|
|
23
30
|
const generatedId = React__default.useId();
|
|
24
31
|
const sliderId = id || generatedId;
|
|
32
|
+
const shouldReduceMotion = useReducedMotion();
|
|
25
33
|
const helperTextId = typeof helperText === 'string' && helperText ? `${sliderId}-helper` : undefined;
|
|
26
34
|
// Handle controlled/uncontrolled value
|
|
27
35
|
const [internalValue, setInternalValue] = useState((_a = value !== null && value !== void 0 ? value : defaultValue) !== null && _a !== void 0 ? _a : (range ? [min, min] : min));
|
|
@@ -231,25 +239,30 @@ const Slider = React__default.forwardRef(({ state = "default", className = "", l
|
|
|
231
239
|
}
|
|
232
240
|
return `${currentValue}${unit}`;
|
|
233
241
|
};
|
|
234
|
-
|
|
235
|
-
return (jsxs("div", { className: cn(mergedTheme.wrapperStyle, wrapperClassName), ref: ref, ...props, children: [jsx("svg", { width: "0", height: "0", className: "absolute", "aria-hidden": "true", children: jsx("defs", { children: jsxs("filter", { id: filterId, children: [jsx("feGaussianBlur", { in: "SourceGraphic", stdDeviation: "1", result: "blur" }), jsx("feColorMatrix", { in: "blur", type: "matrix", values: "1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -7", result: "goo" }), jsx("feComposite", { in: "SourceGraphic", in2: "goo", operator: "atop" })] }) }) }), label && (typeof label === 'string' ? (jsx(FormLabel, { htmlFor: sliderId, state: state, required: required, className: cn(mergedTheme.labelStyle, labelClassName), children: label })) : (label)), jsxs("div", { className: "flex items-center gap-4", children: [iconStart && (jsx("div", { className: "flex-shrink-0 text-[var(--color-text-muted)]", children: iconStart })), showMinMax && (jsx("span", { className: cn(mergedTheme.minMaxLabelStyle), children: min })), jsxs("div", { className: cn(mergedTheme.rootStyle, className), "data-disabled": isDisabled || undefined, "data-invalid": isInvalid || undefined, "data-orientation": "horizontal", children: [jsxs("div", { ref: trackRef, className: mergedTheme.trackStyle, onPointerDown: handleTrackClick, role: "presentation", children: [jsx("div", { className: mergedTheme.rangeStyle, style: getFilledTrackStyle() }), showTicks &&
|
|
242
|
+
return (jsxs("div", { className: cn(mergedTheme.wrapperStyle, wrapperClassName), ref: ref, ...props, children: [label && (typeof label === 'string' ? (jsx(FormLabel, { htmlFor: sliderId, state: state, required: required, className: cn(mergedTheme.labelStyle, labelClassName), children: label })) : (label)), jsxs("div", { className: "flex items-center gap-4", children: [iconStart && (jsx("div", { className: "flex-shrink-0 text-[var(--color-text-muted)]", children: iconStart })), showMinMax && (jsx("span", { className: cn(mergedTheme.minMaxLabelStyle), children: min })), jsxs("div", { className: cn(mergedTheme.rootStyle, className), "data-disabled": isDisabled || undefined, "data-invalid": isInvalid || undefined, "data-orientation": "horizontal", children: [jsxs("div", { ref: trackRef, className: mergedTheme.trackStyle, onPointerDown: handleTrackClick, role: "presentation", children: [jsx("div", { className: mergedTheme.rangeStyle, style: getFilledTrackStyle() }), showTicks &&
|
|
236
243
|
ticks.map((tick) => {
|
|
237
244
|
const percentage = getPercentage(tick);
|
|
238
245
|
return (jsx("div", { className: mergedTheme.tickStyle, style: { left: `${percentage}%` } }, tick));
|
|
239
246
|
})] }), values.map((val, index) => {
|
|
240
247
|
const percentage = getPercentage(val);
|
|
241
|
-
return (
|
|
248
|
+
return (jsx(motion.div, { className: mergedTheme.thumbStyle, style: {
|
|
242
249
|
left: `${percentage}%`,
|
|
243
|
-
transform: "translate(-50%, -50%)",
|
|
244
250
|
position: "absolute",
|
|
245
251
|
top: "50%",
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
252
|
+
x: "-50%",
|
|
253
|
+
y: "-50%",
|
|
254
|
+
}, onPointerDown: (e) => handlePointerDown(e, index), onKeyDown: (e) => handleKeyDown(e, index), role: "slider", "aria-valuemin": min, "aria-valuemax": max, "aria-valuenow": val, "aria-orientation": "horizontal", "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : (range ? `Slider thumb ${index + 1}` : "Slider"), "aria-labelledby": ariaLabelledby, "aria-describedby": ariaDescribedby !== null && ariaDescribedby !== void 0 ? ariaDescribedby : helperTextId, "aria-invalid": isInvalid || undefined, tabIndex: isDisabled ? -1 : 0, "data-disabled": isDisabled || undefined, "data-invalid": isInvalid || undefined, ...(isDisabled || shouldReduceMotion
|
|
255
|
+
? {}
|
|
256
|
+
: {
|
|
257
|
+
variants: thumbPressVariants,
|
|
258
|
+
animate: "rest",
|
|
259
|
+
whileHover: "hover",
|
|
260
|
+
whileTap: "press",
|
|
261
|
+
}), children: jsx(Tooltip, { content: jsxs("span", { className: "whitespace-nowrap", children: [val, unit] }), isOpen: dragIndex === index, placement: "top", disabled: isDisabled, triggerClassName: "block w-full h-full",
|
|
262
|
+
// Thumb moves via left%/transform on every pointermove during
|
|
263
|
+
// a drag, with no scroll/resize event to key off — force the
|
|
264
|
+
// portal to recalc so it tracks the thumb.
|
|
265
|
+
recalcTrigger: val, children: jsx("div", { className: "w-full h-full", "aria-hidden": "true" }) }) }, index));
|
|
253
266
|
}), name && (jsx("input", { type: "hidden", name: name, value: Array.isArray(currentValue)
|
|
254
267
|
? currentValue.join(",")
|
|
255
268
|
: currentValue }))] }), showMinMax && (jsx("span", { className: cn(mergedTheme.minMaxLabelStyle), children: max })), showValue && (jsx("div", { className: cn(mergedTheme.valueDisplayStyle), children: formatValueDisplay() })), iconEnd && (jsx("div", { className: "flex-shrink-0 text-[var(--color-text-muted)]", children: iconEnd }))] }), helperText && (typeof helperText === 'string' ? (jsx("div", { id: helperTextId, className: cn(mergedTheme.helperTextStyle, helperTextClassName), children: helperText })) : (helperText))] }));
|
|
@@ -12,9 +12,15 @@ const sliderTheme = {
|
|
|
12
12
|
// Track (background)
|
|
13
13
|
trackStyle: "relative w-full h-2 grow rounded-full bg-[var(--color-surface-sunken)] overflow-hidden data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 data-[orientation=vertical]:w-2 data-[orientation=vertical]:h-full shadow-inner-real-sm",
|
|
14
14
|
// Range (filled portion) - rounded to match track clipping
|
|
15
|
-
rangeStyle: "absolute h-full bg-gradient-to-r from-[var(--color-primary-500)] to-[var(--color-primary-700)]
|
|
16
|
-
// Thumb (draggable handle)
|
|
17
|
-
|
|
15
|
+
rangeStyle: "absolute h-full bg-gradient-to-r from-[var(--color-primary-500)] to-[var(--color-primary-700)] rounded-full data-[disabled]:bg-[var(--color-background-disabled)] data-[invalid]:bg-[var(--color-danger)]",
|
|
16
|
+
// Thumb (draggable handle). Solid surface bg (backdrop-filter glitches in
|
|
17
|
+
// WebKit under 3D transforms); glass look = specular inset highlights +
|
|
18
|
+
// shadow-lg-strength drop shadow, with the white speculars dialed down in
|
|
19
|
+
// dark mode where they would read as a glowing rim.
|
|
20
|
+
thumbStyle: "block h-5 w-7 rounded-full p-0 bg-[var(--color-surface)] outline-[2px] outline-[var(--color-border)]/80 ring-0 " +
|
|
21
|
+
"shadow-[inset_1px_1px_0_rgba(255,255,255,0.45),inset_1px_3px_0_rgba(0,0,0,0.03),inset_0_0_14px_rgba(255,255,255,0.15),inset_-1px_-1px_0_rgba(0,0,0,0.06),0_10px_15px_-3px_rgba(0,0,0,0.1),0_4px_6px_-4px_rgba(0,0,0,0.1)] " +
|
|
22
|
+
"dark:shadow-[inset_1px_1px_0_rgba(255,255,255,0.12),inset_1px_3px_0_rgba(0,0,0,0.15),inset_0_0_14px_rgba(255,255,255,0.04),inset_-1px_-1px_0_rgba(0,0,0,0.35),0_10px_15px_-3px_rgba(0,0,0,0.45),0_4px_6px_-4px_rgba(0,0,0,0.45)] " +
|
|
23
|
+
"cursor-grab active:cursor-grabbing focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-border)] focus-visible:ring-offset-2 data-[disabled]:cursor-not-allowed data-[invalid]:focus-visible:ring-[var(--color-danger)]",
|
|
18
24
|
// Value display
|
|
19
25
|
valueDisplayStyle: "text-sm font-medium text-[var(--color-text-secondary)] w-fit min-w-12",
|
|
20
26
|
// Min/max labels
|
|
@@ -17,7 +17,7 @@ const switchTheme = {
|
|
|
17
17
|
// No `invalid` key: a switch is binary — on and off are both valid values, so there is
|
|
18
18
|
// nothing to validate. (See §9 carve-out: invalid only applies to controls with a value.)
|
|
19
19
|
trackStates: {
|
|
20
|
-
unchecked: "bg-[var(--color-
|
|
20
|
+
unchecked: "bg-[var(--color-mono-200)] dark:bg-[var(--color-mono-700)]",
|
|
21
21
|
checked: "bg-[var(--color-primary)]",
|
|
22
22
|
disabled: "bg-[var(--color-background-disabled)] cursor-not-allowed",
|
|
23
23
|
},
|
|
@@ -33,7 +33,7 @@ const timePickerTheme = {
|
|
|
33
33
|
// Placeholder text style - matches Select/Combobox placeholder styling
|
|
34
34
|
placeholderTextStyle: formsBaseTheme.placeholderStyle,
|
|
35
35
|
// Selected value text style
|
|
36
|
-
valueTextStyle: "text-[var(--color-text-primary)]
|
|
36
|
+
valueTextStyle: "text-[var(--color-text-primary)]",
|
|
37
37
|
// Clear button styles (positioned between left content and right icon)
|
|
38
38
|
clearButtonStyle: "absolute right-8 top-1/2 -translate-y-1/2 p-1 rounded text-[var(--color-text-muted)] hover:text-[var(--color-text-primary)] hover:bg-[var(--color-background-secondary)] transition-colors z-10",
|
|
39
39
|
// Dropdown container styles (TimePicker-specific)
|
|
@@ -49,8 +49,8 @@ const timePickerTheme = {
|
|
|
49
49
|
helperTextStyle: formsBaseTheme.helperText,
|
|
50
50
|
// Helper text state variants
|
|
51
51
|
helperTextStates: {
|
|
52
|
-
default: "text-[var(--color-text-muted)]
|
|
53
|
-
disabled: "text-[var(--color-text-disabled)]
|
|
52
|
+
default: "text-[var(--color-text-muted)]",
|
|
53
|
+
disabled: "text-[var(--color-text-disabled)]",
|
|
54
54
|
invalid: "text-[var(--color-danger)] dark:text-[var(--color-danger-400)]",
|
|
55
55
|
},
|
|
56
56
|
// ============================================
|
|
@@ -72,14 +72,13 @@ const timePickerTheme = {
|
|
|
72
72
|
footerStyle: "flex justify-end items-center gap-2 px-2 py-2 border-t border-[var(--color-border)] ",
|
|
73
73
|
// Inner input element style - transparent bg, no outline, tabular-nums for aligned digits
|
|
74
74
|
inputStyle: "bg-transparent outline-none flex-1 tabular-nums min-w-0 " +
|
|
75
|
-
"text-[var(--color-text-primary)] placeholder:text-[var(--color-text-placeholder)]
|
|
76
|
-
"dark:text-[var(--color-neutral-200)] dark:placeholder:text-[var(--color-neutral-500)]",
|
|
75
|
+
"text-[var(--color-text-primary)] placeholder:text-[var(--color-text-placeholder)]",
|
|
77
76
|
// AM/PM period toggle button
|
|
78
77
|
periodToggleStyle: "px-1.5 py-0.5 text-xs font-semibold rounded-md " +
|
|
79
78
|
"bg-[var(--color-surface-sunken)] text-[var(--color-text-primary)] " +
|
|
80
79
|
"hover:bg-[var(--color-surface-hover)] transition-colors cursor-pointer select-none " +
|
|
81
|
-
"dark:bg-[var(--color-
|
|
82
|
-
"dark:hover:bg-[var(--color-
|
|
80
|
+
"dark:bg-[var(--color-mono-700)] " +
|
|
81
|
+
"dark:hover:bg-[var(--color-mono-600)]",
|
|
83
82
|
};
|
|
84
83
|
|
|
85
84
|
export { timePickerTheme };
|
|
@@ -81,7 +81,7 @@ const TimePickerContent = ({ isOpen, onCancel, onSave, portal = true, placement
|
|
|
81
81
|
minWidth: `${position.width}px`,
|
|
82
82
|
}
|
|
83
83
|
: {}),
|
|
84
|
-
}, variants: animations, initial: "initial", animate: "visible", exit: "exit", onKeyDown: handleKeyDown, role: "dialog", "aria-modal": "true", "aria-label": "Select time", children: jsxs(SurfaceProvider, { level: surfaceLevel, children: [jsx("div", { className: cn(theme.wheelContainerStyle), style: { height: 200 }, children: children }), jsxs("div", { className: cn(theme.footerStyle), children: [jsx(Button, { size: "sm", variant: "outline", color: "
|
|
84
|
+
}, variants: animations, initial: "initial", animate: "visible", exit: "exit", onKeyDown: handleKeyDown, role: "dialog", "aria-modal": "true", "aria-label": "Select time", children: jsxs(SurfaceProvider, { level: surfaceLevel, children: [jsx("div", { className: cn(theme.wheelContainerStyle), style: { height: 200 }, children: children }), jsxs("div", { className: cn(theme.footerStyle), children: [jsx(Button, { size: "sm", variant: "outline", color: "mono", onClick: onCancel, "aria-label": "Cancel time selection", className: "flex-1", children: "Cancel" }), jsx(Button, { size: "sm", onClick: onSave, "aria-label": "Save selected time", className: "flex-1", children: "Save" })] })] }) })) }));
|
|
85
85
|
// Use portal if enabled and client-side - wrap with dark class for dark mode support
|
|
86
86
|
return portal && isClient
|
|
87
87
|
? createPortal(jsx("div", { "data-flikkui-portal": "", className: isDarkMode ? "dark" : undefined, children: contentElement }), document.body)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
3
|
import { useContext } from 'react';
|
|
4
|
-
import {
|
|
4
|
+
import { Clock, X, CaretUpDown } from '@phosphor-icons/react';
|
|
5
5
|
import { cn } from '../../../utils/cn.js';
|
|
6
6
|
import { TimePickerContext } from './TimePickerContext.js';
|
|
7
7
|
|
|
@@ -45,10 +45,10 @@ const TimePickerTrigger = ({ id, disabled, isOpen, state = 'default', size = 'md
|
|
|
45
45
|
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
46
46
|
setIsOpen(true);
|
|
47
47
|
}, className: cn(baseStyle, stateStyle, hoverStateStyle, activeFocusState, 'w-full items-center', className // User overrides take highest precedence
|
|
48
|
-
), children: [jsxs("div", { className: "relative flex-1", children: [jsx("input", { ref: inputRef, id: id, type: "text", inputMode: "numeric", value: inputValue, onChange: (e) => onInputChange(e.target.value), onFocus: onInputFocus, onKeyDown: onInputKeyDown, placeholder: placeholder, maxLength: 5, disabled: disabled, className: cn(inputStyle, sizeStyle, hasStartIcon && iconStartPadding), role: "combobox", "aria-expanded": isOpen, "aria-haspopup": "dialog", "aria-controls": dialogId, "aria-label": "Enter time", "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedby, autoComplete: "off" }), iconStart !== undefined ? (iconStart && jsx("div", { className: iconStartStyle, children: iconStart })) : (jsx("div", { className: iconStartStyle, children: jsx(
|
|
48
|
+
), children: [jsxs("div", { className: "relative flex-1", children: [jsx("input", { ref: inputRef, id: id, type: "text", inputMode: "numeric", value: inputValue, onChange: (e) => onInputChange(e.target.value), onFocus: onInputFocus, onKeyDown: onInputKeyDown, placeholder: placeholder, maxLength: 5, disabled: disabled, className: cn(inputStyle, sizeStyle, hasStartIcon && iconStartPadding), role: "combobox", "aria-expanded": isOpen, "aria-haspopup": "dialog", "aria-controls": dialogId, "aria-label": "Enter time", "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedby, autoComplete: "off" }), iconStart !== undefined ? (iconStart && jsx("div", { className: iconStartStyle, children: iconStart })) : (jsx("div", { className: iconStartStyle, children: jsx(Clock, { className: "h-4 w-4" }) }))] }), format === '12h' && (jsx("button", { type: "button", onClick: onPeriodToggle, disabled: disabled, className: cn(periodToggleStyle, "shrink-0"), "aria-label": `Toggle AM/PM, current: ${period}`, tabIndex: -1, children: period || 'AM' })), clearable && hasValue && !disabled && (jsx("button", { type: "button", onClick: (e) => {
|
|
49
49
|
e.stopPropagation();
|
|
50
50
|
onClear === null || onClear === void 0 ? void 0 : onClear();
|
|
51
|
-
}, className: "shrink-0 p-0.5 rounded text-[var(--color-text-muted)] hover:text-[var(--color-text-primary)] hover:bg-[var(--color-background-secondary)] transition-colors", "aria-label": "Clear time", tabIndex: -1, children: jsx(
|
|
51
|
+
}, className: "shrink-0 p-0.5 rounded text-[var(--color-text-muted)] hover:text-[var(--color-text-primary)] hover:bg-[var(--color-background-secondary)] transition-colors", "aria-label": "Clear time", tabIndex: -1, children: jsx(X, { className: "w-4 h-4" }) })), iconEnd !== undefined ? (iconEnd && (jsx("span", { className: "shrink-0 flex items-center pr-3 pointer-events-none text-[var(--color-text-muted)]", children: iconEnd }))) : (jsx("span", { className: "shrink-0 flex items-center pr-3 pointer-events-none text-[var(--color-text-muted)]", children: jsx(CaretUpDown, { className: "h-4 w-4" }) }))] }) }));
|
|
52
52
|
};
|
|
53
53
|
|
|
54
54
|
export { TimePickerTrigger };
|