@dxos/plugin-deck 0.8.4-main.1da679c → 0.8.4-main.21d9917
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/lib/browser/app-graph-builder-DTVCULQ4.mjs +120 -0
- package/dist/lib/browser/app-graph-builder-DTVCULQ4.mjs.map +7 -0
- package/dist/lib/browser/{check-app-scheme-BKIOCWXT.mjs → check-app-scheme-JSRXXIYF.mjs} +9 -9
- package/dist/lib/browser/check-app-scheme-JSRXXIYF.mjs.map +7 -0
- package/dist/lib/browser/{chunk-F5BQOOEG.mjs → chunk-ATFPDN6J.mjs} +155 -23
- package/dist/lib/browser/chunk-ATFPDN6J.mjs.map +7 -0
- package/dist/lib/browser/chunk-EREEXCHO.mjs +1448 -0
- package/dist/lib/browser/chunk-EREEXCHO.mjs.map +7 -0
- package/dist/lib/browser/{chunk-CNTGBCMK.mjs → chunk-NHABISX2.mjs} +40 -33
- package/dist/lib/browser/chunk-NHABISX2.mjs.map +7 -0
- package/dist/lib/browser/chunk-UNG4CLLP.mjs +161 -0
- package/dist/lib/browser/chunk-UNG4CLLP.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +73 -68
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/operation-resolver-CDYBLZJ4.mjs +595 -0
- package/dist/lib/browser/operation-resolver-CDYBLZJ4.mjs.map +7 -0
- package/dist/lib/browser/react-root-LYNEKGHM.mjs +47 -0
- package/dist/lib/browser/react-root-LYNEKGHM.mjs.map +7 -0
- package/dist/lib/browser/react-surface-RPKD7XUR.mjs +42 -0
- package/dist/lib/browser/react-surface-RPKD7XUR.mjs.map +7 -0
- package/dist/lib/browser/settings-OMHVGZ6V.mjs +37 -0
- package/dist/lib/browser/settings-OMHVGZ6V.mjs.map +7 -0
- package/dist/lib/browser/state-OC3BSB6E.mjs +103 -0
- package/dist/lib/browser/state-OC3BSB6E.mjs.map +7 -0
- package/dist/lib/browser/toolkit-R53LD3EA.mjs +53 -0
- package/dist/lib/browser/toolkit-R53LD3EA.mjs.map +7 -0
- package/dist/lib/browser/types/index.mjs +11 -4
- package/dist/lib/browser/url-handler-53TE6JZO.mjs +93 -0
- package/dist/lib/browser/url-handler-53TE6JZO.mjs.map +7 -0
- package/dist/lib/node-esm/app-graph-builder-473BNZDJ.mjs +121 -0
- package/dist/lib/node-esm/app-graph-builder-473BNZDJ.mjs.map +7 -0
- package/dist/lib/node-esm/check-app-scheme-IVYRHKRH.mjs +33 -0
- package/dist/lib/node-esm/check-app-scheme-IVYRHKRH.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-ADPMWKLL.mjs +154 -0
- package/dist/lib/node-esm/chunk-ADPMWKLL.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-SKEVPQ7E.mjs +162 -0
- package/dist/lib/node-esm/chunk-SKEVPQ7E.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-V6VEXRD4.mjs +1449 -0
- package/dist/lib/node-esm/chunk-V6VEXRD4.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-XAKTY3EB.mjs +294 -0
- package/dist/lib/node-esm/chunk-XAKTY3EB.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +181 -0
- package/dist/lib/node-esm/index.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -0
- package/dist/lib/node-esm/operation-resolver-WUOE33ID.mjs +596 -0
- package/dist/lib/node-esm/operation-resolver-WUOE33ID.mjs.map +7 -0
- package/dist/lib/node-esm/react-root-L7H43AS3.mjs +48 -0
- package/dist/lib/node-esm/react-root-L7H43AS3.mjs.map +7 -0
- package/dist/lib/node-esm/react-surface-77DKVMDV.mjs +43 -0
- package/dist/lib/node-esm/react-surface-77DKVMDV.mjs.map +7 -0
- package/dist/lib/node-esm/settings-2HB6FKIK.mjs +38 -0
- package/dist/lib/node-esm/settings-2HB6FKIK.mjs.map +7 -0
- package/dist/lib/node-esm/state-JRQ45ACJ.mjs +104 -0
- package/dist/lib/node-esm/state-JRQ45ACJ.mjs.map +7 -0
- package/dist/lib/node-esm/toolkit-JLPZNNKB.mjs +54 -0
- package/dist/lib/node-esm/toolkit-JLPZNNKB.mjs.map +7 -0
- package/dist/lib/node-esm/types/index.mjs +40 -0
- package/dist/lib/node-esm/url-handler-QGF2R24T.mjs +94 -0
- package/dist/lib/node-esm/url-handler-QGF2R24T.mjs.map +7 -0
- package/dist/types/src/DeckPlugin.d.ts +2 -1
- package/dist/types/src/DeckPlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts +6 -0
- package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +1 -0
- package/dist/types/src/capabilities/app-graph-builder/index.d.ts +3 -0
- package/dist/types/src/capabilities/app-graph-builder/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/check-app-scheme/check-app-scheme.d.ts +5 -0
- package/dist/types/src/capabilities/check-app-scheme/check-app-scheme.d.ts.map +1 -0
- package/dist/types/src/capabilities/check-app-scheme/index.d.ts +3 -0
- package/dist/types/src/capabilities/check-app-scheme/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +8 -13
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/operation-resolver/index.d.ts +3 -0
- package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +5 -0
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-root/index.d.ts +6 -0
- package/dist/types/src/capabilities/react-root/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-root/react-root.d.ts +9 -0
- package/dist/types/src/capabilities/react-root/react-root.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-surface/index.d.ts +3 -0
- package/dist/types/src/capabilities/react-surface/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts +5 -0
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +1 -0
- package/dist/types/src/capabilities/settings/index.d.ts +19 -0
- package/dist/types/src/capabilities/settings/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/settings/settings.d.ts +21 -0
- package/dist/types/src/capabilities/settings/settings.d.ts.map +1 -0
- package/dist/types/src/capabilities/state/index.d.ts +172 -0
- package/dist/types/src/capabilities/state/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/state/state.d.ts +175 -0
- package/dist/types/src/capabilities/state/state.d.ts.map +1 -0
- package/dist/types/src/capabilities/toolkit/index.d.ts +3 -0
- package/dist/types/src/capabilities/toolkit/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/toolkit/toolkit.d.ts +26 -0
- package/dist/types/src/capabilities/toolkit/toolkit.d.ts.map +1 -0
- package/dist/types/src/capabilities/tools/index.d.ts +3 -0
- package/dist/types/src/capabilities/tools/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/tools/tools.d.ts +12 -0
- package/dist/types/src/capabilities/tools/tools.d.ts.map +1 -0
- package/dist/types/src/capabilities/url-handler/index.d.ts +3 -0
- package/dist/types/src/capabilities/url-handler/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/url-handler/url-handler.d.ts +5 -0
- package/dist/types/src/capabilities/url-handler/url-handler.d.ts.map +1 -0
- package/dist/types/src/components/DeckLayout/ContentEmpty.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/DeckLayout.d.ts +2 -3
- package/dist/types/src/components/DeckLayout/DeckLayout.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/DeckLayout.stories.d.ts +74 -0
- package/dist/types/src/components/DeckLayout/DeckLayout.stories.d.ts.map +1 -0
- package/dist/types/src/components/DeckLayout/DeckMain.d.ts +3 -0
- package/dist/types/src/components/DeckLayout/DeckMain.d.ts.map +1 -0
- package/dist/types/src/components/DeckLayout/Dialog.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/Popover.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/Toast.d.ts +7 -2
- package/dist/types/src/components/DeckLayout/Toast.d.ts.map +1 -1
- package/dist/types/src/components/DeckSettings/DeckSettings.d.ts +4 -2
- package/dist/types/src/components/DeckSettings/DeckSettings.d.ts.map +1 -1
- package/dist/types/src/components/Plank/Plank.d.ts +3 -3
- package/dist/types/src/components/Plank/Plank.d.ts.map +1 -1
- package/dist/types/src/components/Plank/Plank.stories.d.ts +25 -6
- package/dist/types/src/components/Plank/Plank.stories.d.ts.map +1 -1
- package/dist/types/src/components/Plank/PlankControls.d.ts +1 -1
- package/dist/types/src/components/Plank/PlankControls.d.ts.map +1 -1
- package/dist/types/src/components/Plank/PlankError.d.ts +1 -1
- package/dist/types/src/components/Plank/PlankError.d.ts.map +1 -1
- package/dist/types/src/components/Plank/PlankHeading.d.ts +2 -2
- package/dist/types/src/components/Plank/PlankHeading.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/ComplementarySidebar.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/Sidebar.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/SidebarButton.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +1 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useDeckCompanions.d.ts +3 -3
- package/dist/types/src/hooks/useDeckCompanions.d.ts.map +1 -1
- package/dist/types/src/hooks/useDeckState.d.ts +17 -0
- package/dist/types/src/hooks/useDeckState.d.ts.map +1 -0
- package/dist/types/src/hooks/useHoistStatusbar.d.ts +1 -1
- package/dist/types/src/hooks/useHoistStatusbar.d.ts.map +1 -1
- package/dist/types/src/hooks/useNodeActionExpander.d.ts +1 -1
- package/dist/types/src/hooks/useNodeActionExpander.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +2 -3
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +2 -1
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/{capabilities → types}/capabilities.d.ts +96 -90
- package/dist/types/src/types/capabilities.d.ts.map +1 -0
- package/dist/types/src/types/events.d.ts +7 -0
- package/dist/types/src/types/events.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +2 -0
- package/dist/types/src/types/index.d.ts.map +1 -1
- package/dist/types/src/types/schema.d.ts +90 -30
- package/dist/types/src/types/schema.d.ts.map +1 -1
- package/dist/types/src/util/set-active.d.ts +18 -3
- package/dist/types/src/util/set-active.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +54 -48
- package/src/DeckPlugin.ts +44 -66
- package/src/capabilities/app-graph-builder/app-graph-builder.ts +118 -0
- package/src/capabilities/app-graph-builder/index.ts +7 -0
- package/src/capabilities/{check-app-scheme.ts → check-app-scheme/check-app-scheme.ts} +12 -11
- package/src/capabilities/check-app-scheme/index.ts +7 -0
- package/src/capabilities/index.ts +9 -14
- package/src/capabilities/operation-resolver/index.ts +10 -0
- package/src/capabilities/operation-resolver/operation-resolver.ts +555 -0
- package/src/capabilities/react-root/index.ts +7 -0
- package/src/capabilities/react-root/react-root.tsx +47 -0
- package/src/capabilities/react-surface/index.ts +7 -0
- package/src/capabilities/react-surface/react-surface.tsx +37 -0
- package/src/capabilities/settings/index.ts +7 -0
- package/src/capabilities/settings/settings.ts +38 -0
- package/src/capabilities/state/index.ts +7 -0
- package/src/capabilities/state/state.ts +104 -0
- package/src/capabilities/toolkit/index.ts +7 -0
- package/src/capabilities/toolkit/toolkit.ts +63 -0
- package/src/capabilities/tools/index.ts +7 -0
- package/src/capabilities/tools/tools.ts +92 -0
- package/src/capabilities/url-handler/index.ts +7 -0
- package/src/capabilities/url-handler/url-handler.ts +95 -0
- package/src/components/DeckLayout/ActiveNode.tsx +1 -1
- package/src/components/DeckLayout/Banner.tsx +5 -5
- package/src/components/DeckLayout/ContentEmpty.tsx +3 -4
- package/src/components/DeckLayout/DeckLayout.stories.tsx +51 -0
- package/src/components/DeckLayout/DeckLayout.tsx +17 -285
- package/src/components/DeckLayout/DeckMain.tsx +286 -0
- package/src/components/DeckLayout/Dialog.tsx +13 -10
- package/src/components/DeckLayout/Fallback.tsx +4 -4
- package/src/components/DeckLayout/Popover.tsx +44 -32
- package/src/components/DeckLayout/StatusBar.tsx +1 -1
- package/src/components/DeckLayout/Toast.tsx +30 -5
- package/src/components/DeckSettings/DeckSettings.tsx +26 -10
- package/src/components/Plank/Plank.stories.tsx +17 -11
- package/src/components/Plank/Plank.tsx +86 -54
- package/src/components/Plank/PlankControls.tsx +9 -9
- package/src/components/Plank/PlankError.tsx +4 -4
- package/src/components/Plank/PlankHeading.tsx +35 -40
- package/src/components/Sidebar/ComplementarySidebar.tsx +58 -31
- package/src/components/Sidebar/Sidebar.tsx +6 -6
- package/src/components/Sidebar/SidebarButton.tsx +39 -32
- package/src/components/fragments.ts +1 -1
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useCompanions.ts +1 -1
- package/src/hooks/useDeckCompanions.ts +6 -4
- package/src/hooks/useDeckState.ts +82 -0
- package/src/hooks/useHoistStatusbar.ts +4 -5
- package/src/hooks/useNodeActionExpander.ts +4 -4
- package/src/index.ts +1 -2
- package/src/meta.ts +8 -5
- package/src/translations.ts +2 -1
- package/src/types/capabilities.ts +33 -0
- package/src/types/events.ts +20 -0
- package/src/types/index.ts +2 -0
- package/src/types/schema.ts +86 -14
- package/src/util/layoutAppliesTopbar.ts +1 -1
- package/src/util/set-active.ts +49 -29
- package/dist/lib/browser/app-graph-builder-DD2EJBLZ.mjs +0 -152
- package/dist/lib/browser/app-graph-builder-DD2EJBLZ.mjs.map +0 -7
- package/dist/lib/browser/check-app-scheme-BKIOCWXT.mjs.map +0 -7
- package/dist/lib/browser/chunk-CNTGBCMK.mjs.map +0 -7
- package/dist/lib/browser/chunk-F5BQOOEG.mjs.map +0 -7
- package/dist/lib/browser/chunk-FMGWFTHR.mjs +0 -1498
- package/dist/lib/browser/chunk-FMGWFTHR.mjs.map +0 -7
- package/dist/lib/browser/chunk-KCXWTPSU.mjs +0 -127
- package/dist/lib/browser/chunk-KCXWTPSU.mjs.map +0 -7
- package/dist/lib/browser/chunk-M57WD3V6.mjs +0 -16
- package/dist/lib/browser/chunk-M57WD3V6.mjs.map +0 -7
- package/dist/lib/browser/chunk-NRCPV6AV.mjs +0 -129
- package/dist/lib/browser/chunk-NRCPV6AV.mjs.map +0 -7
- package/dist/lib/browser/chunk-Z5KITAZW.mjs +0 -13
- package/dist/lib/browser/chunk-Z5KITAZW.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-XSCCU7JI.mjs +0 -521
- package/dist/lib/browser/intent-resolver-XSCCU7JI.mjs.map +0 -7
- package/dist/lib/browser/react-root-E54PO26O.mjs +0 -43
- package/dist/lib/browser/react-root-E54PO26O.mjs.map +0 -7
- package/dist/lib/browser/react-surface-DIZC3J4P.mjs +0 -40
- package/dist/lib/browser/react-surface-DIZC3J4P.mjs.map +0 -7
- package/dist/lib/browser/settings-RNPLZT5S.mjs +0 -29
- package/dist/lib/browser/settings-RNPLZT5S.mjs.map +0 -7
- package/dist/lib/browser/state-CRXR7X63.mjs +0 -12
- package/dist/lib/browser/toolkit-HPFRHY67.mjs +0 -61
- package/dist/lib/browser/toolkit-HPFRHY67.mjs.map +0 -7
- package/dist/lib/browser/url-handler-6IJME37M.mjs +0 -70
- package/dist/lib/browser/url-handler-6IJME37M.mjs.map +0 -7
- package/dist/types/src/capabilities/app-graph-builder.d.ts +0 -4
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +0 -1
- package/dist/types/src/capabilities/capabilities.d.ts.map +0 -1
- package/dist/types/src/capabilities/check-app-scheme.d.ts +0 -4
- package/dist/types/src/capabilities/check-app-scheme.d.ts.map +0 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
- package/dist/types/src/capabilities/react-root.d.ts +0 -7
- package/dist/types/src/capabilities/react-root.d.ts.map +0 -1
- package/dist/types/src/capabilities/react-surface.d.ts +0 -4
- package/dist/types/src/capabilities/react-surface.d.ts.map +0 -1
- package/dist/types/src/capabilities/settings.d.ts +0 -4
- package/dist/types/src/capabilities/settings.d.ts.map +0 -1
- package/dist/types/src/capabilities/state.d.ts +0 -101
- package/dist/types/src/capabilities/state.d.ts.map +0 -1
- package/dist/types/src/capabilities/toolkit.d.ts +0 -5
- package/dist/types/src/capabilities/toolkit.d.ts.map +0 -1
- package/dist/types/src/capabilities/tools.d.ts +0 -11
- package/dist/types/src/capabilities/tools.d.ts.map +0 -1
- package/dist/types/src/capabilities/url-handler.d.ts +0 -4
- package/dist/types/src/capabilities/url-handler.d.ts.map +0 -1
- package/dist/types/src/events.d.ts +0 -4
- package/dist/types/src/events.d.ts.map +0 -1
- package/src/capabilities/app-graph-builder.ts +0 -142
- package/src/capabilities/capabilities.ts +0 -14
- package/src/capabilities/intent-resolver.ts +0 -469
- package/src/capabilities/react-root.tsx +0 -39
- package/src/capabilities/react-surface.tsx +0 -30
- package/src/capabilities/settings.ts +0 -26
- package/src/capabilities/state.ts +0 -105
- package/src/capabilities/toolkit.ts +0 -55
- package/src/capabilities/tools.ts +0 -84
- package/src/capabilities/url-handler.ts +0 -60
- package/src/events.ts +0 -11
- /package/dist/lib/{browser/state-CRXR7X63.mjs.map → node-esm/types/index.mjs.map} +0 -0
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { createContext } from '@radix-ui/react-context';
|
|
6
|
-
import React, { type PropsWithChildren, useCallback, useEffect,
|
|
6
|
+
import React, { type PropsWithChildren, useCallback, useEffect, useRef, useState } from 'react';
|
|
7
7
|
|
|
8
|
-
import { Surface
|
|
9
|
-
import { Popover, type PopoverContentInteractOutsideEvent } from '@dxos/react-ui';
|
|
8
|
+
import { Surface } from '@dxos/app-framework/react';
|
|
9
|
+
import { Popover, type PopoverContentInteractOutsideEvent, toLocalizedString, useTranslation } from '@dxos/react-ui';
|
|
10
|
+
import { Card } from '@dxos/react-ui-mosaic';
|
|
10
11
|
|
|
11
|
-
import {
|
|
12
|
+
import { useDeckState } from '../../hooks';
|
|
13
|
+
import { meta } from '../../meta';
|
|
12
14
|
|
|
13
15
|
export type DeckPopoverRootProps = PropsWithChildren<{}>;
|
|
14
16
|
|
|
@@ -21,32 +23,32 @@ type DeckPopoverContextValue = {
|
|
|
21
23
|
const [DeckPopoverProvider, useDeckPopoverContext] = createContext<DeckPopoverContextValue>('DeckPopover');
|
|
22
24
|
|
|
23
25
|
export const PopoverRoot = ({ children }: DeckPopoverRootProps) => {
|
|
24
|
-
const
|
|
26
|
+
const { state } = useDeckState();
|
|
25
27
|
const virtualRef = useRef<HTMLButtonElement | null>(null);
|
|
26
28
|
const [virtualIter, setVirtualIter] = useState(0);
|
|
27
29
|
const [open, setOpen] = useState(false);
|
|
28
30
|
const debounceRef = useRef<NodeJS.Timeout | null>(null);
|
|
29
31
|
|
|
30
32
|
// TODO(thure): This is a workaround for the race condition between displaying a Popover and either rendering
|
|
31
|
-
// the anchor further down the tree or measuring the virtual trigger
|
|
33
|
+
// the anchor further down the tree or measuring the virtual trigger's client rect.
|
|
32
34
|
useEffect(() => {
|
|
33
35
|
setOpen(false);
|
|
34
|
-
if (
|
|
36
|
+
if (state.popoverOpen) {
|
|
35
37
|
if (debounceRef.current) {
|
|
36
38
|
clearTimeout(debounceRef.current);
|
|
37
39
|
}
|
|
38
|
-
if (
|
|
39
|
-
virtualRef.current =
|
|
40
|
+
if (state.popoverAnchor && virtualRef.current !== state.popoverAnchor) {
|
|
41
|
+
virtualRef.current = state.popoverAnchor ?? null;
|
|
40
42
|
setVirtualIter((iter) => iter + 1);
|
|
41
43
|
}
|
|
42
44
|
debounceRef.current = setTimeout(() => setOpen(true), DEBOUNCE_DELAY);
|
|
43
45
|
}
|
|
44
|
-
}, [
|
|
46
|
+
}, [state.popoverOpen, state.popoverAnchorId, state.popoverAnchor, state.popoverContent]);
|
|
45
47
|
|
|
46
48
|
return (
|
|
47
49
|
<DeckPopoverProvider setOpen={setOpen}>
|
|
48
50
|
<Popover.Root modal={false} open={open}>
|
|
49
|
-
{
|
|
51
|
+
{state.popoverAnchor && <Popover.VirtualTrigger key={virtualIter} virtualRef={virtualRef} />}
|
|
50
52
|
{children}
|
|
51
53
|
</Popover.Root>
|
|
52
54
|
</DeckPopoverProvider>
|
|
@@ -54,10 +56,22 @@ export const PopoverRoot = ({ children }: DeckPopoverRootProps) => {
|
|
|
54
56
|
};
|
|
55
57
|
|
|
56
58
|
export const PopoverContent = () => {
|
|
57
|
-
const
|
|
59
|
+
const { t } = useTranslation(meta.id);
|
|
60
|
+
const { state, updateEphemeral } = useDeckState();
|
|
58
61
|
const { setOpen } = useDeckPopoverContext('PopoverContent');
|
|
59
62
|
|
|
60
|
-
const handleClose = useCallback(
|
|
63
|
+
const handleClose = useCallback(() => {
|
|
64
|
+
setOpen(false);
|
|
65
|
+
updateEphemeral((state) => ({
|
|
66
|
+
...state,
|
|
67
|
+
popoverOpen: false,
|
|
68
|
+
popoverAnchor: undefined,
|
|
69
|
+
popoverAnchorId: undefined,
|
|
70
|
+
popoverSide: undefined,
|
|
71
|
+
}));
|
|
72
|
+
}, [updateEphemeral]);
|
|
73
|
+
|
|
74
|
+
const handleInteractOutside = useCallback(
|
|
61
75
|
(event: KeyboardEvent | PopoverContentInteractOutsideEvent) => {
|
|
62
76
|
if (
|
|
63
77
|
// TODO(thure): CodeMirror should not focus itself when it updates.
|
|
@@ -66,36 +80,34 @@ export const PopoverContent = () => {
|
|
|
66
80
|
) {
|
|
67
81
|
event.preventDefault();
|
|
68
82
|
} else {
|
|
69
|
-
|
|
70
|
-
layout.popoverOpen = false;
|
|
71
|
-
layout.popoverAnchor = undefined;
|
|
72
|
-
layout.popoverAnchorId = undefined;
|
|
73
|
-
layout.popoverSide = undefined;
|
|
83
|
+
handleClose();
|
|
74
84
|
}
|
|
75
85
|
},
|
|
76
|
-
[
|
|
86
|
+
[handleClose],
|
|
77
87
|
);
|
|
78
88
|
|
|
79
|
-
const collisionBoundaries: HTMLElement[] = useMemo(() => {
|
|
80
|
-
const closest = layout.popoverAnchor?.closest('[data-popover-collision-boundary]') as
|
|
81
|
-
| HTMLElement
|
|
82
|
-
| null
|
|
83
|
-
| undefined;
|
|
84
|
-
return closest ? [closest] : [];
|
|
85
|
-
}, [layout.popoverAnchor]);
|
|
86
|
-
|
|
87
89
|
return (
|
|
88
90
|
<Popover.Portal>
|
|
89
91
|
<Popover.Content
|
|
90
|
-
side={
|
|
91
|
-
onInteractOutside={handleClose}
|
|
92
|
-
onEscapeKeyDown={handleClose}
|
|
93
|
-
collisionBoundary={collisionBoundaries}
|
|
92
|
+
side={state.popoverSide}
|
|
94
93
|
sticky='always'
|
|
95
94
|
hideWhenDetached
|
|
95
|
+
onInteractOutside={handleInteractOutside}
|
|
96
|
+
onEscapeKeyDown={handleInteractOutside}
|
|
96
97
|
>
|
|
97
98
|
<Popover.Viewport>
|
|
98
|
-
|
|
99
|
+
{state.popoverKind === 'card' && (
|
|
100
|
+
<Card.Root>
|
|
101
|
+
<Card.Toolbar>
|
|
102
|
+
{/* TODO(wittjosiah): Cleaner way to handle no drag handle in toolbar? */}
|
|
103
|
+
<span />
|
|
104
|
+
{state.popoverTitle ? <Card.Title>{toLocalizedString(state.popoverTitle, t)}</Card.Title> : <span />}
|
|
105
|
+
<Card.Close onClick={handleClose} />
|
|
106
|
+
</Card.Toolbar>
|
|
107
|
+
<Surface role='card--content' data={state.popoverContent} limit={1} />
|
|
108
|
+
</Card.Root>
|
|
109
|
+
)}
|
|
110
|
+
{state.popoverKind === 'base' && <Surface role='popover' data={state.popoverContent} limit={1} />}
|
|
99
111
|
</Popover.Viewport>
|
|
100
112
|
<Popover.Arrow />
|
|
101
113
|
</Popover.Content>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import React from 'react';
|
|
6
6
|
|
|
7
|
-
import { type
|
|
7
|
+
import { type Common } from '@dxos/app-framework';
|
|
8
8
|
import {
|
|
9
9
|
Button,
|
|
10
10
|
Icon,
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
useTranslation,
|
|
15
15
|
} from '@dxos/react-ui';
|
|
16
16
|
|
|
17
|
-
import {
|
|
17
|
+
import { meta } from '../../meta';
|
|
18
18
|
|
|
19
19
|
// TODO(wittjosiah): Render remaining duration as a progress bar within the toast.
|
|
20
20
|
export const Toast = ({
|
|
@@ -28,14 +28,14 @@ export const Toast = ({
|
|
|
28
28
|
closeLabel,
|
|
29
29
|
onAction,
|
|
30
30
|
onOpenChange,
|
|
31
|
-
}:
|
|
32
|
-
const { t } = useTranslation(
|
|
31
|
+
}: Common.LayoutOperation.Toast & Pick<ToastRootProps, 'onOpenChange'>) => {
|
|
32
|
+
const { t } = useTranslation(meta.id);
|
|
33
33
|
|
|
34
34
|
return (
|
|
35
35
|
<NaturalToast.Root data-testid={id} defaultOpen duration={duration} onOpenChange={onOpenChange}>
|
|
36
36
|
<NaturalToast.Body>
|
|
37
37
|
<NaturalToast.Title classNames='items-center'>
|
|
38
|
-
{icon && <Icon icon={icon}
|
|
38
|
+
{icon && <Icon icon={icon} classNames='inline mr-1' />}
|
|
39
39
|
{title && <span>{toLocalizedString(title, t)}</span>}
|
|
40
40
|
</NaturalToast.Title>
|
|
41
41
|
{description && (
|
|
@@ -59,3 +59,28 @@ export const Toast = ({
|
|
|
59
59
|
</NaturalToast.Root>
|
|
60
60
|
);
|
|
61
61
|
};
|
|
62
|
+
|
|
63
|
+
export type ToasterProps = {
|
|
64
|
+
toasts?: Common.LayoutOperation.Toast[];
|
|
65
|
+
onDismissToast?: (id: string) => void;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const Toaster = ({ toasts, onDismissToast }: ToasterProps) => {
|
|
69
|
+
return (
|
|
70
|
+
<>
|
|
71
|
+
{toasts?.map((toast) => (
|
|
72
|
+
<Toast
|
|
73
|
+
{...toast}
|
|
74
|
+
key={toast.id}
|
|
75
|
+
onOpenChange={(open: boolean) => {
|
|
76
|
+
if (!open) {
|
|
77
|
+
onDismissToast?.(toast.id);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return open;
|
|
81
|
+
}}
|
|
82
|
+
/>
|
|
83
|
+
))}
|
|
84
|
+
</>
|
|
85
|
+
);
|
|
86
|
+
};
|
|
@@ -7,7 +7,7 @@ import React from 'react';
|
|
|
7
7
|
import { Input, Select, useTranslation } from '@dxos/react-ui';
|
|
8
8
|
import { ControlGroup, ControlItemInput, ControlPage, ControlSection } from '@dxos/react-ui-form';
|
|
9
9
|
|
|
10
|
-
import {
|
|
10
|
+
import { meta } from '../../meta';
|
|
11
11
|
import {
|
|
12
12
|
type DeckSettingsProps,
|
|
13
13
|
type NewPlankPositioning,
|
|
@@ -18,24 +18,37 @@ import {
|
|
|
18
18
|
|
|
19
19
|
const isSocket = !!(globalThis as any).__args;
|
|
20
20
|
|
|
21
|
-
export
|
|
22
|
-
|
|
21
|
+
export type DeckSettingsComponentProps = {
|
|
22
|
+
settings: DeckSettingsProps;
|
|
23
|
+
onSettingsChange: (fn: (current: DeckSettingsProps) => DeckSettingsProps) => void;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const DeckSettings = ({ settings, onSettingsChange }: DeckSettingsComponentProps) => {
|
|
27
|
+
const { t } = useTranslation(meta.id);
|
|
23
28
|
|
|
24
29
|
return (
|
|
25
30
|
<ControlPage>
|
|
26
|
-
<ControlSection title={t('settings title', { ns:
|
|
31
|
+
<ControlSection title={t('settings title', { ns: meta.id })}>
|
|
27
32
|
<ControlGroup>
|
|
28
33
|
<ControlItemInput title={t('settings enable deck label')}>
|
|
29
34
|
<Input.Switch
|
|
30
35
|
checked={settings.enableDeck}
|
|
31
|
-
onCheckedChange={(checked) => (
|
|
36
|
+
onCheckedChange={(checked) => onSettingsChange((s) => ({ ...s, enableDeck: checked }))}
|
|
37
|
+
/>
|
|
38
|
+
</ControlItemInput>
|
|
39
|
+
<ControlItemInput title={t('settings encapsulated planks label')}>
|
|
40
|
+
<Input.Switch
|
|
41
|
+
checked={settings.encapsulatedPlanks ?? false}
|
|
42
|
+
onCheckedChange={(checked) => onSettingsChange((s) => ({ ...s, encapsulatedPlanks: checked }))}
|
|
32
43
|
/>
|
|
33
44
|
</ControlItemInput>
|
|
34
45
|
<ControlItemInput title={t('select new plank positioning label')}>
|
|
35
46
|
<Select.Root
|
|
36
47
|
disabled={!settings.enableDeck}
|
|
37
48
|
value={settings.newPlankPositioning ?? 'start'}
|
|
38
|
-
onValueChange={(value) =>
|
|
49
|
+
onValueChange={(value) =>
|
|
50
|
+
onSettingsChange((s) => ({ ...s, newPlankPositioning: value as NewPlankPositioning }))
|
|
51
|
+
}
|
|
39
52
|
>
|
|
40
53
|
<Select.TriggerButton placeholder={t('select new plank positioning placeholder')} />
|
|
41
54
|
<Select.Portal>
|
|
@@ -56,7 +69,7 @@ export const DeckSettings = ({ settings }: { settings: DeckSettingsProps }) => {
|
|
|
56
69
|
<Select.Root
|
|
57
70
|
disabled={!settings.enableDeck}
|
|
58
71
|
value={settings.overscroll ?? 'none'}
|
|
59
|
-
onValueChange={(value) => (
|
|
72
|
+
onValueChange={(value) => onSettingsChange((s) => ({ ...s, overscroll: value as Overscroll }))}
|
|
60
73
|
>
|
|
61
74
|
<Select.TriggerButton placeholder={t('select overscroll placeholder')} />
|
|
62
75
|
<Select.Portal>
|
|
@@ -76,17 +89,20 @@ export const DeckSettings = ({ settings }: { settings: DeckSettingsProps }) => {
|
|
|
76
89
|
<ControlItemInput title={t('settings enable statusbar label')}>
|
|
77
90
|
<Input.Switch
|
|
78
91
|
checked={settings.enableStatusbar}
|
|
79
|
-
onCheckedChange={(checked) => (
|
|
92
|
+
onCheckedChange={(checked) => onSettingsChange((s) => ({ ...s, enableStatusbar: checked }))}
|
|
80
93
|
/>
|
|
81
94
|
</ControlItemInput>
|
|
82
95
|
<ControlItemInput title={t('settings show hints label')}>
|
|
83
|
-
<Input.Switch
|
|
96
|
+
<Input.Switch
|
|
97
|
+
checked={settings.showHints}
|
|
98
|
+
onCheckedChange={(checked) => onSettingsChange((s) => ({ ...s, showHints: checked }))}
|
|
99
|
+
/>
|
|
84
100
|
</ControlItemInput>
|
|
85
101
|
{!isSocket && (
|
|
86
102
|
<ControlItemInput title={t('settings native redirect label')}>
|
|
87
103
|
<Input.Switch
|
|
88
104
|
checked={settings.enableNativeRedirect}
|
|
89
|
-
onCheckedChange={(checked) => (
|
|
105
|
+
onCheckedChange={(checked) => onSettingsChange((s) => ({ ...s, enableNativeRedirect: checked }))}
|
|
90
106
|
/>
|
|
91
107
|
</ControlItemInput>
|
|
92
108
|
)}
|
|
@@ -2,23 +2,30 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@dxos-theme';
|
|
6
|
-
|
|
7
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
8
6
|
import React from 'react';
|
|
9
7
|
|
|
10
|
-
import {
|
|
8
|
+
import { Capability, Common, Plugin } from '@dxos/app-framework';
|
|
11
9
|
import { withPluginManager } from '@dxos/app-framework/testing';
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
10
|
+
import { corePlugins } from '@dxos/plugin-testing';
|
|
11
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
14
12
|
import { Stack } from '@dxos/react-ui-stack';
|
|
15
|
-
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
16
13
|
|
|
17
|
-
import {
|
|
14
|
+
import { DeckState } from '../../capabilities';
|
|
15
|
+
import { meta as pluginMeta } from '../../meta';
|
|
18
16
|
import { translations } from '../../translations';
|
|
19
17
|
|
|
20
18
|
import { Plank } from './Plank';
|
|
21
19
|
|
|
20
|
+
const TestPlugin = Plugin.define(pluginMeta).pipe(
|
|
21
|
+
Plugin.addModule({
|
|
22
|
+
id: Capability.getModuleTag(DeckState),
|
|
23
|
+
activatesOn: Common.ActivationEvent.AppGraphReady,
|
|
24
|
+
activate: () => DeckState(),
|
|
25
|
+
}),
|
|
26
|
+
Plugin.make,
|
|
27
|
+
);
|
|
28
|
+
|
|
22
29
|
const meta = {
|
|
23
30
|
title: 'plugins/plugin-deck/Plank',
|
|
24
31
|
component: Plank,
|
|
@@ -30,14 +37,13 @@ const meta = {
|
|
|
30
37
|
);
|
|
31
38
|
},
|
|
32
39
|
decorators: [
|
|
40
|
+
withTheme,
|
|
33
41
|
withPluginManager({
|
|
34
|
-
plugins: [
|
|
35
|
-
capabilities: () => DeckStateFactory(),
|
|
42
|
+
plugins: [...corePlugins(), TestPlugin()],
|
|
36
43
|
}),
|
|
37
|
-
withTheme,
|
|
38
|
-
withLayout({ fullscreen: true }),
|
|
39
44
|
],
|
|
40
45
|
parameters: {
|
|
46
|
+
layout: 'fullscreen',
|
|
41
47
|
translations,
|
|
42
48
|
},
|
|
43
49
|
} satisfies Meta<typeof Plank>;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { useFocusFinders } from '@fluentui/react-tabster';
|
|
5
6
|
import React, {
|
|
6
7
|
type KeyboardEvent,
|
|
7
8
|
type PropsWithChildren,
|
|
@@ -12,24 +13,17 @@ import React, {
|
|
|
12
13
|
useRef,
|
|
13
14
|
} from 'react';
|
|
14
15
|
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
Surface,
|
|
18
|
-
createIntent,
|
|
19
|
-
useAppGraph,
|
|
20
|
-
useCapability,
|
|
21
|
-
useIntentDispatcher,
|
|
22
|
-
} from '@dxos/app-framework';
|
|
16
|
+
import { Common } from '@dxos/app-framework';
|
|
17
|
+
import { Surface, useAppGraph, useOperationInvoker } from '@dxos/app-framework/react';
|
|
23
18
|
import { debounce } from '@dxos/async';
|
|
24
19
|
import { type Node, useNode } from '@dxos/plugin-graph';
|
|
25
20
|
import { ATTENDABLE_PATH_SEPARATOR, useAttentionAttributes } from '@dxos/react-ui-attention';
|
|
26
21
|
import { StackItem, railGridHorizontal } from '@dxos/react-ui-stack';
|
|
27
|
-
import { mainIntrinsicSize, mx } from '@dxos/
|
|
22
|
+
import { mainIntrinsicSize, mx } from '@dxos/ui-theme';
|
|
28
23
|
|
|
29
|
-
import {
|
|
30
|
-
import { useCompanions, useMainSize } from '../../hooks';
|
|
24
|
+
import { useCompanions, useDeckState, useMainSize } from '../../hooks';
|
|
31
25
|
import { parseEntryId } from '../../layout';
|
|
32
|
-
import {
|
|
26
|
+
import { DeckOperation, type DeckSettingsProps, type LayoutMode, type ResolvedPart } from '../../types';
|
|
33
27
|
|
|
34
28
|
import { PlankContentError, PlankError } from './PlankError';
|
|
35
29
|
import { PlankHeading } from './PlankHeading';
|
|
@@ -37,6 +31,10 @@ import { PlankLoading } from './PlankLoading';
|
|
|
37
31
|
|
|
38
32
|
const UNKNOWN_ID = 'unknown_id';
|
|
39
33
|
|
|
34
|
+
//
|
|
35
|
+
// Plank
|
|
36
|
+
//
|
|
37
|
+
|
|
40
38
|
export type PlankProps = Pick<PlankComponentProps, 'layoutMode' | 'part' | 'path' | 'order' | 'active' | 'settings'> & {
|
|
41
39
|
id?: string;
|
|
42
40
|
companionId?: string;
|
|
@@ -50,10 +48,10 @@ export type PlankProps = Pick<PlankComponentProps, 'layoutMode' | 'part' | 'path
|
|
|
50
48
|
// benefits. I think where we anticipate users will definitely want to quickly switch between showing and hiding entire
|
|
51
49
|
// articles, over the (again probably large) performance benefit that unmounting them would confer, we can mount and
|
|
52
50
|
// hide them, but I think that scenario in its most unambiguous form is probably rare. You could extrapolate
|
|
53
|
-
// the scenario to include all
|
|
54
|
-
// don
|
|
51
|
+
// the scenario to include all "potential" planks such as companions, which we could keep mounted and hidden, but I
|
|
52
|
+
// don't think the resulting performance would be acceptable. I think the real issue is "perceived performance" which
|
|
55
53
|
// has mitigations that are in between mounting and un-mounting since both of those have tradeoffs; we may need one or more
|
|
56
|
-
//
|
|
54
|
+
// "partially-mounted" experiences, like loading skeletons at the simple end, or screenshots of "sleeping" planks at
|
|
57
55
|
// the advanced end.
|
|
58
56
|
|
|
59
57
|
/**
|
|
@@ -68,7 +66,11 @@ export const Plank = memo(({ id = UNKNOWN_ID, companionId, ...props }: PlankProp
|
|
|
68
66
|
const hasCompanion = !!(companionId && currentCompanion);
|
|
69
67
|
|
|
70
68
|
return (
|
|
71
|
-
<PlankContainer
|
|
69
|
+
<PlankContainer
|
|
70
|
+
solo={props.part === 'solo'}
|
|
71
|
+
companion={hasCompanion}
|
|
72
|
+
encapsulate={!!props.settings?.encapsulatedPlanks}
|
|
73
|
+
>
|
|
72
74
|
<PlankComponent
|
|
73
75
|
id={id}
|
|
74
76
|
node={node}
|
|
@@ -92,7 +94,13 @@ export const Plank = memo(({ id = UNKNOWN_ID, companionId, ...props }: PlankProp
|
|
|
92
94
|
);
|
|
93
95
|
});
|
|
94
96
|
|
|
95
|
-
|
|
97
|
+
//
|
|
98
|
+
// PlankContainer
|
|
99
|
+
//
|
|
100
|
+
|
|
101
|
+
type PlankContainerProps = PropsWithChildren<{ solo: boolean; companion: boolean; encapsulate: boolean }>;
|
|
102
|
+
|
|
103
|
+
const PlankContainer = ({ children, solo, companion, encapsulate }: PlankContainerProps) => {
|
|
96
104
|
const sizeAttrs = useMainSize();
|
|
97
105
|
if (!solo) {
|
|
98
106
|
return children;
|
|
@@ -102,7 +110,14 @@ const PlankContainer = ({ children, solo, companion }: PropsWithChildren<{ solo:
|
|
|
102
110
|
return (
|
|
103
111
|
<div
|
|
104
112
|
role='none'
|
|
105
|
-
|
|
113
|
+
data-popover-collision-boundary={true}
|
|
114
|
+
className={mx(
|
|
115
|
+
'absolute inset-[--main-spacing] grid',
|
|
116
|
+
encapsulate && 'border border-separator rounded overflow-hidden',
|
|
117
|
+
companion && 'grid-cols-[6fr_4fr]', // TODO(burdon): Resize.
|
|
118
|
+
railGridHorizontal,
|
|
119
|
+
mainIntrinsicSize,
|
|
120
|
+
)}
|
|
106
121
|
{...sizeAttrs}
|
|
107
122
|
>
|
|
108
123
|
{children}
|
|
@@ -110,6 +125,10 @@ const PlankContainer = ({ children, solo, companion }: PropsWithChildren<{ solo:
|
|
|
110
125
|
);
|
|
111
126
|
};
|
|
112
127
|
|
|
128
|
+
//
|
|
129
|
+
// PlankComponent
|
|
130
|
+
//
|
|
131
|
+
|
|
113
132
|
type PlankComponentProps = {
|
|
114
133
|
layoutMode: LayoutMode;
|
|
115
134
|
id: string;
|
|
@@ -117,11 +136,10 @@ type PlankComponentProps = {
|
|
|
117
136
|
path?: string[];
|
|
118
137
|
order?: number;
|
|
119
138
|
active?: string[];
|
|
120
|
-
// TODO(burdon): Change to role?
|
|
121
139
|
companioned?: 'primary' | 'companion';
|
|
122
|
-
node?: Node;
|
|
123
|
-
primary?: Node;
|
|
124
|
-
companions?: Node[];
|
|
140
|
+
node?: Node.Node;
|
|
141
|
+
primary?: Node.Node;
|
|
142
|
+
companions?: Node.Node[];
|
|
125
143
|
settings?: DeckSettingsProps;
|
|
126
144
|
};
|
|
127
145
|
|
|
@@ -139,8 +157,10 @@ const PlankComponent = memo(
|
|
|
139
157
|
companions,
|
|
140
158
|
settings,
|
|
141
159
|
}: PlankComponentProps) => {
|
|
142
|
-
const {
|
|
143
|
-
const {
|
|
160
|
+
const { invokePromise } = useOperationInvoker();
|
|
161
|
+
const { state, deck } = useDeckState();
|
|
162
|
+
const { popoverAnchorId, scrollIntoView } = state;
|
|
163
|
+
const { findFirstFocusable } = useFocusFinders();
|
|
144
164
|
const canResize = layoutMode === 'deck';
|
|
145
165
|
|
|
146
166
|
const attentionAttrs = useAttentionAttributes(primary?.id ?? id);
|
|
@@ -157,29 +177,32 @@ const PlankComponent = memo(
|
|
|
157
177
|
|
|
158
178
|
const handleSizeChange = useCallback(
|
|
159
179
|
debounce((nextSize: number) => {
|
|
160
|
-
return
|
|
180
|
+
return invokePromise(DeckOperation.UpdatePlankSize, { id: sizeKey, size: nextSize });
|
|
161
181
|
}, 200),
|
|
162
|
-
[
|
|
182
|
+
[invokePromise, sizeKey],
|
|
163
183
|
);
|
|
164
184
|
|
|
165
|
-
// TODO(thure): Tabster
|
|
185
|
+
// TODO(thure): Tabster's focus group should handle moving focus to Main, but something is blocking it.
|
|
166
186
|
const handleKeyDown = useCallback((event: KeyboardEvent) => {
|
|
167
|
-
if (event.target === event.currentTarget
|
|
168
|
-
|
|
187
|
+
if (event.target === event.currentTarget) {
|
|
188
|
+
switch (event.key) {
|
|
189
|
+
case 'Escape':
|
|
190
|
+
rootElement.current?.closest('main')?.focus();
|
|
191
|
+
break;
|
|
192
|
+
case 'Enter':
|
|
193
|
+
rootElement.current && findFirstFocusable(rootElement.current)?.focus();
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
169
196
|
}
|
|
170
197
|
}, []);
|
|
171
198
|
|
|
172
199
|
useLayoutEffect(() => {
|
|
173
200
|
if (scrollIntoView === id) {
|
|
174
|
-
|
|
175
|
-
// Forcing focus to something smaller than the plank prevents large focus ring in the interim.
|
|
176
|
-
const focusable = rootElement.current?.querySelector('button') || rootElement.current;
|
|
177
|
-
focusable?.focus({ preventScroll: true });
|
|
178
|
-
layoutMode === 'deck' && focusable?.scrollIntoView({ behavior: 'smooth', inline: 'center' });
|
|
201
|
+
layoutMode === 'deck' && rootElement.current?.scrollIntoView({ behavior: 'smooth', inline: 'center' });
|
|
179
202
|
// Clear the scroll into view state once it has been actioned.
|
|
180
|
-
void
|
|
203
|
+
void invokePromise(Common.LayoutOperation.ScrollIntoView, { subject: undefined });
|
|
181
204
|
}
|
|
182
|
-
}, [id, scrollIntoView, layoutMode]);
|
|
205
|
+
}, [id, scrollIntoView, layoutMode, invokePromise]);
|
|
183
206
|
|
|
184
207
|
const isSolo = layoutMode.startsWith('solo') && part === 'solo';
|
|
185
208
|
const isAttendable =
|
|
@@ -190,34 +213,42 @@ const PlankComponent = memo(
|
|
|
190
213
|
const data = useMemo(
|
|
191
214
|
() =>
|
|
192
215
|
node && {
|
|
216
|
+
attendableId: id,
|
|
193
217
|
subject: node.data,
|
|
194
218
|
companionTo: primary?.data,
|
|
219
|
+
properties: node.properties,
|
|
195
220
|
variant,
|
|
196
221
|
path,
|
|
197
222
|
popoverAnchorId,
|
|
198
223
|
},
|
|
199
|
-
[node, node?.data, path, popoverAnchorId, primary?.data, variant],
|
|
224
|
+
[node, node?.data, node?.properties, path, popoverAnchorId, primary?.data, variant],
|
|
200
225
|
);
|
|
201
226
|
|
|
202
227
|
// TODO(wittjosiah): Change prop to accept a component.
|
|
203
228
|
const placeholder = useMemo(() => <PlankLoading />, []);
|
|
204
229
|
|
|
205
230
|
const Root = part.startsWith('solo') ? 'article' : StackItem.Root;
|
|
231
|
+
const fullscreen = layoutMode === 'solo--fullscreen';
|
|
206
232
|
const className = mx(
|
|
207
233
|
'attention-surface relative dx-focus-ring-inset-over-all density-coarse',
|
|
208
|
-
isSolo && mainIntrinsicSize,
|
|
209
|
-
isSolo && railGridHorizontal,
|
|
210
234
|
isSolo && 'absolute inset-0',
|
|
235
|
+
isSolo && mainIntrinsicSize,
|
|
236
|
+
railGridHorizontal,
|
|
211
237
|
part.startsWith('solo') && 'grid',
|
|
238
|
+
part.startsWith('solo-') && 'grid-rows-subgrid row-span-2 min-is-0',
|
|
239
|
+
fullscreen && 'grid-rows-1',
|
|
212
240
|
part === 'deck' && (companioned === 'companion' ? '!border-separator border-ie' : '!border-separator border-li'),
|
|
213
|
-
part.startsWith('solo-') && 'row-span-2 grid-rows-subgrid min-is-0',
|
|
214
241
|
part === 'solo-companion' && '!border-separator border-is',
|
|
242
|
+
settings?.encapsulatedPlanks &&
|
|
243
|
+
!part.startsWith('solo') &&
|
|
244
|
+
'mli-[--main-spacing] !border-separator border rounded overflow-hidden',
|
|
215
245
|
);
|
|
216
246
|
|
|
217
247
|
return (
|
|
218
248
|
<Root
|
|
219
249
|
ref={rootElement}
|
|
220
250
|
data-testid='deck.plank'
|
|
251
|
+
data-popover-collision-boundary={true}
|
|
221
252
|
tabIndex={0}
|
|
222
253
|
{...(part.startsWith('solo')
|
|
223
254
|
? ({ ...sizeAttrs, className } as any)
|
|
@@ -234,19 +265,21 @@ const PlankComponent = memo(
|
|
|
234
265
|
>
|
|
235
266
|
{node ? (
|
|
236
267
|
<>
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
268
|
+
{!fullscreen && (
|
|
269
|
+
<PlankHeading
|
|
270
|
+
id={id}
|
|
271
|
+
part={part.startsWith('solo-') ? 'solo' : part}
|
|
272
|
+
node={node}
|
|
273
|
+
layoutMode={layoutMode}
|
|
274
|
+
deckEnabled={settings?.enableDeck}
|
|
275
|
+
canIncrementStart={canIncrementStart}
|
|
276
|
+
canIncrementEnd={canIncrementEnd}
|
|
277
|
+
popoverAnchorId={popoverAnchorId}
|
|
278
|
+
primaryId={primary?.id}
|
|
279
|
+
companioned={companioned}
|
|
280
|
+
companions={companions}
|
|
281
|
+
/>
|
|
282
|
+
)}
|
|
250
283
|
<Surface
|
|
251
284
|
key={node.id}
|
|
252
285
|
role='article'
|
|
@@ -259,7 +292,6 @@ const PlankComponent = memo(
|
|
|
259
292
|
) : (
|
|
260
293
|
<PlankError id={id} part={part} />
|
|
261
294
|
)}
|
|
262
|
-
|
|
263
295
|
{canResize && <StackItem.ResizeHandle />}
|
|
264
296
|
</Root>
|
|
265
297
|
);
|