@multiplatform.one/components 7.11.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 +2 -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.native.js +70 -22
- package/dist/cjs/SheetModal/index.native.js.map +1 -1
- package/dist/cjs/Tabs/index.cjs +2 -6
- package/dist/cjs/Tabs/index.native.js +2 -6
- 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/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/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.native.js +71 -23
- 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 +3 -7
- package/dist/esm/Tabs/index.mjs.map +1 -1
- package/dist/esm/Tabs/index.native.js +3 -7
- 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.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.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.native.js +70 -22
- package/dist/jsx/SheetModal/index.native.js.map +1 -1
- package/dist/jsx/Tabs/index.mjs +3 -7
- package/dist/jsx/Tabs/index.mjs.map +1 -1
- package/dist/jsx/Tabs/index.native.js +2 -6
- 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/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/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 +10 -10
- package/src/Accordion/Accordion.spec.tsx +20 -0
- package/src/Accordion/index.tsx +7 -3
- 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.touch.spec.tsx +63 -0
- package/src/SheetModal/index.native.tsx +95 -17
- package/src/Tabs/Tabs.hydration.spec.tsx +123 -0
- package/src/Tabs/index.tsx +3 -2
- 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/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/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.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/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/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
package/src/Toast/Toast.spec.tsx
CHANGED
|
@@ -735,6 +735,56 @@ describe("Toast data attributes reach the DOM", () => {
|
|
|
735
735
|
});
|
|
736
736
|
});
|
|
737
737
|
|
|
738
|
+
describe("Toast density moves padX and gap on the host (MPO-42)", () => {
|
|
739
|
+
afterEach(cleanup);
|
|
740
|
+
|
|
741
|
+
const padX = ["_px-", "_pl-", "_pr-"];
|
|
742
|
+
const gap = ["_gap-"];
|
|
743
|
+
|
|
744
|
+
function hostAtoms(node: ReactElement) {
|
|
745
|
+
renderWithProviders(node);
|
|
746
|
+
const host = screen.getByTestId("toast");
|
|
747
|
+
const measured = {
|
|
748
|
+
density: host.getAttribute("data-density"),
|
|
749
|
+
padX: classesByPrefix(host, padX),
|
|
750
|
+
gap: classesByPrefix(host, gap),
|
|
751
|
+
};
|
|
752
|
+
cleanup();
|
|
753
|
+
return measured;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
it("the density knob changes padX and gap between the two stops", () => {
|
|
757
|
+
const comfortable = hostAtoms(
|
|
758
|
+
<Preset overrides={{ density: "comfortable" }}>
|
|
759
|
+
<Toast title="Saved" onDismiss={() => {}} />
|
|
760
|
+
</Preset>,
|
|
761
|
+
);
|
|
762
|
+
const compact = hostAtoms(
|
|
763
|
+
<Preset overrides={{ density: "compact" }}>
|
|
764
|
+
<Toast title="Saved" onDismiss={() => {}} />
|
|
765
|
+
</Preset>,
|
|
766
|
+
);
|
|
767
|
+
expect(comfortable.density).toBe("comfortable");
|
|
768
|
+
expect(compact.density).toBe("compact");
|
|
769
|
+
expect(comfortable.padX.length).toBeGreaterThan(0);
|
|
770
|
+
expect(comfortable.gap.length).toBeGreaterThan(0);
|
|
771
|
+
expect(compact.padX).not.toEqual(comfortable.padX);
|
|
772
|
+
expect(compact.gap).not.toEqual(comfortable.gap);
|
|
773
|
+
});
|
|
774
|
+
|
|
775
|
+
it("the compact prop lands the same padX and gap as the density knob", () => {
|
|
776
|
+
const knob = hostAtoms(
|
|
777
|
+
<Preset overrides={{ density: "compact" }}>
|
|
778
|
+
<Toast title="Saved" onDismiss={() => {}} />
|
|
779
|
+
</Preset>,
|
|
780
|
+
);
|
|
781
|
+
const prop = hostAtoms(<Toast compact title="Saved" onDismiss={() => {}} />);
|
|
782
|
+
expect(prop.density).toBe("compact");
|
|
783
|
+
expect(prop.padX).toEqual(knob.padX);
|
|
784
|
+
expect(prop.gap).toEqual(knob.gap);
|
|
785
|
+
});
|
|
786
|
+
});
|
|
787
|
+
|
|
738
788
|
describe("Toast action label weight and contrast (TEXT NODE)", () => {
|
|
739
789
|
it("Undo is weight 400 on the TEXT NODE, never 600 (R7 / §6.1)", () => {
|
|
740
790
|
const action = renderActionWeight(
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* @vitest-environment jsdom
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { fireEvent } from "@testing-library/react";
|
|
6
|
-
import { OVERLAY_ANCHOR_GAP, __resetDevWarnSeen } from "@multiplatform.one/theme";
|
|
5
|
+
import { act, fireEvent } from "@testing-library/react";
|
|
6
|
+
import { OVERLAY_ANCHOR_GAP, Preset, __resetDevWarnSeen } from "@multiplatform.one/theme";
|
|
7
7
|
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
8
8
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
9
9
|
import { Button } from "@multiplatform.one/forms";
|
|
@@ -99,6 +99,59 @@ describe("Tooltip interaction", () => {
|
|
|
99
99
|
});
|
|
100
100
|
});
|
|
101
101
|
|
|
102
|
+
describe("Tooltip content rides the border, elevation and animation knobs", () => {
|
|
103
|
+
const stops = [
|
|
104
|
+
{ borderWidth: "none", elevation: "none", animation: "none" },
|
|
105
|
+
{ borderWidth: "small", elevation: "small", animation: "quick" },
|
|
106
|
+
{ borderWidth: "large", elevation: "large", animation: "slow" },
|
|
107
|
+
] as const;
|
|
108
|
+
|
|
109
|
+
async function measure(stop: (typeof stops)[number]) {
|
|
110
|
+
const result = renderWithProviders(
|
|
111
|
+
<Preset overrides={stop}>
|
|
112
|
+
<Tooltip content="Hint" open>
|
|
113
|
+
<Button>Edit</Button>
|
|
114
|
+
</Tooltip>
|
|
115
|
+
</Preset>,
|
|
116
|
+
);
|
|
117
|
+
await act(async () => {
|
|
118
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
119
|
+
});
|
|
120
|
+
const content = document.querySelector<HTMLElement>("[data-tooltip='content']");
|
|
121
|
+
const classes = content?.className.split(/\s+/) ?? [];
|
|
122
|
+
const measured = {
|
|
123
|
+
mounted: content !== null,
|
|
124
|
+
border: classes.find((c) => c.startsWith("_btw-")),
|
|
125
|
+
shadow: classes.find((c) => c.startsWith("_bxsh-"))?.match(/^_bxsh-\d+px\d+px\d+px/)?.[0],
|
|
126
|
+
transition: content?.style.transition.match(/^all \d+ms/)?.[0],
|
|
127
|
+
};
|
|
128
|
+
result.unmount();
|
|
129
|
+
return measured;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
it("follows each stop on the mounted bubble, and none carries no border, shadow or motion", async () => {
|
|
133
|
+
const none = await measure(stops[0]);
|
|
134
|
+
const small = await measure(stops[1]);
|
|
135
|
+
const large = await measure(stops[2]);
|
|
136
|
+
expect(none).toEqual({
|
|
137
|
+
mounted: true,
|
|
138
|
+
border: "_btw-0px",
|
|
139
|
+
shadow: undefined,
|
|
140
|
+
transition: undefined,
|
|
141
|
+
});
|
|
142
|
+
expect(small).toMatchObject({
|
|
143
|
+
mounted: true,
|
|
144
|
+
border: "_btw-0--5px",
|
|
145
|
+
shadow: "_bxsh-0px3px6px",
|
|
146
|
+
});
|
|
147
|
+
// Overlay large is the ladder's own $5 dialog stop, not the control $4 (MPO-99).
|
|
148
|
+
expect(large).toMatchObject({ mounted: true, border: "_btw-2px", shadow: "_bxsh-0px12px24px" });
|
|
149
|
+
expect(small.transition).toMatch(/^all \d+ms$/);
|
|
150
|
+
expect(large.transition).toMatch(/^all \d+ms$/);
|
|
151
|
+
expect(large.transition).not.toBe(small.transition);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
|
|
102
155
|
describe("Tooltip native long-press open path", () => {
|
|
103
156
|
beforeEach(() => {
|
|
104
157
|
vi.useFakeTimers();
|
|
@@ -84,7 +84,7 @@ describe("TreeSelect cover + width (MPO-53 AC-3)", () => {
|
|
|
84
84
|
open
|
|
85
85
|
/>,
|
|
86
86
|
);
|
|
87
|
-
const trigger = result.
|
|
87
|
+
const trigger = result.baseElement.querySelector(
|
|
88
88
|
'[data-testid="tree-select-trigger"]',
|
|
89
89
|
) as HTMLElement;
|
|
90
90
|
expect(trigger).toBeTruthy();
|
|
@@ -93,7 +93,7 @@ describe("TreeSelect cover + width (MPO-53 AC-3)", () => {
|
|
|
93
93
|
|
|
94
94
|
try {
|
|
95
95
|
await waitFor(() => {
|
|
96
|
-
const panel = result.
|
|
96
|
+
const panel = result.baseElement.querySelector(
|
|
97
97
|
'[data-testid="tree-select-panel"]',
|
|
98
98
|
) as HTMLElement | null;
|
|
99
99
|
expect(panel).toBeTruthy();
|
|
@@ -114,7 +114,7 @@ describe("TreeSelect LC-49 one tab stop", () => {
|
|
|
114
114
|
const result = renderWithProviders(
|
|
115
115
|
<TreeSelect label="Account" nodes={accounts} value="hdfc" />,
|
|
116
116
|
);
|
|
117
|
-
const closedStops = tabStops(result.
|
|
117
|
+
const closedStops = tabStops(result.baseElement);
|
|
118
118
|
expect(closedStops.length).toBe(1);
|
|
119
119
|
expect(closedStops[0]?.getAttribute("data-testid")).toBe("tree-select-trigger");
|
|
120
120
|
|
|
@@ -128,7 +128,7 @@ describe("TreeSelect LC-49 one tab stop", () => {
|
|
|
128
128
|
/>,
|
|
129
129
|
);
|
|
130
130
|
await waitFor(() => {
|
|
131
|
-
expect(result.
|
|
131
|
+
expect(result.baseElement.querySelector('[data-testid="tree-select-search"]')).toBeTruthy();
|
|
132
132
|
});
|
|
133
133
|
const openRoot = result.baseElement;
|
|
134
134
|
const search = openRoot.querySelector(
|
|
@@ -169,16 +169,16 @@ describe("TreeSelect LC-21 commit vs expand", () => {
|
|
|
169
169
|
/>,
|
|
170
170
|
);
|
|
171
171
|
await waitFor(() => {
|
|
172
|
-
expect(result.
|
|
172
|
+
expect(result.baseElement.querySelector("[data-treeselect-caret]")).toBeTruthy();
|
|
173
173
|
});
|
|
174
|
-
const caret = result.
|
|
174
|
+
const caret = result.baseElement.querySelector("[data-treeselect-caret]") as HTMLElement;
|
|
175
175
|
await act(async () => {
|
|
176
176
|
fireEvent.click(caret);
|
|
177
177
|
});
|
|
178
178
|
expect(onChange).not.toHaveBeenCalled();
|
|
179
179
|
expect(onOpenChange).not.toHaveBeenCalledWith(false);
|
|
180
180
|
|
|
181
|
-
const cash = result.
|
|
181
|
+
const cash = result.baseElement.querySelector(
|
|
182
182
|
'[data-treeselect-row="liabilities"]',
|
|
183
183
|
) as HTMLElement;
|
|
184
184
|
await act(async () => {
|
|
@@ -201,10 +201,10 @@ describe("TreeSelect sheet at <=640", () => {
|
|
|
201
201
|
/>,
|
|
202
202
|
);
|
|
203
203
|
await waitFor(() => {
|
|
204
|
-
expect(desktop.
|
|
204
|
+
expect(desktop.baseElement.querySelector("[data-treeselect-row]")).toBeTruthy();
|
|
205
205
|
});
|
|
206
|
-
const desktopTree = desktop.
|
|
207
|
-
const desktopRows = [...desktop.
|
|
206
|
+
const desktopTree = desktop.baseElement.querySelector('[data-testid="tree-select-tree"]');
|
|
207
|
+
const desktopRows = [...desktop.baseElement.querySelectorAll("[data-treeselect-row]")].map(
|
|
208
208
|
(el) => ({
|
|
209
209
|
id: el.getAttribute("data-treeselect-row"),
|
|
210
210
|
depth: el.getAttribute("data-depth"),
|
|
@@ -226,7 +226,7 @@ describe("TreeSelect sheet at <=640", () => {
|
|
|
226
226
|
await waitFor(() => {
|
|
227
227
|
expect(mobile.baseElement.querySelector("[data-treeselect-row]")).toBeTruthy();
|
|
228
228
|
});
|
|
229
|
-
expect(mobile.
|
|
229
|
+
expect(mobile.baseElement.querySelector('[data-testid="floating-panel-viewport"]')).toBeNull();
|
|
230
230
|
const mobileTree = mobile.baseElement.querySelector('[data-testid="tree-select-tree"]');
|
|
231
231
|
const mobileRows = [...mobile.baseElement.querySelectorAll("[data-treeselect-row]")].map(
|
|
232
232
|
(el) => ({
|
|
@@ -247,19 +247,19 @@ describe("TreeSelect empty filter", () => {
|
|
|
247
247
|
<TreeSelect label="Account" nodes={accounts} open emptyMessage="No matching accounts" />,
|
|
248
248
|
);
|
|
249
249
|
await waitFor(() => {
|
|
250
|
-
expect(result.
|
|
250
|
+
expect(result.baseElement.querySelector('[data-testid="tree-select-search"]')).toBeTruthy();
|
|
251
251
|
});
|
|
252
|
-
const search = result.
|
|
252
|
+
const search = result.baseElement.querySelector(
|
|
253
253
|
'[data-testid="tree-select-search"] input',
|
|
254
254
|
) as HTMLInputElement;
|
|
255
255
|
await act(async () => {
|
|
256
256
|
fireEvent.change(search, { target: { value: "xyzzy" } });
|
|
257
257
|
});
|
|
258
|
-
const empty = result.
|
|
258
|
+
const empty = result.baseElement.querySelector(
|
|
259
259
|
'[data-testid="tree-select-empty"]',
|
|
260
260
|
) as HTMLElement;
|
|
261
261
|
expect(empty).toBeTruthy();
|
|
262
262
|
expect(empty.textContent).toContain("No matching accounts");
|
|
263
|
-
expect(result.
|
|
263
|
+
expect(result.baseElement.querySelector('[data-testid="empty-state"]')).toBeNull();
|
|
264
264
|
});
|
|
265
265
|
});
|
package/src/TreeSelect/index.tsx
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
FloatingPanel,
|
|
4
4
|
formCommonColors,
|
|
5
5
|
InputParts,
|
|
6
|
+
PanelPortal,
|
|
6
7
|
useFloatingPanel,
|
|
7
8
|
useFormField,
|
|
8
9
|
useViewportGtSm,
|
|
@@ -751,59 +752,61 @@ function FloatingTreeSelect({
|
|
|
751
752
|
accessibilityLabel={accessibilityLabel}
|
|
752
753
|
/>
|
|
753
754
|
{panel.mounted && (
|
|
754
|
-
<
|
|
755
|
-
<
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
{
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
activeDescendant={activeDescendant}
|
|
790
|
-
sizeToken={sizeToken}
|
|
791
|
-
/>
|
|
792
|
-
<YStack overflow="scroll" maxHeight={320} id={treeId}>
|
|
793
|
-
<TreeSelectPanelBody
|
|
794
|
-
rows={state.rows}
|
|
795
|
-
selectedId={value}
|
|
796
|
-
activeIndex={state.activeIndex}
|
|
797
|
-
keyboardRing={state.keyboardRing}
|
|
755
|
+
<PanelPortal anchor={panel.triggerRef.current}>
|
|
756
|
+
<FloatingFocusManager context={panel.context} modal={false} initialFocus={-1}>
|
|
757
|
+
<YStack
|
|
758
|
+
{...getFloatingProps({
|
|
759
|
+
ref: panel.refs.setFloating,
|
|
760
|
+
})}
|
|
761
|
+
data-testid="tree-select-panel"
|
|
762
|
+
data-cover=""
|
|
763
|
+
data-width-mode={TREE_SELECT_WIDTH_MODE}
|
|
764
|
+
data-dismiss-class="commit"
|
|
765
|
+
data-fp-panel=""
|
|
766
|
+
outlineWidth={0}
|
|
767
|
+
pointerEvents={panel.visible ? "auto" : "none"}
|
|
768
|
+
{...panel.knobProps.elevatedSurface}
|
|
769
|
+
borderRadius={panel.dropdownRadius}
|
|
770
|
+
overflow="hidden"
|
|
771
|
+
style={
|
|
772
|
+
{
|
|
773
|
+
position: "fixed",
|
|
774
|
+
top: overlayStyle.current?.top ?? 0,
|
|
775
|
+
left: 0,
|
|
776
|
+
zIndex: zIndex.dropdown,
|
|
777
|
+
opacity: panel.visible ? 1 : 0,
|
|
778
|
+
transform: panel.visible ? "scale(1)" : "scale(0.96)",
|
|
779
|
+
transition: panelTransition,
|
|
780
|
+
boxSizing: "border-box",
|
|
781
|
+
} as Record<string, unknown>
|
|
782
|
+
}
|
|
783
|
+
>
|
|
784
|
+
<SearchRow
|
|
785
|
+
value={state.filter}
|
|
786
|
+
placeholder={searchPlaceholder}
|
|
787
|
+
inputRef={searchRef}
|
|
788
|
+
onChange={state.setFilter}
|
|
789
|
+
onKeyDown={onSearchKeyDown}
|
|
798
790
|
treeId={treeId}
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
onCommit={commit}
|
|
802
|
-
onToggle={state.toggle}
|
|
791
|
+
activeDescendant={activeDescendant}
|
|
792
|
+
sizeToken={sizeToken}
|
|
803
793
|
/>
|
|
794
|
+
<YStack overflow="scroll" maxHeight={320} id={treeId}>
|
|
795
|
+
<TreeSelectPanelBody
|
|
796
|
+
rows={state.rows}
|
|
797
|
+
selectedId={value}
|
|
798
|
+
activeIndex={state.activeIndex}
|
|
799
|
+
keyboardRing={state.keyboardRing}
|
|
800
|
+
treeId={treeId}
|
|
801
|
+
emptyMessage={emptyMessage}
|
|
802
|
+
loading={loading}
|
|
803
|
+
onCommit={commit}
|
|
804
|
+
onToggle={state.toggle}
|
|
805
|
+
/>
|
|
806
|
+
</YStack>
|
|
804
807
|
</YStack>
|
|
805
|
-
</
|
|
806
|
-
</
|
|
808
|
+
</FloatingFocusManager>
|
|
809
|
+
</PanelPortal>
|
|
807
810
|
)}
|
|
808
811
|
</>
|
|
809
812
|
);
|
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
MIN_PRESS_TARGET,
|
|
3
3
|
ensureKeyboardModalityTracking,
|
|
4
4
|
useResolvedKnobs,
|
|
5
|
+
transitionProps,
|
|
5
6
|
} from "@multiplatform.one/theme";
|
|
6
7
|
import {
|
|
7
8
|
CornersInIcon,
|
|
@@ -83,7 +84,7 @@ function ChromeButton({
|
|
|
83
84
|
hoverStyle={{ backgroundColor: "$color4" }}
|
|
84
85
|
pressStyle={{ opacity: 0.85 }}
|
|
85
86
|
focusVisibleStyle={{ ...control.focusVisibleKnobProps }}
|
|
86
|
-
{...(knobProps.transition
|
|
87
|
+
{...transitionProps(knobProps.transition)}
|
|
87
88
|
onPress={(e: { stopPropagation?: () => void }) => {
|
|
88
89
|
e.stopPropagation?.();
|
|
89
90
|
onPress();
|
|
@@ -205,7 +206,7 @@ function SeekBar({
|
|
|
205
206
|
backgroundColor="$color8"
|
|
206
207
|
borderRadius={radius}
|
|
207
208
|
overflow="hidden"
|
|
208
|
-
{...(knobProps.transition
|
|
209
|
+
{...transitionProps(knobProps.transition)}
|
|
209
210
|
>
|
|
210
211
|
<YStack
|
|
211
212
|
height="100%"
|
|
@@ -300,7 +301,7 @@ export function PlayerChrome({
|
|
|
300
301
|
onFocusChange(false);
|
|
301
302
|
},
|
|
302
303
|
} as Record<string, unknown>)}
|
|
303
|
-
{...(knobProps.transition
|
|
304
|
+
{...transitionProps(knobProps.transition)}
|
|
304
305
|
>
|
|
305
306
|
<YStack flex={1} alignItems="center" justifyContent="center" pointerEvents="none">
|
|
306
307
|
{playing ? null : (
|
package/src/Wheel/Wheel.spec.tsx
CHANGED
|
@@ -275,7 +275,7 @@ describe("Wheel design-law (MPO-60)", () => {
|
|
|
275
275
|
expect("default" in mod).toBe(false);
|
|
276
276
|
});
|
|
277
277
|
|
|
278
|
-
it("selected row type stays on body weight 400, never 600 (R7 / design-audit)", () => {
|
|
278
|
+
it("selected row type stays on the body weight channel (400/700), never 500/600 (R7 / design-audit)", () => {
|
|
279
279
|
renderWithProviders(
|
|
280
280
|
<Wheel items={[1, 2, 3, 4, 5]} value={3} onChange={() => {}} visibleItems={5} />,
|
|
281
281
|
);
|
|
@@ -284,7 +284,7 @@ describe("Wheel design-law (MPO-60)", () => {
|
|
|
284
284
|
.querySelector('[data-testid="wheel-item"][data-selected="true"]') as HTMLElement;
|
|
285
285
|
expect(selected).toBeTruthy();
|
|
286
286
|
const text = selected.querySelector("[class]") as HTMLElement;
|
|
287
|
-
expect(text.className).toMatch(/_fow-400\b/);
|
|
287
|
+
expect(text.className).toMatch(/_fow-(400|700|bold)\b/);
|
|
288
288
|
expect(text.className).not.toMatch(/_fow-600\b/);
|
|
289
289
|
expect(text.className).not.toMatch(/_fow-500\b/);
|
|
290
290
|
});
|
|
@@ -298,7 +298,7 @@ describe("Wheel design-law (MPO-60)", () => {
|
|
|
298
298
|
const noneFrame = none.container.querySelector('[data-testid="wheel"]') as HTMLElement;
|
|
299
299
|
const noneAtoms = String(noneFrame.className)
|
|
300
300
|
.split(" ")
|
|
301
|
-
.filter((c) => c.startsWith("_btlr-"));
|
|
301
|
+
.filter((c) => c.startsWith("_btlr-") && c !== "_btlr-0px");
|
|
302
302
|
none.unmount();
|
|
303
303
|
|
|
304
304
|
const full = renderWithProviders(
|
|
@@ -309,7 +309,7 @@ describe("Wheel design-law (MPO-60)", () => {
|
|
|
309
309
|
const fullFrame = full.container.querySelector('[data-testid="wheel"]') as HTMLElement;
|
|
310
310
|
const fullAtoms = String(fullFrame.className)
|
|
311
311
|
.split(" ")
|
|
312
|
-
.filter((c) => c.startsWith("_btlr-"));
|
|
312
|
+
.filter((c) => c.startsWith("_btlr-") && c !== "_btlr-0px");
|
|
313
313
|
expect(noneAtoms).toEqual([]);
|
|
314
314
|
expect(fullAtoms).toEqual([]);
|
|
315
315
|
});
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `00` L1 test 1, the adjacency check (MPO-23, gap ledger GL-41). A Button,
|
|
3
|
+
* an Input, a Select trigger and a ListItem in one `XStack` at the same size
|
|
4
|
+
* token, with only a `gap`, must agree on height and on radius. They differ
|
|
5
|
+
* only in interior padding (`00` L9f). `constraintAudit` checks that each
|
|
6
|
+
* value lands on a token step; nothing checked that siblings agree.
|
|
7
|
+
*
|
|
8
|
+
* The DOM here cannot lay out and does not resolve Tamagui's CSS variables,
|
|
9
|
+
* so each frame's box is read from the atoms it paints (`_h-44px`,
|
|
10
|
+
* `_btlr-t-radius-4`, `_mih-t-size-4`) and resolved through the live token
|
|
11
|
+
* table. That is the same box a browser computes for these frames: none of
|
|
12
|
+
* them grows past its height or min-height with one line of content.
|
|
13
|
+
*
|
|
14
|
+
* The law holds for height at every size stop and for the controls' radius at
|
|
15
|
+
* the default stop. ListItem joins the height check only: it is a flush row
|
|
16
|
+
* (SP-EDGE, radius 0) and never takes the controls' radius (Clay 2026-09-26,
|
|
17
|
+
* MPO-23 ruling 1A). Two disagreements are open and pinned below as expected
|
|
18
|
+
* failures, each naming its culprit. Fixing one makes its `it.fails` go red,
|
|
19
|
+
* which is the signal to turn it into a plain assertion.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { Input, Select } from "@multiplatform.one/forms";
|
|
23
|
+
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
24
|
+
import { Preset, type Size } from "@multiplatform.one/theme";
|
|
25
|
+
import { cleanup } from "@testing-library/react";
|
|
26
|
+
import type { ReactElement } from "react";
|
|
27
|
+
import { getTokens } from "tamagui";
|
|
28
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
29
|
+
import { Button } from "./Button";
|
|
30
|
+
import { ListItem, XStack } from "./tamagui";
|
|
31
|
+
|
|
32
|
+
afterEach(cleanup);
|
|
33
|
+
|
|
34
|
+
type Box = { height: number; radius: number };
|
|
35
|
+
type Row = Record<"Button" | "Input" | "Select trigger" | "ListItem", Box>;
|
|
36
|
+
|
|
37
|
+
const stops = [
|
|
38
|
+
["small", "$3"],
|
|
39
|
+
["medium", "$4"],
|
|
40
|
+
["large", "$5"],
|
|
41
|
+
] as const satisfies readonly (readonly [Size, string])[];
|
|
42
|
+
|
|
43
|
+
function atom(el: HTMLElement, prop: string) {
|
|
44
|
+
for (const cls of String(el.className || "").split(/\s+/)) {
|
|
45
|
+
if (!cls.startsWith(`_${prop}-`)) continue;
|
|
46
|
+
const value = cls.slice(prop.length + 2);
|
|
47
|
+
if (/^-?\d+(?:\.\d+)?px$|^t-(?:size|radius)-\d+$/.test(value)) return value;
|
|
48
|
+
}
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function px(value: string | undefined): number | undefined {
|
|
53
|
+
if (value === undefined) return undefined;
|
|
54
|
+
const literal = value.match(/^(-?\d+(?:\.\d+)?)px$/);
|
|
55
|
+
if (literal) return Number(literal[1]);
|
|
56
|
+
const [, scale, step] = value.match(/^t-(size|radius)-(\d+)$/) ?? [];
|
|
57
|
+
const tokens = getTokens() as unknown as Record<string, Record<string, { val: unknown }>>;
|
|
58
|
+
return Number.parseFloat(String(tokens[scale ?? ""]?.[`$${step}`]?.val));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function box(el: HTMLElement | null, name: string): Box {
|
|
62
|
+
if (!el) throw new Error(`${name} frame not rendered`);
|
|
63
|
+
const height = px(atom(el, "h") ?? atom(el, "mih"));
|
|
64
|
+
if (height === undefined) throw new Error(`${name} paints no height`);
|
|
65
|
+
return { height, radius: px(atom(el, "btlr")) ?? 0 };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function measure(ui: ReactElement): Row {
|
|
69
|
+
const { container } = renderWithProviders(ui);
|
|
70
|
+
const frame = (selector: string) => container.querySelector<HTMLElement>(selector);
|
|
71
|
+
return {
|
|
72
|
+
Button: box(frame("[data-mp-button-height]"), "Button"),
|
|
73
|
+
Input: box(frame("[data-mp-input-box]"), "Input"),
|
|
74
|
+
"Select trigger": box(frame('[data-testid="select-trigger"]'), "Select trigger"),
|
|
75
|
+
ListItem: box(frame('[data-testid="l1-list-item"]'), "ListItem"),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** The mpo size channel: the size knob, which every house control reads. */
|
|
80
|
+
function atKnob(knob: Size, token: string) {
|
|
81
|
+
return measure(
|
|
82
|
+
<Preset overrides={{ size: knob }}>
|
|
83
|
+
<XStack gap="$2">
|
|
84
|
+
<Button>Save</Button>
|
|
85
|
+
<Input placeholder="Name" />
|
|
86
|
+
<Select options={[{ value: "a", label: "A" }]} placeholder="Pick" />
|
|
87
|
+
<ListItem size={token as "$4"} title="Row" data-testid="l1-list-item" />
|
|
88
|
+
</XStack>
|
|
89
|
+
</Preset>,
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** The same token handed to each component directly. */
|
|
94
|
+
function atSizeProp(token: "$3" | "$4" | "$5") {
|
|
95
|
+
return measure(
|
|
96
|
+
<XStack gap="$2">
|
|
97
|
+
<Button size={token}>Save</Button>
|
|
98
|
+
<Input size={token} placeholder="Name" />
|
|
99
|
+
<Select size={token} options={[{ value: "a", label: "A" }]} placeholder="Pick" />
|
|
100
|
+
<ListItem size={token} title="Row" data-testid="l1-list-item" />
|
|
101
|
+
</XStack>,
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function heights(row: Row) {
|
|
106
|
+
return Object.fromEntries(Object.entries(row).map(([name, b]) => [name, b.height]));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function radii(row: Row, names: (keyof Row)[]) {
|
|
110
|
+
return Object.fromEntries(names.map((name) => [name, row[name].radius]));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function agreed(values: Record<string, number>) {
|
|
114
|
+
const first = Object.values(values)[0];
|
|
115
|
+
return Object.fromEntries(Object.keys(values).map((name) => [name, first]));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const controls: (keyof Row)[] = ["Button", "Input", "Select trigger"];
|
|
119
|
+
|
|
120
|
+
describe("00 L1 adjacency: Button, Input, Select trigger and ListItem at one size token", () => {
|
|
121
|
+
for (const [knob, token] of stops) {
|
|
122
|
+
it(`all four paint one height at size ${knob} (${token})`, () => {
|
|
123
|
+
const row = heights(atKnob(knob, token));
|
|
124
|
+
expect(row).toEqual(agreed(row));
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
it("catches a deliberate violation: a Button ejected to its own height", () => {
|
|
129
|
+
const row = heights(
|
|
130
|
+
measure(
|
|
131
|
+
<XStack gap="$2">
|
|
132
|
+
<Button height={30} sizeRecipeEscape="L1 adjacency fixture">
|
|
133
|
+
Save
|
|
134
|
+
</Button>
|
|
135
|
+
<Input placeholder="Name" />
|
|
136
|
+
<Select options={[{ value: "a", label: "A" }]} placeholder="Pick" />
|
|
137
|
+
<ListItem size="$4" title="Row" data-testid="l1-list-item" />
|
|
138
|
+
</XStack>,
|
|
139
|
+
),
|
|
140
|
+
);
|
|
141
|
+
expect(row.Button).toBe(30);
|
|
142
|
+
expect(row).not.toEqual(agreed(row));
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it("Button, Input and Select trigger paint one radius at the default size", () => {
|
|
146
|
+
const row = radii(atKnob("medium", "$4"), controls);
|
|
147
|
+
expect(row).toEqual(agreed(row));
|
|
148
|
+
expect(row.Button).toBeGreaterThan(0);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it("ListItem stays a flush row beside them: radius 0, never the controls' radius", () => {
|
|
152
|
+
const row = radii(atKnob("medium", "$4"), [...controls, "ListItem"]);
|
|
153
|
+
expect(row.ListItem).toBe(0);
|
|
154
|
+
expect(row.Button).toBeGreaterThan(0);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
for (const [knob, token] of stops.filter(([k]) => k !== "medium")) {
|
|
158
|
+
it.fails(`OPEN: Button and Input paint one radius at size ${knob} (Button's radius follows size, Input's only the radius knob)`, () => {
|
|
159
|
+
const row = radii(atKnob(knob, token), controls);
|
|
160
|
+
expect(row).toEqual(agreed(row));
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
it("an explicit size prop agrees with itself at the default token", () => {
|
|
165
|
+
const row = heights(atSizeProp("$4"));
|
|
166
|
+
expect(row).toEqual(agreed(row));
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
for (const token of ["$3", "$5"] as const) {
|
|
170
|
+
it.fails(`OPEN: an explicit size=${token} moves Input and Select trigger with Button (Input paints the knob height, Select ignores size)`, () => {
|
|
171
|
+
const row = heights(atSizeProp(token));
|
|
172
|
+
expect(row).toEqual(agreed(row));
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
2
|
-
import { describe, expect, it
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
3
|
import { Code, CodeInline } from "./index";
|
|
4
4
|
|
|
5
5
|
describe("Code", () => {
|
|
@@ -27,7 +27,7 @@ describe("Code", () => {
|
|
|
27
27
|
const codeElement = container.querySelector("code");
|
|
28
28
|
expect(codeElement).toBeTruthy();
|
|
29
29
|
expect(codeElement!.getAttribute("data-code-font")).toBe("mono");
|
|
30
|
-
//
|
|
30
|
+
// An RN prop map on this host would land as dataset="[object Object]".
|
|
31
31
|
expect(codeElement!.hasAttribute("dataset")).toBe(false);
|
|
32
32
|
});
|
|
33
33
|
});
|
|
@@ -51,21 +51,4 @@ describe("CodeInline", () => {
|
|
|
51
51
|
const codeElement = container.querySelector("code");
|
|
52
52
|
expect(codeElement).toBeDefined();
|
|
53
53
|
});
|
|
54
|
-
|
|
55
|
-
it("emits data-code-font on web without a dataSet host-prop leak", () => {
|
|
56
|
-
const leak = /does not recognize the `dataSet` prop on a DOM element/;
|
|
57
|
-
const errorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
|
|
58
|
-
try {
|
|
59
|
-
const { container } = renderWithProviders(<CodeInline>npm install</CodeInline>);
|
|
60
|
-
const codeElement = container.querySelector("code");
|
|
61
|
-
expect(codeElement).toBeDefined();
|
|
62
|
-
expect(codeElement?.getAttribute("data-code-font")).toBe("mono");
|
|
63
|
-
const leaks = errorSpy.mock.calls
|
|
64
|
-
.map((args) => args.map(String).join(" "))
|
|
65
|
-
.filter((message) => leak.test(message));
|
|
66
|
-
expect(leaks).toEqual([]);
|
|
67
|
-
} finally {
|
|
68
|
-
errorSpy.mockRestore();
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
54
|
});
|
package/src/code/Code/index.tsx
CHANGED
|
@@ -81,12 +81,6 @@ export const CodeInline = CodeInlineFrame.styleable((props, ref) => {
|
|
|
81
81
|
fontFamily="$mono"
|
|
82
82
|
letterSpacing={0}
|
|
83
83
|
data-code-font="mono"
|
|
84
|
-
// react-native-web reads dataSet; React-DOM warns on the camel host
|
|
85
|
-
// prop. Keep the kebab attribute on every target; spread dataSet
|
|
86
|
-
// only when TAMAGUI_TARGET is native.
|
|
87
|
-
{...(process.env.TAMAGUI_TARGET === "native"
|
|
88
|
-
? ({ dataSet: { codeFont: "mono" } } as object)
|
|
89
|
-
: {})}
|
|
90
84
|
/>
|
|
91
85
|
);
|
|
92
86
|
});
|