@multiplatform.one/components 7.77.2 → 7.79.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/Accordion/index.native.js +1 -1
- package/dist/cjs/Accordion/index.native.js.map +1 -1
- package/dist/cjs/Alert/index.native.js.map +1 -1
- package/dist/cjs/AnimateHeight/index.native.js.map +1 -1
- package/dist/cjs/Avatar/getInitials.native.js.map +1 -1
- package/dist/cjs/Avatar/index.native.js.map +1 -1
- package/dist/cjs/Badge/index.native.js.map +1 -1
- package/dist/cjs/Button.native.js.map +1 -1
- package/dist/cjs/Card.native.js.map +1 -1
- package/dist/cjs/CardFooter.native.js.map +1 -1
- package/dist/cjs/CardHeader.native.js.map +1 -1
- package/dist/cjs/Carousel/index.native.js +3 -3
- package/dist/cjs/Carousel/index.native.js.map +1 -1
- package/dist/cjs/Chip/index.native.js.map +1 -1
- package/dist/cjs/Collapsible.native.js.map +1 -1
- package/dist/cjs/ContextMenu/index.native.js.map +1 -1
- package/dist/cjs/CopyField/CopyMenuButton.native.js +1 -1
- package/dist/cjs/CopyField/CopyMenuButton.native.js.map +1 -1
- package/dist/cjs/CopyField/index.native.js.map +1 -1
- package/dist/cjs/Dialog.native.js.map +1 -1
- package/dist/cjs/Diff/diff.cjs +84 -0
- package/dist/cjs/Diff/diff.native.js +108 -0
- package/dist/cjs/Diff/diff.native.js.map +1 -0
- package/dist/cjs/Diff/index.cjs +174 -0
- package/dist/cjs/Diff/index.native.js +181 -0
- package/dist/cjs/Diff/index.native.js.map +1 -0
- package/dist/cjs/DotIndicator/index.native.js.map +1 -1
- package/dist/cjs/DropdownMenu/index.native.js.map +1 -1
- package/dist/cjs/DropdownMenu/menuSettle.native.js.map +1 -1
- package/dist/cjs/ElapsedProgress/index.cjs +102 -0
- package/dist/cjs/ElapsedProgress/index.native.js +112 -0
- package/dist/cjs/ElapsedProgress/index.native.js.map +1 -0
- package/dist/cjs/ErrorBoundary/index.native.js.map +1 -1
- package/dist/cjs/Heading.native.js.map +1 -1
- package/dist/cjs/Kbd/index.native.js.map +1 -1
- package/dist/cjs/Kbd/keys.native.js.map +1 -1
- package/dist/cjs/Lightbox/MediaControl.cjs +2 -6
- package/dist/cjs/Lightbox/MediaControl.native.js +2 -8
- package/dist/cjs/Lightbox/MediaControl.native.js.map +1 -1
- package/dist/cjs/Lightbox/index.gnome.native.js.map +1 -1
- package/dist/cjs/Lightbox/index.native.js +1 -1
- package/dist/cjs/Lightbox/shared.native.js.map +1 -1
- package/dist/cjs/Lightbox/useLightbox.native.js.map +1 -1
- package/dist/cjs/MachineLiteral/index.cjs +98 -0
- package/dist/cjs/MachineLiteral/index.native.js +102 -0
- package/dist/cjs/MachineLiteral/index.native.js.map +1 -0
- package/dist/cjs/Material/blur.cjs +34 -0
- package/dist/cjs/Material/blur.native.js +100 -0
- package/dist/cjs/Material/blur.native.js.map +1 -0
- package/dist/cjs/Material/index.cjs +9 -3
- package/dist/cjs/Material/index.native.js +9 -3
- package/dist/cjs/Material/index.native.js.map +1 -1
- package/dist/cjs/Meter/index.cjs +3 -1
- package/dist/cjs/Meter/index.native.js +4 -2
- package/dist/cjs/Meter/index.native.js.map +1 -1
- package/dist/cjs/Meter/meter.native.js.map +1 -1
- package/dist/cjs/OverflowRow/index.native.js +1 -1
- package/dist/cjs/OverflowRow/index.native.js.map +1 -1
- package/dist/cjs/Pagination.native.js +1 -1
- package/dist/cjs/Pagination.native.js.map +1 -1
- package/dist/cjs/Popover.native.js +1 -1
- package/dist/cjs/Popover.native.js.map +1 -1
- package/dist/cjs/ProgressSteps/index.native.js.map +1 -1
- package/dist/cjs/Quote/index.native.js.map +1 -1
- package/dist/cjs/SchemeToggle/index.native.js +1 -1
- package/dist/cjs/SchemeToggle/index.native.js.map +1 -1
- package/dist/cjs/ScrollView/revealFocusedField.native.js.map +1 -1
- package/dist/cjs/Separator/index.native.js.map +1 -1
- package/dist/cjs/Sheet.native.js.map +1 -1
- package/dist/cjs/SheetModal/SheetHeader.native.js.map +1 -1
- package/dist/cjs/SheetModal/SheetNavigation.native.js.map +1 -1
- package/dist/cjs/SheetModal/detents.native.js.map +1 -1
- package/dist/cjs/SheetModal/useSheetFrameFocus.native.js.map +1 -1
- package/dist/cjs/Skeleton/index.native.js.map +1 -1
- package/dist/cjs/SkipLink/index.native.js.map +1 -1
- package/dist/cjs/SortableList/SortableHandle.native.js.map +1 -1
- package/dist/cjs/SortableList/index.cjs +4 -1
- package/dist/cjs/SortableList/index.native.js +4 -1
- package/dist/cjs/SortableList/index.native.js.map +1 -1
- package/dist/cjs/SortableList/useSortableRows.native.js.map +1 -1
- package/dist/cjs/SortableList/useUserOrder.cjs +84 -0
- package/dist/cjs/SortableList/useUserOrder.native.js +107 -0
- package/dist/cjs/SortableList/useUserOrder.native.js.map +1 -0
- package/dist/cjs/Tabs/index.native.js +1 -1
- package/dist/cjs/Tabs/index.native.js.map +1 -1
- package/dist/cjs/Text.native.js.map +1 -1
- package/dist/cjs/ThemePresetPicker/index.native.js +2 -2
- package/dist/cjs/ThemePresetPicker/index.native.js.map +1 -1
- package/dist/cjs/Toast/index.native.js.map +1 -1
- package/dist/cjs/Toast/store.native.js.map +1 -1
- package/dist/cjs/Tooltip/nativePress.native.js.map +1 -1
- package/dist/cjs/Tooltip/tooltipShared.native.js.map +1 -1
- package/dist/cjs/TreeSelect/index.cjs +7 -1
- package/dist/cjs/TreeSelect/index.native.js +8 -2
- package/dist/cjs/TreeSelect/index.native.js.map +1 -1
- package/dist/cjs/TreeSelect/treeSelectModel.native.js.map +1 -1
- package/dist/cjs/Video/PlayerChrome.native.js.map +1 -1
- package/dist/cjs/Video/VideoFrame.native.js.map +1 -1
- package/dist/cjs/Video/types.native.js.map +1 -1
- package/dist/cjs/Wheel/index.native.js.map +1 -1
- package/dist/cjs/Wizard/index.native.js +2 -2
- package/dist/cjs/Wizard/index.native.js.map +1 -1
- package/dist/cjs/actions/ActionBar.native.js.map +1 -1
- package/dist/cjs/actions/DangerSection.native.js.map +1 -1
- package/dist/cjs/actions/DestructiveAction.native.js.map +1 -1
- package/dist/cjs/actions/HeaderActions.native.js +2 -2
- package/dist/cjs/actions/HeaderActions.native.js.map +1 -1
- package/dist/cjs/actions/StandardAction.native.js +1 -1
- package/dist/cjs/actions/StandardAction.native.js.map +1 -1
- package/dist/cjs/actions/devWarn.native.js.map +1 -1
- package/dist/cjs/actions/index.native.js.map +1 -1
- package/dist/cjs/actions/severity.native.js.map +1 -1
- package/dist/cjs/appShell/Dock.native.js.map +1 -1
- package/dist/cjs/appShell/MpoTabHost.native.js.map +1 -1
- package/dist/cjs/appShell/ScopeMenu.native.js.map +1 -1
- package/dist/cjs/appShell/SettingsSplit.native.js +1 -1
- package/dist/cjs/appShell/SettingsSplit.native.js.map +1 -1
- package/dist/cjs/appShell/Springboard.native.js +1 -1
- package/dist/cjs/appShell/Springboard.native.js.map +1 -1
- package/dist/cjs/appShell/SystemBar.native.js.map +1 -1
- package/dist/cjs/appShell/TabBar.cjs +10 -5
- package/dist/cjs/appShell/TabBar.native.js +11 -6
- package/dist/cjs/appShell/TabBar.native.js.map +1 -1
- package/dist/cjs/appShell/TabHost.native.js +1 -0
- package/dist/cjs/appShell/TabHost.native.js.map +1 -1
- package/dist/cjs/appShell/appTile.native.js +1 -1
- package/dist/cjs/appShell/appTile.native.js.map +1 -1
- package/dist/cjs/appShell/bottomChrome.native.js.map +1 -1
- package/dist/cjs/appShell/index.native.js.map +1 -1
- package/dist/cjs/charts/Axis.native.js.map +1 -1
- package/dist/cjs/charts/BarChart.native.js.map +1 -1
- package/dist/cjs/charts/ChartDataView.native.js +1 -1
- package/dist/cjs/charts/ChartDataView.native.js.map +1 -1
- package/dist/cjs/charts/ChartSurface.native.js.map +1 -1
- package/dist/cjs/charts/LineChart.native.js.map +1 -1
- package/dist/cjs/charts/PieChart.native.js.map +1 -1
- package/dist/cjs/charts/Sparkline.cjs +1 -1
- package/dist/cjs/charts/Sparkline.native.js +1 -1
- package/dist/cjs/charts/Sparkline.native.js.map +1 -1
- package/dist/cjs/charts/accessibility.native.js.map +1 -1
- package/dist/cjs/charts/chartHeight.native.js.map +1 -1
- package/dist/cjs/charts/composeChart.native.js.map +1 -1
- package/dist/cjs/charts/index.native.js.map +1 -1
- package/dist/cjs/charts/math.native.js.map +1 -1
- package/dist/cjs/charts/series.native.js.map +1 -1
- package/dist/cjs/charts/svg.native.js.map +1 -1
- package/dist/cjs/charts/types.native.js.map +1 -1
- package/dist/cjs/charts/useChartTheme.native.js.map +1 -1
- package/dist/cjs/code/Code/index.native.js.map +1 -1
- package/dist/cjs/code/CodeBlock/index.native.js +7 -7
- package/dist/cjs/code/CodeBlock/index.native.js.map +1 -1
- package/dist/cjs/code/HighlightedCode/index.native.js.map +1 -1
- package/dist/cjs/code/Highlighter/houseSyntaxTheme.native.js.map +1 -1
- package/dist/cjs/code/Highlighter/index.native.js.map +1 -1
- package/dist/cjs/code/Highlighter/namedGroupMatchAll.native.js.map +1 -1
- package/dist/cjs/code/Pre/index.native.js.map +1 -1
- package/dist/cjs/code/index.native.js +5 -5
- package/dist/cjs/code/index.native.js.map +1 -1
- package/dist/cjs/componentColors.cjs +1 -1
- package/dist/cjs/componentColors.native.js +1 -1
- package/dist/cjs/componentColors.native.js.map +1 -1
- package/dist/cjs/feedback/ConfirmDialog.native.js.map +1 -1
- package/dist/cjs/feedback/NotifyHost.native.js +2 -2
- package/dist/cjs/feedback/NotifyHost.native.js.map +1 -1
- package/dist/cjs/feedback/copy.native.js.map +1 -1
- package/dist/cjs/feedback/index.native.js.map +1 -1
- package/dist/cjs/feedback/notify.native.js.map +1 -1
- package/dist/cjs/feedback/route.native.js.map +1 -1
- package/dist/cjs/feedback/store.native.js.map +1 -1
- package/dist/cjs/formLayouts/FormLayouts.native.js +1 -1
- package/dist/cjs/formLayouts/FormLayouts.native.js.map +1 -1
- package/dist/cjs/formLayouts/PreferencePanel.native.js +2 -2
- package/dist/cjs/formLayouts/PreferencePanel.native.js.map +1 -1
- package/dist/cjs/formLayouts/index.native.js.map +1 -1
- package/dist/cjs/hooks/index.native.js +1 -1
- package/dist/cjs/hooks/index.native.js.map +1 -1
- package/dist/cjs/hooks/useClipboard.native.js.map +1 -1
- package/dist/cjs/hooks/useDocumentTitle.native.js.map +1 -1
- package/dist/cjs/hooks/useHoldCue.native.js.map +1 -1
- package/dist/cjs/icons/CheckRegular.native.js.map +1 -1
- package/dist/cjs/icons/MinusRegular.native.js.map +1 -1
- package/dist/cjs/icons/index.native.js.map +1 -1
- package/dist/cjs/icons/lucide.native.js.map +1 -1
- package/dist/cjs/icons/themed.native.js.map +1 -1
- package/dist/cjs/images/Image/ImageFrame.native.js +1 -1
- package/dist/cjs/images/Image/ImageFrame.native.js.map +1 -1
- package/dist/cjs/images/Image/framing.native.js.map +1 -1
- package/dist/cjs/images/Image/index.native.js +1 -1
- package/dist/cjs/images/Image/mediaRadius.native.js.map +1 -1
- package/dist/cjs/images/Image/shared.native.js +1 -1
- package/dist/cjs/images/Image/shared.native.js.map +1 -1
- package/dist/cjs/images/Image/types.native.js.map +1 -1
- package/dist/cjs/images/index.native.js.map +1 -1
- package/dist/cjs/index.cjs +6 -1
- package/dist/cjs/index.native.js +42 -37
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/knobImmuneExports.native.js.map +1 -1
- package/dist/cjs/layouts/AsyncBoundary.native.js +2 -2
- package/dist/cjs/layouts/AsyncBoundary.native.js.map +1 -1
- package/dist/cjs/layouts/Debug/index.native.js.map +1 -1
- package/dist/cjs/layouts/EmptyState.native.js.map +1 -1
- package/dist/cjs/layouts/IdentityPlate.native.js.map +1 -1
- package/dist/cjs/layouts/KeyboardAvoidingWrapper/behavior.native.js.map +1 -1
- package/dist/cjs/layouts/PageTemplates.native.js.map +1 -1
- package/dist/cjs/layouts/PaneScaffold.native.js.map +1 -1
- package/dist/cjs/layouts/SafeAreaWrapper/insets.native.js.map +1 -1
- package/dist/cjs/layouts/StatusDot.native.js.map +1 -1
- package/dist/cjs/layouts/StatusGlyphStrip.native.js +1 -1
- package/dist/cjs/layouts/StatusGlyphStrip.native.js.map +1 -1
- package/dist/cjs/layouts/ViewSwitcher.native.js.map +1 -1
- package/dist/cjs/layouts/attachments.native.js +1 -1
- package/dist/cjs/layouts/attachments.native.js.map +1 -1
- package/dist/cjs/layouts/bottomAccessory.native.js.map +1 -1
- package/dist/cjs/layouts/breadcrumbs.native.js.map +1 -1
- package/dist/cjs/layouts/index.native.js +3 -3
- package/dist/cjs/layouts/index.native.js.map +1 -1
- package/dist/cjs/layouts/page.cjs +0 -4
- package/dist/cjs/layouts/page.native.js +2 -6
- package/dist/cjs/layouts/page.native.js.map +1 -1
- package/dist/cjs/layouts/pageHeadingScope.native.js.map +1 -1
- package/dist/cjs/layouts/screenScroll.native.js.map +1 -1
- package/dist/cjs/layouts/shellSidebarSlot.native.js.map +1 -1
- package/dist/cjs/layouts/sidebar.native.js +1 -1
- package/dist/cjs/layouts/sidebar.native.js.map +1 -1
- package/dist/cjs/layouts/tags.native.js +2 -2
- package/dist/cjs/layouts/tags.native.js.map +1 -1
- package/dist/cjs/layouts/timeline.native.js +2 -2
- package/dist/cjs/layouts/timeline.native.js.map +1 -1
- package/dist/cjs/layouts/toolbar.native.js +1 -1
- package/dist/cjs/layouts/toolbar.native.js.map +1 -1
- package/dist/cjs/shared/actionScan.native.js.map +1 -1
- package/dist/cjs/shared/i18n.native.js.map +1 -1
- package/dist/cjs/shared/restoreRetries.native.js.map +1 -1
- package/dist/cjs/shared/t.native.js.map +1 -1
- package/dist/cjs/shared/textRidesText.native.js.map +1 -1
- package/dist/cjs/shared/useReturnFocusOnClose.native.js.map +1 -1
- package/dist/cjs/surfaces.native.js +1 -1
- package/dist/cjs/surfaces.native.js.map +1 -1
- package/dist/cjs/tamagui.native.js +1 -1
- package/dist/cjs/tamagui.native.js.map +1 -1
- package/dist/cjs/testSetup.native.js.map +1 -1
- package/dist/cjs/utils/setTinted.native.js.map +1 -1
- package/dist/cjs/utils/unwrapText.native.js.map +1 -1
- package/dist/cjs/views/Calendar.native.js +1 -1
- package/dist/cjs/views/Calendar.native.js.map +1 -1
- package/dist/cjs/views/Dashboard.native.js +2 -2
- package/dist/cjs/views/Dashboard.native.js.map +1 -1
- package/dist/cjs/views/Gantt.native.js +2 -2
- package/dist/cjs/views/Gantt.native.js.map +1 -1
- package/dist/cjs/views/GanttDateGrip.native.js.map +1 -1
- package/dist/cjs/views/ImageGrid.cjs +9 -12
- package/dist/cjs/views/ImageGrid.native.js +11 -18
- package/dist/cjs/views/ImageGrid.native.js.map +1 -1
- package/dist/cjs/views/Kanban.native.js +1 -1
- package/dist/cjs/views/List.native.js.map +1 -1
- package/dist/cjs/views/ListGroup.native.js.map +1 -1
- package/dist/cjs/views/ListRow.native.js.map +1 -1
- package/dist/cjs/views/Matrix.native.js +2 -2
- package/dist/cjs/views/Matrix.native.js.map +1 -1
- package/dist/cjs/views/ReportBuilder.cjs +3 -3
- package/dist/cjs/views/ReportBuilder.native.js +5 -5
- package/dist/cjs/views/ReportBuilder.native.js.map +1 -1
- package/dist/cjs/views/ShortcutCard.native.js.map +1 -1
- package/dist/cjs/views/TreeView.native.js.map +1 -1
- package/dist/cjs/views/calendarMath.native.js.map +1 -1
- package/dist/cjs/views/ganttIntervals.native.js.map +1 -1
- package/dist/cjs/views/ganttMath.native.js.map +1 -1
- package/dist/cjs/views/index.cjs +3 -1
- package/dist/cjs/views/index.native.js +3 -1
- package/dist/cjs/views/index.native.js.map +1 -1
- package/dist/cjs/views/kanbanDnd.native.js.map +1 -1
- package/dist/cjs/views/matrixMath.native.js.map +1 -1
- package/dist/cjs/views/sameNameScope.cjs +39 -0
- package/dist/cjs/views/sameNameScope.native.js +63 -0
- package/dist/cjs/views/sameNameScope.native.js.map +1 -0
- package/dist/cjs/views/treeViewDnd.native.js.map +1 -1
- package/dist/cjs/views/treeViewLayout.native.js.map +1 -1
- package/dist/cjs/views/treeViewMotion.native.js.map +1 -1
- package/dist/cjs/views/treeViewReveal.native.js.map +1 -1
- package/dist/cjs/views/usePageFlowLoadMore.cjs +83 -0
- package/dist/cjs/views/usePageFlowLoadMore.native.js +93 -0
- package/dist/cjs/views/usePageFlowLoadMore.native.js.map +1 -0
- package/dist/cjs/views/widgetChrome.native.js.map +1 -1
- package/dist/esm/Diff/diff.mjs +58 -0
- package/dist/esm/Diff/diff.mjs.map +1 -0
- package/dist/esm/Diff/diff.native.js +79 -0
- package/dist/esm/Diff/diff.native.js.map +1 -0
- package/dist/esm/Diff/index.mjs +147 -0
- package/dist/esm/Diff/index.mjs.map +1 -0
- package/dist/esm/Diff/index.native.js +151 -0
- package/dist/esm/Diff/index.native.js.map +1 -0
- package/dist/esm/ElapsedProgress/index.mjs +76 -0
- package/dist/esm/ElapsedProgress/index.mjs.map +1 -0
- package/dist/esm/ElapsedProgress/index.native.js +83 -0
- package/dist/esm/ElapsedProgress/index.native.js.map +1 -0
- package/dist/esm/Lightbox/MediaControl.mjs +3 -7
- package/dist/esm/Lightbox/MediaControl.mjs.map +1 -1
- package/dist/esm/Lightbox/MediaControl.native.js +3 -9
- package/dist/esm/Lightbox/MediaControl.native.js.map +1 -1
- package/dist/esm/MachineLiteral/index.mjs +73 -0
- package/dist/esm/MachineLiteral/index.mjs.map +1 -0
- package/dist/esm/MachineLiteral/index.native.js +74 -0
- package/dist/esm/MachineLiteral/index.native.js.map +1 -0
- package/dist/esm/Material/blur.mjs +8 -0
- package/dist/esm/Material/blur.mjs.map +1 -0
- package/dist/esm/Material/blur.native.js +67 -0
- package/dist/esm/Material/blur.native.js.map +1 -0
- package/dist/esm/Material/index.mjs +10 -4
- package/dist/esm/Material/index.mjs.map +1 -1
- package/dist/esm/Material/index.native.js +10 -4
- package/dist/esm/Material/index.native.js.map +1 -1
- package/dist/esm/Meter/index.mjs +4 -3
- package/dist/esm/Meter/index.mjs.map +1 -1
- package/dist/esm/Meter/index.native.js +4 -3
- package/dist/esm/Meter/index.native.js.map +1 -1
- package/dist/esm/SortableList/index.mjs +2 -1
- package/dist/esm/SortableList/index.mjs.map +1 -1
- package/dist/esm/SortableList/index.native.js +2 -1
- package/dist/esm/SortableList/index.native.js.map +1 -1
- package/dist/esm/SortableList/useUserOrder.mjs +58 -0
- package/dist/esm/SortableList/useUserOrder.mjs.map +1 -0
- package/dist/esm/SortableList/useUserOrder.native.js +78 -0
- package/dist/esm/SortableList/useUserOrder.native.js.map +1 -0
- package/dist/esm/TreeSelect/index.mjs +8 -2
- package/dist/esm/TreeSelect/index.mjs.map +1 -1
- package/dist/esm/TreeSelect/index.native.js +8 -2
- package/dist/esm/TreeSelect/index.native.js.map +1 -1
- package/dist/esm/appShell/TabBar.mjs +10 -5
- package/dist/esm/appShell/TabBar.mjs.map +1 -1
- package/dist/esm/appShell/TabBar.native.js +10 -5
- package/dist/esm/appShell/TabBar.native.js.map +1 -1
- package/dist/esm/appShell/TabHost.native.js +1 -0
- package/dist/esm/appShell/TabHost.native.js.map +1 -1
- package/dist/esm/charts/Sparkline.mjs +1 -1
- package/dist/esm/charts/Sparkline.mjs.map +1 -1
- package/dist/esm/charts/Sparkline.native.js +1 -1
- package/dist/esm/charts/Sparkline.native.js.map +1 -1
- package/dist/esm/componentColors.mjs +1 -1
- package/dist/esm/componentColors.native.js +1 -1
- package/dist/esm/index.mjs +5 -2
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +5 -2
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/layouts/page.mjs +0 -4
- package/dist/esm/layouts/page.mjs.map +1 -1
- package/dist/esm/layouts/page.native.js +0 -4
- package/dist/esm/layouts/page.native.js.map +1 -1
- package/dist/esm/views/ImageGrid.mjs +10 -13
- package/dist/esm/views/ImageGrid.mjs.map +1 -1
- package/dist/esm/views/ImageGrid.native.js +10 -17
- package/dist/esm/views/ImageGrid.native.js.map +1 -1
- package/dist/esm/views/ReportBuilder.mjs +4 -4
- package/dist/esm/views/ReportBuilder.mjs.map +1 -1
- package/dist/esm/views/ReportBuilder.native.js +4 -4
- package/dist/esm/views/ReportBuilder.native.js.map +1 -1
- package/dist/esm/views/index.mjs +2 -1
- package/dist/esm/views/index.mjs.map +1 -1
- package/dist/esm/views/index.native.js +2 -1
- package/dist/esm/views/index.native.js.map +1 -1
- package/dist/esm/views/sameNameScope.mjs +14 -0
- package/dist/esm/views/sameNameScope.mjs.map +1 -0
- package/dist/esm/views/sameNameScope.native.js +35 -0
- package/dist/esm/views/sameNameScope.native.js.map +1 -0
- package/dist/esm/views/usePageFlowLoadMore.mjs +57 -0
- package/dist/esm/views/usePageFlowLoadMore.mjs.map +1 -0
- package/dist/esm/views/usePageFlowLoadMore.native.js +64 -0
- package/dist/esm/views/usePageFlowLoadMore.native.js.map +1 -0
- package/dist/jsx/Diff/diff.mjs +58 -0
- package/dist/jsx/Diff/diff.mjs.map +1 -0
- package/dist/jsx/Diff/diff.native.js +108 -0
- package/dist/jsx/Diff/diff.native.js.map +1 -0
- package/dist/jsx/Diff/index.mjs +147 -0
- package/dist/jsx/Diff/index.mjs.map +1 -0
- package/dist/jsx/Diff/index.native.js +181 -0
- package/dist/jsx/Diff/index.native.js.map +1 -0
- package/dist/jsx/ElapsedProgress/index.mjs +76 -0
- package/dist/jsx/ElapsedProgress/index.mjs.map +1 -0
- package/dist/jsx/ElapsedProgress/index.native.js +112 -0
- package/dist/jsx/ElapsedProgress/index.native.js.map +1 -0
- package/dist/jsx/Lightbox/MediaControl.mjs +3 -7
- package/dist/jsx/Lightbox/MediaControl.mjs.map +1 -1
- package/dist/jsx/Lightbox/MediaControl.native.js +2 -8
- package/dist/jsx/Lightbox/MediaControl.native.js.map +1 -1
- package/dist/jsx/MachineLiteral/index.mjs +73 -0
- package/dist/jsx/MachineLiteral/index.mjs.map +1 -0
- package/dist/jsx/MachineLiteral/index.native.js +102 -0
- package/dist/jsx/MachineLiteral/index.native.js.map +1 -0
- package/dist/jsx/Material/blur.mjs +8 -0
- package/dist/jsx/Material/blur.mjs.map +1 -0
- package/dist/jsx/Material/blur.native.js +100 -0
- package/dist/jsx/Material/blur.native.js.map +1 -0
- package/dist/jsx/Material/index.mjs +10 -4
- package/dist/jsx/Material/index.mjs.map +1 -1
- package/dist/jsx/Material/index.native.js +9 -3
- package/dist/jsx/Material/index.native.js.map +1 -1
- package/dist/jsx/Meter/index.mjs +4 -3
- package/dist/jsx/Meter/index.mjs.map +1 -1
- package/dist/jsx/Meter/index.native.js +3 -1
- package/dist/jsx/Meter/index.native.js.map +1 -1
- package/dist/jsx/SortableList/index.mjs +2 -1
- package/dist/jsx/SortableList/index.mjs.map +1 -1
- package/dist/jsx/SortableList/index.native.js +4 -1
- package/dist/jsx/SortableList/index.native.js.map +1 -1
- package/dist/jsx/SortableList/useUserOrder.mjs +58 -0
- package/dist/jsx/SortableList/useUserOrder.mjs.map +1 -0
- package/dist/jsx/SortableList/useUserOrder.native.js +107 -0
- package/dist/jsx/SortableList/useUserOrder.native.js.map +1 -0
- package/dist/jsx/TreeSelect/index.mjs +8 -2
- package/dist/jsx/TreeSelect/index.mjs.map +1 -1
- package/dist/jsx/TreeSelect/index.native.js +7 -1
- package/dist/jsx/TreeSelect/index.native.js.map +1 -1
- package/dist/jsx/appShell/TabBar.mjs +10 -5
- package/dist/jsx/appShell/TabBar.mjs.map +1 -1
- package/dist/jsx/appShell/TabBar.native.js +10 -5
- package/dist/jsx/appShell/TabBar.native.js.map +1 -1
- package/dist/jsx/appShell/TabHost.native.js +1 -0
- package/dist/jsx/appShell/TabHost.native.js.map +1 -1
- package/dist/jsx/charts/Sparkline.mjs +1 -1
- package/dist/jsx/charts/Sparkline.mjs.map +1 -1
- package/dist/jsx/charts/Sparkline.native.js +1 -1
- package/dist/jsx/charts/Sparkline.native.js.map +1 -1
- package/dist/jsx/componentColors.mjs +1 -1
- package/dist/jsx/componentColors.native.js +1 -1
- package/dist/jsx/feedback/NotifyHost.native.js +1 -1
- package/dist/jsx/formLayouts/PreferencePanel.native.js +1 -1
- package/dist/jsx/index.js +5 -2
- package/dist/jsx/index.js.map +1 -1
- package/dist/jsx/index.mjs +5 -2
- package/dist/jsx/index.mjs.map +1 -1
- package/dist/jsx/index.native.js +7 -2
- package/dist/jsx/index.native.js.map +1 -1
- package/dist/jsx/layouts/AsyncBoundary.native.js +1 -1
- package/dist/jsx/layouts/AsyncBoundary.native.js.map +1 -1
- package/dist/jsx/layouts/page.mjs +0 -4
- package/dist/jsx/layouts/page.mjs.map +1 -1
- package/dist/jsx/layouts/page.native.js +0 -4
- package/dist/jsx/layouts/page.native.js.map +1 -1
- package/dist/jsx/views/ImageGrid.mjs +10 -13
- package/dist/jsx/views/ImageGrid.mjs.map +1 -1
- package/dist/jsx/views/ImageGrid.native.js +9 -16
- package/dist/jsx/views/ImageGrid.native.js.map +1 -1
- package/dist/jsx/views/ReportBuilder.mjs +4 -4
- package/dist/jsx/views/ReportBuilder.mjs.map +1 -1
- package/dist/jsx/views/ReportBuilder.native.js +3 -3
- package/dist/jsx/views/ReportBuilder.native.js.map +1 -1
- package/dist/jsx/views/index.mjs +2 -1
- package/dist/jsx/views/index.mjs.map +1 -1
- package/dist/jsx/views/index.native.js +2 -0
- package/dist/jsx/views/index.native.js.map +1 -1
- package/dist/jsx/views/sameNameScope.mjs +14 -0
- package/dist/jsx/views/sameNameScope.mjs.map +1 -0
- package/dist/jsx/views/sameNameScope.native.js +63 -0
- package/dist/jsx/views/sameNameScope.native.js.map +1 -0
- package/dist/jsx/views/usePageFlowLoadMore.mjs +57 -0
- package/dist/jsx/views/usePageFlowLoadMore.mjs.map +1 -0
- package/dist/jsx/views/usePageFlowLoadMore.native.js +93 -0
- package/dist/jsx/views/usePageFlowLoadMore.native.js.map +1 -0
- package/package.json +18 -9
- package/src/Diff/Diff.spec.tsx +105 -0
- package/src/Diff/Diff.stories.tsx +44 -0
- package/src/Diff/diff.ts +61 -0
- package/src/Diff/index.tsx +145 -0
- package/src/ElapsedProgress/ElapsedProgress.spec.tsx +66 -0
- package/src/ElapsedProgress/ElapsedProgress.stories.tsx +43 -0
- package/src/ElapsedProgress/index.tsx +89 -0
- package/src/Lightbox/Lightbox.spec.tsx +1 -1
- package/src/Lightbox/MediaControl.tsx +6 -14
- package/src/MachineLiteral/MachineLiteral.spec.tsx +86 -0
- package/src/MachineLiteral/MachineLiteral.stories.tsx +44 -0
- package/src/MachineLiteral/index.tsx +75 -0
- package/src/Material/blur.native.spec.tsx +135 -0
- package/src/Material/blur.native.tsx +93 -0
- package/src/Material/blur.ts +11 -0
- package/src/Material/index.tsx +18 -6
- package/src/Meter/index.tsx +4 -2
- package/src/SortableList/index.tsx +2 -0
- package/src/SortableList/useUserOrder.spec.tsx +110 -0
- package/src/SortableList/useUserOrder.ts +96 -0
- package/src/TreeSelect/TreeSelect.rows.spec.tsx +44 -0
- package/src/TreeSelect/index.tsx +12 -1
- package/src/appShell/TabBar.tsx +3 -0
- package/src/appShell/TabHost.native.spec.tsx +21 -1
- package/src/appShell/TabHost.native.tsx +8 -0
- package/src/charts/Sparkline.tsx +3 -3
- package/src/componentColors.ts +1 -1
- package/src/index.ts +7 -0
- package/src/layouts/page.tsx +1 -8
- package/src/layouts/pageChrome.phone.spec.tsx +14 -0
- package/src/presentationEmpty.spec.tsx +71 -0
- package/src/views/ImageGrid.native-press.spec.tsx +172 -0
- package/src/views/ImageGrid.tsx +11 -17
- package/src/views/ReportBuilder.tsx +4 -3
- package/src/views/index.ts +1 -0
- package/src/views/sameNameScope.spec.tsx +55 -0
- package/src/views/sameNameScope.ts +22 -0
- package/src/views/usePageFlowLoadMore.ts +79 -0
- package/types/Diff/diff.d.ts +17 -0
- package/types/Diff/diff.d.ts.map +1 -0
- package/types/Diff/index.d.ts +15 -0
- package/types/Diff/index.d.ts.map +1 -0
- package/types/ElapsedProgress/index.d.ts +15 -0
- package/types/ElapsedProgress/index.d.ts.map +1 -0
- package/types/Lightbox/MediaControl.d.ts +2 -4
- package/types/Lightbox/MediaControl.d.ts.map +1 -1
- package/types/MachineLiteral/index.d.ts +13 -0
- package/types/MachineLiteral/index.d.ts.map +1 -0
- package/types/Material/blur.d.ts +9 -0
- package/types/Material/blur.d.ts.map +1 -0
- package/types/Material/blur.native.d.ts +38 -0
- package/types/Material/blur.native.d.ts.map +1 -0
- package/types/Material/index.d.ts.map +1 -1
- package/types/Meter/index.d.ts +2 -0
- package/types/Meter/index.d.ts.map +1 -1
- package/types/SortableList/index.d.ts +2 -0
- package/types/SortableList/index.d.ts.map +1 -1
- package/types/SortableList/useUserOrder.d.ts +28 -0
- package/types/SortableList/useUserOrder.d.ts.map +1 -0
- package/types/TreeSelect/index.d.ts.map +1 -1
- package/types/appShell/TabBar.d.ts.map +1 -1
- package/types/appShell/TabHost.native.d.ts +1 -0
- package/types/appShell/TabHost.native.d.ts.map +1 -1
- package/types/charts/Sparkline.d.ts +2 -2
- package/types/charts/Sparkline.d.ts.map +1 -1
- package/types/componentColors.d.ts +1 -1
- package/types/index.d.ts +5 -2
- package/types/index.d.ts.map +1 -1
- package/types/layouts/page.d.ts.map +1 -1
- package/types/views/ImageGrid.d.ts.map +1 -1
- package/types/views/ReportBuilder.d.ts.map +1 -1
- package/types/views/index.d.ts +1 -0
- package/types/views/index.d.ts.map +1 -1
- package/types/views/sameNameScope.d.ts +8 -0
- package/types/views/sameNameScope.d.ts.map +1 -0
- package/types/views/usePageFlowLoadMore.d.ts +26 -0
- package/types/views/usePageFlowLoadMore.d.ts.map +1 -0
|
@@ -23,6 +23,8 @@ import { Text } from "../Text";
|
|
|
23
23
|
export { SortableHandle, SortableHandleWell } from "./SortableHandle";
|
|
24
24
|
export { SortableSessionProvider, useSortableRows } from "./useSortableRows";
|
|
25
25
|
export type { SortableSession, UseSortableRowsOptions } from "./useSortableRows";
|
|
26
|
+
export { applyUserOrder, useUserOrder } from "./useUserOrder";
|
|
27
|
+
export type { UseUserOrderOptions, UserOrderStorage } from "./useUserOrder";
|
|
26
28
|
|
|
27
29
|
export type SortableDisabledStyle = "keepLabel" | "dimWhole";
|
|
28
30
|
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LC-209 USER-ORDER: a hand-arranged collection keeps the user's order. A new
|
|
3
|
+
* item lands last with every other index unchanged, a data refresh that
|
|
4
|
+
* returns the source's own order changes nothing, and a reload reads the same
|
|
5
|
+
* arrangement back.
|
|
6
|
+
*/
|
|
7
|
+
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
8
|
+
import { act, cleanup, fireEvent } from "@testing-library/react";
|
|
9
|
+
import { useState } from "react";
|
|
10
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
11
|
+
import { SortableList } from "./index";
|
|
12
|
+
import { applyUserOrder, useUserOrder, type UserOrderStorage } from "./useUserOrder";
|
|
13
|
+
|
|
14
|
+
afterEach(cleanup);
|
|
15
|
+
|
|
16
|
+
interface Pin {
|
|
17
|
+
id: string;
|
|
18
|
+
label: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const source: Pin[] = [
|
|
22
|
+
{ id: "mail", label: "Mail" },
|
|
23
|
+
{ id: "files", label: "Files" },
|
|
24
|
+
{ id: "chat", label: "Chat" },
|
|
25
|
+
];
|
|
26
|
+
const idOf = (pin: Pin) => pin.id;
|
|
27
|
+
|
|
28
|
+
function memoryStorage(): UserOrderStorage & { data: Map<string, string> } {
|
|
29
|
+
const data = new Map<string, string>();
|
|
30
|
+
return {
|
|
31
|
+
data,
|
|
32
|
+
getItem: (key) => data.get(key) ?? null,
|
|
33
|
+
setItem: (key, value) => {
|
|
34
|
+
data.set(key, value);
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
let refresh: (pins: Pin[]) => void = () => {};
|
|
40
|
+
|
|
41
|
+
function Dock({ storage }: { storage: UserOrderStorage }) {
|
|
42
|
+
const [pins, setPins] = useState(source);
|
|
43
|
+
refresh = setPins;
|
|
44
|
+
const ordered = useUserOrder("dock", pins, idOf, { storage });
|
|
45
|
+
return (
|
|
46
|
+
<SortableList
|
|
47
|
+
items={ordered.items}
|
|
48
|
+
getId={idOf}
|
|
49
|
+
getLabel={(pin) => pin.label}
|
|
50
|
+
onChange={ordered.onChange}
|
|
51
|
+
/>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function shown(container: HTMLElement) {
|
|
56
|
+
return [...container.querySelectorAll("[data-sortable-row]")].map((row) =>
|
|
57
|
+
row.getAttribute("data-sortable-row"),
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function moveDown(container: HTMLElement, id: string) {
|
|
62
|
+
const row = container.querySelector(`[data-sortable-row="${id}"]`) as HTMLElement;
|
|
63
|
+
row.focus();
|
|
64
|
+
fireEvent.keyDown(row, { key: " " });
|
|
65
|
+
fireEvent.keyDown(row, { key: "ArrowDown" });
|
|
66
|
+
fireEvent.keyDown(row, { key: " " });
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
describe("applyUserOrder (LC-209)", () => {
|
|
70
|
+
it("keeps saved places and appends new ids at the end", () => {
|
|
71
|
+
const result = applyUserOrder(
|
|
72
|
+
[...source, { id: "maps", label: "Maps" }],
|
|
73
|
+
["chat", "mail", "files"],
|
|
74
|
+
idOf,
|
|
75
|
+
);
|
|
76
|
+
expect(result.items.map(idOf)).toEqual(["chat", "mail", "files", "maps"]);
|
|
77
|
+
expect(result.order).toEqual(["chat", "mail", "files", "maps"]);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it("an id missing from a partial read keeps its slot", () => {
|
|
81
|
+
const result = applyUserOrder([source[0]!, source[2]!], ["files", "chat", "mail"], idOf);
|
|
82
|
+
expect(result.items.map(idOf)).toEqual(["chat", "mail"]);
|
|
83
|
+
expect(result.order).toEqual(["files", "chat", "mail"]);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
describe("a reorderable dock keeps the user's order (LC-209)", () => {
|
|
88
|
+
it("a new item lands last and the others keep their index", () => {
|
|
89
|
+
const storage = memoryStorage();
|
|
90
|
+
const { container } = renderWithProviders(<Dock storage={storage} />);
|
|
91
|
+
moveDown(container, "mail");
|
|
92
|
+
expect(shown(container)).toEqual(["files", "mail", "chat"]);
|
|
93
|
+
|
|
94
|
+
act(() => refresh([...source, { id: "maps", label: "Maps" }]));
|
|
95
|
+
expect(shown(container)).toEqual(["files", "mail", "chat", "maps"]);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("a refresh in the source's order and a reload both keep the arrangement", () => {
|
|
99
|
+
const storage = memoryStorage();
|
|
100
|
+
const first = renderWithProviders(<Dock storage={storage} />);
|
|
101
|
+
moveDown(first.container, "mail");
|
|
102
|
+
act(() => refresh([...source]));
|
|
103
|
+
expect(shown(first.container)).toEqual(["files", "mail", "chat"]);
|
|
104
|
+
first.unmount();
|
|
105
|
+
|
|
106
|
+
const reloaded = renderWithProviders(<Dock storage={storage} />);
|
|
107
|
+
expect(shown(reloaded.container)).toEqual(["files", "mail", "chat"]);
|
|
108
|
+
expect(JSON.parse(storage.data.get("dock") ?? "[]")).toEqual(["files", "mail", "chat"]);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
2
|
+
|
|
3
|
+
/** Where a user's arrangement lives; defaults to the browser's localStorage. */
|
|
4
|
+
export interface UserOrderStorage {
|
|
5
|
+
getItem: (key: string) => string | null;
|
|
6
|
+
setItem: (key: string, value: string) => void;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const memory = new Map<string, string>();
|
|
10
|
+
const memoryStorage: UserOrderStorage = {
|
|
11
|
+
getItem: (key) => memory.get(key) ?? null,
|
|
12
|
+
setItem: (key, value) => {
|
|
13
|
+
memory.set(key, value);
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
function defaultStorage(): UserOrderStorage {
|
|
18
|
+
try {
|
|
19
|
+
const local = (globalThis as { localStorage?: UserOrderStorage }).localStorage;
|
|
20
|
+
if (local && typeof local.getItem === "function") return local;
|
|
21
|
+
} catch {
|
|
22
|
+
// storage blocked
|
|
23
|
+
}
|
|
24
|
+
return memoryStorage;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function readOrder(storage: UserOrderStorage, key: string): string[] {
|
|
28
|
+
try {
|
|
29
|
+
const parsed = JSON.parse(storage.getItem(key) ?? "[]") as unknown;
|
|
30
|
+
return Array.isArray(parsed) ? parsed.filter((id): id is string => typeof id === "string") : [];
|
|
31
|
+
} catch {
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* The items in the user's order (LC-209): known ids keep their saved place,
|
|
38
|
+
* new ids land at the end in the order the source gave them. Ids missing
|
|
39
|
+
* from this read keep their slot in `order`, so a partial refresh never
|
|
40
|
+
* reshuffles them.
|
|
41
|
+
*/
|
|
42
|
+
export function applyUserOrder<T>(
|
|
43
|
+
items: readonly T[],
|
|
44
|
+
order: readonly string[],
|
|
45
|
+
getId: (item: T) => string,
|
|
46
|
+
): { items: T[]; order: string[] } {
|
|
47
|
+
const byId = new Map(items.map((item) => [getId(item), item] as const));
|
|
48
|
+
const known = new Set(order);
|
|
49
|
+
const placed = order.flatMap((id) => {
|
|
50
|
+
const item = byId.get(id);
|
|
51
|
+
return item === undefined ? [] : [item];
|
|
52
|
+
});
|
|
53
|
+
const added = items.filter((item) => !known.has(getId(item)));
|
|
54
|
+
return {
|
|
55
|
+
items: [...placed, ...added],
|
|
56
|
+
order: [...order, ...added.map(getId)],
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface UseUserOrderOptions {
|
|
61
|
+
storage?: UserOrderStorage;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Keeps a hand-arranged collection in the user's order across data refreshes
|
|
66
|
+
* and reloads. Feed `items` from any source order; render the returned
|
|
67
|
+
* `items`; pass `onChange` to SortableList.
|
|
68
|
+
*/
|
|
69
|
+
export function useUserOrder<T>(
|
|
70
|
+
key: string,
|
|
71
|
+
items: readonly T[],
|
|
72
|
+
getId: (item: T) => string,
|
|
73
|
+
options: UseUserOrderOptions = {},
|
|
74
|
+
) {
|
|
75
|
+
const storage = useMemo(() => options.storage ?? defaultStorage(), [options.storage]);
|
|
76
|
+
const [order, setOrder] = useState(() => readOrder(storage, key));
|
|
77
|
+
const arranged = useMemo(() => applyUserOrder(items, order, getId), [items, order, getId]);
|
|
78
|
+
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
if (arranged.order.length === order.length) return;
|
|
81
|
+
storage.setItem(key, JSON.stringify(arranged.order));
|
|
82
|
+
setOrder(arranged.order);
|
|
83
|
+
}, [arranged.order, order.length, storage, key]);
|
|
84
|
+
|
|
85
|
+
const onChange = useCallback(
|
|
86
|
+
(next: T[]) => {
|
|
87
|
+
const shown = new Set(next.map(getId));
|
|
88
|
+
const ids = [...next.map(getId), ...order.filter((id) => !shown.has(id))];
|
|
89
|
+
storage.setItem(key, JSON.stringify(ids));
|
|
90
|
+
setOrder(ids);
|
|
91
|
+
},
|
|
92
|
+
[getId, order, storage, key],
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
return { items: arranged.items, onChange };
|
|
96
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LC-222 LIST-HEIGHT-IN-ROWS: the desktop tree panel caps its scroller at a
|
|
3
|
+
* visible-row count times its row pitch, not a pixel literal.
|
|
4
|
+
*/
|
|
5
|
+
import { listHeightForRows } from "@multiplatform.one/theme";
|
|
6
|
+
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
7
|
+
import { cleanup, waitFor } from "@testing-library/react";
|
|
8
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
9
|
+
import type { TreeNode } from "../views/TreeView";
|
|
10
|
+
import { TreeSelect } from "./index";
|
|
11
|
+
|
|
12
|
+
afterEach(cleanup);
|
|
13
|
+
|
|
14
|
+
const nodes: TreeNode[] = Array.from({ length: 12 }, (_, index) => ({
|
|
15
|
+
id: `n${index}`,
|
|
16
|
+
label: `Account ${index + 1}`,
|
|
17
|
+
}));
|
|
18
|
+
|
|
19
|
+
describe("TreeSelect panel height (LC-222)", () => {
|
|
20
|
+
it("states its cap as eight rows at the row pitch", async () => {
|
|
21
|
+
Object.defineProperty(window, "innerWidth", {
|
|
22
|
+
configurable: true,
|
|
23
|
+
writable: true,
|
|
24
|
+
value: 1200,
|
|
25
|
+
});
|
|
26
|
+
window.dispatchEvent(new Event("resize"));
|
|
27
|
+
const { baseElement } = renderWithProviders(<TreeSelect label="Account" nodes={nodes} open />);
|
|
28
|
+
const scroller = await waitFor(() => {
|
|
29
|
+
const found = baseElement.querySelector("[data-visible-rows]") as HTMLElement | null;
|
|
30
|
+
expect(found).toBeTruthy();
|
|
31
|
+
return found as HTMLElement;
|
|
32
|
+
});
|
|
33
|
+
const rows = Number(scroller.getAttribute("data-visible-rows"));
|
|
34
|
+
const pitch = Number(scroller.getAttribute("data-row-pitch"));
|
|
35
|
+
expect(rows).toBe(8);
|
|
36
|
+
expect(pitch).toBeGreaterThan(0);
|
|
37
|
+
const rowHeights = [...baseElement.querySelectorAll("[data-row-height]")].map((row) =>
|
|
38
|
+
Number(row.getAttribute("data-row-height")),
|
|
39
|
+
);
|
|
40
|
+
expect(new Set(rowHeights)).toEqual(new Set([pitch]));
|
|
41
|
+
const style = `${scroller.getAttribute("style") ?? ""} ${scroller.className}`;
|
|
42
|
+
expect(style).toContain(String(listHeightForRows(rows, pitch)));
|
|
43
|
+
});
|
|
44
|
+
});
|
package/src/TreeSelect/index.tsx
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
ensureFocusVisibleRing,
|
|
27
27
|
ensureKeyboardModalityTracking,
|
|
28
28
|
keyboardFocusRingProps,
|
|
29
|
+
listHeightForRows,
|
|
29
30
|
useMenuRowCheckInk,
|
|
30
31
|
menuRowChecked,
|
|
31
32
|
useResolvedKnobs,
|
|
@@ -617,6 +618,9 @@ function handleTreeKeys(args: {
|
|
|
617
618
|
}
|
|
618
619
|
}
|
|
619
620
|
|
|
621
|
+
/** Rows the desktop tree panel shows before it scrolls (LC-222). */
|
|
622
|
+
const TREE_SELECT_VISIBLE_ROWS = 8;
|
|
623
|
+
|
|
620
624
|
function FloatingTreeSelect({
|
|
621
625
|
nodes,
|
|
622
626
|
value,
|
|
@@ -653,6 +657,7 @@ function FloatingTreeSelect({
|
|
|
653
657
|
accessibilityLabel?: string;
|
|
654
658
|
}) {
|
|
655
659
|
const overlayZIndex = useOverlayZIndex("dropdown");
|
|
660
|
+
const { knobProps } = useResolvedKnobs();
|
|
656
661
|
const treeId = useId();
|
|
657
662
|
const searchRef = useRef<HTMLInputElement | null>(null);
|
|
658
663
|
const state = useTreeSelectState({ nodes, value, open, defaultExpandedIds });
|
|
@@ -790,7 +795,13 @@ function FloatingTreeSelect({
|
|
|
790
795
|
activeDescendant={activeDescendant}
|
|
791
796
|
sizeToken={sizeToken}
|
|
792
797
|
/>
|
|
793
|
-
<YStack
|
|
798
|
+
<YStack
|
|
799
|
+
overflow="scroll"
|
|
800
|
+
maxHeight={listHeightForRows(TREE_SELECT_VISIBLE_ROWS, knobProps.nestedControl.px)}
|
|
801
|
+
data-visible-rows={TREE_SELECT_VISIBLE_ROWS}
|
|
802
|
+
data-row-pitch={knobProps.nestedControl.px}
|
|
803
|
+
id={treeId}
|
|
804
|
+
>
|
|
794
805
|
<TreeSelectPanelBody
|
|
795
806
|
rows={state.rows}
|
|
796
807
|
selectedId={value}
|
package/src/appShell/TabBar.tsx
CHANGED
|
@@ -23,6 +23,7 @@ import { isWeb } from "@multiplatform.one/platform";
|
|
|
23
23
|
import { type ComponentType, type ReactNode, useEffect, useState } from "react";
|
|
24
24
|
import { XStack, YStack } from "tamagui";
|
|
25
25
|
import { materials, useMaterial } from "../Material";
|
|
26
|
+
import { MaterialBlurFill } from "../Material/blur";
|
|
26
27
|
import { Text } from "../Text";
|
|
27
28
|
import { setBottomChromeInset, setFloatingBarMounted, useBottomAccessory } from "./bottomChrome";
|
|
28
29
|
import { useBottomInset } from "./bottomInset";
|
|
@@ -248,6 +249,7 @@ export function TabBar({
|
|
|
248
249
|
onLayout={(event) => setAccessoryHeight(Math.round(event.nativeEvent.layout.height))}
|
|
249
250
|
data-testid={`${testID}-accessory`}
|
|
250
251
|
>
|
|
252
|
+
<MaterialBlurFill radius={1000} />
|
|
251
253
|
{accessory}
|
|
252
254
|
</XStack>
|
|
253
255
|
) : null}
|
|
@@ -261,6 +263,7 @@ export function TabBar({
|
|
|
261
263
|
{...material}
|
|
262
264
|
data-testid={`${testID}-capsule`}
|
|
263
265
|
>
|
|
266
|
+
<MaterialBlurFill radius={1000} />
|
|
264
267
|
{items.map((item) => (
|
|
265
268
|
<TabBarButton
|
|
266
269
|
key={item.key}
|
|
@@ -46,10 +46,18 @@ const fakeTabs: NativeTabs = {
|
|
|
46
46
|
/>
|
|
47
47
|
</div>
|
|
48
48
|
),
|
|
49
|
-
Screen: ({
|
|
49
|
+
Screen: ({
|
|
50
|
+
children,
|
|
51
|
+
tabKey,
|
|
52
|
+
isFocused,
|
|
53
|
+
icon,
|
|
54
|
+
title,
|
|
55
|
+
overrideScrollViewContentInsetAdjustmentBehavior,
|
|
56
|
+
}) => (
|
|
50
57
|
<section
|
|
51
58
|
data-testid={`native-screen-${tabKey}`}
|
|
52
59
|
data-focused={String(Boolean(isFocused))}
|
|
60
|
+
data-inset-adjust={String(overrideScrollViewContentInsetAdjustmentBehavior)}
|
|
53
61
|
data-symbol={icon?.ios.name}
|
|
54
62
|
aria-label={title}
|
|
55
63
|
>
|
|
@@ -164,6 +172,18 @@ describe("NativeTabHost", () => {
|
|
|
164
172
|
);
|
|
165
173
|
expect(screen.getByTestId("inset").textContent).toBe("0");
|
|
166
174
|
});
|
|
175
|
+
|
|
176
|
+
it("clears the bar once: the published inset, never the native scroll-inset adjustment too (FZ-8640)", () => {
|
|
177
|
+
renderNative("/pokemon");
|
|
178
|
+
expect(Number(screen.getByTestId("inset").textContent)).toBeGreaterThanOrEqual(
|
|
179
|
+
nativeTabBarHeight,
|
|
180
|
+
);
|
|
181
|
+
for (const item of items) {
|
|
182
|
+
expect(
|
|
183
|
+
screen.getByTestId(`native-screen-${item.key}`).getAttribute("data-inset-adjust"),
|
|
184
|
+
).toBe("false");
|
|
185
|
+
}
|
|
186
|
+
});
|
|
167
187
|
});
|
|
168
188
|
|
|
169
189
|
describe("TabHost fallback", () => {
|
|
@@ -13,6 +13,12 @@
|
|
|
13
13
|
* without RNSTabsHost, a platform other than iOS, or an item without an SF
|
|
14
14
|
* Symbol keeps the MPO TabBar. Android stays on the MPO TabBar until the
|
|
15
15
|
* items carry image icons the Material bar can draw.
|
|
16
|
+
*
|
|
17
|
+
* The bar's clearance is the inset this host publishes, as with the MPO
|
|
18
|
+
* TabBar, so a Screen pads by it whether or not it scrolls. Each tab screen
|
|
19
|
+
* leaves its scroll view's inset adjustment off: react-native-screens would
|
|
20
|
+
* otherwise flip the first scroll view to `automatic`, and UIKit would add
|
|
21
|
+
* the bar's height a second time (FZ-8640).
|
|
16
22
|
*/
|
|
17
23
|
import { useGlyphColor, useIdentityInkOnSurface } from "@multiplatform.one/theme";
|
|
18
24
|
import { type ComponentType, type ReactNode, useEffect, useRef, useState } from "react";
|
|
@@ -53,6 +59,7 @@ export interface NativeTabs {
|
|
|
53
59
|
selectedIcon?: IconProp["ios"];
|
|
54
60
|
tabBarItemAccessibilityLabel?: string;
|
|
55
61
|
tabBarItemTestID?: string;
|
|
62
|
+
overrideScrollViewContentInsetAdjustmentBehavior?: boolean;
|
|
56
63
|
}>;
|
|
57
64
|
}
|
|
58
65
|
|
|
@@ -139,6 +146,7 @@ export function NativeTabHost({
|
|
|
139
146
|
}
|
|
140
147
|
tabBarItemAccessibilityLabel={item.label}
|
|
141
148
|
tabBarItemTestID={`tab-bar-item-${item.key.replace(/^\/+/, "") || "root"}`}
|
|
149
|
+
overrideScrollViewContentInsetAdjustmentBehavior={false}
|
|
142
150
|
>
|
|
143
151
|
{item.key === focusedKey ? children : null}
|
|
144
152
|
</Screen>
|
package/src/charts/Sparkline.tsx
CHANGED
|
@@ -9,8 +9,8 @@ import type { ChartCurve, ChartDatum } from "./types";
|
|
|
9
9
|
import { useChartTheme } from "./useChartTheme";
|
|
10
10
|
|
|
11
11
|
export interface SparklineProps extends Omit<YStackProps, "children" | "width" | "height"> {
|
|
12
|
-
/** Series values — bare numbers or full data points. */
|
|
13
|
-
data: Array<number | ChartDatum
|
|
12
|
+
/** Series values — bare numbers or full data points. Null is no reading (LC-220). */
|
|
13
|
+
data: Array<number | ChartDatum> | null | undefined;
|
|
14
14
|
/** Drawing height as a theme size token or pixels (default 36). */
|
|
15
15
|
height?: ChartHeight;
|
|
16
16
|
/** Fixed width; omit to track the parent responsively. */
|
|
@@ -50,7 +50,7 @@ export function Sparkline({
|
|
|
50
50
|
const { t } = useTranslation();
|
|
51
51
|
const { palette } = useChartTheme();
|
|
52
52
|
const stroke = color ?? palette.single;
|
|
53
|
-
const normalized: ChartDatum[] = data.map((entry, index) =>
|
|
53
|
+
const normalized: ChartDatum[] = (data ?? []).map((entry, index) =>
|
|
54
54
|
typeof entry === "number" ? { label: String(index + 1), value: entry } : entry,
|
|
55
55
|
);
|
|
56
56
|
const ariaLabel =
|
package/src/componentColors.ts
CHANGED
|
@@ -131,7 +131,7 @@ export const componentColors = {
|
|
|
131
131
|
debug: "$color9",
|
|
132
132
|
|
|
133
133
|
/**
|
|
134
|
-
* The round
|
|
134
|
+
* The flat round plate under an icon control floating over a photo
|
|
135
135
|
* (LC-176). The fill sits steps above the viewer's dark ground so the
|
|
136
136
|
* plate reads on black as well as on a bright frame (FZ-8009 r2).
|
|
137
137
|
*/
|
package/src/index.ts
CHANGED
|
@@ -5,22 +5,29 @@ export {
|
|
|
5
5
|
SortableHandle,
|
|
6
6
|
SortableHandleWell,
|
|
7
7
|
SortableSessionProvider,
|
|
8
|
+
applyUserOrder,
|
|
8
9
|
useSortableRows,
|
|
10
|
+
useUserOrder,
|
|
9
11
|
} from "./SortableList";
|
|
10
12
|
export type {
|
|
11
13
|
SortableListProps,
|
|
12
14
|
SortableDisabledStyle,
|
|
13
15
|
SortableSession,
|
|
14
16
|
UseSortableRowsOptions,
|
|
17
|
+
UseUserOrderOptions,
|
|
18
|
+
UserOrderStorage,
|
|
15
19
|
} from "./SortableList";
|
|
16
20
|
export * from "./Badge";
|
|
17
21
|
export * from "./Carousel";
|
|
18
22
|
export * from "./Chip";
|
|
19
23
|
export * from "./Kbd";
|
|
20
24
|
export * from "./CopyField";
|
|
25
|
+
export * from "./Diff";
|
|
26
|
+
export * from "./ElapsedProgress";
|
|
21
27
|
export * from "./DotIndicator";
|
|
22
28
|
export * from "./DropdownMenu";
|
|
23
29
|
export * from "./ContextMenu";
|
|
30
|
+
export * from "./MachineLiteral";
|
|
24
31
|
export * from "./Material";
|
|
25
32
|
export * from "./Meter";
|
|
26
33
|
export { Lightbox, useLightbox } from "./Lightbox";
|
package/src/layouts/page.tsx
CHANGED
|
@@ -517,14 +517,7 @@ export function PageHeader({
|
|
|
517
517
|
>
|
|
518
518
|
{/* LC-153: page-head actions are a bar; neutral buttons go plain. */}
|
|
519
519
|
<Surface bar>
|
|
520
|
-
<IconButtonGroup
|
|
521
|
-
{...knobProps.gap}
|
|
522
|
-
justifyContent="flex-end"
|
|
523
|
-
flexWrap="wrap"
|
|
524
|
-
flexGrow={1}
|
|
525
|
-
flexShrink={1}
|
|
526
|
-
minWidth={0}
|
|
527
|
-
>
|
|
520
|
+
<IconButtonGroup {...knobProps.gap} justifyContent="flex-end">
|
|
528
521
|
{actions}
|
|
529
522
|
</IconButtonGroup>
|
|
530
523
|
</Surface>
|
|
@@ -61,4 +61,18 @@ describe("PageHeader actions (LC-142)", () => {
|
|
|
61
61
|
expect(atoms(row, "_jc-")).toEqual(["_jc-flex-end"]);
|
|
62
62
|
expect(atoms(row?.parentElement ?? null, "_fw-")).toEqual([]);
|
|
63
63
|
});
|
|
64
|
+
|
|
65
|
+
it("hug their buttons: the group never wraps or grows (FZ-8521)", () => {
|
|
66
|
+
const { container } = renderWithProviders(
|
|
67
|
+
<PageHeader
|
|
68
|
+
title="Pokemon"
|
|
69
|
+
subtitle="21 Pokemon in the Pokédex"
|
|
70
|
+
actions={<button type="button">Add</button>}
|
|
71
|
+
/>,
|
|
72
|
+
);
|
|
73
|
+
const group = container.querySelector("[data-page-header-actions] [data-mp-icon-button-group]");
|
|
74
|
+
expect(group).toBeTruthy();
|
|
75
|
+
expect(atoms(group, "_fw-")).toEqual([]);
|
|
76
|
+
expect(atoms(group, "_fg-")).toEqual([]);
|
|
77
|
+
});
|
|
64
78
|
});
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LC-220 EMPTY-IS-DRAWN: a presentation component given no reading draws its
|
|
3
|
+
* own empty form at the populated box (the bare track, the em dash, the empty
|
|
4
|
+
* surface), shows no "0", and its accessible name says there is no reading.
|
|
5
|
+
*/
|
|
6
|
+
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
7
|
+
import { cleanup, screen } from "@testing-library/react";
|
|
8
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
9
|
+
import { Sparkline } from "./charts/Sparkline";
|
|
10
|
+
import { Default as DiffMain, NoReading } from "./Diff/Diff.stories";
|
|
11
|
+
import { Diff, type DiffProps } from "./Diff";
|
|
12
|
+
import { Meter, type MeterProps } from "./Meter";
|
|
13
|
+
import { Default as MeterMain, Unknown } from "./Meter/Meter.stories";
|
|
14
|
+
|
|
15
|
+
afterEach(cleanup);
|
|
16
|
+
|
|
17
|
+
const noZero = /(^|[^\d.])0([^\d.]|$)/;
|
|
18
|
+
|
|
19
|
+
describe("presentation components draw their empty form (LC-220)", () => {
|
|
20
|
+
it("Meter: the bare track at the populated height, an em dash, no fill, no reading spoken", () => {
|
|
21
|
+
const full = renderWithProviders(<Meter {...(MeterMain.args as MeterProps)} />);
|
|
22
|
+
const fullRail = full.container.querySelector("[role='meter']") as HTMLElement;
|
|
23
|
+
const height = fullRail.getAttribute("data-meter-track-height");
|
|
24
|
+
full.unmount();
|
|
25
|
+
|
|
26
|
+
const { container } = renderWithProviders(
|
|
27
|
+
<Meter {...(Unknown.args as MeterProps)} value={null} />,
|
|
28
|
+
);
|
|
29
|
+
const rail = container.querySelector("[role='meter']") as HTMLElement;
|
|
30
|
+
expect(rail).toBeTruthy();
|
|
31
|
+
expect(rail.getAttribute("data-meter-track-height")).toBe(height);
|
|
32
|
+
expect(rail.getAttribute("data-meter-fill")).toBeNull();
|
|
33
|
+
expect(rail.getAttribute("aria-valuenow")).toBeNull();
|
|
34
|
+
expect(rail.getAttribute("aria-valuetext")).toBe("No reading");
|
|
35
|
+
expect(container.textContent).toContain("—");
|
|
36
|
+
expect(container.textContent).not.toMatch(noZero);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("Diff: the same frame with an em dash and a no-reading name, never 0 added", () => {
|
|
40
|
+
const full = renderWithProviders(<Diff {...(DiffMain.args as DiffProps)} />);
|
|
41
|
+
const fullFrame = full.container.querySelector("[role='region']") as HTMLElement;
|
|
42
|
+
const fullClass = fullFrame.className;
|
|
43
|
+
full.unmount();
|
|
44
|
+
|
|
45
|
+
const { container } = renderWithProviders(<Diff {...(NoReading.args as DiffProps)} />);
|
|
46
|
+
const frame = container.querySelector("[role='region']") as HTMLElement;
|
|
47
|
+
expect(frame.className).toBe(fullClass);
|
|
48
|
+
expect(frame.getAttribute("aria-label")).toMatch(/no reading$/);
|
|
49
|
+
expect(container.textContent).toBe("—");
|
|
50
|
+
expect(container.textContent).not.toMatch(noZero);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("Sparkline: the surface keeps its box and says no data, with no point drawn", () => {
|
|
54
|
+
const full = renderWithProviders(
|
|
55
|
+
<Sparkline width={160} data={[3, 5, 4, 8]} title="Sessions" />,
|
|
56
|
+
);
|
|
57
|
+
const fullSvg = full.container.querySelector("svg") as SVGElement;
|
|
58
|
+
const height = fullSvg.getAttribute("height");
|
|
59
|
+
full.unmount();
|
|
60
|
+
|
|
61
|
+
const { container } = renderWithProviders(
|
|
62
|
+
<Sparkline width={160} data={null} title="Sessions" />,
|
|
63
|
+
);
|
|
64
|
+
const svg = container.querySelector("svg") as SVGElement;
|
|
65
|
+
expect(svg.getAttribute("height")).toBe(height);
|
|
66
|
+
expect(svg.getAttribute("width")).toBe("160");
|
|
67
|
+
expect(screen.getByRole("img").getAttribute("aria-label")).toMatch(/no data$/);
|
|
68
|
+
expect(container.querySelectorAll("path")).toHaveLength(0);
|
|
69
|
+
expect(container.textContent).not.toMatch(noZero);
|
|
70
|
+
});
|
|
71
|
+
});
|