@multiplatform.one/components 7.10.0 → 7.15.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/README.md +100 -2
- package/dist/cjs/Accordion/index.cjs +2 -6
- package/dist/cjs/Accordion/index.native.js +2 -6
- package/dist/cjs/Accordion/index.native.js.map +1 -1
- package/dist/cjs/AnimateHeight/index.cjs +1 -3
- package/dist/cjs/AnimateHeight/index.native.js +1 -3
- package/dist/cjs/AnimateHeight/index.native.js.map +1 -1
- package/dist/cjs/Chip/index.cjs +8 -1
- package/dist/cjs/Chip/index.native.js +8 -1
- package/dist/cjs/Chip/index.native.js.map +1 -1
- package/dist/cjs/SheetModal/index.cjs +22 -3
- package/dist/cjs/SheetModal/index.native.js +115 -27
- package/dist/cjs/SheetModal/index.native.js.map +1 -1
- package/dist/cjs/Tabs/index.cjs +35 -18
- package/dist/cjs/Tabs/index.native.js +39 -18
- package/dist/cjs/Tabs/index.native.js.map +1 -1
- package/dist/cjs/Text.cjs +2 -0
- package/dist/cjs/Text.native.js +2 -0
- package/dist/cjs/Text.native.js.map +1 -1
- package/dist/cjs/TreeSelect/index.cjs +55 -52
- package/dist/cjs/TreeSelect/index.native.js +55 -52
- package/dist/cjs/TreeSelect/index.native.js.map +1 -1
- package/dist/cjs/Video/PlayerChrome.cjs +3 -9
- package/dist/cjs/Video/PlayerChrome.native.js +3 -9
- package/dist/cjs/Video/PlayerChrome.native.js.map +1 -1
- package/dist/cjs/code/Code/index.cjs +6 -0
- package/dist/cjs/code/Code/index.native.js +7 -4
- package/dist/cjs/code/Code/index.native.js.map +1 -1
- package/dist/cjs/code/CodeBlock/index.cjs +4 -5
- package/dist/cjs/code/CodeBlock/index.native.js +4 -5
- package/dist/cjs/code/CodeBlock/index.native.js.map +1 -1
- package/dist/cjs/icons/themed.cjs +2 -1
- package/dist/cjs/icons/themed.native.js +2 -1
- package/dist/cjs/icons/themed.native.js.map +1 -1
- package/dist/cjs/knobImmuneExports.cjs +3 -3
- package/dist/cjs/knobImmuneExports.native.js +3 -3
- package/dist/cjs/layouts/PaneScaffold.cjs +70 -42
- package/dist/cjs/layouts/PaneScaffold.native.js +75 -48
- package/dist/cjs/layouts/PaneScaffold.native.js.map +1 -1
- package/dist/cjs/layouts/page.cjs +2 -1
- package/dist/cjs/layouts/page.native.js +2 -1
- package/dist/cjs/layouts/page.native.js.map +1 -1
- package/dist/cjs/layouts/sidebar.cjs +1 -3
- package/dist/cjs/layouts/sidebar.native.js +1 -3
- package/dist/cjs/layouts/sidebar.native.js.map +1 -1
- package/dist/cjs/layouts/tags.native.js.map +1 -1
- package/dist/cjs/surfaces.cjs +0 -32
- package/dist/cjs/surfaces.native.js +0 -32
- package/dist/cjs/surfaces.native.js.map +1 -1
- package/dist/cjs/views/List.cjs +1 -3
- package/dist/cjs/views/List.native.js +1 -3
- package/dist/cjs/views/List.native.js.map +1 -1
- package/dist/cjs/views/Matrix.cjs +568 -0
- package/dist/cjs/views/Matrix.native.js +612 -0
- package/dist/cjs/views/Matrix.native.js.map +1 -0
- package/dist/cjs/views/TreeView.cjs +175 -43
- package/dist/cjs/views/TreeView.native.js +181 -46
- package/dist/cjs/views/TreeView.native.js.map +1 -1
- package/dist/cjs/views/ganttMath.cjs +2 -0
- package/dist/cjs/views/ganttMath.native.js +2 -0
- package/dist/cjs/views/ganttMath.native.js.map +1 -1
- package/dist/cjs/views/index.cjs +16 -0
- package/dist/cjs/views/index.native.js +16 -0
- package/dist/cjs/views/index.native.js.map +1 -1
- package/dist/cjs/views/matrixMath.cjs +157 -0
- package/dist/cjs/views/matrixMath.native.js +229 -0
- package/dist/cjs/views/matrixMath.native.js.map +1 -0
- package/dist/esm/Accordion/index.mjs +3 -7
- package/dist/esm/Accordion/index.mjs.map +1 -1
- package/dist/esm/Accordion/index.native.js +3 -7
- package/dist/esm/Accordion/index.native.js.map +1 -1
- package/dist/esm/AnimateHeight/index.mjs +2 -4
- package/dist/esm/AnimateHeight/index.mjs.map +1 -1
- package/dist/esm/AnimateHeight/index.native.js +2 -4
- 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.native.js.map +1 -1
- package/dist/esm/Carousel/index.native.js.map +1 -1
- package/dist/esm/Chip/index.mjs +9 -2
- package/dist/esm/Chip/index.mjs.map +1 -1
- package/dist/esm/Chip/index.native.js +9 -2
- package/dist/esm/Chip/index.native.js.map +1 -1
- package/dist/esm/Collapsible.native.js.map +1 -1
- package/dist/esm/ContextMenu/index.native.js.map +1 -1
- 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.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.native.js.map +1 -1
- package/dist/esm/Meter/meter.native.js.map +1 -1
- 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/SheetModal/index.mjs +22 -3
- package/dist/esm/SheetModal/index.mjs.map +1 -1
- package/dist/esm/SheetModal/index.native.js +117 -29
- package/dist/esm/SheetModal/index.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 +36 -19
- package/dist/esm/Tabs/index.mjs.map +1 -1
- package/dist/esm/Tabs/index.native.js +40 -19
- package/dist/esm/Tabs/index.native.js.map +1 -1
- package/dist/esm/Text.mjs +3 -1
- package/dist/esm/Text.mjs.map +1 -1
- package/dist/esm/Text.native.js +3 -1
- package/dist/esm/Text.native.js.map +1 -1
- 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.mjs +56 -53
- package/dist/esm/TreeSelect/index.mjs.map +1 -1
- package/dist/esm/TreeSelect/index.native.js +56 -53
- 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.mjs +4 -10
- package/dist/esm/Video/PlayerChrome.mjs.map +1 -1
- package/dist/esm/Video/PlayerChrome.native.js +4 -10
- 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.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.native.js.map +1 -1
- package/dist/esm/charts/BarChart.native.js.map +1 -1
- package/dist/esm/charts/ChartDataView.native.js.map +1 -1
- package/dist/esm/charts/ChartSurface.native.js.map +1 -1
- package/dist/esm/charts/LineChart.native.js.map +1 -1
- package/dist/esm/charts/PieChart.native.js.map +1 -1
- package/dist/esm/charts/Sparkline.native.js.map +1 -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.native.js.map +1 -1
- package/dist/esm/charts/math.native.js.map +1 -1
- package/dist/esm/charts/series.native.js.map +1 -1
- 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/Code/index.mjs +6 -0
- package/dist/esm/code/Code/index.mjs.map +1 -1
- package/dist/esm/code/Code/index.native.js +10 -7
- package/dist/esm/code/Code/index.native.js.map +1 -1
- package/dist/esm/code/CodeBlock/index.mjs +5 -6
- package/dist/esm/code/CodeBlock/index.mjs.map +1 -1
- package/dist/esm/code/CodeBlock/index.native.js +5 -6
- 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.native.js.map +1 -1
- package/dist/esm/feedback/NotifyHost.native.js.map +1 -1
- package/dist/esm/feedback/copy.native.js.map +1 -1
- package/dist/esm/feedback/index.native.js.map +1 -1
- package/dist/esm/feedback/notify.native.js.map +1 -1
- package/dist/esm/feedback/route.native.js.map +1 -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.native.js.map +1 -1
- package/dist/esm/icons/themed.mjs +3 -2
- package/dist/esm/icons/themed.mjs.map +1 -1
- package/dist/esm/icons/themed.native.js +3 -2
- 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 +3 -3
- package/dist/esm/knobImmuneExports.native.js +3 -3
- 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 +70 -42
- package/dist/esm/layouts/PaneScaffold.mjs.map +1 -1
- package/dist/esm/layouts/PaneScaffold.native.js +75 -48
- 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.native.js.map +1 -1
- package/dist/esm/layouts/page.mjs +3 -2
- package/dist/esm/layouts/page.mjs.map +1 -1
- package/dist/esm/layouts/page.native.js +3 -2
- 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.mjs +2 -4
- package/dist/esm/layouts/sidebar.mjs.map +1 -1
- package/dist/esm/layouts/sidebar.native.js +2 -4
- package/dist/esm/layouts/sidebar.native.js.map +1 -1
- package/dist/esm/layouts/tags.mjs.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/useReturnFocusOnClose.native.js.map +1 -1
- package/dist/esm/surfaces.mjs +1 -33
- package/dist/esm/surfaces.mjs.map +1 -1
- package/dist/esm/surfaces.native.js +1 -33
- package/dist/esm/surfaces.native.js.map +1 -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.native.js.map +1 -1
- 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.mjs +2 -4
- package/dist/esm/views/List.mjs.map +1 -1
- package/dist/esm/views/List.native.js +2 -4
- package/dist/esm/views/List.native.js.map +1 -1
- package/dist/esm/views/Matrix.mjs +543 -0
- package/dist/esm/views/Matrix.mjs.map +1 -0
- package/dist/esm/views/Matrix.native.js +573 -0
- package/dist/esm/views/Matrix.native.js.map +1 -0
- package/dist/esm/views/ReportBuilder.native.js.map +1 -1
- package/dist/esm/views/TreeView.mjs +175 -43
- package/dist/esm/views/TreeView.mjs.map +1 -1
- package/dist/esm/views/TreeView.native.js +181 -46
- 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 +1 -1
- package/dist/esm/views/ganttMath.mjs.map +1 -1
- package/dist/esm/views/ganttMath.native.js +1 -1
- package/dist/esm/views/ganttMath.native.js.map +1 -1
- package/dist/esm/views/index.mjs +4 -2
- package/dist/esm/views/index.mjs.map +1 -1
- package/dist/esm/views/index.native.js +4 -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/matrixMath.mjs +122 -0
- package/dist/esm/views/matrixMath.mjs.map +1 -0
- package/dist/esm/views/matrixMath.native.js +191 -0
- package/dist/esm/views/matrixMath.native.js.map +1 -0
- 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/esm/views/treeViewReveal.native.js.map +1 -1
- package/dist/jsx/Accordion/index.mjs +3 -7
- package/dist/jsx/Accordion/index.mjs.map +1 -1
- package/dist/jsx/Accordion/index.native.js +2 -6
- package/dist/jsx/Accordion/index.native.js.map +1 -1
- package/dist/jsx/AnimateHeight/index.mjs +2 -4
- package/dist/jsx/AnimateHeight/index.mjs.map +1 -1
- package/dist/jsx/AnimateHeight/index.native.js +1 -3
- package/dist/jsx/AnimateHeight/index.native.js.map +1 -1
- package/dist/jsx/Chip/index.mjs +9 -2
- package/dist/jsx/Chip/index.mjs.map +1 -1
- package/dist/jsx/Chip/index.native.js +8 -1
- package/dist/jsx/Chip/index.native.js.map +1 -1
- package/dist/jsx/SheetModal/index.mjs +22 -3
- package/dist/jsx/SheetModal/index.mjs.map +1 -1
- package/dist/jsx/SheetModal/index.native.js +115 -27
- package/dist/jsx/SheetModal/index.native.js.map +1 -1
- package/dist/jsx/Tabs/index.mjs +36 -19
- package/dist/jsx/Tabs/index.mjs.map +1 -1
- package/dist/jsx/Tabs/index.native.js +39 -18
- package/dist/jsx/Tabs/index.native.js.map +1 -1
- package/dist/jsx/Text.mjs +3 -1
- package/dist/jsx/Text.mjs.map +1 -1
- package/dist/jsx/Text.native.js +2 -0
- package/dist/jsx/Text.native.js.map +1 -1
- package/dist/jsx/TreeSelect/index.mjs +56 -53
- package/dist/jsx/TreeSelect/index.mjs.map +1 -1
- package/dist/jsx/TreeSelect/index.native.js +55 -52
- package/dist/jsx/TreeSelect/index.native.js.map +1 -1
- package/dist/jsx/Video/PlayerChrome.mjs +4 -10
- package/dist/jsx/Video/PlayerChrome.mjs.map +1 -1
- package/dist/jsx/Video/PlayerChrome.native.js +3 -9
- package/dist/jsx/Video/PlayerChrome.native.js.map +1 -1
- package/dist/jsx/code/Code/index.mjs +6 -0
- package/dist/jsx/code/Code/index.mjs.map +1 -1
- package/dist/jsx/code/Code/index.native.js +7 -4
- package/dist/jsx/code/Code/index.native.js.map +1 -1
- package/dist/jsx/code/CodeBlock/index.mjs +5 -6
- package/dist/jsx/code/CodeBlock/index.mjs.map +1 -1
- package/dist/jsx/code/CodeBlock/index.native.js +4 -5
- package/dist/jsx/code/CodeBlock/index.native.js.map +1 -1
- package/dist/jsx/icons/themed.mjs +3 -2
- package/dist/jsx/icons/themed.mjs.map +1 -1
- package/dist/jsx/icons/themed.native.js +2 -1
- package/dist/jsx/icons/themed.native.js.map +1 -1
- package/dist/jsx/knobImmuneExports.mjs +3 -3
- package/dist/jsx/knobImmuneExports.native.js +3 -3
- package/dist/jsx/layouts/PaneScaffold.mjs +70 -42
- package/dist/jsx/layouts/PaneScaffold.mjs.map +1 -1
- package/dist/jsx/layouts/PaneScaffold.native.js +75 -48
- package/dist/jsx/layouts/PaneScaffold.native.js.map +1 -1
- package/dist/jsx/layouts/page.mjs +3 -2
- package/dist/jsx/layouts/page.mjs.map +1 -1
- package/dist/jsx/layouts/page.native.js +2 -1
- package/dist/jsx/layouts/page.native.js.map +1 -1
- package/dist/jsx/layouts/sidebar.mjs +2 -4
- package/dist/jsx/layouts/sidebar.mjs.map +1 -1
- package/dist/jsx/layouts/sidebar.native.js +1 -3
- package/dist/jsx/layouts/sidebar.native.js.map +1 -1
- package/dist/jsx/layouts/tags.mjs.map +1 -1
- package/dist/jsx/layouts/tags.native.js.map +1 -1
- package/dist/jsx/surfaces.mjs +1 -33
- package/dist/jsx/surfaces.mjs.map +1 -1
- package/dist/jsx/surfaces.native.js +0 -32
- package/dist/jsx/surfaces.native.js.map +1 -1
- package/dist/jsx/views/List.mjs +2 -4
- package/dist/jsx/views/List.mjs.map +1 -1
- package/dist/jsx/views/List.native.js +1 -3
- package/dist/jsx/views/List.native.js.map +1 -1
- package/dist/jsx/views/Matrix.mjs +543 -0
- package/dist/jsx/views/Matrix.mjs.map +1 -0
- package/dist/jsx/views/Matrix.native.js +612 -0
- package/dist/jsx/views/Matrix.native.js.map +1 -0
- package/dist/jsx/views/TreeView.mjs +175 -43
- package/dist/jsx/views/TreeView.mjs.map +1 -1
- package/dist/jsx/views/TreeView.native.js +181 -46
- package/dist/jsx/views/TreeView.native.js.map +1 -1
- package/dist/jsx/views/ganttMath.mjs +1 -1
- package/dist/jsx/views/ganttMath.mjs.map +1 -1
- package/dist/jsx/views/ganttMath.native.js +2 -0
- package/dist/jsx/views/ganttMath.native.js.map +1 -1
- package/dist/jsx/views/index.mjs +4 -2
- package/dist/jsx/views/index.mjs.map +1 -1
- package/dist/jsx/views/index.native.js +16 -0
- package/dist/jsx/views/index.native.js.map +1 -1
- package/dist/jsx/views/matrixMath.mjs +122 -0
- package/dist/jsx/views/matrixMath.mjs.map +1 -0
- package/dist/jsx/views/matrixMath.native.js +229 -0
- package/dist/jsx/views/matrixMath.native.js.map +1 -0
- package/package.json +12 -12
- package/src/Accordion/Accordion.spec.tsx +20 -0
- package/src/Accordion/index.tsx +8 -4
- package/src/AnimateHeight/index.tsx +143 -142
- package/src/Chip/Chip.borderLadder.spec.tsx +54 -0
- package/src/Chip/Chip.pressSlop.spec.tsx +57 -0
- package/src/Chip/index.tsx +15 -1
- package/src/Heading.native.spec.tsx +1 -1
- package/src/Separator/index.tsx +3 -3
- package/src/SheetModal/SheetModal.detentLayout.spec.tsx +173 -0
- package/src/SheetModal/SheetModal.fill.spec.tsx +147 -0
- package/src/SheetModal/SheetModal.ownedBody.spec.tsx +200 -0
- package/src/SheetModal/SheetModal.stories.spec.tsx +23 -2
- package/src/SheetModal/SheetModal.stories.tsx +275 -2
- package/src/SheetModal/SheetModal.touch.spec.tsx +63 -0
- package/src/SheetModal/index.native.tsx +143 -21
- package/src/SheetModal/index.tsx +40 -3
- package/src/Tabs/Tabs.hydration.spec.tsx +123 -0
- package/src/Tabs/Tabs.lifecycle.spec.tsx +123 -0
- package/src/Tabs/Tabs.measurement.spec.tsx +186 -0
- package/src/Tabs/Tabs.stories.tsx +43 -0
- package/src/Tabs/index.tsx +45 -15
- package/src/Text.spec.tsx +32 -2
- package/src/Text.tsx +7 -6
- package/src/Toast/Toast.spec.tsx +50 -0
- package/src/Tooltip/Tooltip.spec.tsx +55 -2
- package/src/TreeSelect/TreeSelect.spec.tsx +15 -15
- package/src/TreeSelect/index.tsx +53 -50
- package/src/Video/PlayerChrome.tsx +4 -3
- package/src/Wheel/Wheel.spec.tsx +4 -4
- package/src/adjacency.l1.spec.tsx +175 -0
- package/src/code/Code/code.spec.tsx +2 -19
- package/src/code/Code/index.tsx +0 -6
- package/src/code/CodeBlock/index.tsx +5 -3
- package/src/code/highlightedCode.spec.tsx +2 -2
- package/src/code/hostProps.spec.tsx +55 -0
- package/src/icons/themed.hydration.spec.tsx +60 -0
- package/src/icons/themed.tsx +3 -6
- package/src/knobImmuneExports.ts +3 -3
- package/src/layouts/PaneScaffold.spec.tsx +148 -2
- package/src/layouts/PaneScaffold.stories.tsx +33 -1
- package/src/layouts/PaneScaffold.tsx +101 -48
- package/src/layouts/page.designLaw.spec.tsx +20 -0
- package/src/layouts/page.tsx +2 -0
- package/src/layouts/sidebar.tsx +2 -3
- package/src/layouts/tags.tsx +2 -1
- package/src/overlayElevation.spec.tsx +39 -51
- package/src/surfaces.spec.tsx +13 -10
- package/src/surfaces.tsx +4 -33
- package/src/tamagui.spec.ts +4 -3
- package/src/textAccentSecondary.spec.tsx +100 -2
- package/src/views/List.tsx +2 -1
- package/src/views/Matrix.spec.tsx +339 -0
- package/src/views/Matrix.stories.spec.tsx +68 -0
- package/src/views/Matrix.stories.tsx +153 -0
- package/src/views/Matrix.tsx +738 -0
- package/src/views/TreeView.reveal.spec.tsx +7 -0
- package/src/views/TreeView.reveal.stories.tsx +134 -0
- package/src/views/TreeView.scroll-index.spec.tsx +246 -0
- package/src/views/TreeView.scroll.spec.tsx +711 -50
- package/src/views/TreeView.tsx +230 -49
- package/src/views/ganttMath.ts +4 -2
- package/src/views/index.ts +30 -0
- package/src/views/matrixMath.spec.ts +237 -0
- package/src/views/matrixMath.ts +251 -0
- package/src/views/views.spec.tsx +3 -1
- package/types/Accordion/index.d.ts.map +1 -1
- package/types/AnimateHeight/index.d.ts.map +1 -1
- package/types/Chip/index.d.ts.map +1 -1
- package/types/Separator/index.d.ts +3 -3
- package/types/SheetModal/index.d.ts +8 -1
- package/types/SheetModal/index.d.ts.map +1 -1
- package/types/SheetModal/index.native.d.ts +1 -1
- package/types/SheetModal/index.native.d.ts.map +1 -1
- package/types/Tabs/index.d.ts.map +1 -1
- package/types/Text.d.ts.map +1 -1
- package/types/TreeSelect/index.d.ts.map +1 -1
- package/types/Video/PlayerChrome.d.ts.map +1 -1
- package/types/code/Code/index.d.ts.map +1 -1
- package/types/code/CodeBlock/index.d.ts.map +1 -1
- package/types/icons/themed.d.ts.map +1 -1
- package/types/layouts/PaneScaffold.d.ts +14 -1
- package/types/layouts/PaneScaffold.d.ts.map +1 -1
- package/types/layouts/page.d.ts.map +1 -1
- package/types/layouts/sidebar.d.ts.map +1 -1
- package/types/layouts/tags.d.ts.map +1 -1
- package/types/surfaces.d.ts.map +1 -1
- package/types/views/List.d.ts.map +1 -1
- package/types/views/Matrix.d.ts +102 -0
- package/types/views/Matrix.d.ts.map +1 -0
- package/types/views/TreeView.d.ts +10 -1
- package/types/views/TreeView.d.ts.map +1 -1
- package/types/views/ganttMath.d.ts +4 -0
- package/types/views/ganttMath.d.ts.map +1 -1
- package/types/views/index.d.ts +3 -1
- package/types/views/index.d.ts.map +1 -1
- package/types/views/matrixMath.d.ts +114 -0
- package/types/views/matrixMath.d.ts.map +1 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MPO-68 / MPO-299: what the native sheet lays out at a settled detent.
|
|
3
|
+
*
|
|
4
|
+
* The iOS simulator run on 965825866 dragged a sheet to a lower detent: it
|
|
5
|
+
* kept its full height and slid it below the screen, or under the keyboard,
|
|
6
|
+
* so the tail of a list inside it was unreachable.
|
|
7
|
+
*/
|
|
8
|
+
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
9
|
+
import { act, cleanup } from "@testing-library/react";
|
|
10
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
11
|
+
import { Animated, PanResponder, type PanResponderCallbacks } from "react-native";
|
|
12
|
+
import { Text } from "tamagui";
|
|
13
|
+
import { resolveSheetDetents } from "./detents";
|
|
14
|
+
import type { SheetModalProps } from "./index";
|
|
15
|
+
import { SheetModal } from "./index.native";
|
|
16
|
+
|
|
17
|
+
const keyboard = vi.hoisted(() => ({ inset: 0 }));
|
|
18
|
+
|
|
19
|
+
vi.mock("react-native-web", async (importOriginal) => ({
|
|
20
|
+
...(await importOriginal<typeof import("react-native")>()),
|
|
21
|
+
ActionSheetIOS: undefined,
|
|
22
|
+
Modal: ({ children }: { children: import("react").ReactNode }) => children,
|
|
23
|
+
useWindowDimensions: () => ({ width: 390, height: 844, scale: 3, fontScale: 1 }),
|
|
24
|
+
}));
|
|
25
|
+
vi.mock("../shared/useKeyboardInset", () => ({ useKeyboardInset: () => keyboard.inset }));
|
|
26
|
+
|
|
27
|
+
let pan: PanResponderCallbacks;
|
|
28
|
+
let springs: Array<{ toValue: number; done?: (result: { finished: boolean }) => void }>;
|
|
29
|
+
|
|
30
|
+
beforeEach(() => {
|
|
31
|
+
keyboard.inset = 0;
|
|
32
|
+
springs = [];
|
|
33
|
+
vi.spyOn(PanResponder, "create").mockImplementation((config) => {
|
|
34
|
+
pan = config;
|
|
35
|
+
return { panHandlers: {} } as never;
|
|
36
|
+
});
|
|
37
|
+
vi.spyOn(Animated, "spring").mockImplementation((_value, config) => ({
|
|
38
|
+
start: (done) => {
|
|
39
|
+
springs.push({ toValue: config.toValue as number, done });
|
|
40
|
+
},
|
|
41
|
+
stop: vi.fn(),
|
|
42
|
+
reset: vi.fn(),
|
|
43
|
+
}));
|
|
44
|
+
vi.spyOn(Animated, "timing").mockImplementation(() => ({
|
|
45
|
+
start: (done) => done?.({ finished: true }),
|
|
46
|
+
stop: vi.fn(),
|
|
47
|
+
reset: vi.fn(),
|
|
48
|
+
}));
|
|
49
|
+
});
|
|
50
|
+
afterEach(() => {
|
|
51
|
+
cleanup();
|
|
52
|
+
vi.restoreAllMocks();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
function px(value: string) {
|
|
56
|
+
return Number.parseFloat(value);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function open(props: Partial<SheetModalProps> = {}) {
|
|
60
|
+
const view = renderWithProviders(
|
|
61
|
+
<SheetModal open onOpenChange={() => {}} scrollable {...props}>
|
|
62
|
+
<Text>row</Text>
|
|
63
|
+
</SheetModal>,
|
|
64
|
+
);
|
|
65
|
+
const frame = view.getByTestId("sheet-modal-frame");
|
|
66
|
+
const full = px(frame.style.maxHeight);
|
|
67
|
+
return { view, frame, full };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** react-native-web keeps the onLayout handler on the node; call it the way a device layout would. */
|
|
71
|
+
function layout(element: HTMLElement, height: number) {
|
|
72
|
+
const handler = (element as unknown as Record<string, (event: unknown) => void>)
|
|
73
|
+
.__reactLayoutHandler;
|
|
74
|
+
act(() => handler({ nativeEvent: { layout: { x: 0, y: 0, width: 390, height } } }));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function drag(dy: number) {
|
|
78
|
+
act(() => {
|
|
79
|
+
pan.onPanResponderGrant?.({} as never, {} as never);
|
|
80
|
+
pan.onPanResponderMove?.({} as never, { dy } as never);
|
|
81
|
+
pan.onPanResponderRelease?.({} as never, { dy, vy: 0 } as never);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function settle() {
|
|
86
|
+
const last = springs[springs.length - 1];
|
|
87
|
+
act(() => last.done?.({ finished: true }));
|
|
88
|
+
return last;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
describe("a native sheet at rest on a lower detent", () => {
|
|
92
|
+
it("is laid out at the detent height, not slid down at full height", () => {
|
|
93
|
+
const { frame, full } = open();
|
|
94
|
+
const [, lower] = resolveSheetDetents({ travel: full, scrollable: true });
|
|
95
|
+
expect(lower).toBeLessThan(full);
|
|
96
|
+
drag(full - lower);
|
|
97
|
+
expect(settle().toValue).toBe(full - lower);
|
|
98
|
+
expect(px(frame.style.maxHeight)).toBe(lower);
|
|
99
|
+
expect(frame.style.transform).toContain("translateY(0px)");
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it("gives a filled body the detent as its definite height", () => {
|
|
103
|
+
const { frame, full } = open({ fill: true });
|
|
104
|
+
const [, lower] = resolveSheetDetents({ travel: full, scrollable: true });
|
|
105
|
+
drag(full - lower);
|
|
106
|
+
settle();
|
|
107
|
+
expect(px(frame.style.height)).toBe(lower);
|
|
108
|
+
expect(px(frame.style.maxHeight)).toBe(lower);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it("ends above the keyboard when the keyboard is up", () => {
|
|
112
|
+
keyboard.inset = 300;
|
|
113
|
+
const { frame, full } = open();
|
|
114
|
+
expect(frame.parentElement?.style.paddingBottom).toBe("300px");
|
|
115
|
+
const [, lower] = resolveSheetDetents({ travel: full, scrollable: true });
|
|
116
|
+
drag(full - lower);
|
|
117
|
+
settle();
|
|
118
|
+
expect(px(frame.style.maxHeight)).toBe(lower);
|
|
119
|
+
expect(frame.style.transform).toContain("translateY(0px)");
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it("grows back to full height under a still top edge when a drag picks it up", () => {
|
|
123
|
+
const { frame, full } = open();
|
|
124
|
+
const [, lower] = resolveSheetDetents({ travel: full, scrollable: true });
|
|
125
|
+
drag(full - lower);
|
|
126
|
+
settle();
|
|
127
|
+
act(() => pan.onPanResponderGrant?.({} as never, {} as never));
|
|
128
|
+
expect(px(frame.style.maxHeight)).toBe(full);
|
|
129
|
+
expect(frame.style.transform).toContain(`translateY(${full - lower}px)`);
|
|
130
|
+
act(() => pan.onPanResponderRelease?.({} as never, { dy: -(full - lower), vy: 0 } as never));
|
|
131
|
+
expect(settle().toValue).toBe(0);
|
|
132
|
+
expect(px(frame.style.maxHeight)).toBe(full);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it("keeps its top edge when the keyboard moved the max height under it", () => {
|
|
136
|
+
const { view, frame, full } = open();
|
|
137
|
+
layout(frame, full);
|
|
138
|
+
const [, lower] = resolveSheetDetents({ travel: full, scrollable: true });
|
|
139
|
+
drag(full - lower);
|
|
140
|
+
settle();
|
|
141
|
+
keyboard.inset = 300;
|
|
142
|
+
view.rerender(
|
|
143
|
+
<SheetModal open onOpenChange={() => {}} scrollable>
|
|
144
|
+
<Text>row</Text>
|
|
145
|
+
</SheetModal>,
|
|
146
|
+
);
|
|
147
|
+
const lifted = 844 - 300 - 48;
|
|
148
|
+
expect(px(frame.style.maxHeight)).toBe(Math.min(lifted, lower));
|
|
149
|
+
act(() => pan.onPanResponderGrant?.({} as never, {} as never));
|
|
150
|
+
expect(px(frame.style.maxHeight)).toBe(lifted);
|
|
151
|
+
expect(frame.style.transform).toContain(`translateY(${lifted - lower}px)`);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it("keeps the drag when a scroll inside the sheet asks for the touch", () => {
|
|
155
|
+
open();
|
|
156
|
+
expect(pan.onPanResponderTerminationRequest?.({} as never, {} as never)).toBe(false);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it("forgets the rest height when the sheet closes and opens again", () => {
|
|
160
|
+
const { view, frame, full } = open();
|
|
161
|
+
const [, lower] = resolveSheetDetents({ travel: full, scrollable: true });
|
|
162
|
+
drag(full - lower);
|
|
163
|
+
settle();
|
|
164
|
+
const sheet = (next: boolean) => (
|
|
165
|
+
<SheetModal open={next} onOpenChange={() => {}} scrollable>
|
|
166
|
+
<Text>row</Text>
|
|
167
|
+
</SheetModal>
|
|
168
|
+
);
|
|
169
|
+
view.rerender(sheet(false));
|
|
170
|
+
view.rerender(sheet(true));
|
|
171
|
+
expect(px(frame.style.maxHeight)).toBe(full);
|
|
172
|
+
});
|
|
173
|
+
});
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MPO-299 phase 2 — the `fill` sizing contract.
|
|
3
|
+
*
|
|
4
|
+
* Phase 1 measured the failure on device: a consumer-owned flexible body
|
|
5
|
+
* inside the native sheet was delivered height 0, so a viewport that mounts
|
|
6
|
+
* on its measurement mounted nothing, while a sibling with a declared 240pt
|
|
7
|
+
* height got the space it asked for. `fill` opts into the sheet's existing
|
|
8
|
+
* keyboard-aware cap as a DEFINITE height and opens every link between the
|
|
9
|
+
* frame and the body, so the owned viewport has something to bootstrap from.
|
|
10
|
+
*
|
|
11
|
+
* These are composition checks, not Yoga geometry: happy-dom lays nothing
|
|
12
|
+
* out. A missing intermediate link has to fail here, because opening only
|
|
13
|
+
* the outer frame reproduces the measured zero. Device acceptance is the
|
|
14
|
+
* parent's, on a real run.
|
|
15
|
+
*/
|
|
16
|
+
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
17
|
+
import { cleanup } from "@testing-library/react";
|
|
18
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
19
|
+
import { Text } from "tamagui";
|
|
20
|
+
import { SheetModal as WebSheetModal, type SheetModalProps } from "./index";
|
|
21
|
+
import { SheetModal as NativeSheetModal } from "./index.native";
|
|
22
|
+
|
|
23
|
+
vi.mock("react-native-web", async (importOriginal) => ({
|
|
24
|
+
...(await importOriginal<typeof import("react-native")>()),
|
|
25
|
+
ActionSheetIOS: undefined,
|
|
26
|
+
Modal: ({ children }: { children: import("react").ReactNode }) => children,
|
|
27
|
+
}));
|
|
28
|
+
|
|
29
|
+
afterEach(cleanup);
|
|
30
|
+
|
|
31
|
+
/** Tamagui emits atomic classes; `flex: 1` is grow+shrink+basis together. */
|
|
32
|
+
const flexOne = ["_fg-1", "_fs-1", "_fb-0px"];
|
|
33
|
+
const minZero = "_mih-0px";
|
|
34
|
+
|
|
35
|
+
function classes(element: HTMLElement) {
|
|
36
|
+
return element.className.split(/\s+/);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function renderNative(props: Partial<SheetModalProps> = {}) {
|
|
40
|
+
return renderWithProviders(
|
|
41
|
+
<NativeSheetModal open onOpenChange={() => {}} header={<Text>Move to project</Text>} {...props}>
|
|
42
|
+
<Text>row</Text>
|
|
43
|
+
</NativeSheetModal>,
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
describe("native fill allocates the sheet body", () => {
|
|
48
|
+
it("turns the existing cap into a definite frame height only when filling", () => {
|
|
49
|
+
const filled = renderNative({ fill: true }).getByTestId("sheet-modal-frame");
|
|
50
|
+
expect(filled.style.height).not.toBe("");
|
|
51
|
+
expect(filled.style.height).toBe(filled.style.maxHeight);
|
|
52
|
+
cleanup();
|
|
53
|
+
const intrinsic = renderNative().getByTestId("sheet-modal-frame");
|
|
54
|
+
expect(intrinsic.style.height).toBe("");
|
|
55
|
+
expect(intrinsic.style.maxHeight).not.toBe("");
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("opens every link between the frame and the body, not just the outer one", () => {
|
|
59
|
+
const view = renderNative({ fill: true });
|
|
60
|
+
for (const id of ["sheet-modal-surface", "sheet-modal-content"]) {
|
|
61
|
+
const link = classes(view.getByTestId(id));
|
|
62
|
+
expect(link, `${id} grows`).toEqual(expect.arrayContaining(flexOne));
|
|
63
|
+
expect(link, `${id} can collapse`).toContain(minZero);
|
|
64
|
+
}
|
|
65
|
+
const body = view.getByTestId("sheet-modal-body");
|
|
66
|
+
expect(body.style.flexGrow).toBe("1");
|
|
67
|
+
expect(body.style.minHeight).toBe("0px");
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("leaves the default branch intrinsic, and false is the same as absent", () => {
|
|
71
|
+
for (const props of [{}, { fill: false }]) {
|
|
72
|
+
const view = renderNative(props);
|
|
73
|
+
expect(view.queryByTestId("sheet-modal-body")).toBeNull();
|
|
74
|
+
expect(classes(view.getByTestId("sheet-modal-surface"))).not.toContain("_fg-1");
|
|
75
|
+
expect(classes(view.getByTestId("sheet-modal-content"))).not.toContain("_fg-1");
|
|
76
|
+
cleanup();
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it("keeps the grabber and header out of the flexible body", () => {
|
|
81
|
+
const view = renderNative({ fill: true });
|
|
82
|
+
const body = view.getByTestId("sheet-modal-body");
|
|
83
|
+
const grabber = view.getByTestId("sheet-modal-grabber");
|
|
84
|
+
expect(grabber.style.flexShrink).toBe("0");
|
|
85
|
+
expect(body.contains(grabber)).toBe(false);
|
|
86
|
+
const header = view.getByText("Move to project");
|
|
87
|
+
expect(body.contains(header)).toBe(false);
|
|
88
|
+
expect(view.getByTestId("sheet-modal-content").contains(body)).toBe(true);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("adds no scroll owner when the consumer keeps scrolling, and exactly one when it does not", () => {
|
|
92
|
+
expect(renderNative({ fill: true }).queryAllByTestId("sheet-modal-scroll")).toHaveLength(0);
|
|
93
|
+
cleanup();
|
|
94
|
+
const scrollers = renderNative({ fill: true, scrollable: true }).getAllByTestId(
|
|
95
|
+
"sheet-modal-scroll",
|
|
96
|
+
);
|
|
97
|
+
expect(scrollers).toHaveLength(1);
|
|
98
|
+
expect(scrollers[0].style.flexGrow).toBe("1");
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it("keeps the content-sized scroller on the default branch", () => {
|
|
102
|
+
const scroller = renderNative({ scrollable: true }).getByTestId("sheet-modal-scroll");
|
|
103
|
+
expect(scroller.style.flexGrow).toBe("0");
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
/*
|
|
108
|
+
* Web already gets a definite percent height from the Sheet's snap point, so
|
|
109
|
+
* fill only has to open the body chain inside it. tamagui renders the sheet
|
|
110
|
+
* through a portal AND inline, so every query here is plural on purpose.
|
|
111
|
+
*/
|
|
112
|
+
function renderWeb(props: Partial<SheetModalProps> = {}) {
|
|
113
|
+
return renderWithProviders(
|
|
114
|
+
<WebSheetModal open onOpenChange={() => {}} header={<Text>Move to project</Text>} {...props}>
|
|
115
|
+
<Text>row</Text>
|
|
116
|
+
</WebSheetModal>,
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
describe("web fill opens the body inside the snapped frame", () => {
|
|
121
|
+
it("mounts a growing body slot only when filling", () => {
|
|
122
|
+
const filled = renderWeb({ fill: true }).getAllByTestId("sheet-modal-body");
|
|
123
|
+
expect(filled.length).toBeGreaterThan(0);
|
|
124
|
+
for (const slot of filled) {
|
|
125
|
+
expect(classes(slot)).toEqual(expect.arrayContaining(flexOne));
|
|
126
|
+
expect(classes(slot)).toContain(minZero);
|
|
127
|
+
}
|
|
128
|
+
cleanup();
|
|
129
|
+
expect(renderWeb().queryAllByTestId("sheet-modal-body")).toHaveLength(0);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("hands the body slot to the sheet scroller when the sheet owns scrolling", () => {
|
|
133
|
+
const view = renderWeb({ fill: true, scrollable: true });
|
|
134
|
+
const bodies = view.getAllByTestId("sheet-modal-body");
|
|
135
|
+
const scrollers = view.getAllByTestId("sheet-modal-scroll");
|
|
136
|
+
expect(scrollers.length).toBe(bodies.length);
|
|
137
|
+
for (const body of bodies) {
|
|
138
|
+
expect(body.querySelectorAll('[data-testid="sheet-modal-scroll"]')).toHaveLength(1);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it("keeps one scroll owner and no body slot on the default branch", () => {
|
|
143
|
+
const view = renderWeb({ scrollable: true });
|
|
144
|
+
expect(view.queryAllByTestId("sheet-modal-body")).toHaveLength(0);
|
|
145
|
+
expect(view.getAllByTestId("sheet-modal-scroll").length).toBeGreaterThan(0);
|
|
146
|
+
});
|
|
147
|
+
});
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
2
|
+
import { act, cleanup, fireEvent } from "@testing-library/react";
|
|
3
|
+
import { afterEach, expect, it, vi } from "vitest";
|
|
4
|
+
import * as stories from "./SheetModal.stories";
|
|
5
|
+
|
|
6
|
+
const hosts = vi.hoisted(() => ({
|
|
7
|
+
props: new Map<string, Record<string, any>>(),
|
|
8
|
+
measurements: [] as Array<{ id: string; callback: (...bounds: number[]) => void }>,
|
|
9
|
+
}));
|
|
10
|
+
vi.mock("@multiplatform.one/components", async (importOriginal) => {
|
|
11
|
+
const actual = await importOriginal<typeof import("@multiplatform.one/components")>();
|
|
12
|
+
const React = await import("react");
|
|
13
|
+
function observed(Component: any) {
|
|
14
|
+
return React.forwardRef((props: Record<string, any>, ref) => {
|
|
15
|
+
if (props.testID) hosts.props.set(props.testID, props);
|
|
16
|
+
React.useImperativeHandle(ref, () => {
|
|
17
|
+
const host = {
|
|
18
|
+
measureInWindow: (callback: (...bounds: number[]) => void) => {
|
|
19
|
+
hosts.measurements.push({ id: props.testID, callback });
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
return { ...host, getNativeScrollRef: () => host };
|
|
23
|
+
});
|
|
24
|
+
return (
|
|
25
|
+
<Component
|
|
26
|
+
{...props}
|
|
27
|
+
onLayout={undefined}
|
|
28
|
+
onContentSizeChange={undefined}
|
|
29
|
+
onScroll={undefined}
|
|
30
|
+
/>
|
|
31
|
+
);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
...actual,
|
|
36
|
+
YStack: observed(actual.YStack),
|
|
37
|
+
ScrollView: observed(actual.ScrollView),
|
|
38
|
+
SheetModal: (props: any) => {
|
|
39
|
+
hosts.props.set("public-sheet-modal", props);
|
|
40
|
+
return props.open ? (
|
|
41
|
+
<>
|
|
42
|
+
{props.header}
|
|
43
|
+
{props.children}
|
|
44
|
+
</>
|
|
45
|
+
) : null;
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
});
|
|
49
|
+
afterEach(() => {
|
|
50
|
+
cleanup();
|
|
51
|
+
hosts.props.clear();
|
|
52
|
+
hosts.measurements = [];
|
|
53
|
+
});
|
|
54
|
+
function sheetProps() {
|
|
55
|
+
return hosts.props.get("public-sheet-modal")!;
|
|
56
|
+
}
|
|
57
|
+
function renderStory(name: "OwnedMeasuredViewport" | "OwnedScrollView") {
|
|
58
|
+
const story = (stories as Record<string, any>)[name];
|
|
59
|
+
expect(story, `${name} is a registered story`).toBeDefined();
|
|
60
|
+
return renderWithProviders(<>{story.render(story.args ?? {}, {})}</>);
|
|
61
|
+
}
|
|
62
|
+
function layout(id: string, height: number) {
|
|
63
|
+
act(() =>
|
|
64
|
+
hosts.props.get(id)!.onLayout({ nativeEvent: { layout: { x: 0, y: 44, width: 300, height } } }),
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
function readings(view: ReturnType<typeof renderStory>) {
|
|
68
|
+
return JSON.parse(view.getByTestId("owned-sheet-readings").textContent!);
|
|
69
|
+
}
|
|
70
|
+
it("keeps the measured subject unmeasured until a delivered layout and distinguishes zero", () => {
|
|
71
|
+
const view = renderStory("OwnedMeasuredViewport");
|
|
72
|
+
fireEvent.click(view.getByText("Open flex subject"));
|
|
73
|
+
expect(readings(view).viewportLayout).toBe("unmeasured");
|
|
74
|
+
expect(hosts.props.get("owned-sheet-frame")!.height).toBeUndefined();
|
|
75
|
+
expect(view.queryByText("Record 60")).toBeNull();
|
|
76
|
+
layout("owned-sheet-viewport", 0);
|
|
77
|
+
expect(readings(view).viewportLayout.height).toBe(0);
|
|
78
|
+
expect(view.queryByText("Record 60")).toBeNull();
|
|
79
|
+
layout("owned-sheet-viewport", 187.5);
|
|
80
|
+
expect(readings(view).viewportLayout.height).toBe(187.5);
|
|
81
|
+
expect(view.getByText("Record 60")).toBeDefined();
|
|
82
|
+
});
|
|
83
|
+
it("provides a named fixed control without treating its declared height as a measurement", () => {
|
|
84
|
+
const view = renderStory("OwnedMeasuredViewport");
|
|
85
|
+
fireEvent.click(view.getByText("Open 240pt control"));
|
|
86
|
+
expect(hosts.props.get("owned-sheet-frame")!.height).toBe(240);
|
|
87
|
+
expect(readings(view).mode).toBe("control-240");
|
|
88
|
+
expect(readings(view).frameLayout).toBe("unmeasured");
|
|
89
|
+
layout("owned-sheet-viewport", 192);
|
|
90
|
+
expect(view.getByText("Record 60")).toBeDefined();
|
|
91
|
+
expect(hosts.props.get("owned-sheet-scroll")).toBeDefined();
|
|
92
|
+
});
|
|
93
|
+
it("mounts the owned scroller without a measurement gate and records delivered content and offset", () => {
|
|
94
|
+
const view = renderStory("OwnedScrollView");
|
|
95
|
+
fireEvent.click(view.getByText("Open flex subject"));
|
|
96
|
+
expect(view.getByText("Record 60")).toBeDefined();
|
|
97
|
+
expect(view.getAllByText(/^Record \d+$/)).toHaveLength(60);
|
|
98
|
+
expect(readings(view).offset).toBe("unmeasured");
|
|
99
|
+
const scroll = hosts.props.get("owned-sheet-scroll")!;
|
|
100
|
+
act(() => {
|
|
101
|
+
scroll.onContentSizeChange(300, 2500.5);
|
|
102
|
+
scroll.onScroll({ nativeEvent: { contentOffset: { x: 0, y: 123.25 } } });
|
|
103
|
+
});
|
|
104
|
+
expect(readings(view).content).toEqual({ width: 300, height: 2500.5 });
|
|
105
|
+
expect(readings(view).offset).toEqual({ x: 0, y: 123.25 });
|
|
106
|
+
fireEvent.click(view.getByText("Activate Record 60"));
|
|
107
|
+
expect(readings(view).tailPresses).toBe(1);
|
|
108
|
+
});
|
|
109
|
+
it("records public window-bound callbacks and rejects callbacks from a closed presentation", () => {
|
|
110
|
+
const view = renderStory("OwnedScrollView");
|
|
111
|
+
fireEvent.click(view.getByText("Open flex subject"));
|
|
112
|
+
fireEvent.click(view.getByText("Measure bounds"));
|
|
113
|
+
const pending = [...hosts.measurements];
|
|
114
|
+
const frame = pending.find((item) => item.id === "owned-sheet-frame")!;
|
|
115
|
+
expect(frame).toBeDefined();
|
|
116
|
+
expect(pending.some((item) => item.id === "owned-sheet-scroll")).toBe(true);
|
|
117
|
+
act(() => frame.callback(18, 300, 354, 240));
|
|
118
|
+
expect(readings(view).frameWindow).toEqual({ x: 18, y: 300, width: 354, height: 240 });
|
|
119
|
+
const viewport = pending.find((item) => item.id === "owned-sheet-viewport")!;
|
|
120
|
+
fireEvent.click(view.getByText("Close fixture"));
|
|
121
|
+
fireEvent.click(view.getByText("Open 240pt control"));
|
|
122
|
+
act(() => viewport.callback(18, 344, 354, 196));
|
|
123
|
+
expect(readings(view).viewportWindow).toBe("unmeasured");
|
|
124
|
+
expect(readings(view).frameWindow).toBe("unmeasured");
|
|
125
|
+
});
|
|
126
|
+
it("reports invalid readings rather than converting them to zero", () => {
|
|
127
|
+
const view = renderStory("OwnedScrollView");
|
|
128
|
+
fireEvent.click(view.getByText("Open flex subject"));
|
|
129
|
+
layout("owned-sheet-viewport", Number.NaN);
|
|
130
|
+
expect(readings(view).viewportLayout).toBe("invalid");
|
|
131
|
+
expect(readings(view).sheetFrameWindow).toBe("unavailable: SheetModal has no public frame ref");
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it("keeps an absent measured scroller unavailable and ignores superseded samples", () => {
|
|
135
|
+
const view = renderStory("OwnedMeasuredViewport");
|
|
136
|
+
fireEvent.click(view.getByText("Open flex subject"));
|
|
137
|
+
fireEvent.click(view.getByText("Measure bounds"));
|
|
138
|
+
expect(readings(view).scrollWindow).toBe("unavailable");
|
|
139
|
+
expect(readings(view).tailWindow).toBe("unavailable");
|
|
140
|
+
expect(readings(view).frameWindow).toBe("unmeasured");
|
|
141
|
+
const old = hosts.measurements.find((item) => item.id === "owned-sheet-frame")!;
|
|
142
|
+
hosts.measurements = [];
|
|
143
|
+
fireEvent.click(view.getByText("Measure bounds"));
|
|
144
|
+
expect(readings(view).sample).toBe(2);
|
|
145
|
+
act(() => old.callback(18, 300, 354, 240));
|
|
146
|
+
expect(readings(view).frameWindow).toBe("unmeasured");
|
|
147
|
+
const current = hosts.measurements.find((item) => item.id === "owned-sheet-frame")!;
|
|
148
|
+
act(() => current.callback(18, 780, 354, 0));
|
|
149
|
+
expect(readings(view).frameWindow).toEqual({ x: 18, y: 780, width: 354, height: 0 });
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it("retains the closed presentation readings and resets actual tail presses on reopening", () => {
|
|
153
|
+
const view = renderStory("OwnedScrollView");
|
|
154
|
+
fireEvent.click(view.getByText("Open 240pt control"));
|
|
155
|
+
layout("owned-sheet-viewport", 192);
|
|
156
|
+
fireEvent.click(view.getByText("Activate Record 60"));
|
|
157
|
+
fireEvent.click(view.getByText("Close fixture"));
|
|
158
|
+
layout("owned-sheet-viewport", 0);
|
|
159
|
+
expect(readings(view).viewportLayout.height).toBe(192);
|
|
160
|
+
expect(readings(view).tailPresses).toBe(1);
|
|
161
|
+
expect(readings(view).presentation).toBe(1);
|
|
162
|
+
expect(readings(view).open).toBe(false);
|
|
163
|
+
fireEvent.click(view.getByText("Open flex subject"));
|
|
164
|
+
expect(readings(view).viewportLayout).toBe("unmeasured");
|
|
165
|
+
expect(readings(view).tailPresses).toBe(0);
|
|
166
|
+
expect(readings(view).presentation).toBe(2);
|
|
167
|
+
expect(view.getAllByText("Generic detail 1 for this record.")).toHaveLength(60);
|
|
168
|
+
expect(view.getAllByText("Generic detail 4 for this record.")).toHaveLength(15);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it("hands the chosen fill value to the real public sheet rather than inferring it", () => {
|
|
172
|
+
const view = renderStory("OwnedMeasuredViewport");
|
|
173
|
+
fireEvent.click(view.getByText("Open flex subject"));
|
|
174
|
+
expect(sheetProps().fill).toBe(false);
|
|
175
|
+
expect(readings(view).fill).toBe(false);
|
|
176
|
+
fireEvent.click(view.getByText("Close fixture"));
|
|
177
|
+
fireEvent.click(view.getByText("Open flex subject (fill)"));
|
|
178
|
+
expect(sheetProps().fill).toBe(true);
|
|
179
|
+
expect(readings(view).fill).toBe(true);
|
|
180
|
+
expect(readings(view).mode).toBe("subject");
|
|
181
|
+
// The fixed control is a diagnostic, not the height contract: it never
|
|
182
|
+
// asks the sheet to allocate.
|
|
183
|
+
fireEvent.click(view.getByText("Close fixture"));
|
|
184
|
+
fireEvent.click(view.getByText("Open 240pt control"));
|
|
185
|
+
expect(sheetProps().fill).toBe(false);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it("measures the owned toolbar so the parent can subtract it from the body", () => {
|
|
189
|
+
const view = renderStory("OwnedScrollView");
|
|
190
|
+
fireEvent.click(view.getByText("Open flex subject (fill)"));
|
|
191
|
+
expect(readings(view).toolbarLayout).toBe("unmeasured");
|
|
192
|
+
layout("owned-sheet-toolbar", 44.5);
|
|
193
|
+
layout("owned-sheet-frame", 400);
|
|
194
|
+
layout("owned-sheet-viewport", 355.5);
|
|
195
|
+
const captured = readings(view);
|
|
196
|
+
expect(captured.toolbarLayout.height).toBe(44.5);
|
|
197
|
+
expect(captured.frameLayout.height - captured.toolbarLayout.height).toBe(
|
|
198
|
+
captured.viewportLayout.height,
|
|
199
|
+
);
|
|
200
|
+
});
|
|
@@ -10,9 +10,16 @@
|
|
|
10
10
|
* open state is.
|
|
11
11
|
*/
|
|
12
12
|
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
13
|
-
import { cleanup, screen } from "@testing-library/react";
|
|
13
|
+
import { cleanup, fireEvent, screen } from "@testing-library/react";
|
|
14
14
|
import { afterEach, describe, expect, it } from "vitest";
|
|
15
|
-
import meta, {
|
|
15
|
+
import meta, {
|
|
16
|
+
Default,
|
|
17
|
+
OpenOnMount,
|
|
18
|
+
OwnedMeasuredViewport,
|
|
19
|
+
OwnedScrollView,
|
|
20
|
+
Scrollable,
|
|
21
|
+
TallDetent,
|
|
22
|
+
} from "./SheetModal.stories";
|
|
16
23
|
|
|
17
24
|
afterEach(cleanup);
|
|
18
25
|
|
|
@@ -51,4 +58,18 @@ describe("SheetModal stories", () => {
|
|
|
51
58
|
expect(screen.getAllByText("Project 1").length).toBeGreaterThan(0);
|
|
52
59
|
expect(screen.getAllByText("Project 30").length).toBeGreaterThan(0);
|
|
53
60
|
});
|
|
61
|
+
|
|
62
|
+
it.each([OwnedMeasuredViewport, OwnedScrollView])(
|
|
63
|
+
"mounts the public owned fixture and its control",
|
|
64
|
+
(story) => {
|
|
65
|
+
renderWithProviders(<>{story.render?.({} as never, {} as never)}</>);
|
|
66
|
+
expect(screen.getByText("Open flex subject")).toBeDefined();
|
|
67
|
+
fireEvent.click(screen.getByText("Open 240pt control"));
|
|
68
|
+
expect(screen.getAllByText("Measure bounds").length).toBeGreaterThan(0);
|
|
69
|
+
expect(screen.getAllByText("Close fixture").length).toBeGreaterThan(0);
|
|
70
|
+
expect(JSON.parse(screen.getByTestId("owned-sheet-readings").textContent!).mode).toBe(
|
|
71
|
+
"control-240",
|
|
72
|
+
);
|
|
73
|
+
},
|
|
74
|
+
);
|
|
54
75
|
});
|