@multiplatform.one/components 7.7.4 → 7.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/Accordion/index.cjs +4 -0
- package/dist/cjs/Accordion/index.native.js +5 -1
- package/dist/cjs/Accordion/index.native.js.map +1 -1
- package/dist/cjs/Alert/index.native.js.map +1 -1
- package/dist/cjs/AnimateHeight/index.cjs +29 -2
- package/dist/cjs/AnimateHeight/index.native.js +30 -2
- package/dist/cjs/AnimateHeight/index.native.js.map +1 -1
- package/dist/cjs/Avatar/getInitials.native.js.map +1 -1
- package/dist/cjs/Avatar/index.native.js.map +1 -1
- package/dist/cjs/Badge/index.native.js.map +1 -1
- package/dist/cjs/Button.native.js.map +1 -1
- package/dist/cjs/Card.cjs +7 -1
- package/dist/cjs/Card.native.js +11 -1
- package/dist/cjs/Card.native.js.map +1 -1
- package/dist/cjs/CardFooter.cjs +1 -0
- package/dist/cjs/CardFooter.native.js +1 -0
- package/dist/cjs/CardFooter.native.js.map +1 -1
- package/dist/cjs/CardHeader.native.js.map +1 -1
- package/dist/cjs/Carousel/index.native.js +1 -1
- package/dist/cjs/Carousel/index.native.js.map +1 -1
- package/dist/cjs/Chip/index.native.js.map +1 -1
- package/dist/cjs/Collapsible.cjs +48 -0
- package/dist/cjs/Collapsible.native.js +56 -0
- package/dist/cjs/Collapsible.native.js.map +1 -0
- package/dist/cjs/ContextMenu/index.native.js.map +1 -1
- package/dist/cjs/CopyField/index.cjs +6 -1
- package/dist/cjs/CopyField/index.native.js +6 -1
- package/dist/cjs/CopyField/index.native.js.map +1 -1
- package/dist/cjs/DotIndicator/index.native.js.map +1 -1
- package/dist/cjs/DropdownMenu/index.cjs +31 -1
- package/dist/cjs/DropdownMenu/index.native.js +31 -1
- package/dist/cjs/DropdownMenu/index.native.js.map +1 -1
- package/dist/cjs/ErrorBoundary/index.native.js.map +1 -1
- package/dist/cjs/Heading.native.js.map +1 -1
- package/dist/cjs/Meter/index.cjs +12 -5
- package/dist/cjs/Meter/index.native.js +13 -6
- package/dist/cjs/Meter/index.native.js.map +1 -1
- package/dist/cjs/Meter/meter.native.js.map +1 -1
- package/dist/cjs/Pagination.cjs +28 -9
- package/dist/cjs/Pagination.native.js +29 -10
- package/dist/cjs/Pagination.native.js.map +1 -1
- package/dist/cjs/ProgressSteps/index.native.js.map +1 -1
- package/dist/cjs/Quote/index.native.js.map +1 -1
- package/dist/cjs/Separator/index.native.js.map +1 -1
- package/dist/cjs/SheetModal/detents.native.js.map +1 -1
- package/dist/cjs/Skeleton/index.native.js.map +1 -1
- package/dist/cjs/SkipLink/index.native.js.map +1 -1
- package/dist/cjs/SortableList/SortableHandle.native.js.map +1 -1
- package/dist/cjs/SortableList/index.native.js.map +1 -1
- package/dist/cjs/SortableList/useSortableRows.native.js.map +1 -1
- package/dist/cjs/Tabs/index.cjs +145 -91
- package/dist/cjs/Tabs/index.native.js +187 -123
- package/dist/cjs/Tabs/index.native.js.map +1 -1
- package/dist/cjs/Text.native.js.map +1 -1
- package/dist/cjs/Toast/index.cjs +53 -2
- package/dist/cjs/Toast/index.native.js +55 -2
- package/dist/cjs/Toast/index.native.js.map +1 -1
- package/dist/cjs/Toast/store.native.js.map +1 -1
- package/dist/cjs/Tooltip/nativePress.native.js.map +1 -1
- package/dist/cjs/Tooltip/tooltipShared.native.js.map +1 -1
- package/dist/cjs/TreeSelect/index.native.js +1 -1
- package/dist/cjs/TreeSelect/index.native.js.map +1 -1
- package/dist/cjs/TreeSelect/treeSelectModel.native.js.map +1 -1
- package/dist/cjs/Video/PlayerChrome.native.js.map +1 -1
- package/dist/cjs/Video/VideoFrame.native.js.map +1 -1
- package/dist/cjs/Video/types.native.js.map +1 -1
- package/dist/cjs/Wheel/index.native.js.map +1 -1
- package/dist/cjs/Wizard/index.native.js +2 -2
- package/dist/cjs/Wizard/index.native.js.map +1 -1
- package/dist/cjs/actions/ActionBar.native.js.map +1 -1
- package/dist/cjs/actions/DestructiveAction.cjs +7 -13
- package/dist/cjs/actions/DestructiveAction.native.js +7 -15
- package/dist/cjs/actions/DestructiveAction.native.js.map +1 -1
- package/dist/cjs/actions/devWarn.native.js.map +1 -1
- package/dist/cjs/actions/index.native.js.map +1 -1
- package/dist/cjs/actions/severity.native.js.map +1 -1
- package/dist/cjs/charts/Axis.cjs +5 -0
- package/dist/cjs/charts/Axis.native.js +5 -0
- package/dist/cjs/charts/Axis.native.js.map +1 -1
- package/dist/cjs/charts/BarChart.cjs +71 -57
- package/dist/cjs/charts/BarChart.native.js +81 -67
- package/dist/cjs/charts/BarChart.native.js.map +1 -1
- package/dist/cjs/charts/ChartDataView.cjs +212 -0
- package/dist/cjs/charts/ChartDataView.native.js +224 -0
- package/dist/cjs/charts/ChartDataView.native.js.map +1 -0
- package/dist/cjs/charts/ChartSurface.cjs +5 -1
- package/dist/cjs/charts/ChartSurface.native.js +5 -1
- package/dist/cjs/charts/ChartSurface.native.js.map +1 -1
- package/dist/cjs/charts/LineChart.cjs +81 -67
- package/dist/cjs/charts/LineChart.native.js +94 -80
- package/dist/cjs/charts/LineChart.native.js.map +1 -1
- package/dist/cjs/charts/PieChart.cjs +98 -73
- package/dist/cjs/charts/PieChart.native.js +109 -84
- package/dist/cjs/charts/PieChart.native.js.map +1 -1
- package/dist/cjs/charts/Sparkline.cjs +10 -1
- package/dist/cjs/charts/Sparkline.native.js +10 -1
- package/dist/cjs/charts/Sparkline.native.js.map +1 -1
- package/dist/cjs/charts/accessibility.cjs +4 -0
- package/dist/cjs/charts/accessibility.native.js +7 -0
- package/dist/cjs/charts/accessibility.native.js.map +1 -1
- package/dist/cjs/charts/composeChart.native.js.map +1 -1
- package/dist/cjs/charts/index.cjs +3 -1
- package/dist/cjs/charts/index.native.js +2 -0
- package/dist/cjs/charts/index.native.js.map +1 -1
- package/dist/cjs/charts/math.cjs +16 -0
- package/dist/cjs/charts/math.native.js +18 -0
- package/dist/cjs/charts/math.native.js.map +1 -1
- package/dist/cjs/charts/series.cjs +49 -7
- package/dist/cjs/charts/series.native.js +53 -11
- package/dist/cjs/charts/series.native.js.map +1 -1
- package/dist/cjs/charts/svg.cjs +46 -3
- package/dist/cjs/charts/svg.native.js +46 -3
- package/dist/cjs/charts/svg.native.js.map +1 -1
- package/dist/cjs/charts/types.native.js.map +1 -1
- package/dist/cjs/charts/useChartTheme.native.js.map +1 -1
- package/dist/cjs/code/Code/index.native.js.map +1 -1
- package/dist/cjs/code/CodeBlock/index.cjs +6 -1
- package/dist/cjs/code/CodeBlock/index.native.js +12 -7
- package/dist/cjs/code/CodeBlock/index.native.js.map +1 -1
- package/dist/cjs/code/HighlightedCode/index.native.js.map +1 -1
- package/dist/cjs/code/Highlighter/index.native.js.map +1 -1
- package/dist/cjs/code/Pre/index.native.js.map +1 -1
- package/dist/cjs/code/index.native.js +5 -5
- package/dist/cjs/code/index.native.js.map +1 -1
- package/dist/cjs/componentColors.native.js.map +1 -1
- package/dist/cjs/feedback/ConfirmDialog.cjs +7 -21
- package/dist/cjs/feedback/ConfirmDialog.native.js +7 -22
- package/dist/cjs/feedback/ConfirmDialog.native.js.map +1 -1
- package/dist/cjs/feedback/NotifyHost.cjs +2 -1
- package/dist/cjs/feedback/NotifyHost.native.js +5 -4
- package/dist/cjs/feedback/NotifyHost.native.js.map +1 -1
- package/dist/cjs/feedback/copy.cjs +36 -4
- package/dist/cjs/feedback/copy.native.js +38 -4
- package/dist/cjs/feedback/copy.native.js.map +1 -1
- package/dist/cjs/feedback/index.cjs +1 -0
- package/dist/cjs/feedback/index.native.js +1 -0
- package/dist/cjs/feedback/index.native.js.map +1 -1
- package/dist/cjs/feedback/notify.cjs +1 -0
- package/dist/cjs/feedback/notify.native.js +1 -0
- package/dist/cjs/feedback/notify.native.js.map +1 -1
- package/dist/cjs/feedback/route.cjs +3 -0
- package/dist/cjs/feedback/route.native.js +3 -0
- package/dist/cjs/feedback/route.native.js.map +1 -1
- package/dist/cjs/feedback/store.cjs +6 -0
- package/dist/cjs/feedback/store.native.js +8 -0
- package/dist/cjs/feedback/store.native.js.map +1 -1
- package/dist/cjs/hooks/index.native.js +1 -1
- package/dist/cjs/hooks/index.native.js.map +1 -1
- package/dist/cjs/hooks/useClipboard.native.js.map +1 -1
- package/dist/cjs/hooks/useDocumentTitle.native.js.map +1 -1
- package/dist/cjs/icons/CheckRegular.native.js.map +1 -1
- package/dist/cjs/icons/MinusRegular.native.js.map +1 -1
- package/dist/cjs/icons/index.native.js.map +1 -1
- package/dist/cjs/icons/lucide.cjs +2 -1
- package/dist/cjs/icons/lucide.native.js +2 -1
- package/dist/cjs/icons/lucide.native.js.map +1 -1
- package/dist/cjs/icons/themed.native.js.map +1 -1
- package/dist/cjs/images/Image/ImageFrame.native.js +1 -1
- package/dist/cjs/images/Image/ImageFrame.native.js.map +1 -1
- package/dist/cjs/images/Image/index.native.js +1 -1
- package/dist/cjs/images/Image/shared.native.js +1 -1
- package/dist/cjs/images/Image/shared.native.js.map +1 -1
- package/dist/cjs/images/Image/types.native.js.map +1 -1
- package/dist/cjs/images/index.native.js.map +1 -1
- package/dist/cjs/index.native.js +29 -29
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/knobImmuneExports.cjs +0 -1
- package/dist/cjs/knobImmuneExports.native.js +0 -1
- package/dist/cjs/knobImmuneExports.native.js.map +1 -1
- package/dist/cjs/layouts/AsyncBoundary.native.js +2 -2
- package/dist/cjs/layouts/AsyncBoundary.native.js.map +1 -1
- package/dist/cjs/layouts/Debug/index.native.js.map +1 -1
- package/dist/cjs/layouts/EmptyState.native.js.map +1 -1
- package/dist/cjs/layouts/KeyboardAvoidingWrapper/behavior.native.js.map +1 -1
- package/dist/cjs/layouts/PageTemplates.native.js.map +1 -1
- package/dist/cjs/layouts/PaneScaffold.cjs +96 -41
- package/dist/cjs/layouts/PaneScaffold.native.js +97 -41
- package/dist/cjs/layouts/PaneScaffold.native.js.map +1 -1
- package/dist/cjs/layouts/SafeAreaWrapper/insets.native.js.map +1 -1
- package/dist/cjs/layouts/ViewSwitcher.native.js.map +1 -1
- package/dist/cjs/layouts/attachments.native.js +1 -1
- package/dist/cjs/layouts/attachments.native.js.map +1 -1
- package/dist/cjs/layouts/breadcrumbs.native.js.map +1 -1
- package/dist/cjs/layouts/index.cjs +2 -0
- package/dist/cjs/layouts/index.native.js +5 -3
- package/dist/cjs/layouts/index.native.js.map +1 -1
- package/dist/cjs/layouts/page.cjs +48 -7
- package/dist/cjs/layouts/page.native.js +50 -7
- package/dist/cjs/layouts/page.native.js.map +1 -1
- package/dist/cjs/layouts/pageHeadingScope.native.js.map +1 -1
- package/dist/cjs/layouts/sidebar.native.js.map +1 -1
- package/dist/cjs/layouts/tags.native.js +1 -1
- package/dist/cjs/layouts/tags.native.js.map +1 -1
- package/dist/cjs/layouts/timeline.native.js +2 -2
- package/dist/cjs/layouts/timeline.native.js.map +1 -1
- package/dist/cjs/layouts/toolbar.native.js.map +1 -1
- package/dist/cjs/shared/actionScan.native.js.map +1 -1
- package/dist/cjs/shared/i18n.native.js.map +1 -1
- package/dist/cjs/shared/t.native.js.map +1 -1
- package/dist/cjs/shared/textRidesText.native.js.map +1 -1
- package/dist/cjs/shared/useKeyboardInset.cjs +1 -19
- package/dist/cjs/shared/useKeyboardInset.native.js +3 -3
- package/dist/cjs/shared/useKeyboardInset.native.js.map +1 -1
- package/dist/cjs/shared/useReturnFocusOnClose.native.js.map +1 -1
- package/dist/cjs/surfaces.native.js +1 -1
- package/dist/cjs/surfaces.native.js.map +1 -1
- package/dist/cjs/tamagui.cjs +3 -2
- package/dist/cjs/tamagui.native.js +2 -1
- package/dist/cjs/tamagui.native.js.map +1 -1
- package/dist/cjs/testSetup.native.js.map +1 -1
- package/dist/cjs/utils/setTinted.native.js.map +1 -1
- package/dist/cjs/utils/unwrapText.native.js.map +1 -1
- package/dist/cjs/views/Calendar.native.js.map +1 -1
- package/dist/cjs/views/Dashboard.cjs +110 -17
- package/dist/cjs/views/Dashboard.native.js +152 -46
- package/dist/cjs/views/Dashboard.native.js.map +1 -1
- package/dist/cjs/views/Gantt.cjs +374 -91
- package/dist/cjs/views/Gantt.native.js +444 -95
- package/dist/cjs/views/Gantt.native.js.map +1 -1
- package/dist/cjs/views/ImageGrid.native.js +1 -1
- package/dist/cjs/views/ImageGrid.native.js.map +1 -1
- package/dist/cjs/views/List.native.js.map +1 -1
- package/dist/cjs/views/ReportBuilder.native.js +1 -1
- package/dist/cjs/views/ReportBuilder.native.js.map +1 -1
- package/dist/cjs/views/TreeView.native.js.map +1 -1
- package/dist/cjs/views/calendarMath.native.js.map +1 -1
- package/dist/cjs/views/ganttMath.cjs +91 -2
- package/dist/cjs/views/ganttMath.native.js +113 -3
- package/dist/cjs/views/ganttMath.native.js.map +1 -1
- package/dist/cjs/views/index.cjs +20 -1
- package/dist/cjs/views/index.native.js +21 -2
- package/dist/cjs/views/index.native.js.map +1 -1
- package/dist/cjs/views/kanbanDnd.native.js.map +1 -1
- package/dist/cjs/views/treeViewDnd.native.js.map +1 -1
- package/dist/cjs/views/treeViewLayout.native.js.map +1 -1
- package/dist/cjs/views/treeViewMotion.native.js.map +1 -1
- package/dist/esm/Accordion/index.mjs +4 -0
- package/dist/esm/Accordion/index.mjs.map +1 -1
- package/dist/esm/Accordion/index.native.js +4 -0
- package/dist/esm/Accordion/index.native.js.map +1 -1
- package/dist/esm/AnimateHeight/index.mjs +29 -2
- package/dist/esm/AnimateHeight/index.mjs.map +1 -1
- package/dist/esm/AnimateHeight/index.native.js +30 -2
- package/dist/esm/AnimateHeight/index.native.js.map +1 -1
- package/dist/esm/Avatar/getInitials.native.js.map +1 -1
- package/dist/esm/Avatar/index.native.js.map +1 -1
- package/dist/esm/Badge/index.native.js.map +1 -1
- package/dist/esm/Button.mjs.map +1 -1
- package/dist/esm/Button.native.js.map +1 -1
- package/dist/esm/Card.mjs +8 -2
- package/dist/esm/Card.mjs.map +1 -1
- package/dist/esm/Card.native.js +12 -2
- package/dist/esm/Card.native.js.map +1 -1
- package/dist/esm/CardFooter.mjs +1 -0
- package/dist/esm/CardFooter.mjs.map +1 -1
- package/dist/esm/CardFooter.native.js +1 -0
- package/dist/esm/CardFooter.native.js.map +1 -1
- package/dist/esm/Carousel/index.native.js.map +1 -1
- package/dist/esm/Chip/index.native.js.map +1 -1
- package/dist/esm/Collapsible.mjs +23 -0
- package/dist/esm/Collapsible.mjs.map +1 -0
- package/dist/esm/Collapsible.native.js +28 -0
- package/dist/esm/Collapsible.native.js.map +1 -0
- package/dist/esm/ContextMenu/index.native.js.map +1 -1
- package/dist/esm/CopyField/index.mjs +7 -2
- package/dist/esm/CopyField/index.mjs.map +1 -1
- package/dist/esm/CopyField/index.native.js +7 -2
- package/dist/esm/CopyField/index.native.js.map +1 -1
- package/dist/esm/DotIndicator/index.native.js.map +1 -1
- package/dist/esm/DropdownMenu/index.mjs +32 -2
- package/dist/esm/DropdownMenu/index.mjs.map +1 -1
- package/dist/esm/DropdownMenu/index.native.js +32 -2
- package/dist/esm/DropdownMenu/index.native.js.map +1 -1
- package/dist/esm/ErrorBoundary/index.native.js.map +1 -1
- package/dist/esm/Heading.native.js.map +1 -1
- package/dist/esm/Meter/index.mjs +12 -5
- package/dist/esm/Meter/index.mjs.map +1 -1
- package/dist/esm/Meter/index.native.js +12 -5
- package/dist/esm/Meter/index.native.js.map +1 -1
- package/dist/esm/Meter/meter.native.js.map +1 -1
- package/dist/esm/Pagination.mjs +28 -9
- package/dist/esm/Pagination.mjs.map +1 -1
- package/dist/esm/Pagination.native.js +28 -9
- package/dist/esm/Pagination.native.js.map +1 -1
- package/dist/esm/ProgressSteps/index.native.js.map +1 -1
- package/dist/esm/Quote/index.native.js.map +1 -1
- package/dist/esm/Separator/index.native.js.map +1 -1
- package/dist/esm/SheetModal/detents.native.js.map +1 -1
- package/dist/esm/Skeleton/index.native.js.map +1 -1
- package/dist/esm/SkipLink/index.native.js.map +1 -1
- package/dist/esm/SortableList/SortableHandle.native.js.map +1 -1
- package/dist/esm/SortableList/index.native.js.map +1 -1
- package/dist/esm/SortableList/useSortableRows.native.js.map +1 -1
- package/dist/esm/Tabs/index.mjs +145 -91
- package/dist/esm/Tabs/index.mjs.map +1 -1
- package/dist/esm/Tabs/index.native.js +187 -123
- package/dist/esm/Tabs/index.native.js.map +1 -1
- package/dist/esm/Text.native.js.map +1 -1
- package/dist/esm/Toast/index.mjs +52 -3
- package/dist/esm/Toast/index.mjs.map +1 -1
- package/dist/esm/Toast/index.native.js +54 -3
- package/dist/esm/Toast/index.native.js.map +1 -1
- package/dist/esm/Toast/store.native.js.map +1 -1
- package/dist/esm/Tooltip/nativePress.native.js.map +1 -1
- package/dist/esm/Tooltip/tooltipShared.native.js.map +1 -1
- package/dist/esm/TreeSelect/index.native.js.map +1 -1
- package/dist/esm/TreeSelect/treeSelectModel.native.js.map +1 -1
- package/dist/esm/Video/PlayerChrome.native.js.map +1 -1
- package/dist/esm/Video/VideoFrame.native.js.map +1 -1
- package/dist/esm/Video/types.native.js.map +1 -1
- package/dist/esm/Wheel/index.native.js.map +1 -1
- package/dist/esm/Wizard/index.native.js.map +1 -1
- package/dist/esm/actions/ActionBar.native.js.map +1 -1
- package/dist/esm/actions/DestructiveAction.mjs +8 -14
- package/dist/esm/actions/DestructiveAction.mjs.map +1 -1
- package/dist/esm/actions/DestructiveAction.native.js +8 -16
- package/dist/esm/actions/DestructiveAction.native.js.map +1 -1
- package/dist/esm/actions/devWarn.native.js.map +1 -1
- package/dist/esm/actions/index.native.js.map +1 -1
- package/dist/esm/actions/severity.native.js.map +1 -1
- package/dist/esm/charts/Axis.mjs +6 -1
- package/dist/esm/charts/Axis.mjs.map +1 -1
- package/dist/esm/charts/Axis.native.js +6 -1
- package/dist/esm/charts/Axis.native.js.map +1 -1
- package/dist/esm/charts/BarChart.mjs +72 -58
- package/dist/esm/charts/BarChart.mjs.map +1 -1
- package/dist/esm/charts/BarChart.native.js +82 -68
- package/dist/esm/charts/BarChart.native.js.map +1 -1
- package/dist/esm/charts/ChartDataView.mjs +185 -0
- package/dist/esm/charts/ChartDataView.mjs.map +1 -0
- package/dist/esm/charts/ChartDataView.native.js +194 -0
- package/dist/esm/charts/ChartDataView.native.js.map +1 -0
- package/dist/esm/charts/ChartSurface.mjs +5 -1
- package/dist/esm/charts/ChartSurface.mjs.map +1 -1
- package/dist/esm/charts/ChartSurface.native.js +5 -1
- package/dist/esm/charts/ChartSurface.native.js.map +1 -1
- package/dist/esm/charts/LineChart.mjs +82 -68
- package/dist/esm/charts/LineChart.mjs.map +1 -1
- package/dist/esm/charts/LineChart.native.js +95 -81
- package/dist/esm/charts/LineChart.native.js.map +1 -1
- package/dist/esm/charts/PieChart.mjs +100 -75
- package/dist/esm/charts/PieChart.mjs.map +1 -1
- package/dist/esm/charts/PieChart.native.js +111 -86
- package/dist/esm/charts/PieChart.native.js.map +1 -1
- package/dist/esm/charts/Sparkline.mjs +11 -2
- package/dist/esm/charts/Sparkline.mjs.map +1 -1
- package/dist/esm/charts/Sparkline.native.js +11 -2
- package/dist/esm/charts/Sparkline.native.js.map +1 -1
- package/dist/esm/charts/accessibility.mjs +4 -1
- package/dist/esm/charts/accessibility.mjs.map +1 -1
- package/dist/esm/charts/accessibility.native.js +7 -1
- package/dist/esm/charts/accessibility.native.js.map +1 -1
- package/dist/esm/charts/composeChart.native.js.map +1 -1
- package/dist/esm/charts/index.mjs +2 -1
- package/dist/esm/charts/index.mjs.map +1 -1
- package/dist/esm/charts/index.native.js +2 -1
- package/dist/esm/charts/index.native.js.map +1 -1
- package/dist/esm/charts/math.mjs +16 -1
- package/dist/esm/charts/math.mjs.map +1 -1
- package/dist/esm/charts/math.native.js +18 -1
- package/dist/esm/charts/math.native.js.map +1 -1
- package/dist/esm/charts/series.mjs +51 -9
- package/dist/esm/charts/series.mjs.map +1 -1
- package/dist/esm/charts/series.native.js +55 -13
- package/dist/esm/charts/series.native.js.map +1 -1
- package/dist/esm/charts/svg.mjs +40 -4
- package/dist/esm/charts/svg.mjs.map +1 -1
- package/dist/esm/charts/svg.native.js +40 -4
- package/dist/esm/charts/svg.native.js.map +1 -1
- package/dist/esm/charts/types.native.js.map +1 -1
- package/dist/esm/charts/useChartTheme.native.js.map +1 -1
- package/dist/esm/code/CodeBlock/index.mjs +7 -2
- package/dist/esm/code/CodeBlock/index.mjs.map +1 -1
- package/dist/esm/code/CodeBlock/index.native.js +7 -2
- package/dist/esm/code/CodeBlock/index.native.js.map +1 -1
- package/dist/esm/code/HighlightedCode/index.native.js.map +1 -1
- package/dist/esm/code/Highlighter/index.native.js.map +1 -1
- package/dist/esm/code/Pre/index.native.js.map +1 -1
- package/dist/esm/code/index.native.js.map +1 -1
- package/dist/esm/componentColors.native.js.map +1 -1
- package/dist/esm/feedback/ConfirmDialog.mjs +8 -22
- package/dist/esm/feedback/ConfirmDialog.mjs.map +1 -1
- package/dist/esm/feedback/ConfirmDialog.native.js +8 -23
- package/dist/esm/feedback/ConfirmDialog.native.js.map +1 -1
- package/dist/esm/feedback/NotifyHost.mjs +2 -1
- package/dist/esm/feedback/NotifyHost.mjs.map +1 -1
- package/dist/esm/feedback/NotifyHost.native.js +3 -2
- package/dist/esm/feedback/NotifyHost.native.js.map +1 -1
- package/dist/esm/feedback/copy.mjs +35 -4
- package/dist/esm/feedback/copy.mjs.map +1 -1
- package/dist/esm/feedback/copy.native.js +37 -4
- package/dist/esm/feedback/copy.native.js.map +1 -1
- package/dist/esm/feedback/index.mjs +2 -2
- package/dist/esm/feedback/index.mjs.map +1 -1
- package/dist/esm/feedback/index.native.js +2 -2
- package/dist/esm/feedback/index.native.js.map +1 -1
- package/dist/esm/feedback/notify.mjs +1 -0
- package/dist/esm/feedback/notify.mjs.map +1 -1
- package/dist/esm/feedback/notify.native.js +1 -0
- package/dist/esm/feedback/notify.native.js.map +1 -1
- package/dist/esm/feedback/route.mjs +3 -0
- package/dist/esm/feedback/route.mjs.map +1 -1
- package/dist/esm/feedback/route.native.js +3 -0
- package/dist/esm/feedback/route.native.js.map +1 -1
- package/dist/esm/feedback/store.mjs +6 -1
- package/dist/esm/feedback/store.mjs.map +1 -1
- package/dist/esm/feedback/store.native.js +8 -1
- package/dist/esm/feedback/store.native.js.map +1 -1
- package/dist/esm/hooks/index.native.js.map +1 -1
- package/dist/esm/hooks/useClipboard.native.js.map +1 -1
- package/dist/esm/hooks/useDocumentTitle.native.js.map +1 -1
- package/dist/esm/icons/CheckRegular.native.js.map +1 -1
- package/dist/esm/icons/MinusRegular.native.js.map +1 -1
- package/dist/esm/icons/index.native.js.map +1 -1
- package/dist/esm/icons/lucide.mjs +2 -2
- package/dist/esm/icons/lucide.mjs.map +1 -1
- package/dist/esm/icons/lucide.native.js +2 -2
- package/dist/esm/icons/lucide.native.js.map +1 -1
- package/dist/esm/icons/themed.native.js.map +1 -1
- package/dist/esm/images/Image/ImageFrame.native.js.map +1 -1
- package/dist/esm/images/Image/shared.native.js.map +1 -1
- package/dist/esm/images/Image/types.native.js.map +1 -1
- package/dist/esm/images/index.native.js.map +1 -1
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/knobImmuneExports.mjs +0 -1
- package/dist/esm/knobImmuneExports.mjs.map +1 -1
- package/dist/esm/knobImmuneExports.native.js +0 -1
- package/dist/esm/knobImmuneExports.native.js.map +1 -1
- package/dist/esm/layouts/AsyncBoundary.native.js.map +1 -1
- package/dist/esm/layouts/Debug/index.native.js.map +1 -1
- package/dist/esm/layouts/EmptyState.native.js.map +1 -1
- package/dist/esm/layouts/KeyboardAvoidingWrapper/behavior.native.js.map +1 -1
- package/dist/esm/layouts/PageTemplates.native.js.map +1 -1
- package/dist/esm/layouts/PaneScaffold.mjs +97 -42
- package/dist/esm/layouts/PaneScaffold.mjs.map +1 -1
- package/dist/esm/layouts/PaneScaffold.native.js +98 -42
- package/dist/esm/layouts/PaneScaffold.native.js.map +1 -1
- package/dist/esm/layouts/SafeAreaWrapper/insets.native.js.map +1 -1
- package/dist/esm/layouts/ViewSwitcher.native.js.map +1 -1
- package/dist/esm/layouts/attachments.native.js.map +1 -1
- package/dist/esm/layouts/breadcrumbs.native.js.map +1 -1
- package/dist/esm/layouts/index.mjs +2 -1
- package/dist/esm/layouts/index.mjs.map +1 -1
- package/dist/esm/layouts/index.native.js +2 -1
- package/dist/esm/layouts/index.native.js.map +1 -1
- package/dist/esm/layouts/page.mjs +49 -8
- package/dist/esm/layouts/page.mjs.map +1 -1
- package/dist/esm/layouts/page.native.js +51 -8
- package/dist/esm/layouts/page.native.js.map +1 -1
- package/dist/esm/layouts/pageHeadingScope.native.js.map +1 -1
- package/dist/esm/layouts/sidebar.native.js.map +1 -1
- package/dist/esm/layouts/tags.native.js.map +1 -1
- package/dist/esm/layouts/timeline.native.js.map +1 -1
- package/dist/esm/layouts/toolbar.native.js.map +1 -1
- package/dist/esm/shared/actionScan.native.js.map +1 -1
- package/dist/esm/shared/i18n.native.js.map +1 -1
- package/dist/esm/shared/t.native.js.map +1 -1
- package/dist/esm/shared/textRidesText.native.js.map +1 -1
- package/dist/esm/shared/useKeyboardInset.mjs +1 -19
- package/dist/esm/shared/useKeyboardInset.mjs.map +1 -1
- package/dist/esm/shared/useKeyboardInset.native.js.map +1 -1
- package/dist/esm/shared/useReturnFocusOnClose.native.js.map +1 -1
- package/dist/esm/surfaces.native.js.map +1 -1
- package/dist/esm/tamagui.mjs +2 -1
- package/dist/esm/tamagui.mjs.map +1 -1
- package/dist/esm/tamagui.native.js +2 -1
- package/dist/esm/tamagui.native.js.map +1 -1
- package/dist/esm/testSetup.native.js.map +1 -1
- package/dist/esm/utils/setTinted.native.js.map +1 -1
- package/dist/esm/utils/unwrapText.native.js.map +1 -1
- package/dist/esm/views/Calendar.native.js.map +1 -1
- package/dist/esm/views/Dashboard.mjs +112 -19
- package/dist/esm/views/Dashboard.mjs.map +1 -1
- package/dist/esm/views/Dashboard.native.js +153 -47
- package/dist/esm/views/Dashboard.native.js.map +1 -1
- package/dist/esm/views/Gantt.mjs +376 -93
- package/dist/esm/views/Gantt.mjs.map +1 -1
- package/dist/esm/views/Gantt.native.js +445 -96
- package/dist/esm/views/Gantt.native.js.map +1 -1
- package/dist/esm/views/ImageGrid.native.js.map +1 -1
- package/dist/esm/views/List.native.js.map +1 -1
- package/dist/esm/views/ReportBuilder.native.js.map +1 -1
- package/dist/esm/views/TreeView.native.js.map +1 -1
- package/dist/esm/views/calendarMath.native.js.map +1 -1
- package/dist/esm/views/ganttMath.mjs +84 -3
- package/dist/esm/views/ganttMath.mjs.map +1 -1
- package/dist/esm/views/ganttMath.native.js +106 -4
- package/dist/esm/views/ganttMath.native.js.map +1 -1
- package/dist/esm/views/index.mjs +2 -2
- package/dist/esm/views/index.mjs.map +1 -1
- package/dist/esm/views/index.native.js +2 -2
- package/dist/esm/views/index.native.js.map +1 -1
- package/dist/esm/views/kanbanDnd.native.js.map +1 -1
- package/dist/esm/views/treeViewDnd.native.js.map +1 -1
- package/dist/esm/views/treeViewLayout.native.js.map +1 -1
- package/dist/esm/views/treeViewMotion.native.js.map +1 -1
- package/dist/jsx/Accordion/index.mjs +4 -0
- package/dist/jsx/Accordion/index.mjs.map +1 -1
- package/dist/jsx/Accordion/index.native.js +4 -0
- package/dist/jsx/Accordion/index.native.js.map +1 -1
- package/dist/jsx/AnimateHeight/index.mjs +29 -2
- package/dist/jsx/AnimateHeight/index.mjs.map +1 -1
- package/dist/jsx/AnimateHeight/index.native.js +30 -2
- package/dist/jsx/AnimateHeight/index.native.js.map +1 -1
- package/dist/jsx/Button.mjs.map +1 -1
- package/dist/jsx/Button.native.js.map +1 -1
- package/dist/jsx/Card.mjs +8 -2
- package/dist/jsx/Card.mjs.map +1 -1
- package/dist/jsx/Card.native.js +11 -1
- package/dist/jsx/Card.native.js.map +1 -1
- package/dist/jsx/CardFooter.mjs +1 -0
- package/dist/jsx/CardFooter.mjs.map +1 -1
- package/dist/jsx/CardFooter.native.js +1 -0
- package/dist/jsx/CardFooter.native.js.map +1 -1
- package/dist/jsx/Collapsible.mjs +23 -0
- package/dist/jsx/Collapsible.mjs.map +1 -0
- package/dist/jsx/Collapsible.native.js +56 -0
- package/dist/jsx/Collapsible.native.js.map +1 -0
- package/dist/jsx/CopyField/index.mjs +7 -2
- package/dist/jsx/CopyField/index.mjs.map +1 -1
- package/dist/jsx/CopyField/index.native.js +6 -1
- package/dist/jsx/CopyField/index.native.js.map +1 -1
- package/dist/jsx/DropdownMenu/index.mjs +32 -2
- package/dist/jsx/DropdownMenu/index.mjs.map +1 -1
- package/dist/jsx/DropdownMenu/index.native.js +31 -1
- package/dist/jsx/DropdownMenu/index.native.js.map +1 -1
- package/dist/jsx/Meter/index.mjs +12 -5
- package/dist/jsx/Meter/index.mjs.map +1 -1
- package/dist/jsx/Meter/index.native.js +12 -5
- package/dist/jsx/Meter/index.native.js.map +1 -1
- package/dist/jsx/Pagination.mjs +28 -9
- package/dist/jsx/Pagination.mjs.map +1 -1
- package/dist/jsx/Pagination.native.js +28 -9
- package/dist/jsx/Pagination.native.js.map +1 -1
- package/dist/jsx/Tabs/index.mjs +145 -91
- package/dist/jsx/Tabs/index.mjs.map +1 -1
- package/dist/jsx/Tabs/index.native.js +187 -123
- package/dist/jsx/Tabs/index.native.js.map +1 -1
- package/dist/jsx/Toast/index.mjs +52 -3
- package/dist/jsx/Toast/index.mjs.map +1 -1
- package/dist/jsx/Toast/index.native.js +55 -2
- package/dist/jsx/Toast/index.native.js.map +1 -1
- package/dist/jsx/actions/DestructiveAction.mjs +8 -14
- package/dist/jsx/actions/DestructiveAction.mjs.map +1 -1
- package/dist/jsx/actions/DestructiveAction.native.js +7 -15
- package/dist/jsx/actions/DestructiveAction.native.js.map +1 -1
- package/dist/jsx/charts/Axis.mjs +6 -1
- package/dist/jsx/charts/Axis.mjs.map +1 -1
- package/dist/jsx/charts/Axis.native.js +5 -0
- package/dist/jsx/charts/Axis.native.js.map +1 -1
- package/dist/jsx/charts/BarChart.mjs +72 -58
- package/dist/jsx/charts/BarChart.mjs.map +1 -1
- package/dist/jsx/charts/BarChart.native.js +81 -67
- package/dist/jsx/charts/BarChart.native.js.map +1 -1
- package/dist/jsx/charts/ChartDataView.mjs +185 -0
- package/dist/jsx/charts/ChartDataView.mjs.map +1 -0
- package/dist/jsx/charts/ChartDataView.native.js +224 -0
- package/dist/jsx/charts/ChartDataView.native.js.map +1 -0
- package/dist/jsx/charts/ChartSurface.mjs +5 -1
- package/dist/jsx/charts/ChartSurface.mjs.map +1 -1
- package/dist/jsx/charts/ChartSurface.native.js +5 -1
- package/dist/jsx/charts/ChartSurface.native.js.map +1 -1
- package/dist/jsx/charts/LineChart.mjs +82 -68
- package/dist/jsx/charts/LineChart.mjs.map +1 -1
- package/dist/jsx/charts/LineChart.native.js +94 -80
- package/dist/jsx/charts/LineChart.native.js.map +1 -1
- package/dist/jsx/charts/PieChart.mjs +100 -75
- package/dist/jsx/charts/PieChart.mjs.map +1 -1
- package/dist/jsx/charts/PieChart.native.js +109 -84
- package/dist/jsx/charts/PieChart.native.js.map +1 -1
- package/dist/jsx/charts/Sparkline.mjs +11 -2
- package/dist/jsx/charts/Sparkline.mjs.map +1 -1
- package/dist/jsx/charts/Sparkline.native.js +10 -1
- package/dist/jsx/charts/Sparkline.native.js.map +1 -1
- package/dist/jsx/charts/accessibility.mjs +4 -1
- package/dist/jsx/charts/accessibility.mjs.map +1 -1
- package/dist/jsx/charts/accessibility.native.js +7 -0
- package/dist/jsx/charts/accessibility.native.js.map +1 -1
- package/dist/jsx/charts/index.mjs +2 -1
- package/dist/jsx/charts/index.mjs.map +1 -1
- package/dist/jsx/charts/index.native.js +2 -0
- package/dist/jsx/charts/index.native.js.map +1 -1
- package/dist/jsx/charts/math.mjs +16 -1
- package/dist/jsx/charts/math.mjs.map +1 -1
- package/dist/jsx/charts/math.native.js +18 -0
- package/dist/jsx/charts/math.native.js.map +1 -1
- package/dist/jsx/charts/series.mjs +51 -9
- package/dist/jsx/charts/series.mjs.map +1 -1
- package/dist/jsx/charts/series.native.js +53 -11
- package/dist/jsx/charts/series.native.js.map +1 -1
- package/dist/jsx/charts/svg.mjs +40 -4
- package/dist/jsx/charts/svg.mjs.map +1 -1
- package/dist/jsx/charts/svg.native.js +46 -3
- package/dist/jsx/charts/svg.native.js.map +1 -1
- package/dist/jsx/code/CodeBlock/index.mjs +7 -2
- package/dist/jsx/code/CodeBlock/index.mjs.map +1 -1
- package/dist/jsx/code/CodeBlock/index.native.js +6 -1
- package/dist/jsx/code/CodeBlock/index.native.js.map +1 -1
- package/dist/jsx/feedback/ConfirmDialog.mjs +8 -22
- package/dist/jsx/feedback/ConfirmDialog.mjs.map +1 -1
- package/dist/jsx/feedback/ConfirmDialog.native.js +7 -22
- package/dist/jsx/feedback/ConfirmDialog.native.js.map +1 -1
- package/dist/jsx/feedback/NotifyHost.mjs +2 -1
- package/dist/jsx/feedback/NotifyHost.mjs.map +1 -1
- package/dist/jsx/feedback/NotifyHost.native.js +3 -2
- package/dist/jsx/feedback/NotifyHost.native.js.map +1 -1
- package/dist/jsx/feedback/copy.mjs +35 -4
- package/dist/jsx/feedback/copy.mjs.map +1 -1
- package/dist/jsx/feedback/copy.native.js +38 -4
- package/dist/jsx/feedback/copy.native.js.map +1 -1
- package/dist/jsx/feedback/index.mjs +2 -2
- package/dist/jsx/feedback/index.mjs.map +1 -1
- package/dist/jsx/feedback/index.native.js +1 -0
- package/dist/jsx/feedback/index.native.js.map +1 -1
- package/dist/jsx/feedback/notify.mjs +1 -0
- package/dist/jsx/feedback/notify.mjs.map +1 -1
- package/dist/jsx/feedback/notify.native.js +1 -0
- package/dist/jsx/feedback/notify.native.js.map +1 -1
- package/dist/jsx/feedback/route.mjs +3 -0
- package/dist/jsx/feedback/route.mjs.map +1 -1
- package/dist/jsx/feedback/route.native.js +3 -0
- package/dist/jsx/feedback/route.native.js.map +1 -1
- package/dist/jsx/feedback/store.mjs +6 -1
- package/dist/jsx/feedback/store.mjs.map +1 -1
- package/dist/jsx/feedback/store.native.js +8 -0
- package/dist/jsx/feedback/store.native.js.map +1 -1
- package/dist/jsx/icons/lucide.mjs +2 -2
- package/dist/jsx/icons/lucide.mjs.map +1 -1
- package/dist/jsx/icons/lucide.native.js +2 -1
- package/dist/jsx/knobImmuneExports.mjs +0 -1
- package/dist/jsx/knobImmuneExports.mjs.map +1 -1
- package/dist/jsx/knobImmuneExports.native.js +0 -1
- package/dist/jsx/knobImmuneExports.native.js.map +1 -1
- package/dist/jsx/layouts/PaneScaffold.mjs +97 -42
- package/dist/jsx/layouts/PaneScaffold.mjs.map +1 -1
- package/dist/jsx/layouts/PaneScaffold.native.js +97 -41
- package/dist/jsx/layouts/PaneScaffold.native.js.map +1 -1
- package/dist/jsx/layouts/index.mjs +2 -1
- package/dist/jsx/layouts/index.mjs.map +1 -1
- package/dist/jsx/layouts/index.native.js +2 -0
- package/dist/jsx/layouts/index.native.js.map +1 -1
- package/dist/jsx/layouts/page.mjs +49 -8
- package/dist/jsx/layouts/page.mjs.map +1 -1
- package/dist/jsx/layouts/page.native.js +50 -7
- package/dist/jsx/layouts/page.native.js.map +1 -1
- package/dist/jsx/shared/useKeyboardInset.mjs +1 -19
- package/dist/jsx/shared/useKeyboardInset.mjs.map +1 -1
- package/dist/jsx/shared/useKeyboardInset.native.js +3 -3
- package/dist/jsx/shared/useKeyboardInset.native.js.map +1 -1
- package/dist/jsx/tamagui.mjs +2 -1
- package/dist/jsx/tamagui.mjs.map +1 -1
- package/dist/jsx/tamagui.native.js +2 -1
- package/dist/jsx/tamagui.native.js.map +1 -1
- package/dist/jsx/views/Dashboard.mjs +112 -19
- package/dist/jsx/views/Dashboard.mjs.map +1 -1
- package/dist/jsx/views/Dashboard.native.js +151 -45
- package/dist/jsx/views/Dashboard.native.js.map +1 -1
- package/dist/jsx/views/Gantt.mjs +376 -93
- package/dist/jsx/views/Gantt.mjs.map +1 -1
- package/dist/jsx/views/Gantt.native.js +443 -94
- package/dist/jsx/views/Gantt.native.js.map +1 -1
- package/dist/jsx/views/ganttMath.mjs +84 -3
- package/dist/jsx/views/ganttMath.mjs.map +1 -1
- package/dist/jsx/views/ganttMath.native.js +113 -3
- package/dist/jsx/views/ganttMath.native.js.map +1 -1
- package/dist/jsx/views/index.mjs +2 -2
- package/dist/jsx/views/index.mjs.map +1 -1
- package/dist/jsx/views/index.native.js +20 -1
- package/dist/jsx/views/index.native.js.map +1 -1
- package/package.json +11 -9
- package/src/Accordion/index.tsx +7 -1
- package/src/AnimateHeight/AnimateHeight.native.spec.tsx +51 -0
- package/src/AnimateHeight/index.tsx +30 -5
- package/src/Button.tsx +10 -2
- package/src/Card.spec.tsx +76 -3
- package/src/Card.stories.tsx +1 -1
- package/src/Card.tsx +13 -1
- package/src/CardFooter.stories.tsx +3 -7
- package/src/CardFooter.tsx +3 -1
- package/src/CardHeader.stories.tsx +1 -3
- package/src/Collapsible.stories.tsx +2 -2
- package/src/Collapsible.tsx +23 -0
- package/src/CopyField/CopyField.spec.tsx +66 -1
- package/src/CopyField/index.tsx +4 -3
- package/src/DropdownMenu/DropdownMenu.spec.tsx +112 -1
- package/src/DropdownMenu/DropdownMenu.stories.tsx +1 -3
- package/src/DropdownMenu/index.tsx +67 -6
- package/src/LinearGradient.stories.tsx +2 -2
- package/src/Meter/Meter.spec.tsx +59 -2
- package/src/Meter/Meter.stories.tsx +38 -0
- package/src/Meter/index.tsx +9 -4
- package/src/Pagination.simple.spec.tsx +23 -0
- package/src/Pagination.stories.tsx +8 -0
- package/src/Pagination.tsx +27 -10
- package/src/Panel.stories.tsx +1 -1
- package/src/SortableList/SortableList.spec.tsx +3 -3
- package/src/Tabs/Tabs.bandColor.spec.tsx +23 -0
- package/src/Tabs/Tabs.native.spec.tsx +35 -0
- package/src/Tabs/Tabs.spec.tsx +91 -1
- package/src/Tabs/Tabs.stories.tsx +36 -1
- package/src/Tabs/index.tsx +272 -187
- package/src/Toast/Toast.spec.tsx +56 -1
- package/src/Toast/index.tsx +68 -3
- package/src/Unspaced.stories.tsx +2 -2
- package/src/VisuallyHidden.stories.tsx +2 -2
- package/src/actions/DestructiveAction.spec.tsx +19 -3
- package/src/actions/DestructiveAction.tsx +9 -14
- package/src/charts/Axis.tsx +6 -1
- package/src/charts/BarChart.tsx +82 -67
- package/src/charts/ChartDataView.spec.tsx +104 -0
- package/src/charts/ChartDataView.tsx +158 -0
- package/src/charts/ChartSurface.tsx +7 -2
- package/src/charts/Charts.stories.tsx +213 -9
- package/src/charts/LineChart.tsx +90 -75
- package/src/charts/PieChart.knobs.spec.tsx +25 -0
- package/src/charts/PieChart.tsx +51 -9
- package/src/charts/Sparkline.tsx +25 -3
- package/src/charts/accessibility.ts +8 -0
- package/src/charts/charts.spec.tsx +77 -3
- package/src/charts/index.ts +2 -0
- package/src/charts/math.spec.ts +19 -0
- package/src/charts/math.ts +36 -0
- package/src/charts/series.tsx +101 -21
- package/src/charts/svg.spec.ts +28 -0
- package/src/charts/svg.ts +56 -2
- package/src/code/CodeBlock/CodeBlock.copy.spec.tsx +23 -0
- package/src/code/CodeBlock/index.tsx +4 -3
- package/src/disclosureForm.spec.tsx +57 -0
- package/src/disclosureNativeProps.spec.tsx +35 -0
- package/src/feedback/ConfirmDialog.nativeFocus.spec.tsx +52 -0
- package/src/feedback/ConfirmDialog.spec.tsx +20 -0
- package/src/feedback/ConfirmDialog.tsx +9 -15
- package/src/feedback/NotifyHost.tsx +11 -2
- package/src/feedback/copy.ts +36 -4
- package/src/feedback/index.ts +1 -0
- package/src/feedback/notify.spec.ts +15 -1
- package/src/feedback/notify.ts +1 -0
- package/src/feedback/route.ts +4 -0
- package/src/feedback/store.ts +7 -0
- package/src/icons/lucide.ts +1 -1
- package/src/images/SvgUri/index.native.ts +11 -3
- package/src/knobImmuneExports.ts +0 -2
- package/src/layouts/EmptyState.stories.tsx +2 -2
- package/src/layouts/Page.weight.spec.tsx +75 -0
- package/src/layouts/PageHeader.stories.tsx +4 -4
- package/src/layouts/PageTemplates.stories.tsx +2 -2
- package/src/layouts/PaneScaffold.spec.tsx +144 -4
- package/src/layouts/PaneScaffold.stories.tsx +58 -2
- package/src/layouts/PaneScaffold.tsx +156 -58
- package/src/layouts/ScreenToolbar.stories.tsx +6 -23
- package/src/layouts/index.tsx +11 -0
- package/src/layouts/layouts.spec.tsx +51 -0
- package/src/layouts/page.designLaw.spec.tsx +25 -0
- package/src/layouts/page.tsx +46 -9
- package/src/primitives.spec.tsx +19 -4
- package/src/shared/useKeyboardInset.native.ts +43 -0
- package/src/shared/useKeyboardInset.ts +2 -41
- package/src/tamagui.spec.ts +63 -0
- package/src/tamagui.ts +3 -1
- package/src/views/Dashboard.stories.tsx +38 -1
- package/src/views/Dashboard.tsx +119 -21
- package/src/views/Gantt.scroll.spec.tsx +120 -0
- package/src/views/Gantt.spec.tsx +376 -0
- package/src/views/Gantt.stories.tsx +75 -2
- package/src/views/Gantt.tsx +564 -96
- package/src/views/Kanban.spec.tsx +11 -0
- package/src/views/ganttMath.ts +142 -4
- package/src/views/index.ts +44 -1
- package/src/views/views.spec.tsx +39 -0
- package/types/Accordion/index.d.ts +2 -0
- package/types/Accordion/index.d.ts.map +1 -1
- package/types/AnimateHeight/index.d.ts +3 -4
- package/types/AnimateHeight/index.d.ts.map +1 -1
- package/types/Button.d.ts +12 -2
- package/types/Button.d.ts.map +1 -1
- package/types/Card.d.ts.map +1 -1
- package/types/CardFooter.d.ts +2 -1
- package/types/CardFooter.d.ts.map +1 -1
- package/types/Collapsible.d.ts +19 -0
- package/types/Collapsible.d.ts.map +1 -0
- package/types/CopyField/index.d.ts.map +1 -1
- package/types/DropdownMenu/index.d.ts +22 -0
- package/types/DropdownMenu/index.d.ts.map +1 -1
- package/types/Meter/index.d.ts.map +1 -1
- package/types/Pagination.d.ts +1 -1
- package/types/Pagination.d.ts.map +1 -1
- package/types/Tabs/index.d.ts +7 -3
- package/types/Tabs/index.d.ts.map +1 -1
- package/types/Toast/index.d.ts +16 -0
- package/types/Toast/index.d.ts.map +1 -1
- package/types/actions/DestructiveAction.d.ts.map +1 -1
- package/types/charts/Axis.d.ts.map +1 -1
- package/types/charts/BarChart.d.ts.map +1 -1
- package/types/charts/ChartDataView.d.ts +22 -0
- package/types/charts/ChartDataView.d.ts.map +1 -0
- package/types/charts/ChartSurface.d.ts +4 -1
- package/types/charts/ChartSurface.d.ts.map +1 -1
- package/types/charts/LineChart.d.ts.map +1 -1
- package/types/charts/PieChart.d.ts +1 -1
- package/types/charts/PieChart.d.ts.map +1 -1
- package/types/charts/Sparkline.d.ts +3 -1
- package/types/charts/Sparkline.d.ts.map +1 -1
- package/types/charts/accessibility.d.ts +3 -0
- package/types/charts/accessibility.d.ts.map +1 -1
- package/types/charts/index.d.ts +1 -0
- package/types/charts/index.d.ts.map +1 -1
- package/types/charts/math.d.ts +12 -0
- package/types/charts/math.d.ts.map +1 -1
- package/types/charts/series.d.ts +1 -1
- package/types/charts/series.d.ts.map +1 -1
- package/types/charts/svg.d.ts +18 -2
- package/types/charts/svg.d.ts.map +1 -1
- package/types/code/CodeBlock/index.d.ts.map +1 -1
- package/types/feedback/ConfirmDialog.d.ts.map +1 -1
- package/types/feedback/NotifyHost.d.ts +3 -1
- package/types/feedback/NotifyHost.d.ts.map +1 -1
- package/types/feedback/copy.d.ts +12 -2
- package/types/feedback/copy.d.ts.map +1 -1
- package/types/feedback/index.d.ts +1 -1
- package/types/feedback/index.d.ts.map +1 -1
- package/types/feedback/notify.d.ts.map +1 -1
- package/types/feedback/route.d.ts +3 -0
- package/types/feedback/route.d.ts.map +1 -1
- package/types/feedback/store.d.ts +2 -0
- package/types/feedback/store.d.ts.map +1 -1
- package/types/icons/lucide.d.ts +1 -1
- package/types/icons/lucide.d.ts.map +1 -1
- package/types/images/SvgUri/index.native.d.ts +4 -3
- package/types/images/SvgUri/index.native.d.ts.map +1 -1
- package/types/knobImmuneExports.d.ts.map +1 -1
- package/types/layouts/PaneScaffold.d.ts +27 -5
- package/types/layouts/PaneScaffold.d.ts.map +1 -1
- package/types/layouts/index.d.ts +1 -0
- package/types/layouts/index.d.ts.map +1 -1
- package/types/layouts/page.d.ts +10 -5
- package/types/layouts/page.d.ts.map +1 -1
- package/types/shared/useKeyboardInset.d.ts +1 -14
- package/types/shared/useKeyboardInset.d.ts.map +1 -1
- package/types/shared/useKeyboardInset.native.d.ts +16 -0
- package/types/shared/useKeyboardInset.native.d.ts.map +1 -0
- package/types/tamagui.d.ts +2 -1
- package/types/tamagui.d.ts.map +1 -1
- package/types/views/Dashboard.d.ts.map +1 -1
- package/types/views/Gantt.d.ts +132 -13
- package/types/views/Gantt.d.ts.map +1 -1
- package/types/views/ganttMath.d.ts +73 -0
- package/types/views/ganttMath.d.ts.map +1 -1
- package/types/views/index.d.ts +2 -2
- package/types/views/index.d.ts.map +1 -1
package/src/views/Gantt.tsx
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
Intent,
|
|
9
9
|
MIN_PRESS_TARGET,
|
|
10
10
|
ensureKeyboardModalityTracking,
|
|
11
|
+
formatAbsoluteDate,
|
|
11
12
|
formatDayOfMonth,
|
|
12
13
|
formatMonthYear,
|
|
13
14
|
hairline,
|
|
@@ -27,6 +28,7 @@ import {
|
|
|
27
28
|
barGeometry,
|
|
28
29
|
clampResizeDayDelta,
|
|
29
30
|
computeGanttRange,
|
|
31
|
+
dateLineX,
|
|
30
32
|
dateToX,
|
|
31
33
|
dayDiff,
|
|
32
34
|
dxToDayDelta,
|
|
@@ -34,12 +36,18 @@ import {
|
|
|
34
36
|
formatSpanLabel,
|
|
35
37
|
ganttTaskAccessibleLabel,
|
|
36
38
|
generateTicks,
|
|
39
|
+
isBoundedSpan,
|
|
40
|
+
openBarGeometry,
|
|
41
|
+
openSpanExtents,
|
|
42
|
+
openSpanLabelParts,
|
|
37
43
|
rangeDays,
|
|
38
44
|
resizeSpanByDays,
|
|
45
|
+
scrollAnchorX,
|
|
39
46
|
shiftSpanByDays,
|
|
40
47
|
spanInclusiveDays,
|
|
41
48
|
startOfDay,
|
|
42
49
|
todayLineX,
|
|
50
|
+
type GanttOpenSpan,
|
|
43
51
|
type GanttRange,
|
|
44
52
|
type GanttResizeEdge,
|
|
45
53
|
type GanttSpan,
|
|
@@ -52,17 +60,39 @@ import {
|
|
|
52
60
|
const CanvasScroller = (isWeb ? ScrollView : RNScrollView) as typeof ScrollView;
|
|
53
61
|
|
|
54
62
|
/**
|
|
55
|
-
*
|
|
63
|
+
* One drawn span on a Gantt row: a duration bar, or an open-ended one.
|
|
64
|
+
*
|
|
65
|
+
* BOTH BOUNDS ARE OPTIONAL, and an absent bound means the span is open at
|
|
66
|
+
* that end — not that the caller forgot it. Each of the three shapes paints
|
|
67
|
+
* differently, because a viewer must never read an edge nobody chose:
|
|
68
|
+
*
|
|
69
|
+
* | `start` | `end` | drawn as |
|
|
70
|
+
* |---|---|---|
|
|
71
|
+
* | set | set | a capped bar between the two dates (inclusive whole days) |
|
|
72
|
+
* | set | absent | a bar from `start`, uncapped, running off the chart's end edge with a `»` |
|
|
73
|
+
* | absent | set | a bar to `end`, uncapped, running off the chart's start edge with a `«` |
|
|
74
|
+
* | absent | absent | a thin half-height RAIL across the whole chart, `«` and `»` at both ends |
|
|
75
|
+
*
|
|
76
|
+
* The rail is a different SHAPE on purpose. Painting an eternal span as a
|
|
77
|
+
* full-width BAR would put two capped edges on screen at the chart's own
|
|
78
|
+
* padding, and the reader would take that padding for a decision.
|
|
79
|
+
*
|
|
80
|
+
* Rescheduling needs both bounds. A span missing either one gets no drag
|
|
81
|
+
* session, no resize handles and no keyboard moves — there is no second
|
|
82
|
+
* edge to preserve a duration against. `progress` is likewise ignored on an
|
|
83
|
+
* open span: a percentage of an unknown duration says nothing.
|
|
56
84
|
*/
|
|
57
|
-
export interface
|
|
58
|
-
/**
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
|
|
85
|
+
export interface GanttTaskSpan {
|
|
86
|
+
/**
|
|
87
|
+
* Stable id, unique within the task. Used as the React key, the drag
|
|
88
|
+
* session key and the `data-gantt-bar` attribute. Optional: a row's spans
|
|
89
|
+
* fall back to `<task id>#<index>`.
|
|
90
|
+
*/
|
|
91
|
+
id?: string;
|
|
92
|
+
/** Span start date. Absent = open at the start. */
|
|
93
|
+
start?: Date;
|
|
94
|
+
/** Span end date (midnight ends are inclusive whole days — Frappe date fields). Absent = open at the end. */
|
|
95
|
+
end?: Date;
|
|
66
96
|
/**
|
|
67
97
|
* Explicit bar color (hex/rgb/token). Passes through untouched — the
|
|
68
98
|
* literal is the value (Axiom 11). Wins over `intent`.
|
|
@@ -72,13 +102,54 @@ export interface GanttTask {
|
|
|
72
102
|
intent?: "accent" | "error" | "warning" | "success";
|
|
73
103
|
/**
|
|
74
104
|
* Optional completion 0–100. Paints a darker overlay on the bar (Frappe
|
|
75
|
-
* Gantt / MS Project progress). Omitted or 0 shows an empty bar.
|
|
105
|
+
* Gantt / MS Project progress). Omitted or 0 shows an empty bar. Ignored
|
|
106
|
+
* on an open-ended span.
|
|
76
107
|
*/
|
|
77
108
|
progress?: number;
|
|
109
|
+
/** Bar label, when it should differ from the row's title. */
|
|
110
|
+
title?: string;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* A Gantt task rendered as one row.
|
|
115
|
+
*
|
|
116
|
+
* The row carries ONE span by default — the task's own `start`/`end`, which
|
|
117
|
+
* is what every caller before `spans` existed passes — or SEVERAL when
|
|
118
|
+
* `spans` is set. Several is for one logical subject that ships a variant
|
|
119
|
+
* per period: three rules named `..._2026`, `..._2027`, `..._2028` are one
|
|
120
|
+
* emitter and want one row carrying three strips, not three unrelated rows.
|
|
121
|
+
*/
|
|
122
|
+
export interface GanttTask extends GanttTaskSpan {
|
|
123
|
+
/** Unique task identifier */
|
|
124
|
+
id: string;
|
|
125
|
+
/** Task title shown in the label column and the bar's accessible name */
|
|
126
|
+
title: string;
|
|
127
|
+
/**
|
|
128
|
+
* Several spans on this one row. When set and non-empty it REPLACES the
|
|
129
|
+
* task's own `start`/`end` as the thing drawn; the label column still
|
|
130
|
+
* shows one row. Leave it off for the one-bar-per-row shape, which is
|
|
131
|
+
* unchanged in every respect down to the `data-gantt-bar` attribute.
|
|
132
|
+
*/
|
|
133
|
+
spans?: GanttTaskSpan[];
|
|
78
134
|
/** Any additional data */
|
|
79
135
|
[key: string]: unknown;
|
|
80
136
|
}
|
|
81
137
|
|
|
138
|
+
/**
|
|
139
|
+
* Which span of a row a callback is about.
|
|
140
|
+
*
|
|
141
|
+
* A single-span row reports `index: 0` and `key: task.id`, so a caller that
|
|
142
|
+
* never sets `spans` can keep ignoring this argument entirely.
|
|
143
|
+
*/
|
|
144
|
+
export interface GanttSpanRef {
|
|
145
|
+
/** The span itself — the task object for a single-span row. */
|
|
146
|
+
span: GanttTaskSpan;
|
|
147
|
+
/** Position within `task.spans`, or 0 for a single-span row. */
|
|
148
|
+
index: number;
|
|
149
|
+
/** Stable key: `span.id`, else `task.id` (single-span) or `<task id>#<index>`. */
|
|
150
|
+
key: string;
|
|
151
|
+
}
|
|
152
|
+
|
|
82
153
|
/** New start/end range produced by a bar drag-move. */
|
|
83
154
|
export interface GanttItemMoveRange {
|
|
84
155
|
start: Date;
|
|
@@ -105,8 +176,16 @@ export interface GanttViewProps extends Omit<YStackProps, "children"> {
|
|
|
105
176
|
* pointer only). All paths preserve wall-clock times and snap to whole
|
|
106
177
|
* days. Web drags use pointer tracking (Escape cancels); native uses the
|
|
107
178
|
* responder system (best-effort — scroll locks while dragging).
|
|
179
|
+
*
|
|
180
|
+
* `span` names WHICH span of a multi-span row moved. A single-span row
|
|
181
|
+
* reports `{ index: 0, key: task.id }` and the span object IS the task, so
|
|
182
|
+
* a two-argument handler stays correct and needs no change.
|
|
183
|
+
*
|
|
184
|
+
* Only fully-bounded spans reschedule: an open-ended one has no second
|
|
185
|
+
* edge to hold a duration against, so it is never dragged and this never
|
|
186
|
+
* fires for it.
|
|
108
187
|
*/
|
|
109
|
-
onItemMove?: (task: GanttTask, range: GanttItemMoveRange) => void;
|
|
188
|
+
onItemMove?: (task: GanttTask, range: GanttItemMoveRange, span?: GanttSpanRef) => void;
|
|
110
189
|
/**
|
|
111
190
|
* Enable bar rescheduling — pointer drag, keyboard arrows, and edge
|
|
112
191
|
* resize (default: enabled when onItemMove is provided).
|
|
@@ -139,6 +218,50 @@ export interface GanttViewProps extends Omit<YStackProps, "children"> {
|
|
|
139
218
|
firstDayOfWeek?: 0 | 1;
|
|
140
219
|
/** Date scrolled into view on mount (defaults to today) */
|
|
141
220
|
initialDate?: Date;
|
|
221
|
+
/**
|
|
222
|
+
* Controlled marker date — a playhead the caller owns.
|
|
223
|
+
*
|
|
224
|
+
* Independent of both `showToday`, which pins a line to the real today and
|
|
225
|
+
* cannot move, and `initialDate`, which only picks the mount scroll
|
|
226
|
+
* position. Set it and a marker line paints across the axis and the rows
|
|
227
|
+
* with a grab handle on the axis; leave it unset and nothing renders. The
|
|
228
|
+
* component never moves it on its own — it draws exactly the date it is
|
|
229
|
+
* given, which is what makes an as-of view possible.
|
|
230
|
+
*/
|
|
231
|
+
markerDate?: Date;
|
|
232
|
+
/**
|
|
233
|
+
* Called when the marker is scrubbed: drag its axis handle, or focus the
|
|
234
|
+
* handle and press ArrowLeft/ArrowRight (Shift = 7 days). Fires per whole
|
|
235
|
+
* day crossed, not per pointer move, and Escape mid-drag fires once more
|
|
236
|
+
* with the date the drag started from.
|
|
237
|
+
*/
|
|
238
|
+
onMarkerDateChange?: (date: Date) => void;
|
|
239
|
+
/**
|
|
240
|
+
* Enable scrubbing the marker (default: enabled when `onMarkerDateChange`
|
|
241
|
+
* is provided). A marker with no callback still renders, read-only.
|
|
242
|
+
*/
|
|
243
|
+
enableMarkerDrag?: boolean;
|
|
244
|
+
/** Accessible name for the marker handle (default: "Marker"). */
|
|
245
|
+
markerLabel?: string;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* The spans a row draws, in paint order.
|
|
250
|
+
*
|
|
251
|
+
* A task with no `spans` IS its own single span and takes the task id as its
|
|
252
|
+
* key, so every data attribute, drag session and callback on the
|
|
253
|
+
* one-bar-per-row path is exactly what it was before `spans` existed.
|
|
254
|
+
*/
|
|
255
|
+
/** The span as a closed duration, or null when either bound is open. */
|
|
256
|
+
function boundedSpan(ref: GanttSpanRef): GanttSpan | null {
|
|
257
|
+
const span = ref.span;
|
|
258
|
+
return isBoundedSpan(span) ? { start: span.start, end: span.end } : null;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function resolveSpans(task: GanttTask): GanttSpanRef[] {
|
|
262
|
+
const list = task.spans;
|
|
263
|
+
if (!list || list.length === 0) return [{ span: task, index: 0, key: task.id }];
|
|
264
|
+
return list.map((span, index) => ({ span, index, key: span.id ?? `${task.id}#${index}` }));
|
|
142
265
|
}
|
|
143
266
|
|
|
144
267
|
// ── Interaction constants (gesture recognition, not animation timing) ──
|
|
@@ -345,6 +468,15 @@ function GanttTaskName({
|
|
|
345
468
|
* invert so "toward earlier dates" always matches the visual direction.
|
|
346
469
|
* Native RTL follows `I18nManager` (best-effort — not device-verified).
|
|
347
470
|
*
|
|
471
|
+
* Three things make it a TRACK view as well as a schedule. A span's bounds
|
|
472
|
+
* are both optional, and the missing side paints as an uncapped edge (or, with
|
|
473
|
+
* neither bound, a half-height rail) instead of an invented date. A row can
|
|
474
|
+
* carry SEVERAL spans via `task.spans`, so one subject that ships a variant
|
|
475
|
+
* per period reads as one row. And `markerDate` is a controlled playhead the
|
|
476
|
+
* caller owns — scrubbed by dragging its handle on the axis or by arrows on
|
|
477
|
+
* the focused handle, reported through `onMarkerDateChange` — independent of
|
|
478
|
+
* the today line, which stays pinned to the real today.
|
|
479
|
+
*
|
|
348
480
|
* @example
|
|
349
481
|
* ```tsx
|
|
350
482
|
* <GanttView
|
|
@@ -354,6 +486,22 @@ function GanttTaskName({
|
|
|
354
486
|
* onItemMove={(task, range) => reschedule(task, range)}
|
|
355
487
|
* />
|
|
356
488
|
* ```
|
|
489
|
+
*
|
|
490
|
+
* @example A track view: open-ended spans, several per row, a scrubbed marker.
|
|
491
|
+
* ```tsx
|
|
492
|
+
* <GanttView
|
|
493
|
+
* tasks={[
|
|
494
|
+
* { id: "fed", title: "Federal true-up", spans: [
|
|
495
|
+
* { id: "2026", start: jan(2026), end: dec(2026) },
|
|
496
|
+
* { id: "2027", start: jan(2027), end: dec(2027) },
|
|
497
|
+
* ] },
|
|
498
|
+
* { id: "vat", title: "VAT", start: jan(2025) }, // no end: open at the end
|
|
499
|
+
* { id: "base", title: "Base policy" }, // no dates: a rail
|
|
500
|
+
* ]}
|
|
501
|
+
* markerDate={asOf}
|
|
502
|
+
* onMarkerDateChange={setAsOf}
|
|
503
|
+
* />
|
|
504
|
+
* ```
|
|
357
505
|
*/
|
|
358
506
|
export function GanttView({
|
|
359
507
|
tasks,
|
|
@@ -374,6 +522,10 @@ export function GanttView({
|
|
|
374
522
|
showZoomSwitcher = true,
|
|
375
523
|
firstDayOfWeek = 0,
|
|
376
524
|
initialDate,
|
|
525
|
+
markerDate,
|
|
526
|
+
onMarkerDateChange,
|
|
527
|
+
enableMarkerDrag,
|
|
528
|
+
markerLabel,
|
|
377
529
|
...stackProps
|
|
378
530
|
}: GanttViewProps) {
|
|
379
531
|
const { t } = useTranslation();
|
|
@@ -424,16 +576,26 @@ export function GanttView({
|
|
|
424
576
|
const space = knobProps.space;
|
|
425
577
|
const barInset = space === "small" ? 4 : space === "large" ? 9 : 6;
|
|
426
578
|
const barHeight = Math.max(10, rowHeight - barInset * 2);
|
|
579
|
+
// An eternal span is a RAIL, not a bar: half the height, no caps. The
|
|
580
|
+
// shape is the message — a full-width capped bar would put two chosen-
|
|
581
|
+
// looking edges on the chart's own padding.
|
|
582
|
+
const railHeight = Math.max(4, Math.round(barHeight / 2));
|
|
427
583
|
const transition = knobProps.transition;
|
|
428
584
|
// Layout props (left) only tween on web — the RN driver cannot animate
|
|
429
585
|
// layout, so native keeps committed jumps instant (Axiom 4 note).
|
|
430
586
|
const webLayoutTransition = isWeb ? transition : undefined;
|
|
431
587
|
|
|
432
588
|
// ── Chart range + axis ───────────────────────────────────────────────────
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
589
|
+
// Every span on every row, in one flat list. Open spans contribute only
|
|
590
|
+
// the date they actually name (an eternal one contributes nothing, so it
|
|
591
|
+
// cannot stretch the axis), and the marker joins them so it always has
|
|
592
|
+
// somewhere to land — the same courtesy computeGanttRange pays today.
|
|
593
|
+
const spans = useMemo<GanttSpan[]>(() => {
|
|
594
|
+
const flat: GanttOpenSpan[] = [];
|
|
595
|
+
for (const task of tasks) for (const ref of resolveSpans(task)) flat.push(ref.span);
|
|
596
|
+
if (markerDate !== undefined) flat.push({ start: markerDate, end: markerDate });
|
|
597
|
+
return openSpanExtents(flat);
|
|
598
|
+
}, [tasks, markerDate]);
|
|
437
599
|
const range = useMemo(
|
|
438
600
|
() => computeGanttRange(spans, zoom, new Date(), firstDayOfWeek),
|
|
439
601
|
[spans, zoom, firstDayOfWeek],
|
|
@@ -461,20 +623,19 @@ export function GanttView({
|
|
|
461
623
|
const hScrollRef = useRef<any>(null);
|
|
462
624
|
const axisScrollRef = useRef<any>(null);
|
|
463
625
|
const canvasViewportRef = useRef<number | null>(null);
|
|
464
|
-
//
|
|
465
|
-
const
|
|
626
|
+
// Re-anchor in either direction once the canvas viewport has been measured.
|
|
627
|
+
const pendingAnchorRef = useRef<Date | null>(null);
|
|
466
628
|
|
|
467
629
|
const scrollToDate = useCallback(
|
|
468
630
|
(date: Date, animated: boolean) => {
|
|
469
|
-
const
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
}
|
|
631
|
+
const viewportWidth = canvasViewportRef.current;
|
|
632
|
+
if (viewportWidth === null) pendingAnchorRef.current = date;
|
|
633
|
+
const x = scrollAnchorX(date, range.start, pxPerDay, {
|
|
634
|
+
labelWidth,
|
|
635
|
+
chartWidth,
|
|
636
|
+
viewportWidth,
|
|
637
|
+
rtl,
|
|
638
|
+
});
|
|
478
639
|
hScrollRef.current?.scrollTo?.({ x, animated });
|
|
479
640
|
// Keep the pinned axis strip in step even where programmatic scrolls
|
|
480
641
|
// don't emit onScroll.
|
|
@@ -500,11 +661,11 @@ export function GanttView({
|
|
|
500
661
|
|
|
501
662
|
const handleCanvasLayout = useCallback((event: any) => {
|
|
502
663
|
const width = event?.nativeEvent?.layout?.width;
|
|
503
|
-
if (typeof width !== "number") return;
|
|
664
|
+
if (typeof width !== "number" || !Number.isFinite(width) || width <= 0) return;
|
|
504
665
|
canvasViewportRef.current = width;
|
|
505
|
-
const pending =
|
|
666
|
+
const pending = pendingAnchorRef.current;
|
|
506
667
|
if (pending) {
|
|
507
|
-
|
|
668
|
+
pendingAnchorRef.current = null;
|
|
508
669
|
scrollToDateRef.current(pending, false);
|
|
509
670
|
}
|
|
510
671
|
}, []);
|
|
@@ -515,11 +676,14 @@ export function GanttView({
|
|
|
515
676
|
const webDragEnabled = dragEnabled && hasDom;
|
|
516
677
|
const nativeDragEnabled = dragEnabled && !isWeb;
|
|
517
678
|
|
|
518
|
-
|
|
679
|
+
// Sessions key on the SPAN key, not the task id — a row can carry several
|
|
680
|
+
// spans and only the grabbed one moves. For a single-span row the span key
|
|
681
|
+
// IS the task id, so this is the same value it always was.
|
|
682
|
+
const [drag, setDrag] = useState<{ key: string; dx: number; dayDelta: number } | null>(null);
|
|
519
683
|
// Edge-resize session (web pointer only): logicalDx is clamped so the bar
|
|
520
684
|
// never shrinks below one inclusive day.
|
|
521
685
|
const [resize, setResize] = useState<{
|
|
522
|
-
|
|
686
|
+
key: string;
|
|
523
687
|
edge: GanttResizeEdge;
|
|
524
688
|
logicalDx: number;
|
|
525
689
|
dayDelta: number;
|
|
@@ -529,6 +693,8 @@ export function GanttView({
|
|
|
529
693
|
const dragCleanupRef = useRef<(() => void) | null>(null);
|
|
530
694
|
const nativeSessionRef = useRef<{
|
|
531
695
|
task: GanttTask;
|
|
696
|
+
ref: GanttSpanRef;
|
|
697
|
+
span: GanttSpan;
|
|
532
698
|
startX: number;
|
|
533
699
|
dragging: boolean;
|
|
534
700
|
liftTimer: ReturnType<typeof setTimeout> | null;
|
|
@@ -544,10 +710,8 @@ export function GanttView({
|
|
|
544
710
|
}, []);
|
|
545
711
|
|
|
546
712
|
const commitDrag = useCallback(
|
|
547
|
-
(task: GanttTask, dayDelta: number) => {
|
|
548
|
-
if (dayDelta !== 0)
|
|
549
|
-
onItemMove?.(task, shiftSpanByDays({ start: task.start, end: task.end }, dayDelta));
|
|
550
|
-
}
|
|
713
|
+
(task: GanttTask, ref: GanttSpanRef, span: GanttSpan, dayDelta: number) => {
|
|
714
|
+
if (dayDelta !== 0) onItemMove?.(task, shiftSpanByDays(span, dayDelta), ref);
|
|
551
715
|
},
|
|
552
716
|
[onItemMove],
|
|
553
717
|
);
|
|
@@ -558,6 +722,7 @@ export function GanttView({
|
|
|
558
722
|
const handleBarPointerDown = useCallback(
|
|
559
723
|
(
|
|
560
724
|
task: GanttTask,
|
|
725
|
+
ref: GanttSpanRef,
|
|
561
726
|
e: {
|
|
562
727
|
button?: number;
|
|
563
728
|
clientX: number;
|
|
@@ -567,6 +732,8 @@ export function GanttView({
|
|
|
567
732
|
},
|
|
568
733
|
) => {
|
|
569
734
|
if (!webDragEnabled) return;
|
|
735
|
+
const span = boundedSpan(ref);
|
|
736
|
+
if (!span) return;
|
|
570
737
|
if (e.button !== undefined && e.button !== 0) return;
|
|
571
738
|
e.stopPropagation?.();
|
|
572
739
|
dragCleanupRef.current?.();
|
|
@@ -588,7 +755,7 @@ export function GanttView({
|
|
|
588
755
|
active = true;
|
|
589
756
|
prevUserSelect = document.body.style.userSelect;
|
|
590
757
|
document.body.style.userSelect = "none";
|
|
591
|
-
setDrag({
|
|
758
|
+
setDrag({ key: ref.key, dx, dayDelta: toDayDelta(dx) });
|
|
592
759
|
};
|
|
593
760
|
|
|
594
761
|
const teardown = () => {
|
|
@@ -616,7 +783,7 @@ export function GanttView({
|
|
|
616
783
|
activate(dx);
|
|
617
784
|
return;
|
|
618
785
|
}
|
|
619
|
-
setDrag({
|
|
786
|
+
setDrag({ key: ref.key, dx, dayDelta: toDayDelta(dx) });
|
|
620
787
|
};
|
|
621
788
|
|
|
622
789
|
const onUp = (ue: PointerEvent) => {
|
|
@@ -625,7 +792,7 @@ export function GanttView({
|
|
|
625
792
|
teardown();
|
|
626
793
|
if (!wasActive) return;
|
|
627
794
|
suppressNextClick();
|
|
628
|
-
commitDrag(task, dayDelta);
|
|
795
|
+
commitDrag(task, ref, span, dayDelta);
|
|
629
796
|
};
|
|
630
797
|
|
|
631
798
|
const onKey = (ke: KeyboardEvent) => {
|
|
@@ -663,14 +830,18 @@ export function GanttView({
|
|
|
663
830
|
// mapping (no hit-testing needed), so this is a full best-effort path —
|
|
664
831
|
// scroll locks once the drag activates.
|
|
665
832
|
const handleNativeGrant = useCallback(
|
|
666
|
-
(task: GanttTask, e: { nativeEvent?: { pageX?: number } }) => {
|
|
833
|
+
(task: GanttTask, ref: GanttSpanRef, e: { nativeEvent?: { pageX?: number } }) => {
|
|
667
834
|
if (!nativeDragEnabled) return;
|
|
835
|
+
const span = boundedSpan(ref);
|
|
836
|
+
if (!span) return;
|
|
668
837
|
// Long-press lift (Kanban/Calendar parity): a stationary hold arms the
|
|
669
838
|
// drag and locks scroll BEFORE any movement, because on iOS the
|
|
670
839
|
// ScrollView's pan gesture is recognized natively and would win any
|
|
671
840
|
// move-threshold race against the JS responder system.
|
|
672
841
|
const session = {
|
|
673
842
|
task,
|
|
843
|
+
ref,
|
|
844
|
+
span,
|
|
674
845
|
startX: e.nativeEvent?.pageX ?? 0,
|
|
675
846
|
dragging: false,
|
|
676
847
|
liftTimer: null as ReturnType<typeof setTimeout> | null,
|
|
@@ -679,7 +850,7 @@ export function GanttView({
|
|
|
679
850
|
session.liftTimer = null;
|
|
680
851
|
if (nativeSessionRef.current !== session) return;
|
|
681
852
|
session.dragging = true;
|
|
682
|
-
setDrag({
|
|
853
|
+
setDrag({ key: ref.key, dx: 0, dayDelta: 0 });
|
|
683
854
|
}, TOUCH_LONG_PRESS_MS);
|
|
684
855
|
nativeSessionRef.current = session;
|
|
685
856
|
},
|
|
@@ -701,7 +872,7 @@ export function GanttView({
|
|
|
701
872
|
return;
|
|
702
873
|
}
|
|
703
874
|
setDrag({
|
|
704
|
-
|
|
875
|
+
key: session.ref.key,
|
|
705
876
|
dx,
|
|
706
877
|
dayDelta: dirSignRef.current * dxToDayDelta(dx, pxPerDay),
|
|
707
878
|
});
|
|
@@ -723,7 +894,7 @@ export function GanttView({
|
|
|
723
894
|
const dayDelta =
|
|
724
895
|
dirSignRef.current * dxToDayDelta((e.nativeEvent?.pageX ?? 0) - session.startX, pxPerDay);
|
|
725
896
|
setDrag(null);
|
|
726
|
-
commitDrag(session.task, dayDelta);
|
|
897
|
+
commitDrag(session.task, session.ref, session.span, dayDelta);
|
|
727
898
|
},
|
|
728
899
|
[onItemPress, pxPerDay, commitDrag],
|
|
729
900
|
);
|
|
@@ -742,6 +913,7 @@ export function GanttView({
|
|
|
742
913
|
const handleResizePointerDown = useCallback(
|
|
743
914
|
(
|
|
744
915
|
task: GanttTask,
|
|
916
|
+
ref: GanttSpanRef,
|
|
745
917
|
edge: GanttResizeEdge,
|
|
746
918
|
e: {
|
|
747
919
|
button?: number;
|
|
@@ -751,12 +923,13 @@ export function GanttView({
|
|
|
751
923
|
},
|
|
752
924
|
) => {
|
|
753
925
|
if (!webDragEnabled) return;
|
|
926
|
+
const span = boundedSpan(ref);
|
|
927
|
+
if (!span) return;
|
|
754
928
|
if (e.button !== undefined && e.button !== 0) return;
|
|
755
929
|
// A handle press must not start a whole-bar move session.
|
|
756
930
|
e.stopPropagation?.();
|
|
757
931
|
dragCleanupRef.current?.();
|
|
758
932
|
|
|
759
|
-
const span: GanttSpan = { start: task.start, end: task.end };
|
|
760
933
|
const maxShrinkPx = (spanInclusiveDays(span) - 1) * pxPerDay;
|
|
761
934
|
const startX = e.clientX;
|
|
762
935
|
const sign = dirSignRef.current;
|
|
@@ -793,7 +966,7 @@ export function GanttView({
|
|
|
793
966
|
prevUserSelect = document.body.style.userSelect;
|
|
794
967
|
document.body.style.userSelect = "none";
|
|
795
968
|
}
|
|
796
|
-
setResize({
|
|
969
|
+
setResize({ key: ref.key, edge, logicalDx: clampLogicalDx(dx), dayDelta: toDayDelta(dx) });
|
|
797
970
|
};
|
|
798
971
|
|
|
799
972
|
const onUp = (ue: PointerEvent) => {
|
|
@@ -802,9 +975,7 @@ export function GanttView({
|
|
|
802
975
|
teardown();
|
|
803
976
|
if (!wasActive) return;
|
|
804
977
|
suppressNextClick();
|
|
805
|
-
if (dayDelta !== 0)
|
|
806
|
-
onItemMove?.(task, resizeSpanByDays(span, edge, dayDelta));
|
|
807
|
-
}
|
|
978
|
+
if (dayDelta !== 0) onItemMove?.(task, resizeSpanByDays(span, edge, dayDelta), ref);
|
|
808
979
|
};
|
|
809
980
|
|
|
810
981
|
const onKey = (ke: KeyboardEvent) => {
|
|
@@ -832,9 +1003,12 @@ export function GanttView({
|
|
|
832
1003
|
);
|
|
833
1004
|
|
|
834
1005
|
const getBarDragProps = useCallback(
|
|
835
|
-
(task: GanttTask): Record<string, unknown> => {
|
|
1006
|
+
(task: GanttTask, ref: GanttSpanRef): Record<string, unknown> => {
|
|
1007
|
+
// An open-ended span has no second edge to hold a duration against, so
|
|
1008
|
+
// it gets no session at all rather than a drag that invents one.
|
|
1009
|
+
if (!boundedSpan(ref)) return {};
|
|
836
1010
|
if (webDragEnabled) {
|
|
837
|
-
return { onPointerDown: (e: any) => handleBarPointerDown(task, e) };
|
|
1011
|
+
return { onPointerDown: (e: any) => handleBarPointerDown(task, ref, e) };
|
|
838
1012
|
}
|
|
839
1013
|
if (nativeDragEnabled) {
|
|
840
1014
|
return {
|
|
@@ -842,7 +1016,7 @@ export function GanttView({
|
|
|
842
1016
|
onStartShouldSetResponder: () => true,
|
|
843
1017
|
onMoveShouldSetResponder: () => true,
|
|
844
1018
|
onResponderTerminationRequest: () => !nativeSessionRef.current?.dragging,
|
|
845
|
-
onResponderGrant: (e: any) => handleNativeGrant(task, e),
|
|
1019
|
+
onResponderGrant: (e: any) => handleNativeGrant(task, ref, e),
|
|
846
1020
|
onResponderMove: handleNativeMove,
|
|
847
1021
|
onResponderRelease: handleNativeRelease,
|
|
848
1022
|
onResponderTerminate: handleNativeTerminate,
|
|
@@ -863,15 +1037,17 @@ export function GanttView({
|
|
|
863
1037
|
|
|
864
1038
|
// ── Keyboard rescheduling (focused bar, discrete jumps — LC-25) ──────────
|
|
865
1039
|
const handleBarKeyboardMove = useCallback(
|
|
866
|
-
(task: GanttTask, key: "ArrowLeft" | "ArrowRight", shiftKey: boolean) => {
|
|
1040
|
+
(task: GanttTask, ref: GanttSpanRef, key: "ArrowLeft" | "ArrowRight", shiftKey: boolean) => {
|
|
1041
|
+
const span = boundedSpan(ref);
|
|
1042
|
+
if (!span) return;
|
|
867
1043
|
const physical = key === "ArrowRight" ? 1 : -1;
|
|
868
1044
|
// Physical arrow direction maps to a logical day delta (inverts in RTL).
|
|
869
1045
|
const dayDelta = physical * dirSignRef.current * (shiftKey ? 7 : 1);
|
|
870
|
-
const next = shiftSpanByDays(
|
|
871
|
-
onItemMove?.(task, next);
|
|
1046
|
+
const next = shiftSpanByDays(span, dayDelta);
|
|
1047
|
+
onItemMove?.(task, next, ref);
|
|
872
1048
|
setAnnouncement(
|
|
873
1049
|
withInterp(t("{{title}} moved to {{range}}"), {
|
|
874
|
-
title: task.title,
|
|
1050
|
+
title: ref.span.title ?? task.title,
|
|
875
1051
|
range: formatSpanLabel(next),
|
|
876
1052
|
}),
|
|
877
1053
|
);
|
|
@@ -879,21 +1055,183 @@ export function GanttView({
|
|
|
879
1055
|
[onItemMove, t],
|
|
880
1056
|
);
|
|
881
1057
|
|
|
1058
|
+
// ── Controlled marker (a playhead the caller owns) ───────────────────────
|
|
1059
|
+
const markerDragEnabled =
|
|
1060
|
+
(enableMarkerDrag ?? onMarkerDateChange !== undefined) && onMarkerDateChange !== undefined;
|
|
1061
|
+
const [markerDragging, setMarkerDragging] = useState(false);
|
|
1062
|
+
// The date the scrub STARTED from. Every emitted date is that date plus a
|
|
1063
|
+
// whole-day delta, never the last emitted one — otherwise a controlled
|
|
1064
|
+
// caller that applies each scrub would compound its own updates.
|
|
1065
|
+
const markerGrantRef = useRef<Date | null>(null);
|
|
1066
|
+
const markerEmittedRef = useRef<number | null>(null);
|
|
1067
|
+
const markerSessionRef = useRef<{ startX: number } | null>(null);
|
|
1068
|
+
|
|
1069
|
+
/** Emit a whole-day offset from the grant date, once per day crossed. */
|
|
1070
|
+
const emitMarker = useCallback(
|
|
1071
|
+
(dayDelta: number) => {
|
|
1072
|
+
const base = markerGrantRef.current;
|
|
1073
|
+
if (!base) return;
|
|
1074
|
+
const next = addDays(base, dayDelta);
|
|
1075
|
+
if (markerEmittedRef.current === next.getTime()) return;
|
|
1076
|
+
markerEmittedRef.current = next.getTime();
|
|
1077
|
+
onMarkerDateChange?.(next);
|
|
1078
|
+
},
|
|
1079
|
+
[onMarkerDateChange],
|
|
1080
|
+
);
|
|
1081
|
+
|
|
1082
|
+
const openMarkerSession = useCallback(() => {
|
|
1083
|
+
if (markerDate === undefined) return false;
|
|
1084
|
+
const base = startOfDay(markerDate);
|
|
1085
|
+
markerGrantRef.current = base;
|
|
1086
|
+
markerEmittedRef.current = base.getTime();
|
|
1087
|
+
return true;
|
|
1088
|
+
}, [markerDate]);
|
|
1089
|
+
|
|
1090
|
+
// Web: the bar drag's session contract on a single control — travel
|
|
1091
|
+
// threshold, 1:1 tracking, Escape restores the date the drag started from.
|
|
1092
|
+
const handleMarkerPointerDown = useCallback(
|
|
1093
|
+
(e: { button?: number; clientX: number; stopPropagation?: () => void }) => {
|
|
1094
|
+
if (!markerDragEnabled || !hasDom) return;
|
|
1095
|
+
if (e.button !== undefined && e.button !== 0) return;
|
|
1096
|
+
if (!openMarkerSession()) return;
|
|
1097
|
+
e.stopPropagation?.();
|
|
1098
|
+
dragCleanupRef.current?.();
|
|
1099
|
+
|
|
1100
|
+
const startX = e.clientX;
|
|
1101
|
+
let active = false;
|
|
1102
|
+
let ended = false;
|
|
1103
|
+
let prevUserSelect = "";
|
|
1104
|
+
const toDayDelta = (dx: number) => dirSignRef.current * dxToDayDelta(dx, pxPerDay);
|
|
1105
|
+
|
|
1106
|
+
const teardown = () => {
|
|
1107
|
+
if (ended) return;
|
|
1108
|
+
ended = true;
|
|
1109
|
+
window.removeEventListener("pointermove", onMove);
|
|
1110
|
+
window.removeEventListener("pointerup", onUp);
|
|
1111
|
+
window.removeEventListener("keydown", onKey, true);
|
|
1112
|
+
if (active) document.body.style.userSelect = prevUserSelect;
|
|
1113
|
+
setMarkerDragging(false);
|
|
1114
|
+
markerGrantRef.current = null;
|
|
1115
|
+
dragCleanupRef.current = null;
|
|
1116
|
+
};
|
|
1117
|
+
|
|
1118
|
+
const onMove = (me: PointerEvent) => {
|
|
1119
|
+
const dx = me.clientX - startX;
|
|
1120
|
+
if (!active) {
|
|
1121
|
+
if (Math.abs(dx) < DRAG_THRESHOLD_PX) return;
|
|
1122
|
+
active = true;
|
|
1123
|
+
prevUserSelect = document.body.style.userSelect;
|
|
1124
|
+
document.body.style.userSelect = "none";
|
|
1125
|
+
setMarkerDragging(true);
|
|
1126
|
+
}
|
|
1127
|
+
emitMarker(toDayDelta(dx));
|
|
1128
|
+
};
|
|
1129
|
+
|
|
1130
|
+
const onUp = () => teardown();
|
|
1131
|
+
|
|
1132
|
+
const onKey = (ke: KeyboardEvent) => {
|
|
1133
|
+
if (ke.key !== "Escape" || !active) return;
|
|
1134
|
+
ke.stopPropagation();
|
|
1135
|
+
emitMarker(0);
|
|
1136
|
+
teardown();
|
|
1137
|
+
};
|
|
1138
|
+
|
|
1139
|
+
window.addEventListener("pointermove", onMove);
|
|
1140
|
+
window.addEventListener("pointerup", onUp);
|
|
1141
|
+
window.addEventListener("keydown", onKey, true);
|
|
1142
|
+
dragCleanupRef.current = teardown;
|
|
1143
|
+
},
|
|
1144
|
+
[markerDragEnabled, hasDom, openMarkerSession, emitMarker, pxPerDay],
|
|
1145
|
+
);
|
|
1146
|
+
|
|
1147
|
+
// Native: the axis strip does not scroll, so the handle can claim the touch
|
|
1148
|
+
// immediately — no long-press lift to arbitrate against a scroller.
|
|
1149
|
+
const markerNativeProps = useMemo<Record<string, unknown>>(() => {
|
|
1150
|
+
if (!markerDragEnabled || isWeb) return {};
|
|
1151
|
+
return {
|
|
1152
|
+
onStartShouldSetResponder: () => true,
|
|
1153
|
+
onMoveShouldSetResponder: () => true,
|
|
1154
|
+
onResponderTerminationRequest: () => false,
|
|
1155
|
+
onResponderGrant: (e: any) => {
|
|
1156
|
+
if (!openMarkerSession()) return;
|
|
1157
|
+
markerSessionRef.current = { startX: e?.nativeEvent?.pageX ?? 0 };
|
|
1158
|
+
setMarkerDragging(true);
|
|
1159
|
+
},
|
|
1160
|
+
onResponderMove: (e: any) => {
|
|
1161
|
+
const session = markerSessionRef.current;
|
|
1162
|
+
if (!session) return;
|
|
1163
|
+
const dx = (e?.nativeEvent?.pageX ?? 0) - session.startX;
|
|
1164
|
+
emitMarker(dirSignRef.current * dxToDayDelta(dx, pxPerDay));
|
|
1165
|
+
},
|
|
1166
|
+
onResponderRelease: () => {
|
|
1167
|
+
markerSessionRef.current = null;
|
|
1168
|
+
markerGrantRef.current = null;
|
|
1169
|
+
setMarkerDragging(false);
|
|
1170
|
+
},
|
|
1171
|
+
onResponderTerminate: () => {
|
|
1172
|
+
markerSessionRef.current = null;
|
|
1173
|
+
markerGrantRef.current = null;
|
|
1174
|
+
setMarkerDragging(false);
|
|
1175
|
+
},
|
|
1176
|
+
};
|
|
1177
|
+
}, [markerDragEnabled, openMarkerSession, emitMarker, pxPerDay]);
|
|
1178
|
+
|
|
1179
|
+
const handleMarkerKeyboardMove = useCallback(
|
|
1180
|
+
(key: "ArrowLeft" | "ArrowRight", shiftKey: boolean) => {
|
|
1181
|
+
if (!markerDragEnabled || markerDate === undefined) return;
|
|
1182
|
+
const physical = key === "ArrowRight" ? 1 : -1;
|
|
1183
|
+
const dayDelta = physical * dirSignRef.current * (shiftKey ? 7 : 1);
|
|
1184
|
+
const next = addDays(startOfDay(markerDate), dayDelta);
|
|
1185
|
+
markerEmittedRef.current = next.getTime();
|
|
1186
|
+
onMarkerDateChange?.(next);
|
|
1187
|
+
setAnnouncement(
|
|
1188
|
+
withInterp(t("Marker moved to {{date}}"), { date: formatAbsoluteDate(next) }),
|
|
1189
|
+
);
|
|
1190
|
+
},
|
|
1191
|
+
[markerDragEnabled, markerDate, onMarkerDateChange, t],
|
|
1192
|
+
);
|
|
1193
|
+
|
|
1194
|
+
const markerX = markerDate === undefined ? null : dateLineX(range, pxPerDay, markerDate);
|
|
1195
|
+
const markerName = markerLabel ?? t("Marker");
|
|
1196
|
+
|
|
882
1197
|
// ── Bar rendering ─────────────────────────────────────────────────────────
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
1198
|
+
|
|
1199
|
+
/**
|
|
1200
|
+
* The bar's spoken name. Bounded spans keep the exact wording they had
|
|
1201
|
+
* ("Design review, Mar 10 – Mar 12"); the open shapes say which end is
|
|
1202
|
+
* open in words, because "…" is silence to a screen reader.
|
|
1203
|
+
*/
|
|
1204
|
+
const spanAccessibleName = (title: string, span: GanttOpenSpan): string => {
|
|
1205
|
+
if (isBoundedSpan(span)) {
|
|
1206
|
+
return ganttTaskAccessibleLabel({ title, start: span.start, end: span.end });
|
|
1207
|
+
}
|
|
1208
|
+
const parts = openSpanLabelParts(span);
|
|
1209
|
+
if (parts.start !== undefined) {
|
|
1210
|
+
return withInterp(t("{{title}}, from {{start}}, no end"), { title, start: parts.start });
|
|
1211
|
+
}
|
|
1212
|
+
if (parts.end !== undefined) {
|
|
1213
|
+
return withInterp(t("{{title}}, until {{end}}, no start"), { title, end: parts.end });
|
|
1214
|
+
}
|
|
1215
|
+
return withInterp(t("{{title}}, always, no dates"), { title });
|
|
1216
|
+
};
|
|
1217
|
+
|
|
1218
|
+
const renderBar = (task: GanttTask, ref: GanttSpanRef) => {
|
|
1219
|
+
const span = ref.span;
|
|
1220
|
+
const barKey = ref.key;
|
|
1221
|
+
const bounded = boundedSpan(ref);
|
|
1222
|
+
const geom = openBarGeometry(span, range, pxPerDay);
|
|
1223
|
+
const activeDrag = drag && drag.key === barKey ? drag : null;
|
|
886
1224
|
const dragging = activeDrag !== null;
|
|
887
|
-
const activeResize = resize && resize.
|
|
1225
|
+
const activeResize = resize && resize.key === barKey ? resize : null;
|
|
888
1226
|
const resizing = activeResize !== null;
|
|
889
1227
|
const sessionLive = dragging || resizing;
|
|
890
1228
|
const dayDelta = activeDrag?.dayDelta ?? activeResize?.dayDelta ?? 0;
|
|
891
|
-
const
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
1229
|
+
const previewSpan =
|
|
1230
|
+
bounded && activeDrag
|
|
1231
|
+
? shiftSpanByDays(bounded, dayDelta)
|
|
1232
|
+
: bounded && activeResize
|
|
1233
|
+
? resizeSpanByDays(bounded, activeResize.edge, activeResize.dayDelta)
|
|
1234
|
+
: null;
|
|
897
1235
|
const previewGeom = previewSpan ? barGeometry(previewSpan, range.start, pxPerDay) : null;
|
|
898
1236
|
// Live geometry: a move rides a pure transform; a resize tracks the
|
|
899
1237
|
// dragged edge 1:1 (the opposite edge stays put in both directions).
|
|
@@ -910,19 +1248,35 @@ export function GanttView({
|
|
|
910
1248
|
: activeResize && activeResize.edge === "start"
|
|
911
1249
|
? activeResize.logicalDx * dirSign
|
|
912
1250
|
: 0;
|
|
1251
|
+
const barColor = span.color ?? task.color;
|
|
1252
|
+
const barIntent = span.intent ?? task.intent;
|
|
1253
|
+
const barTitle = span.title ?? task.title;
|
|
913
1254
|
const fill =
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
const
|
|
1255
|
+
barColor ?? (barIntent && barIntent !== "accent" ? "$color9" : "$accentBackground");
|
|
1256
|
+
// Progress is a fraction of a DURATION; an open span has none, so a bar
|
|
1257
|
+
// that claimed 40% of forever would be inventing the denominator.
|
|
1258
|
+
const progress = bounded ? clampProgress(span.progress ?? task.progress) : null;
|
|
1259
|
+
const showLabel = !geom.eternal && liveWidth >= 44;
|
|
1260
|
+
const isBarFocused = focusedBarId === barKey;
|
|
918
1261
|
const showHandles = hoveredId === task.id || sessionLive;
|
|
919
1262
|
// Edge handles map physical sides to logical edges (mirrored under RTL).
|
|
920
|
-
const handleWidth = geom.width >= 24 ? 8 : geom.width >= 12 ? 4 : 0;
|
|
1263
|
+
const handleWidth = bounded ? (geom.width >= 24 ? 8 : geom.width >= 12 ? 4 : 0) : 0;
|
|
921
1264
|
const physicalLeftEdge: GanttResizeEdge = rtl ? "end" : "start";
|
|
922
1265
|
const physicalRightEdge: GanttResizeEdge = rtl ? "start" : "end";
|
|
1266
|
+
// An open END is physically on the right in LTR and on the left in RTL —
|
|
1267
|
+
// the chevron follows the mirror, and so does which glyph it is.
|
|
1268
|
+
const openStartSide = rtl ? { right: 2 } : { left: 2 };
|
|
1269
|
+
const openEndSide = rtl ? { left: 2 } : { right: 2 };
|
|
1270
|
+
const squareStart = rtl
|
|
1271
|
+
? { borderTopRightRadius: 0, borderBottomRightRadius: 0 }
|
|
1272
|
+
: { borderTopLeftRadius: 0, borderBottomLeftRadius: 0 };
|
|
1273
|
+
const squareEnd = rtl
|
|
1274
|
+
? { borderTopLeftRadius: 0, borderBottomLeftRadius: 0 }
|
|
1275
|
+
: { borderTopRightRadius: 0, borderBottomRightRadius: 0 };
|
|
1276
|
+
const height = geom.eternal ? railHeight : barHeight;
|
|
923
1277
|
|
|
924
1278
|
return (
|
|
925
|
-
<BarIntentWrap key={
|
|
1279
|
+
<BarIntentWrap key={barKey} intent={barColor ? undefined : barIntent}>
|
|
926
1280
|
{/* Snapped drop preview (the raw bar tracks the pointer 1:1). */}
|
|
927
1281
|
{sessionLive && dayDelta !== 0 && previewGeom && (
|
|
928
1282
|
<YStack
|
|
@@ -937,23 +1291,26 @@ export function GanttView({
|
|
|
937
1291
|
backgroundColor="$accentBackground"
|
|
938
1292
|
opacity={0.25}
|
|
939
1293
|
pointerEvents="none"
|
|
940
|
-
{...{ "data-gantt-drop-preview":
|
|
1294
|
+
{...{ "data-gantt-drop-preview": barKey }}
|
|
941
1295
|
/>
|
|
942
1296
|
)}
|
|
943
1297
|
<YStack
|
|
944
1298
|
position="absolute"
|
|
945
1299
|
{...canvasPos(geom.x)}
|
|
946
1300
|
width={liveWidth}
|
|
947
|
-
top={barInset}
|
|
948
|
-
height={
|
|
1301
|
+
top={barInset + (barHeight - height) / 2}
|
|
1302
|
+
height={height}
|
|
949
1303
|
x={liveTransformX}
|
|
950
1304
|
zIndex={sessionLive ? 3 : 1}
|
|
951
1305
|
{...knobProps.borderRadius}
|
|
1306
|
+
{...(geom.openStart ? squareStart : null)}
|
|
1307
|
+
{...(geom.openEnd ? squareEnd : null)}
|
|
952
1308
|
backgroundColor={fill as any}
|
|
953
|
-
|
|
954
|
-
|
|
1309
|
+
// A rail reads as chrome, not as a duration somebody set.
|
|
1310
|
+
opacity={sessionLive ? 0.85 : geom.eternal ? 0.55 : 1}
|
|
1311
|
+
hoverStyle={{ opacity: sessionLive ? 0.85 : geom.eternal ? 0.7 : 0.9 }}
|
|
955
1312
|
pressStyle={{ opacity: 0.8 }}
|
|
956
|
-
cursor={webDragEnabled ? "grab" : onItemPress ? "pointer" : undefined}
|
|
1313
|
+
cursor={bounded && webDragEnabled ? "grab" : onItemPress ? "pointer" : undefined}
|
|
957
1314
|
justifyContent="center"
|
|
958
1315
|
// LC-25: committed/reverted geometry jumps tween on web; the live
|
|
959
1316
|
// drag/resize tracking stays 1:1 (no transition while the session
|
|
@@ -961,15 +1318,15 @@ export function GanttView({
|
|
|
961
1318
|
transition={(sessionLive ? undefined : webLayoutTransition) as any}
|
|
962
1319
|
role="button"
|
|
963
1320
|
tabIndex={0}
|
|
964
|
-
aria-label={
|
|
1321
|
+
aria-label={spanAccessibleName(barTitle, span)}
|
|
965
1322
|
// LC-71: one ring on the bar (the perceived control), keyboard-only.
|
|
966
1323
|
{...(isBarFocused && barKeyboardRing ? keyboardFocusRingProps : { outlineWidth: 0 })}
|
|
967
1324
|
onFocus={() => {
|
|
968
|
-
setFocusedBarId(
|
|
1325
|
+
setFocusedBarId(barKey);
|
|
969
1326
|
setBarKeyboardRing(wasKeyboardFocus());
|
|
970
1327
|
}}
|
|
971
1328
|
onBlur={() => {
|
|
972
|
-
setFocusedBarId((id) => (id ===
|
|
1329
|
+
setFocusedBarId((id) => (id === barKey ? null : id));
|
|
973
1330
|
setBarKeyboardRing(false);
|
|
974
1331
|
}}
|
|
975
1332
|
// Tamagui forwards onHoverIn/onHoverOut at runtime; the RN-flavored
|
|
@@ -986,18 +1343,24 @@ export function GanttView({
|
|
|
986
1343
|
onItemPress?.(task);
|
|
987
1344
|
return;
|
|
988
1345
|
}
|
|
989
|
-
if ((ke.key === "ArrowLeft" || ke.key === "ArrowRight") && dragEnabled) {
|
|
1346
|
+
if ((ke.key === "ArrowLeft" || ke.key === "ArrowRight") && dragEnabled && bounded) {
|
|
990
1347
|
ke.preventDefault?.();
|
|
991
1348
|
ke.stopPropagation?.();
|
|
992
|
-
handleBarKeyboardMove(task, ke.key, ke.shiftKey === true);
|
|
1349
|
+
handleBarKeyboardMove(task, ref, ke.key, ke.shiftKey === true);
|
|
993
1350
|
}
|
|
994
1351
|
}) as any
|
|
995
1352
|
}
|
|
996
|
-
{...{ "data-gantt-bar":
|
|
997
|
-
{...(
|
|
1353
|
+
{...{ "data-gantt-bar": barKey }}
|
|
1354
|
+
{...(geom.eternal ? { "data-gantt-rail": "true" } : null)}
|
|
1355
|
+
{...(geom.openStart || geom.openEnd
|
|
1356
|
+
? {
|
|
1357
|
+
"data-gantt-span-open": geom.eternal ? "both" : geom.openStart ? "start" : "end",
|
|
1358
|
+
}
|
|
1359
|
+
: null)}
|
|
1360
|
+
{...(nativeDragEnabled ? null : getBarDragProps(task, ref))}
|
|
998
1361
|
// Native drag responders own the tap → press is handled on release.
|
|
999
1362
|
onPress={
|
|
1000
|
-
nativeDragEnabled
|
|
1363
|
+
nativeDragEnabled && bounded
|
|
1001
1364
|
? undefined
|
|
1002
1365
|
: (e) => {
|
|
1003
1366
|
(e as any)?.stopPropagation?.();
|
|
@@ -1019,7 +1382,37 @@ export function GanttView({
|
|
|
1019
1382
|
{...{ "data-gantt-progress": String(progress) }}
|
|
1020
1383
|
/>
|
|
1021
1384
|
)}
|
|
1022
|
-
{showLabel && <GanttBarLabel title={
|
|
1385
|
+
{showLabel && <GanttBarLabel title={barTitle} fill={fill} />}
|
|
1386
|
+
|
|
1387
|
+
{/* "This end is not an end" — a mark, never a cap. */}
|
|
1388
|
+
{geom.openStart && (
|
|
1389
|
+
<Text
|
|
1390
|
+
position="absolute"
|
|
1391
|
+
{...openStartSide}
|
|
1392
|
+
{...knobProps.label}
|
|
1393
|
+
color="$color12"
|
|
1394
|
+
opacity={0.75}
|
|
1395
|
+
pointerEvents="none"
|
|
1396
|
+
aria-hidden
|
|
1397
|
+
{...{ "data-gantt-open-start": "true" }}
|
|
1398
|
+
>
|
|
1399
|
+
{rtl ? "»" : "«"}
|
|
1400
|
+
</Text>
|
|
1401
|
+
)}
|
|
1402
|
+
{geom.openEnd && (
|
|
1403
|
+
<Text
|
|
1404
|
+
position="absolute"
|
|
1405
|
+
{...openEndSide}
|
|
1406
|
+
{...knobProps.label}
|
|
1407
|
+
color="$color12"
|
|
1408
|
+
opacity={0.75}
|
|
1409
|
+
pointerEvents="none"
|
|
1410
|
+
aria-hidden
|
|
1411
|
+
{...{ "data-gantt-open-end": "true" }}
|
|
1412
|
+
>
|
|
1413
|
+
{rtl ? "«" : "»"}
|
|
1414
|
+
</Text>
|
|
1415
|
+
)}
|
|
1023
1416
|
|
|
1024
1417
|
{/* Live date label while dragging (honest preview of the commit). */}
|
|
1025
1418
|
{previewSpan && (
|
|
@@ -1054,7 +1447,7 @@ export function GanttView({
|
|
|
1054
1447
|
cursor="ew-resize"
|
|
1055
1448
|
backgroundColor={showHandles ? "$color12" : "transparent"}
|
|
1056
1449
|
opacity={showHandles ? 0.28 : 0}
|
|
1057
|
-
onPointerDown={(e: any) => handleResizePointerDown(task, physicalLeftEdge, e)}
|
|
1450
|
+
onPointerDown={(e: any) => handleResizePointerDown(task, ref, physicalLeftEdge, e)}
|
|
1058
1451
|
{...{ "data-gantt-resize-handle": physicalLeftEdge }}
|
|
1059
1452
|
/>
|
|
1060
1453
|
<YStack
|
|
@@ -1066,7 +1459,7 @@ export function GanttView({
|
|
|
1066
1459
|
cursor="ew-resize"
|
|
1067
1460
|
backgroundColor={showHandles ? "$color12" : "transparent"}
|
|
1068
1461
|
opacity={showHandles ? 0.28 : 0}
|
|
1069
|
-
onPointerDown={(e: any) => handleResizePointerDown(task, physicalRightEdge, e)}
|
|
1462
|
+
onPointerDown={(e: any) => handleResizePointerDown(task, ref, physicalRightEdge, e)}
|
|
1070
1463
|
{...{ "data-gantt-resize-handle": physicalRightEdge }}
|
|
1071
1464
|
/>
|
|
1072
1465
|
</>
|
|
@@ -1075,7 +1468,7 @@ export function GanttView({
|
|
|
1075
1468
|
{/* Native drag surface: responders live on a plain fill view because
|
|
1076
1469
|
the bar's Tamagui pressability would clobber them (Kanban keeps
|
|
1077
1470
|
its drag responders off the pressable Card the same way). */}
|
|
1078
|
-
{nativeDragEnabled && (
|
|
1471
|
+
{nativeDragEnabled && bounded && (
|
|
1079
1472
|
<YStack
|
|
1080
1473
|
position="absolute"
|
|
1081
1474
|
top={0}
|
|
@@ -1083,7 +1476,7 @@ export function GanttView({
|
|
|
1083
1476
|
right={0}
|
|
1084
1477
|
bottom={0}
|
|
1085
1478
|
zIndex={5}
|
|
1086
|
-
{...getBarDragProps(task)}
|
|
1479
|
+
{...getBarDragProps(task, ref)}
|
|
1087
1480
|
/>
|
|
1088
1481
|
)}
|
|
1089
1482
|
</YStack>
|
|
@@ -1092,7 +1485,7 @@ export function GanttView({
|
|
|
1092
1485
|
};
|
|
1093
1486
|
|
|
1094
1487
|
// ── Render ────────────────────────────────────────────────────────────────
|
|
1095
|
-
const scrollLocked = drag !== null || resize !== null;
|
|
1488
|
+
const scrollLocked = drag !== null || resize !== null || markerDragging;
|
|
1096
1489
|
const majorGridColor = "$borderColor";
|
|
1097
1490
|
const minorGridColor = componentColors.divider;
|
|
1098
1491
|
// Manual mirroring owns RTL inside the horizontal scrollers: force their
|
|
@@ -1267,6 +1660,60 @@ export function GanttView({
|
|
|
1267
1660
|
backgroundColor={componentColors.divider}
|
|
1268
1661
|
pointerEvents="none"
|
|
1269
1662
|
/>
|
|
1663
|
+
{/* The marker is scrubbed on the AXIS, never on the rows — a
|
|
1664
|
+
press inside a row stays a press on that bar. */}
|
|
1665
|
+
{markerX !== null && (
|
|
1666
|
+
<>
|
|
1667
|
+
<YStack
|
|
1668
|
+
position="absolute"
|
|
1669
|
+
{...canvasPos(markerX - 1)}
|
|
1670
|
+
top={0}
|
|
1671
|
+
bottom={0}
|
|
1672
|
+
width={2}
|
|
1673
|
+
backgroundColor="$color12"
|
|
1674
|
+
opacity={0.9}
|
|
1675
|
+
pointerEvents="none"
|
|
1676
|
+
/>
|
|
1677
|
+
<YStack
|
|
1678
|
+
position="absolute"
|
|
1679
|
+
{...canvasPos(markerX - 12)}
|
|
1680
|
+
top={0}
|
|
1681
|
+
bottom={0}
|
|
1682
|
+
width={24}
|
|
1683
|
+
alignItems="center"
|
|
1684
|
+
justifyContent="flex-end"
|
|
1685
|
+
zIndex={4}
|
|
1686
|
+
cursor={markerDragEnabled ? "ew-resize" : undefined}
|
|
1687
|
+
role="slider"
|
|
1688
|
+
tabIndex={markerDragEnabled ? 0 : -1}
|
|
1689
|
+
aria-label={markerName}
|
|
1690
|
+
aria-valuetext={markerDate ? formatAbsoluteDate(markerDate) : undefined}
|
|
1691
|
+
{...(markerDragEnabled && hasDom
|
|
1692
|
+
? { onPointerDown: (e: any) => handleMarkerPointerDown(e) }
|
|
1693
|
+
: null)}
|
|
1694
|
+
{...markerNativeProps}
|
|
1695
|
+
onKeyDown={
|
|
1696
|
+
((ke: any) => {
|
|
1697
|
+
if (ke.key !== "ArrowLeft" && ke.key !== "ArrowRight") return;
|
|
1698
|
+
ke.preventDefault?.();
|
|
1699
|
+
ke.stopPropagation?.();
|
|
1700
|
+
handleMarkerKeyboardMove(ke.key, ke.shiftKey === true);
|
|
1701
|
+
}) as any
|
|
1702
|
+
}
|
|
1703
|
+
{...{ "data-gantt-marker-handle": "true" }}
|
|
1704
|
+
>
|
|
1705
|
+
<YStack
|
|
1706
|
+
width={11}
|
|
1707
|
+
height={9}
|
|
1708
|
+
marginBottom={2}
|
|
1709
|
+
borderRadius={2}
|
|
1710
|
+
backgroundColor="$color12"
|
|
1711
|
+
opacity={markerDragging ? 1 : 0.9}
|
|
1712
|
+
pointerEvents="none"
|
|
1713
|
+
/>
|
|
1714
|
+
</YStack>
|
|
1715
|
+
</>
|
|
1716
|
+
)}
|
|
1270
1717
|
</XStack>
|
|
1271
1718
|
</ScrollView>
|
|
1272
1719
|
</XStack>
|
|
@@ -1279,9 +1726,13 @@ export function GanttView({
|
|
|
1279
1726
|
{/* Task label column */}
|
|
1280
1727
|
<YStack width={labelWidth} flexShrink={0} {...hairlineEnd} borderColor="$borderColor">
|
|
1281
1728
|
{tasks.map((task, index) => {
|
|
1282
|
-
const
|
|
1729
|
+
const refs = resolveSpans(task);
|
|
1730
|
+
// A row is "selected" when any of ITS spans holds focus — for
|
|
1731
|
+
// a single-span row that is still `focusedBarId === task.id`.
|
|
1732
|
+
const selected = refs.some((ref) => ref.key === focusedBarId);
|
|
1283
1733
|
const hovered = hoveredId === task.id;
|
|
1284
1734
|
const last = index === tasks.length - 1;
|
|
1735
|
+
const firstKey = refs[0]?.key ?? task.id;
|
|
1285
1736
|
return (
|
|
1286
1737
|
<XStack
|
|
1287
1738
|
key={task.id}
|
|
@@ -1308,12 +1759,12 @@ export function GanttView({
|
|
|
1308
1759
|
onItemPress
|
|
1309
1760
|
? () => {
|
|
1310
1761
|
if (suppressClickRef.current) return;
|
|
1311
|
-
setFocusedBarId(
|
|
1762
|
+
setFocusedBarId(firstKey);
|
|
1312
1763
|
setBarKeyboardRing(false);
|
|
1313
1764
|
onItemPress(task);
|
|
1314
1765
|
}
|
|
1315
1766
|
: () => {
|
|
1316
|
-
setFocusedBarId(
|
|
1767
|
+
setFocusedBarId(firstKey);
|
|
1317
1768
|
setBarKeyboardRing(false);
|
|
1318
1769
|
}
|
|
1319
1770
|
}
|
|
@@ -1385,7 +1836,8 @@ export function GanttView({
|
|
|
1385
1836
|
|
|
1386
1837
|
{/* Task rows */}
|
|
1387
1838
|
{tasks.map((task, index) => {
|
|
1388
|
-
const
|
|
1839
|
+
const refs = resolveSpans(task);
|
|
1840
|
+
const selected = refs.some((ref) => ref.key === focusedBarId);
|
|
1389
1841
|
const hovered = hoveredId === task.id;
|
|
1390
1842
|
const last = index === tasks.length - 1;
|
|
1391
1843
|
return (
|
|
@@ -1408,11 +1860,27 @@ export function GanttView({
|
|
|
1408
1860
|
} as Record<string, unknown>)}
|
|
1409
1861
|
{...{ "data-gantt-row": task.id }}
|
|
1410
1862
|
>
|
|
1411
|
-
{renderBar(task)}
|
|
1863
|
+
{refs.map((ref) => renderBar(task, ref))}
|
|
1412
1864
|
</XStack>
|
|
1413
1865
|
);
|
|
1414
1866
|
})}
|
|
1415
1867
|
|
|
1868
|
+
{/* Marker line (controlled — the caller owns the date) */}
|
|
1869
|
+
{markerX !== null && (
|
|
1870
|
+
<YStack
|
|
1871
|
+
position="absolute"
|
|
1872
|
+
{...canvasPos(markerX - 1)}
|
|
1873
|
+
top={0}
|
|
1874
|
+
bottom={0}
|
|
1875
|
+
width={2}
|
|
1876
|
+
backgroundColor="$color12"
|
|
1877
|
+
opacity={markerDragging ? 0.95 : 0.75}
|
|
1878
|
+
pointerEvents="none"
|
|
1879
|
+
zIndex={2}
|
|
1880
|
+
{...{ "data-gantt-marker": "true" }}
|
|
1881
|
+
/>
|
|
1882
|
+
)}
|
|
1883
|
+
|
|
1416
1884
|
{/* Today line (above bars, non-interactive) */}
|
|
1417
1885
|
{todayX !== null && (
|
|
1418
1886
|
<YStack
|