@dxos/plugin-deck 0.9.1-main.c7dcc2e112 → 0.9.1-staging.ee54ba693a
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/PLUGIN.mdl +3 -1
- package/dist/lib/neutral/{DeckLayout-VX2BP4Q2.mjs → DeckLayout-B3RUUV5P.mjs} +4 -3
- package/dist/lib/neutral/DeckLayout-B3RUUV5P.mjs.map +7 -0
- package/dist/lib/neutral/DeckPlugin.mjs +2 -6
- package/dist/lib/neutral/DeckPlugin.mjs.map +3 -3
- package/dist/lib/neutral/DeckSettings-Z7GMB7XJ.mjs +32 -0
- package/dist/lib/neutral/DeckSettings-Z7GMB7XJ.mjs.map +7 -0
- package/dist/lib/neutral/{add-toast-APKTCLIA.mjs → add-toast-BHNEH5UY.mjs} +2 -2
- package/dist/lib/neutral/{adjust-7CZI4GK3.mjs → adjust-MJB6UMRQ.mjs} +16 -10
- package/dist/lib/neutral/adjust-MJB6UMRQ.mjs.map +7 -0
- package/dist/lib/neutral/{app-graph-builder-6HTXRTU2.mjs → app-graph-builder-2F7P4IFQ.mjs} +4 -3
- package/dist/lib/neutral/app-graph-builder-2F7P4IFQ.mjs.map +7 -0
- package/dist/lib/neutral/capabilities/index.mjs +5 -5
- package/dist/lib/neutral/chunk-FKGYHBUB.mjs +8 -0
- package/dist/lib/neutral/{chunk-CL7JIOI5.mjs → chunk-ICOJ4GMB.mjs} +10 -6
- package/dist/lib/neutral/chunk-ICOJ4GMB.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-NGX6RXNV.mjs → chunk-PP32NEVY.mjs} +2 -2
- package/dist/lib/neutral/chunk-PP32NEVY.mjs.map +7 -0
- package/dist/lib/neutral/chunk-SONATB35.mjs +20 -0
- package/dist/lib/neutral/chunk-SONATB35.mjs.map +7 -0
- package/dist/lib/neutral/chunk-Z2B5RSVI.mjs +1096 -0
- package/dist/lib/neutral/chunk-Z2B5RSVI.mjs.map +7 -0
- package/dist/lib/neutral/{close-KJUCFIJ5.mjs → close-2YGB5IIP.mjs} +4 -3
- package/dist/lib/neutral/{close-KJUCFIJ5.mjs.map → close-2YGB5IIP.mjs.map} +1 -1
- package/dist/lib/neutral/components/index.mjs +201 -16
- package/dist/lib/neutral/components/index.mjs.map +4 -4
- package/dist/lib/neutral/containers/index.mjs +6 -11
- package/dist/lib/neutral/containers/index.mjs.map +3 -3
- package/dist/lib/neutral/hooks/index.mjs +101 -17
- package/dist/lib/neutral/hooks/index.mjs.map +4 -4
- package/dist/lib/neutral/index.mjs +7 -1
- package/dist/lib/neutral/meta.json +1 -1
- package/dist/lib/neutral/{notification-tracker-CUDFRDCF.mjs → notification-tracker-Y5CRTWJM.mjs} +4 -2
- package/dist/lib/neutral/notification-tracker-Y5CRTWJM.mjs.map +7 -0
- package/dist/lib/neutral/{open-VU7YS3HB.mjs → open-P6XQ56M7.mjs} +4 -3
- package/dist/lib/neutral/{open-VU7YS3HB.mjs.map → open-P6XQ56M7.mjs.map} +1 -1
- package/dist/lib/neutral/operations/index.mjs +1 -1
- package/dist/lib/neutral/plugin.mjs +1 -1
- package/dist/lib/neutral/{react-surface-O4POQWYL.mjs → react-surface-H63FXUK3.mjs} +2 -2
- package/dist/lib/neutral/{react-surface-O4POQWYL.mjs.map → react-surface-H63FXUK3.mjs.map} +1 -1
- package/dist/lib/neutral/{revert-workspace-24TKG3I7.mjs → revert-workspace-RXWP2TEE.mjs} +2 -2
- package/dist/lib/neutral/{scroll-into-view-3VXT6TWC.mjs → scroll-into-view-HFV5EGYZ.mjs} +2 -2
- package/dist/lib/neutral/{set-RFOLTI57.mjs → set-HOOVB7E4.mjs} +4 -3
- package/dist/lib/neutral/{set-RFOLTI57.mjs.map → set-HOOVB7E4.mjs.map} +1 -1
- package/dist/lib/neutral/{set-layout-mode-AZ73W52Z.mjs → set-layout-mode-XAGSZZGB.mjs} +2 -2
- package/dist/lib/neutral/{state-D3YXB5NP.mjs → state-F4X5GPGZ.mjs} +3 -2
- package/dist/lib/neutral/{state-D3YXB5NP.mjs.map → state-F4X5GPGZ.mjs.map} +1 -1
- package/dist/lib/neutral/{switch-workspace-TBPT23CZ.mjs → switch-workspace-PA7N6EUX.mjs} +2 -2
- package/dist/lib/neutral/translations.mjs +2 -2
- package/dist/lib/neutral/translations.mjs.map +2 -2
- package/dist/lib/neutral/types/index.mjs +1 -1
- package/dist/lib/neutral/{update-companion-5LCY6QME.mjs → update-companion-6A2SKQAI.mjs} +14 -6
- package/dist/lib/neutral/update-companion-6A2SKQAI.mjs.map +7 -0
- package/dist/lib/neutral/{update-complementary-HZ7QXZYE.mjs → update-complementary-K55I5EV5.mjs} +2 -2
- package/dist/lib/neutral/{update-dialog-A7W3R5EI.mjs → update-dialog-Z3GEXMVV.mjs} +2 -2
- package/dist/lib/neutral/{update-plank-size-XHTYBLSD.mjs → update-plank-size-BTESVV7N.mjs} +2 -2
- package/dist/lib/neutral/{update-popover-RDIHG73B.mjs → update-popover-QEVDSZSH.mjs} +2 -2
- package/dist/lib/neutral/{update-sidebar-GEI7USA5.mjs → update-sidebar-VSRCN47U.mjs} +2 -2
- package/dist/lib/neutral/{url-handler-PUS4X33T.mjs → url-handler-ERZXXEYR.mjs} +3 -2
- package/dist/lib/neutral/{url-handler-PUS4X33T.mjs.map → url-handler-ERZXXEYR.mjs.map} +1 -1
- package/dist/types/src/DeckPlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts +1 -2
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/capabilities/notification-tracker.d.ts +1 -1
- package/dist/types/src/capabilities/notification-tracker.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-root.d.ts +1 -5
- package/dist/types/src/capabilities/react-root.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts +1 -1
- package/dist/types/src/capabilities/settings.d.ts +1 -3
- package/dist/types/src/capabilities/settings.d.ts.map +1 -1
- package/dist/types/src/capabilities/state.d.ts +1 -187
- package/dist/types/src/capabilities/state.d.ts.map +1 -1
- package/dist/types/src/capabilities/tools.d.ts +1 -1
- package/dist/types/src/capabilities/url-handler.d.ts +1 -1
- package/dist/types/src/components/Companion/Companion.d.ts +17 -0
- package/dist/types/src/components/Companion/Companion.d.ts.map +1 -0
- package/dist/types/src/components/Companion/index.d.ts +2 -0
- package/dist/types/src/components/Companion/index.d.ts.map +1 -0
- package/dist/types/src/components/Matrix/Matrix.d.ts +1 -1
- package/dist/types/src/components/Matrix/Matrix.d.ts.map +1 -1
- package/dist/types/src/components/Matrix/Matrix.stories.d.ts +2 -2
- package/dist/types/src/components/Matrix/Matrix.stories.d.ts.map +1 -1
- package/dist/types/src/components/Matrix/index.d.ts +1 -1
- package/dist/types/src/components/Matrix/index.d.ts.map +1 -1
- package/dist/types/src/components/Pane/Pane.d.ts +45 -0
- package/dist/types/src/components/Pane/Pane.d.ts.map +1 -0
- package/dist/types/src/components/Pane/Pane.stories.d.ts +7 -0
- package/dist/types/src/components/Pane/Pane.stories.d.ts.map +1 -0
- package/dist/types/src/components/Pane/index.d.ts +2 -0
- package/dist/types/src/components/Pane/index.d.ts.map +1 -0
- package/dist/types/src/components/Plank/Plank.d.ts +74 -0
- package/dist/types/src/components/Plank/Plank.d.ts.map +1 -0
- package/dist/types/src/components/Plank/Plank.stories.d.ts +6 -0
- package/dist/types/src/components/Plank/Plank.stories.d.ts.map +1 -0
- package/dist/types/src/components/Plank/index.d.ts +2 -0
- package/dist/types/src/components/Plank/index.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +3 -2
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/containers/Deck/Deck.d.ts +1 -1
- package/dist/types/src/containers/Deck/Deck.d.ts.map +1 -1
- package/dist/types/src/containers/Deck/Deck.stories.d.ts +2 -2
- package/dist/types/src/containers/Deck/DeckPlank.d.ts +21 -0
- package/dist/types/src/containers/Deck/DeckPlank.d.ts.map +1 -0
- package/dist/types/src/containers/Deck/DeckViewport.d.ts +3 -1
- package/dist/types/src/containers/Deck/DeckViewport.d.ts.map +1 -1
- package/dist/types/src/containers/{Plank → Deck}/PlankControls.d.ts +3 -10
- package/dist/types/src/containers/Deck/PlankControls.d.ts.map +1 -0
- package/dist/types/src/containers/Deck/PlankFallback.d.ts +6 -0
- package/dist/types/src/containers/Deck/PlankFallback.d.ts.map +1 -0
- package/dist/types/src/containers/Deck/useDeckPlank.d.ts +49 -0
- package/dist/types/src/containers/Deck/useDeckPlank.d.ts.map +1 -0
- package/dist/types/src/containers/DeckLayout/DeckLayout.stories.d.ts +2 -2
- package/dist/types/src/containers/DeckLayout/DeckLayout.stories.d.ts.map +1 -1
- package/dist/types/src/{components → containers}/DeckSettings/DeckSettings.d.ts +1 -1
- package/dist/types/src/containers/DeckSettings/DeckSettings.d.ts.map +1 -0
- package/dist/types/src/{components → containers}/DeckSettings/DeckSettings.stories.d.ts +2 -2
- package/dist/types/src/{components → containers}/DeckSettings/DeckSettings.stories.d.ts.map +1 -1
- package/dist/types/src/containers/DeckSettings/index.d.ts.map +1 -0
- package/dist/types/src/containers/index.d.ts +1 -1
- package/dist/types/src/containers/index.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +2 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useCompanionSplit.d.ts +28 -0
- package/dist/types/src/hooks/useCompanionSplit.d.ts.map +1 -0
- package/dist/types/src/hooks/useCompanions.d.ts +11 -7
- package/dist/types/src/hooks/useCompanions.d.ts.map +1 -1
- package/dist/types/src/hooks/useDeckCompanions.d.ts +2 -2
- package/dist/types/src/hooks/useDeckCompanions.d.ts.map +1 -1
- package/dist/types/src/hooks/useDeckState.d.ts +1 -1
- package/dist/types/src/hooks/useDeckState.d.ts.map +1 -1
- package/dist/types/src/hooks/useSelectedCompanionVariant.d.ts +6 -0
- package/dist/types/src/hooks/useSelectedCompanionVariant.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +4 -0
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/operations/adjust.d.ts.map +1 -1
- package/dist/types/src/operations/update-companion.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +2 -2
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/DeckCapabilities.d.ts +2 -2
- package/dist/types/src/types/DeckCapabilities.d.ts.map +1 -1
- package/dist/types/src/types/DeckOperation.d.ts +2 -2
- package/dist/types/src/types/DeckOperation.d.ts.map +1 -1
- package/dist/types/src/types/schema.d.ts +7 -7
- package/dist/types/src/types/schema.d.ts.map +1 -1
- package/dist/types/src/util/companion-view-state.d.ts +16 -0
- package/dist/types/src/util/companion-view-state.d.ts.map +1 -0
- package/dist/types/src/util/index.d.ts +1 -0
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/plank-url-params.d.ts +2 -0
- package/dist/types/src/util/plank-url-params.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +49 -47
- package/src/DeckPlugin.ts +1 -2
- package/src/capabilities/app-graph-builder.ts +3 -2
- package/src/capabilities/notification-tracker.ts +3 -1
- package/src/capabilities/react-surface.tsx +1 -1
- package/src/components/Companion/Companion.tsx +91 -0
- package/src/components/Companion/index.ts +5 -0
- package/src/components/Matrix/Matrix.stories.tsx +13 -26
- package/src/components/Matrix/Matrix.tsx +3 -3
- package/src/components/Matrix/SPEC.md +1 -1
- package/src/components/Matrix/index.ts +1 -1
- package/src/components/Pane/Pane.stories.tsx +92 -0
- package/src/components/Pane/Pane.tsx +178 -0
- package/src/components/Pane/index.ts +5 -0
- package/src/components/Plank/Plank.stories.tsx +103 -0
- package/src/components/Plank/Plank.tsx +149 -0
- package/src/components/Plank/index.ts +5 -0
- package/src/components/index.ts +3 -4
- package/src/containers/Deck/Deck.tsx +3 -3
- package/src/containers/Deck/DeckPlank.tsx +187 -0
- package/src/containers/Deck/DeckViewport.tsx +116 -243
- package/src/containers/{Plank → Deck}/PlankControls.tsx +19 -17
- package/src/containers/Deck/PlankFallback.tsx +42 -0
- package/src/containers/Deck/useDeckPlank.ts +219 -0
- package/src/containers/DeckLayout/DeckLayout.stories.tsx +38 -51
- package/src/containers/DeckLayout/Dialog.tsx +1 -1
- package/src/{components → containers}/DeckSettings/DeckSettings.stories.tsx +1 -1
- package/src/containers/DeckSettings/DeckSettings.tsx +42 -0
- package/src/containers/Sidebar/ComplementarySidebar.tsx +2 -2
- package/src/containers/index.ts +1 -1
- package/src/hooks/index.ts +2 -0
- package/src/hooks/useCompanionSplit.ts +78 -0
- package/src/hooks/useCompanions.ts +39 -7
- package/src/hooks/useDeckCompanions.ts +3 -3
- package/src/hooks/useDeckState.ts +1 -1
- package/src/hooks/useSelectedCompanionVariant.ts +14 -0
- package/src/index.ts +7 -0
- package/src/operations/adjust.ts +23 -12
- package/src/operations/update-companion.ts +10 -6
- package/src/translations.ts +2 -2
- package/src/types/DeckCapabilities.ts +1 -1
- package/src/types/DeckOperation.ts +2 -1
- package/src/types/schema.ts +5 -4
- package/src/util/companion-view-state.ts +28 -0
- package/src/util/index.ts +1 -0
- package/src/util/plank-url-params.test.ts +5 -0
- package/src/util/plank-url-params.ts +3 -1
- package/src/util/sanitize-persisted-state.test.ts +1 -1
- package/src/util/set-active.test.ts +1 -1
- package/dist/lib/neutral/DeckLayout-VX2BP4Q2.mjs.map +0 -7
- package/dist/lib/neutral/DeckSettings-CQQZJ2YS.mjs +0 -27
- package/dist/lib/neutral/DeckSettings-CQQZJ2YS.mjs.map +0 -7
- package/dist/lib/neutral/adjust-7CZI4GK3.mjs.map +0 -7
- package/dist/lib/neutral/app-graph-builder-6HTXRTU2.mjs.map +0 -7
- package/dist/lib/neutral/chunk-CL7JIOI5.mjs.map +0 -7
- package/dist/lib/neutral/chunk-DNG3L5QN.mjs +0 -1304
- package/dist/lib/neutral/chunk-DNG3L5QN.mjs.map +0 -7
- package/dist/lib/neutral/chunk-NGX6RXNV.mjs.map +0 -7
- package/dist/lib/neutral/chunk-UZLAR4DR.mjs +0 -8
- package/dist/lib/neutral/notification-tracker-CUDFRDCF.mjs.map +0 -7
- package/dist/lib/neutral/update-companion-5LCY6QME.mjs.map +0 -7
- package/dist/types/src/components/DeckSettings/DeckSettings.d.ts.map +0 -1
- package/dist/types/src/components/DeckSettings/index.d.ts.map +0 -1
- package/dist/types/src/containers/Plank/Plank.d.ts +0 -17
- package/dist/types/src/containers/Plank/Plank.d.ts.map +0 -1
- package/dist/types/src/containers/Plank/Plank.stories.d.ts +0 -67
- package/dist/types/src/containers/Plank/Plank.stories.d.ts.map +0 -1
- package/dist/types/src/containers/Plank/PlankComponent.d.ts +0 -17
- package/dist/types/src/containers/Plank/PlankComponent.d.ts.map +0 -1
- package/dist/types/src/containers/Plank/PlankContent.d.ts +0 -10
- package/dist/types/src/containers/Plank/PlankContent.d.ts.map +0 -1
- package/dist/types/src/containers/Plank/PlankControls.d.ts.map +0 -1
- package/dist/types/src/containers/Plank/PlankError.d.ts +0 -15
- package/dist/types/src/containers/Plank/PlankError.d.ts.map +0 -1
- package/dist/types/src/containers/Plank/PlankHeading.d.ts +0 -22
- package/dist/types/src/containers/Plank/PlankHeading.d.ts.map +0 -1
- package/dist/types/src/containers/Plank/PlankLoading.d.ts +0 -3
- package/dist/types/src/containers/Plank/PlankLoading.d.ts.map +0 -1
- package/dist/types/src/containers/Plank/PlankRoot.d.ts +0 -37
- package/dist/types/src/containers/Plank/PlankRoot.d.ts.map +0 -1
- package/dist/types/src/containers/Plank/index.d.ts +0 -4
- package/dist/types/src/containers/Plank/index.d.ts.map +0 -1
- package/src/components/DeckSettings/DeckSettings.tsx +0 -34
- package/src/containers/Plank/Plank.stories.tsx +0 -108
- package/src/containers/Plank/Plank.tsx +0 -22
- package/src/containers/Plank/PlankComponent.tsx +0 -223
- package/src/containers/Plank/PlankContent.tsx +0 -45
- package/src/containers/Plank/PlankError.tsx +0 -82
- package/src/containers/Plank/PlankHeading.tsx +0 -236
- package/src/containers/Plank/PlankLoading.tsx +0 -10
- package/src/containers/Plank/PlankRoot.tsx +0 -49
- package/src/containers/Plank/index.ts +0 -7
- /package/dist/lib/neutral/{add-toast-APKTCLIA.mjs.map → add-toast-BHNEH5UY.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-UZLAR4DR.mjs.map → chunk-FKGYHBUB.mjs.map} +0 -0
- /package/dist/lib/neutral/{revert-workspace-24TKG3I7.mjs.map → revert-workspace-RXWP2TEE.mjs.map} +0 -0
- /package/dist/lib/neutral/{scroll-into-view-3VXT6TWC.mjs.map → scroll-into-view-HFV5EGYZ.mjs.map} +0 -0
- /package/dist/lib/neutral/{set-layout-mode-AZ73W52Z.mjs.map → set-layout-mode-XAGSZZGB.mjs.map} +0 -0
- /package/dist/lib/neutral/{switch-workspace-TBPT23CZ.mjs.map → switch-workspace-PA7N6EUX.mjs.map} +0 -0
- /package/dist/lib/neutral/{update-complementary-HZ7QXZYE.mjs.map → update-complementary-K55I5EV5.mjs.map} +0 -0
- /package/dist/lib/neutral/{update-dialog-A7W3R5EI.mjs.map → update-dialog-Z3GEXMVV.mjs.map} +0 -0
- /package/dist/lib/neutral/{update-plank-size-XHTYBLSD.mjs.map → update-plank-size-BTESVV7N.mjs.map} +0 -0
- /package/dist/lib/neutral/{update-popover-RDIHG73B.mjs.map → update-popover-QEVDSZSH.mjs.map} +0 -0
- /package/dist/lib/neutral/{update-sidebar-GEI7USA5.mjs.map → update-sidebar-VSRCN47U.mjs.map} +0 -0
- /package/dist/types/src/{components → containers}/DeckSettings/index.d.ts +0 -0
- /package/src/{components → containers}/DeckSettings/index.ts +0 -0
|
@@ -2,42 +2,36 @@
|
|
|
2
2
|
// Copyright 2026 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import React, {
|
|
6
|
-
Fragment,
|
|
7
|
-
memo,
|
|
8
|
-
type PropsWithChildren,
|
|
9
|
-
type UIEvent,
|
|
10
|
-
useCallback,
|
|
11
|
-
useEffect,
|
|
12
|
-
useMemo,
|
|
13
|
-
useRef,
|
|
14
|
-
} from 'react';
|
|
5
|
+
import React, { type PropsWithChildren, useCallback, useEffect, useRef } from 'react';
|
|
15
6
|
|
|
16
7
|
import { Surface, useOperationInvoker } from '@dxos/app-framework/ui';
|
|
17
8
|
import { LayoutOperation } from '@dxos/app-toolkit';
|
|
18
|
-
import { useAppGraph } from '@dxos/app-toolkit/ui';
|
|
19
9
|
import { addEventListener } from '@dxos/async';
|
|
20
10
|
import { invariant } from '@dxos/invariant';
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import { DEFAULT_HORIZONTAL_SIZE, Stack, StackContext } from '@dxos/react-ui-stack';
|
|
11
|
+
import { IconButton, Main, type MainContentProps, ScrollArea, useOnTransition, useTranslation } from '@dxos/react-ui';
|
|
12
|
+
import { mainIntrinsicSize, mainPaddingTransitions } from '@dxos/react-ui';
|
|
13
|
+
import { Mosaic, type MosaicStackTileComponent, type MosaicTileProps } from '@dxos/react-ui-mosaic';
|
|
25
14
|
import { hoverableControls, hoverableFocusedWithinControls, mx } from '@dxos/ui-theme';
|
|
26
15
|
|
|
27
|
-
import { useBreakpoints,
|
|
16
|
+
import { useBreakpoints, useDeckState } from '#hooks';
|
|
28
17
|
import { meta } from '#meta';
|
|
29
|
-
import { DeckOperation,
|
|
18
|
+
import { DeckOperation, Keyshortcuts, getMode } from '#types';
|
|
30
19
|
|
|
31
20
|
import { layoutAppliesTopbar } from '../../util';
|
|
32
|
-
import { Plank, PlankRootProps, type PlankComponentProps } from '../Plank';
|
|
33
21
|
import {
|
|
34
22
|
ToggleComplementarySidebarButton as NaturalToggleComplementarySidebarButton,
|
|
35
23
|
ToggleSidebarButton as NaturalToggleSidebarButton,
|
|
36
24
|
} from '../Sidebar';
|
|
25
|
+
import { DeckPlank } from './DeckPlank';
|
|
37
26
|
import { useDeckContext } from './DeckRoot';
|
|
38
27
|
|
|
39
28
|
const DECK_VIEWPORT_NAME = 'DeckViewport';
|
|
40
29
|
|
|
30
|
+
// Multi-mode plank extents (rem); each plank persists its own width via `plankSizing`.
|
|
31
|
+
const DEFAULT_PLANK_SIZE = 50;
|
|
32
|
+
const MIN_PLANK_SIZE = 20;
|
|
33
|
+
const MAX_PLANK_SIZE = 120;
|
|
34
|
+
|
|
41
35
|
//
|
|
42
36
|
// DeckViewport
|
|
43
37
|
//
|
|
@@ -45,11 +39,10 @@ const DECK_VIEWPORT_NAME = 'DeckViewport';
|
|
|
45
39
|
export type DeckViewportProps = PropsWithChildren;
|
|
46
40
|
|
|
47
41
|
/**
|
|
48
|
-
* Deck viewport that renders the main content area and sets CSS variables for
|
|
42
|
+
* Deck viewport that renders the main content area and sets CSS variables for sidebar widths.
|
|
49
43
|
*/
|
|
50
44
|
export const DeckViewport = ({ children }: DeckViewportProps) => {
|
|
51
45
|
const {
|
|
52
|
-
deck: { active, plankSizing },
|
|
53
46
|
state: { sidebarState, complementarySidebarState },
|
|
54
47
|
settings,
|
|
55
48
|
layoutMode,
|
|
@@ -81,8 +74,6 @@ export const DeckViewport = ({ children }: DeckViewportProps) => {
|
|
|
81
74
|
: complementarySidebarState === 'collapsed'
|
|
82
75
|
? 'var(--dx-rail-size)'
|
|
83
76
|
: '0',
|
|
84
|
-
'--main-content-first-width': `${plankSizing[active[0] ?? 'never'] ?? DEFAULT_HORIZONTAL_SIZE}rem`,
|
|
85
|
-
'--main-content-last-width': `${plankSizing[active[(active.length ?? 1) - 1] ?? 'never'] ?? DEFAULT_HORIZONTAL_SIZE}rem`,
|
|
86
77
|
} as MainContentProps['style']
|
|
87
78
|
}
|
|
88
79
|
>
|
|
@@ -119,8 +110,7 @@ export const DeckContentEmpty = () => {
|
|
|
119
110
|
*/
|
|
120
111
|
export const DeckSoloMode = () => {
|
|
121
112
|
const { deck, settings, layoutMode, onLayoutChange } = useDeckContext('DeckSoloMode');
|
|
122
|
-
const { companionOpen,
|
|
123
|
-
const effectiveCompanionVariant = fullscreen ? undefined : companionOpen ? companionVariant : undefined;
|
|
113
|
+
const { companionOpen, fullscreen, solo } = deck;
|
|
124
114
|
const breakpoint = useBreakpoints();
|
|
125
115
|
const topbar = layoutAppliesTopbar(breakpoint, layoutMode);
|
|
126
116
|
invariant(solo);
|
|
@@ -146,21 +136,14 @@ export const DeckSoloMode = () => {
|
|
|
146
136
|
<div className='relative overflow-hidden bg-deck-surface'>
|
|
147
137
|
<DeckSidebarToggles topbar={topbar} fullscreen={fullscreen} />
|
|
148
138
|
{fullscreen && <ExitFullscreenButton onExit={() => onLayoutChange({ mode: 'solo--fullscreen' })} />}
|
|
149
|
-
<
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
id={solo}
|
|
158
|
-
part='solo'
|
|
159
|
-
layoutMode={layoutMode}
|
|
160
|
-
companionVariant={effectiveCompanionVariant}
|
|
161
|
-
settings={settings}
|
|
162
|
-
/>
|
|
163
|
-
</StackContext.Provider>
|
|
139
|
+
<DeckPlank
|
|
140
|
+
id={solo}
|
|
141
|
+
part='solo'
|
|
142
|
+
layoutMode={layoutMode}
|
|
143
|
+
companionShown={!fullscreen && companionOpen}
|
|
144
|
+
settings={settings}
|
|
145
|
+
classNames={mx('absolute inset-0', mainIntrinsicSize)}
|
|
146
|
+
/>
|
|
164
147
|
</div>
|
|
165
148
|
);
|
|
166
149
|
};
|
|
@@ -169,25 +152,65 @@ export const DeckSoloMode = () => {
|
|
|
169
152
|
// DeckMultiMode
|
|
170
153
|
//
|
|
171
154
|
|
|
155
|
+
const getPlankId = (id: string) => id;
|
|
156
|
+
|
|
172
157
|
/**
|
|
173
|
-
*
|
|
158
|
+
* Tile wrapping a {@link DeckPlank} in a resizable {@link Mosaic.Tile}; the committed width persists via
|
|
159
|
+
* `plankSizing`. Reads the deck context directly since the Mosaic stack renders tiles by id.
|
|
160
|
+
*/
|
|
161
|
+
const DeckPlankTile: MosaicStackTileComponent<string> = (props) => {
|
|
162
|
+
const id = props.data;
|
|
163
|
+
const { deck, settings, layoutMode } = useDeckContext('DeckPlankTile');
|
|
164
|
+
const { invokePromise } = useOperationInvoker();
|
|
165
|
+
|
|
166
|
+
const handleSizeChange = useCallback<NonNullable<MosaicTileProps['onSizeChange']>>(
|
|
167
|
+
(size) => {
|
|
168
|
+
if (typeof size === 'number') {
|
|
169
|
+
void invokePromise(DeckOperation.UpdatePlankSize, { id, size: Math.round(size) });
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
[invokePromise, id],
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
return (
|
|
176
|
+
<Mosaic.Tile
|
|
177
|
+
{...props}
|
|
178
|
+
classNames='relative h-full'
|
|
179
|
+
size={deck.plankSizing[id] ?? DEFAULT_PLANK_SIZE}
|
|
180
|
+
minSize={MIN_PLANK_SIZE}
|
|
181
|
+
maxSize={MAX_PLANK_SIZE}
|
|
182
|
+
onSizeChange={handleSizeChange}
|
|
183
|
+
>
|
|
184
|
+
<DeckPlank
|
|
185
|
+
id={id}
|
|
186
|
+
part='multi'
|
|
187
|
+
layoutMode={layoutMode}
|
|
188
|
+
active={deck.active}
|
|
189
|
+
companionShown={deck.companionOpen}
|
|
190
|
+
settings={settings}
|
|
191
|
+
classNames='size-full'
|
|
192
|
+
/>
|
|
193
|
+
<Mosaic.ResizeHandle />
|
|
194
|
+
</Mosaic.Tile>
|
|
195
|
+
);
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Multi-plank horizontal scrolling layout. Planks are resizable {@link Mosaic.Tile}s in a horizontal
|
|
200
|
+
* {@link Mosaic.Stack}; the scroll position is preserved across solo↔multi transitions and the
|
|
201
|
+
* just-navigated plank is scrolled into view.
|
|
174
202
|
*/
|
|
175
203
|
export const DeckMultiMode = () => {
|
|
176
|
-
const {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
} = useDeckContext('DeckMultiMode');
|
|
181
|
-
/** In multi mode the companion column is always shown when the last plank has companions (not gated by `companionOpen`). */
|
|
182
|
-
const effectiveCompanionVariant = companionVariant;
|
|
183
|
-
const lastPlankId = active[active.length - 1];
|
|
184
|
-
const lastPlankCompanions = useCompanions(lastPlankId);
|
|
204
|
+
const { deck, layoutMode } = useDeckContext('DeckMultiMode');
|
|
205
|
+
const { active, fullscreen } = deck;
|
|
206
|
+
const { state } = useDeckState();
|
|
207
|
+
const { invokePromise } = useOperationInvoker();
|
|
185
208
|
const breakpoint = useBreakpoints();
|
|
186
209
|
const topbar = layoutAppliesTopbar(breakpoint, layoutMode);
|
|
187
|
-
const
|
|
210
|
+
const viewportRef = useRef<HTMLDivElement>(null);
|
|
188
211
|
|
|
189
|
-
|
|
190
|
-
const scrollLeftRef = useRef<number>(null);
|
|
212
|
+
// Preserve horizontal scroll position across solo↔multi transitions; a window resize invalidates it.
|
|
213
|
+
const scrollLeftRef = useRef<number | null>(null);
|
|
191
214
|
useEffect(
|
|
192
215
|
() =>
|
|
193
216
|
addEventListener(window, 'resize', () => {
|
|
@@ -195,67 +218,58 @@ export const DeckMultiMode = () => {
|
|
|
195
218
|
}),
|
|
196
219
|
[],
|
|
197
220
|
);
|
|
198
|
-
|
|
199
221
|
const restoreScroll = useCallback(() => {
|
|
200
|
-
if (
|
|
201
|
-
|
|
222
|
+
if (viewportRef.current && scrollLeftRef.current != null) {
|
|
223
|
+
viewportRef.current.scrollLeft = scrollLeftRef.current;
|
|
202
224
|
}
|
|
203
225
|
}, []);
|
|
204
|
-
|
|
205
226
|
useOnTransition(layoutMode, (mode) => mode !== 'multi', 'multi', restoreScroll);
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
if (
|
|
210
|
-
|
|
227
|
+
// Save scroll position as the user scrolls (ScrollArea.Viewport does not forward `onScroll`).
|
|
228
|
+
useEffect(() => {
|
|
229
|
+
const viewport = viewportRef.current;
|
|
230
|
+
if (!viewport) {
|
|
231
|
+
return;
|
|
211
232
|
}
|
|
233
|
+
return addEventListener(viewport, 'scroll', () => {
|
|
234
|
+
scrollLeftRef.current = viewport.scrollLeft;
|
|
235
|
+
});
|
|
212
236
|
}, []);
|
|
213
237
|
|
|
214
|
-
//
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
const
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
{
|
|
226
|
-
|
|
227
|
-
|
|
238
|
+
// Scroll the just-navigated plank into view, then clear the one-shot flag.
|
|
239
|
+
useEffect(() => {
|
|
240
|
+
const id = state.scrollIntoView;
|
|
241
|
+
const viewport = viewportRef.current;
|
|
242
|
+
if (!id || !viewport) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const tile = viewport.querySelector<HTMLElement>(`[data-object-id="${CSS.escape(id)}"]`);
|
|
247
|
+
if (tile) {
|
|
248
|
+
const offset = tile.getBoundingClientRect().left - viewport.getBoundingClientRect().left + viewport.scrollLeft;
|
|
249
|
+
viewport.scrollTo({ left: offset, behavior: 'smooth' });
|
|
250
|
+
}
|
|
251
|
+
void invokePromise(LayoutOperation.ScrollIntoView, { subject: undefined });
|
|
252
|
+
}, [state.scrollIntoView, invokePromise]);
|
|
228
253
|
|
|
229
254
|
return (
|
|
230
255
|
<div className='relative bg-deck-surface overflow-hidden'>
|
|
231
256
|
<DeckSidebarToggles topbar={topbar} fullscreen={fullscreen} />
|
|
232
|
-
<
|
|
233
|
-
classNames={[
|
|
234
|
-
'
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
id={entryId}
|
|
249
|
-
part='multi'
|
|
250
|
-
active={active}
|
|
251
|
-
order={order[entryId]}
|
|
252
|
-
layoutMode={layoutMode}
|
|
253
|
-
companionVariant={effectiveCompanionVariant}
|
|
254
|
-
settings={settings}
|
|
255
|
-
/>
|
|
256
|
-
</Fragment>
|
|
257
|
-
))}
|
|
258
|
-
</Stack>
|
|
257
|
+
<Mosaic.Root>
|
|
258
|
+
<Mosaic.Container orientation='horizontal' classNames={['absolute inset-0', mainPaddingTransitions]}>
|
|
259
|
+
<ScrollArea.Root orientation='horizontal' classNames='size-full'>
|
|
260
|
+
<ScrollArea.Viewport ref={viewportRef}>
|
|
261
|
+
<Mosaic.Stack
|
|
262
|
+
orientation='horizontal'
|
|
263
|
+
classNames='h-full gap-(--main-spacing) px-(--main-spacing)'
|
|
264
|
+
getId={getPlankId}
|
|
265
|
+
items={active}
|
|
266
|
+
Tile={DeckPlankTile}
|
|
267
|
+
draggable={false}
|
|
268
|
+
/>
|
|
269
|
+
</ScrollArea.Viewport>
|
|
270
|
+
</ScrollArea.Root>
|
|
271
|
+
</Mosaic.Container>
|
|
272
|
+
</Mosaic.Root>
|
|
259
273
|
</div>
|
|
260
274
|
);
|
|
261
275
|
};
|
|
@@ -306,144 +320,3 @@ const DeckSidebarToggles = ({ topbar, fullscreen }: { topbar: boolean; fullscree
|
|
|
306
320
|
</>
|
|
307
321
|
);
|
|
308
322
|
};
|
|
309
|
-
|
|
310
|
-
//
|
|
311
|
-
// PlankSeparator
|
|
312
|
-
//
|
|
313
|
-
|
|
314
|
-
const PlankSeparator = ({ order, hidden, encapsulate }: { order: number; hidden?: boolean; encapsulate?: boolean }) =>
|
|
315
|
-
order > 0 && (
|
|
316
|
-
<span
|
|
317
|
-
role='separator'
|
|
318
|
-
className={mx('row-span-2 bg-deck-surface', hidden && 'hidden', encapsulate ? 'w-0' : 'w-4')}
|
|
319
|
-
style={{ gridColumn: order }}
|
|
320
|
-
/>
|
|
321
|
-
);
|
|
322
|
-
|
|
323
|
-
//
|
|
324
|
-
// PlankContainer
|
|
325
|
-
//
|
|
326
|
-
|
|
327
|
-
type PlankContainerProps = Pick<PlankRootProps, 'layoutMode' | 'part' | 'settings'> &
|
|
328
|
-
Pick<PlankComponentProps, 'id'> &
|
|
329
|
-
Partial<Pick<PlankComponentProps, 'path' | 'order' | 'active'>> & {
|
|
330
|
-
companionVariant?: string;
|
|
331
|
-
};
|
|
332
|
-
|
|
333
|
-
/**
|
|
334
|
-
* Connected Plank that calls hooks and renders the radix-style Plank tree.
|
|
335
|
-
* This is the bridge between DeckViewport (which knows about framework hooks) and
|
|
336
|
-
* the pure Plank components (which receive everything via context).
|
|
337
|
-
*/
|
|
338
|
-
const PlankContainer = memo(
|
|
339
|
-
({ id, layoutMode, part, order, settings, companionVariant, active, ...props }: PlankContainerProps) => {
|
|
340
|
-
const { graph } = useAppGraph();
|
|
341
|
-
const { invokePromise } = useOperationInvoker();
|
|
342
|
-
const { state, deck } = useDeckState();
|
|
343
|
-
const node = useNode(graph, id);
|
|
344
|
-
const companions = useCompanions(id);
|
|
345
|
-
const isLastPlankInMulti =
|
|
346
|
-
layoutMode === 'multi' && active && active.length > 0 && active[active.length - 1] === id;
|
|
347
|
-
const variantForThisPlank =
|
|
348
|
-
layoutMode === 'multi' ? (isLastPlankInMulti ? companionVariant : undefined) : companionVariant;
|
|
349
|
-
const { companionId } = useSelectedCompanion(companions, variantForThisPlank);
|
|
350
|
-
const resolvedCompanionId =
|
|
351
|
-
layoutMode === 'multi' && isLastPlankInMulti && companions.length > 0
|
|
352
|
-
? companionId
|
|
353
|
-
: variantForThisPlank
|
|
354
|
-
? companionId
|
|
355
|
-
: undefined;
|
|
356
|
-
const currentCompanion = companions.find(({ id }) => id === resolvedCompanionId);
|
|
357
|
-
const hasCompanion = !!(resolvedCompanionId && currentCompanion);
|
|
358
|
-
|
|
359
|
-
const handleAdjust = useCallback(
|
|
360
|
-
(plankId: string, type: DeckOperation.PartAdjustment) => {
|
|
361
|
-
if (type === 'close') {
|
|
362
|
-
if (part === 'complementary') {
|
|
363
|
-
return invokePromise(LayoutOperation.UpdateComplementary, { state: 'collapsed' });
|
|
364
|
-
} else if (active) {
|
|
365
|
-
// Close the plank and everything to the right (stack pop).
|
|
366
|
-
const index = active.indexOf(plankId);
|
|
367
|
-
const toClose = index !== -1 ? active.slice(index) : [plankId];
|
|
368
|
-
return invokePromise(LayoutOperation.Close, { subject: toClose });
|
|
369
|
-
} else {
|
|
370
|
-
return invokePromise(LayoutOperation.Close, { subject: [plankId] });
|
|
371
|
-
}
|
|
372
|
-
} else {
|
|
373
|
-
return invokePromise(DeckOperation.Adjust, { type, id: plankId });
|
|
374
|
-
}
|
|
375
|
-
},
|
|
376
|
-
[invokePromise, part, active],
|
|
377
|
-
);
|
|
378
|
-
|
|
379
|
-
const handleResize = useCallback(
|
|
380
|
-
(plankId: string, size: number) => invokePromise(DeckOperation.UpdatePlankSize, { id: plankId, size }),
|
|
381
|
-
[invokePromise],
|
|
382
|
-
);
|
|
383
|
-
|
|
384
|
-
const handleScrollIntoView = useCallback(
|
|
385
|
-
(subject?: string) => invokePromise(LayoutOperation.ScrollIntoView, { subject }),
|
|
386
|
-
[invokePromise],
|
|
387
|
-
);
|
|
388
|
-
|
|
389
|
-
const handleUpdateCompanion = useCallback(
|
|
390
|
-
(companion: string | null) => invokePromise(LayoutOperation.UpdateCompanion, { subject: companion }),
|
|
391
|
-
[invokePromise],
|
|
392
|
-
);
|
|
393
|
-
|
|
394
|
-
return (
|
|
395
|
-
<Plank.Root
|
|
396
|
-
graph={graph}
|
|
397
|
-
layoutMode={layoutMode}
|
|
398
|
-
part={part}
|
|
399
|
-
settings={settings}
|
|
400
|
-
popoverAnchorId={state.popoverAnchorId}
|
|
401
|
-
scrollIntoView={state.scrollIntoView}
|
|
402
|
-
plankSizing={deck.plankSizing}
|
|
403
|
-
onAdjust={handleAdjust}
|
|
404
|
-
onResize={handleResize}
|
|
405
|
-
onScrollIntoView={handleScrollIntoView}
|
|
406
|
-
onUpdateCompanion={handleUpdateCompanion}
|
|
407
|
-
>
|
|
408
|
-
<Plank.Content solo={part === 'solo'} companion={hasCompanion} encapsulate={!!settings?.encapsulatedPlanks}>
|
|
409
|
-
<Plank.Component
|
|
410
|
-
{...props}
|
|
411
|
-
active={active}
|
|
412
|
-
id={id}
|
|
413
|
-
node={node}
|
|
414
|
-
companioned={hasCompanion ? 'primary' : undefined}
|
|
415
|
-
companions={hasCompanion ? [] : companions}
|
|
416
|
-
order={order}
|
|
417
|
-
{...(part === 'solo'
|
|
418
|
-
? {
|
|
419
|
-
part: 'solo-primary',
|
|
420
|
-
}
|
|
421
|
-
: {
|
|
422
|
-
part,
|
|
423
|
-
})}
|
|
424
|
-
/>
|
|
425
|
-
{hasCompanion && (
|
|
426
|
-
<Plank.Component
|
|
427
|
-
{...props}
|
|
428
|
-
active={active}
|
|
429
|
-
id={resolvedCompanionId}
|
|
430
|
-
node={currentCompanion}
|
|
431
|
-
companions={companions}
|
|
432
|
-
companioned='companion'
|
|
433
|
-
primary={node}
|
|
434
|
-
{...(part === 'solo'
|
|
435
|
-
? {
|
|
436
|
-
order,
|
|
437
|
-
part: 'solo-companion',
|
|
438
|
-
}
|
|
439
|
-
: {
|
|
440
|
-
order: (order ?? 0) + 1,
|
|
441
|
-
part,
|
|
442
|
-
})}
|
|
443
|
-
/>
|
|
444
|
-
)}
|
|
445
|
-
</Plank.Content>
|
|
446
|
-
</Plank.Root>
|
|
447
|
-
);
|
|
448
|
-
},
|
|
449
|
-
);
|
|
@@ -9,18 +9,11 @@ import { LayoutOperation } from '@dxos/app-toolkit';
|
|
|
9
9
|
import { ButtonGroup, type ButtonGroupProps, type ButtonProps, IconButton, useTranslation } from '@dxos/react-ui';
|
|
10
10
|
|
|
11
11
|
import { meta } from '#meta';
|
|
12
|
-
import { type
|
|
12
|
+
import { type DeckOperation, type LayoutMode } from '#types';
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
import { type PlankCapabilities } from './useDeckPlank';
|
|
15
15
|
|
|
16
|
-
export type
|
|
17
|
-
incrementStart?: boolean;
|
|
18
|
-
incrementEnd?: boolean;
|
|
19
|
-
deck?: boolean;
|
|
20
|
-
solo?: boolean;
|
|
21
|
-
fullscreen?: boolean;
|
|
22
|
-
companion?: boolean;
|
|
23
|
-
};
|
|
16
|
+
export type PlankControlHandler = (event: DeckOperation.PartAdjustment) => void;
|
|
24
17
|
|
|
25
18
|
//
|
|
26
19
|
// Controls
|
|
@@ -166,13 +159,22 @@ export const PlankControls = forwardRef<HTMLDivElement, PlankControlsProps>(
|
|
|
166
159
|
)}
|
|
167
160
|
|
|
168
161
|
{capabilities.companion && (
|
|
169
|
-
<
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
162
|
+
<ButtonGroup>
|
|
163
|
+
<PlankControl
|
|
164
|
+
label={t('open-companion.label')}
|
|
165
|
+
classNames={buttonClassNames}
|
|
166
|
+
data-testid='plankHeading.companion'
|
|
167
|
+
icon='ph--square-split-horizontal--regular'
|
|
168
|
+
onClick={() => onClick?.('companion')}
|
|
169
|
+
/>
|
|
170
|
+
<PlankControl
|
|
171
|
+
label={t('open-companion-vertical.label')}
|
|
172
|
+
classNames={buttonClassNames}
|
|
173
|
+
data-testid='plankHeading.companion-vertical'
|
|
174
|
+
icon='ph--square-split-vertical--regular'
|
|
175
|
+
onClick={() => onClick?.('companion-vertical')}
|
|
176
|
+
/>
|
|
177
|
+
</ButtonGroup>
|
|
176
178
|
)}
|
|
177
179
|
{children}
|
|
178
180
|
</ButtonGroup>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React, { useEffect } from 'react';
|
|
6
|
+
|
|
7
|
+
import { log } from '@dxos/log';
|
|
8
|
+
import { ErrorFallback, type ErrorFallbackProps, useTranslation } from '@dxos/react-ui';
|
|
9
|
+
import { descriptionMessage, mx } from '@dxos/ui-theme';
|
|
10
|
+
|
|
11
|
+
import { meta } from '#meta';
|
|
12
|
+
|
|
13
|
+
// TODO(burdon): Show skeleton: https://github.com/dxos/dxos/issues/8259
|
|
14
|
+
export const PlankLoading = () => <div className='grid place-items-center dx-attention-surface' />;
|
|
15
|
+
|
|
16
|
+
/** User-facing error fallback for a plank's content Surface. */
|
|
17
|
+
export const PlankErrorFallback = ({ error }: ErrorFallbackProps) => {
|
|
18
|
+
const { t } = useTranslation(meta.profile.key);
|
|
19
|
+
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (error) {
|
|
22
|
+
log.error('plank error', { error });
|
|
23
|
+
}
|
|
24
|
+
}, [error]);
|
|
25
|
+
|
|
26
|
+
if (process.env.NODE_ENV === 'development') {
|
|
27
|
+
return <ErrorFallback title='Plank Error' error={error} />;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Show only a generic message to end users; raw error details stay in logs / the dev fallback above.
|
|
31
|
+
return (
|
|
32
|
+
<div
|
|
33
|
+
role='alert'
|
|
34
|
+
data-testid='plank-content-error'
|
|
35
|
+
className='dx-attention-surface overflow-y-auto p-8 grid place-items-center'
|
|
36
|
+
>
|
|
37
|
+
<div className='flex flex-col items-center gap-2'>
|
|
38
|
+
<p className={mx(descriptionMessage, 'break-all rounded-md p-4')}>{t('error-fallback.message')}</p>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
);
|
|
42
|
+
};
|