forgebook 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -6
- package/dist/bin/forgebook/agentClient.d.ts +17 -0
- package/dist/bin/forgebook/agentClient.d.ts.map +1 -1
- package/dist/bin/forgebook/agentClient.js +21 -0
- package/dist/bin/forgebook/agentClient.js.map +1 -1
- package/dist/bin/forgebook/agentLoopCommands.d.mts +9 -0
- package/dist/bin/forgebook/agentLoopCommands.d.mts.map +1 -0
- package/dist/bin/forgebook/agentLoopCommands.mjs +217 -0
- package/dist/bin/forgebook/agentLoopCommands.mjs.map +1 -0
- package/dist/bin/forgebook/agentText.d.ts +37 -1
- package/dist/bin/forgebook/agentText.d.ts.map +1 -1
- package/dist/bin/forgebook/agentText.js +49 -2
- package/dist/bin/forgebook/agentText.js.map +1 -1
- package/dist/bin/forgebook/agents.md +46 -0
- package/dist/bin/forgebook/agentsText.d.ts +29 -0
- package/dist/bin/forgebook/agentsText.d.ts.map +1 -0
- package/dist/bin/forgebook/agentsText.js +48 -0
- package/dist/bin/forgebook/agentsText.js.map +1 -0
- package/dist/bin/forgebook/catalogueCommands.d.ts +51 -0
- package/dist/bin/forgebook/catalogueCommands.d.ts.map +1 -0
- package/dist/bin/forgebook/catalogueCommands.js +90 -0
- package/dist/bin/forgebook/catalogueCommands.js.map +1 -0
- package/dist/bin/forgebook/errorsRun.d.ts +27 -0
- package/dist/bin/forgebook/errorsRun.d.ts.map +1 -0
- package/dist/bin/forgebook/errorsRun.js +60 -0
- package/dist/bin/forgebook/errorsRun.js.map +1 -0
- package/dist/bin/forgebook/forgebook.mjs +109 -84
- package/dist/bin/forgebook/forgebook.mjs.map +1 -1
- package/dist/bin/forgebook/importers/storybook.d.ts +53 -0
- package/dist/bin/forgebook/importers/storybook.d.ts.map +1 -0
- package/dist/bin/forgebook/importers/storybook.js +318 -0
- package/dist/bin/forgebook/importers/storybook.js.map +1 -0
- package/dist/bin/forgebook/initCommands.d.mts +9 -0
- package/dist/bin/forgebook/initCommands.d.mts.map +1 -0
- package/dist/bin/forgebook/initCommands.mjs +86 -0
- package/dist/bin/forgebook/initCommands.mjs.map +1 -0
- package/dist/bin/forgebook/initConfig.d.ts +22 -0
- package/dist/bin/forgebook/initConfig.d.ts.map +1 -0
- package/dist/bin/forgebook/initConfig.js +51 -0
- package/dist/bin/forgebook/initConfig.js.map +1 -0
- package/dist/bin/forgebook/mcpTools.d.ts +29 -3
- package/dist/bin/forgebook/mcpTools.d.ts.map +1 -1
- package/dist/bin/forgebook/mcpTools.js +130 -7
- package/dist/bin/forgebook/mcpTools.js.map +1 -1
- package/dist/bin/forgebook/newStories.d.ts +27 -0
- package/dist/bin/forgebook/newStories.d.ts.map +1 -0
- package/dist/bin/forgebook/newStories.js +109 -0
- package/dist/bin/forgebook/newStories.js.map +1 -0
- package/dist/bin/forgebook/newStoriesFile.d.ts +18 -0
- package/dist/bin/forgebook/newStoriesFile.d.ts.map +1 -0
- package/dist/bin/forgebook/newStoriesFile.js +58 -0
- package/dist/bin/forgebook/newStoriesFile.js.map +1 -0
- package/dist/bin/forgebook/storyCheckRun.d.ts +39 -0
- package/dist/bin/forgebook/storyCheckRun.d.ts.map +1 -0
- package/dist/bin/forgebook/storyCheckRun.js +177 -0
- package/dist/bin/forgebook/storyCheckRun.js.map +1 -0
- package/dist/bin/forgebook-docs/catalogueDocs.d.ts +24 -0
- package/dist/bin/forgebook-docs/catalogueDocs.d.ts.map +1 -0
- package/dist/bin/forgebook-docs/catalogueDocs.js +71 -0
- package/dist/bin/forgebook-docs/catalogueDocs.js.map +1 -0
- package/dist/bin/forgebook-docs/catalogueDocs.types.d.ts +8 -0
- package/dist/bin/forgebook-docs/catalogueDocs.types.d.ts.map +1 -1
- package/dist/bin/forgebook-docs/catalogueMarkdown.d.ts +3 -1
- package/dist/bin/forgebook-docs/catalogueMarkdown.d.ts.map +1 -1
- package/dist/bin/forgebook-docs/catalogueMarkdown.js +62 -42
- package/dist/bin/forgebook-docs/catalogueMarkdown.js.map +1 -1
- package/dist/bin/forgebook-docs/catalogueOptions.d.ts +39 -0
- package/dist/bin/forgebook-docs/catalogueOptions.d.ts.map +1 -0
- package/dist/bin/forgebook-docs/catalogueOptions.js +76 -0
- package/dist/bin/forgebook-docs/catalogueOptions.js.map +1 -0
- package/dist/bin/forgebook-docs/collectDocs.d.ts +3 -1
- package/dist/bin/forgebook-docs/collectDocs.d.ts.map +1 -1
- package/dist/bin/forgebook-docs/collectDocs.js +37 -13
- package/dist/bin/forgebook-docs/collectDocs.js.map +1 -1
- package/dist/bin/forgebook-docs/forgebook-docs.mjs +17 -80
- package/dist/bin/forgebook-docs/forgebook-docs.mjs.map +1 -1
- package/dist/bin/forgebook-docs/llmsText.d.ts +24 -0
- package/dist/bin/forgebook-docs/llmsText.d.ts.map +1 -0
- package/dist/bin/forgebook-docs/llmsText.js +33 -0
- package/dist/bin/forgebook-docs/llmsText.js.map +1 -0
- package/dist/bin/forgebook-docs/sourceId.d.ts +9 -0
- package/dist/bin/forgebook-docs/sourceId.d.ts.map +1 -0
- package/dist/bin/forgebook-docs/sourceId.js +45 -0
- package/dist/bin/forgebook-docs/sourceId.js.map +1 -0
- package/dist/bin/frameworkDocs.d.ts +10 -0
- package/dist/bin/frameworkDocs.d.ts.map +1 -0
- package/dist/bin/frameworkDocs.js +43 -0
- package/dist/bin/frameworkDocs.js.map +1 -0
- package/dist/src/argTypes.d.ts +23 -0
- package/dist/src/argTypes.d.ts.map +1 -1
- package/dist/src/argTypes.js +27 -0
- package/dist/src/argTypes.js.map +1 -1
- package/dist/src/catalogue.d.ts +70 -3
- package/dist/src/catalogue.d.ts.map +1 -1
- package/dist/src/catalogue.js +85 -3
- package/dist/src/catalogue.js.map +1 -1
- package/dist/src/controlKeys.d.ts +85 -0
- package/dist/src/controlKeys.d.ts.map +1 -0
- package/dist/src/controlKeys.js +118 -0
- package/dist/src/controlKeys.js.map +1 -0
- package/dist/src/frame/frame.css +33 -2
- package/dist/src/frame/frameView.d.ts +2 -2
- package/dist/src/frame/frameView.d.ts.map +1 -1
- package/dist/src/frame/frameView.js +7 -3
- package/dist/src/frame/frameView.js.map +1 -1
- package/dist/src/frame/mountFrame.d.ts.map +1 -1
- package/dist/src/frame/mountFrame.js +26 -2
- package/dist/src/frame/mountFrame.js.map +1 -1
- package/dist/src/frame/spillOutline.d.ts +10 -0
- package/dist/src/frame/spillOutline.d.ts.map +1 -0
- package/dist/src/frame/spillOutline.js +80 -0
- package/dist/src/frame/spillOutline.js.map +1 -0
- package/dist/src/liveErrors.d.ts +57 -0
- package/dist/src/liveErrors.d.ts.map +1 -0
- package/dist/src/liveErrors.js +52 -0
- package/dist/src/liveErrors.js.map +1 -0
- package/dist/src/messages.d.ts +12 -0
- package/dist/src/messages.d.ts.map +1 -1
- package/dist/src/messages.js +4 -0
- package/dist/src/messages.js.map +1 -1
- package/dist/src/namedViews.d.ts +80 -0
- package/dist/src/namedViews.d.ts.map +1 -0
- package/dist/src/namedViews.js +88 -0
- package/dist/src/namedViews.js.map +1 -0
- package/dist/src/shell/AppearanceMenu.d.ts +15 -0
- package/dist/src/shell/AppearanceMenu.d.ts.map +1 -0
- package/dist/src/shell/AppearanceMenu.js +28 -0
- package/dist/src/shell/AppearanceMenu.js.map +1 -0
- package/dist/src/shell/BoxWidth.d.ts +40 -0
- package/dist/src/shell/BoxWidth.d.ts.map +1 -0
- package/dist/src/shell/BoxWidth.js +56 -0
- package/dist/src/shell/BoxWidth.js.map +1 -0
- package/dist/src/shell/ComponentPage.d.ts +17 -1
- package/dist/src/shell/ComponentPage.d.ts.map +1 -1
- package/dist/src/shell/ComponentPage.js +19 -54
- package/dist/src/shell/ComponentPage.js.map +1 -1
- package/dist/src/shell/ControlKeyField.d.ts +21 -0
- package/dist/src/shell/ControlKeyField.d.ts.map +1 -0
- package/dist/src/shell/ControlKeyField.js +46 -0
- package/dist/src/shell/ControlKeyField.js.map +1 -0
- package/dist/src/shell/ControlRow.d.ts +31 -0
- package/dist/src/shell/ControlRow.d.ts.map +1 -0
- package/dist/src/shell/ControlRow.js +27 -0
- package/dist/src/shell/ControlRow.js.map +1 -0
- package/dist/src/shell/Example.d.ts +58 -0
- package/dist/src/shell/Example.d.ts.map +1 -0
- package/dist/src/shell/Example.js +89 -0
- package/dist/src/shell/Example.js.map +1 -0
- package/dist/src/shell/NamedViews.d.ts +23 -0
- package/dist/src/shell/NamedViews.d.ts.map +1 -0
- package/dist/src/shell/NamedViews.js +49 -0
- package/dist/src/shell/NamedViews.js.map +1 -0
- package/dist/src/shell/PinnedControl.d.ts +25 -0
- package/dist/src/shell/PinnedControl.d.ts.map +1 -0
- package/dist/src/shell/PinnedControl.js +81 -0
- package/dist/src/shell/PinnedControl.js.map +1 -0
- package/dist/src/shell/PropsTab.d.ts +5 -2
- package/dist/src/shell/PropsTab.d.ts.map +1 -1
- package/dist/src/shell/PropsTab.js +12 -15
- package/dist/src/shell/PropsTab.js.map +1 -1
- package/dist/src/shell/Shell.d.ts.map +1 -1
- package/dist/src/shell/Shell.js +27 -2
- package/dist/src/shell/Shell.js.map +1 -1
- package/dist/src/shell/Sidebar.d.ts +11 -9
- package/dist/src/shell/Sidebar.d.ts.map +1 -1
- package/dist/src/shell/Sidebar.js +48 -42
- package/dist/src/shell/Sidebar.js.map +1 -1
- package/dist/src/shell/SidebarEntries.d.ts +50 -0
- package/dist/src/shell/SidebarEntries.d.ts.map +1 -0
- package/dist/src/shell/SidebarEntries.js +51 -0
- package/dist/src/shell/SidebarEntries.js.map +1 -0
- package/dist/src/shell/Stage.d.ts.map +1 -1
- package/dist/src/shell/Stage.js +19 -2
- package/dist/src/shell/Stage.js.map +1 -1
- package/dist/src/shell/Toolbar.d.ts +7 -3
- package/dist/src/shell/Toolbar.d.ts.map +1 -1
- package/dist/src/shell/Toolbar.js +38 -68
- package/dist/src/shell/Toolbar.js.map +1 -1
- package/dist/src/shell/ToolbarControl.d.ts +47 -0
- package/dist/src/shell/ToolbarControl.d.ts.map +1 -0
- package/dist/src/shell/ToolbarControl.js +150 -0
- package/dist/src/shell/ToolbarControl.js.map +1 -0
- package/dist/src/shell/UsedIn.d.ts +38 -0
- package/dist/src/shell/UsedIn.d.ts.map +1 -0
- package/dist/src/shell/UsedIn.js +77 -0
- package/dist/src/shell/UsedIn.js.map +1 -0
- package/dist/src/shell/ViewMenu.d.ts +37 -0
- package/dist/src/shell/ViewMenu.d.ts.map +1 -0
- package/dist/src/shell/ViewMenu.js +216 -0
- package/dist/src/shell/ViewMenu.js.map +1 -0
- package/dist/src/shell/controlCycle.d.ts +28 -0
- package/dist/src/shell/controlCycle.d.ts.map +1 -0
- package/dist/src/shell/controlCycle.js +51 -0
- package/dist/src/shell/controlCycle.js.map +1 -0
- package/dist/src/shell/dockTabs.d.ts +3 -0
- package/dist/src/shell/dockTabs.d.ts.map +1 -1
- package/dist/src/shell/dockTabs.js +1 -1
- package/dist/src/shell/dockTabs.js.map +1 -1
- package/dist/src/shell/icons.d.ts +6 -0
- package/dist/src/shell/icons.d.ts.map +1 -1
- package/dist/src/shell/icons.js +7 -1
- package/dist/src/shell/icons.js.map +1 -1
- package/dist/src/shell/keyboard.d.ts +2 -1
- package/dist/src/shell/keyboard.d.ts.map +1 -1
- package/dist/src/shell/keyboard.js +5 -2
- package/dist/src/shell/keyboard.js.map +1 -1
- package/dist/src/shell/shell.css +826 -243
- package/dist/src/shell/strings.d.ts +45 -0
- package/dist/src/shell/strings.d.ts.map +1 -1
- package/dist/src/shell/strings.js +45 -0
- package/dist/src/shell/strings.js.map +1 -1
- package/dist/src/shell/useAppearance.d.ts +17 -0
- package/dist/src/shell/useAppearance.d.ts.map +1 -0
- package/dist/src/shell/useAppearance.js +36 -0
- package/dist/src/shell/useAppearance.js.map +1 -0
- package/dist/src/shell/useControlKeys.d.ts +23 -0
- package/dist/src/shell/useControlKeys.d.ts.map +1 -0
- package/dist/src/shell/useControlKeys.js +44 -0
- package/dist/src/shell/useControlKeys.js.map +1 -0
- package/dist/src/shell/useFold.d.ts +27 -0
- package/dist/src/shell/useFold.d.ts.map +1 -0
- package/dist/src/shell/useFold.js +87 -0
- package/dist/src/shell/useFold.js.map +1 -0
- package/dist/src/shell/useFrameMessages.d.ts +2 -0
- package/dist/src/shell/useFrameMessages.d.ts.map +1 -1
- package/dist/src/shell/useFrameMessages.js +3 -0
- package/dist/src/shell/useFrameMessages.js.map +1 -1
- package/dist/src/shell/useFullPage.d.ts +45 -0
- package/dist/src/shell/useFullPage.d.ts.map +1 -0
- package/dist/src/shell/useFullPage.js +149 -0
- package/dist/src/shell/useFullPage.js.map +1 -0
- package/dist/src/shell/usePopover.d.ts +17 -3
- package/dist/src/shell/usePopover.d.ts.map +1 -1
- package/dist/src/shell/usePopover.js +65 -4
- package/dist/src/shell/usePopover.js.map +1 -1
- package/dist/src/shell/useStored.d.ts +13 -2
- package/dist/src/shell/useStored.d.ts.map +1 -1
- package/dist/src/shell/useStored.js +1 -1
- package/dist/src/shell/useStored.js.map +1 -1
- package/dist/src/shell/useToolbarLayout.d.ts +39 -0
- package/dist/src/shell/useToolbarLayout.d.ts.map +1 -0
- package/dist/src/shell/useToolbarLayout.js +58 -0
- package/dist/src/shell/useToolbarLayout.js.map +1 -0
- package/dist/src/shell/useToolbarOverflow.d.ts +31 -0
- package/dist/src/shell/useToolbarOverflow.d.ts.map +1 -0
- package/dist/src/shell/useToolbarOverflow.js +62 -0
- package/dist/src/shell/useToolbarOverflow.js.map +1 -0
- package/dist/src/shell/useWorstCase.d.ts +46 -0
- package/dist/src/shell/useWorstCase.d.ts.map +1 -0
- package/dist/src/shell/useWorstCase.js +42 -0
- package/dist/src/shell/useWorstCase.js.map +1 -0
- package/dist/src/shell/worstArgs.d.ts +42 -0
- package/dist/src/shell/worstArgs.d.ts.map +1 -0
- package/dist/src/shell/worstArgs.js +47 -0
- package/dist/src/shell/worstArgs.js.map +1 -0
- package/dist/src/spills.d.ts +31 -0
- package/dist/src/spills.d.ts.map +1 -0
- package/dist/src/spills.js +65 -0
- package/dist/src/spills.js.map +1 -0
- package/dist/src/storyCheck.d.ts +105 -0
- package/dist/src/storyCheck.d.ts.map +1 -0
- package/dist/src/storyCheck.js +63 -0
- package/dist/src/storyCheck.js.map +1 -0
- package/dist/src/switches.d.ts +16 -4
- package/dist/src/switches.d.ts.map +1 -1
- package/dist/src/switches.js +30 -5
- package/dist/src/switches.js.map +1 -1
- package/dist/src/toolbarLayout.d.ts +119 -0
- package/dist/src/toolbarLayout.d.ts.map +1 -0
- package/dist/src/toolbarLayout.js +155 -0
- package/dist/src/toolbarLayout.js.map +1 -0
- package/dist/src/usedIn.d.ts +60 -0
- package/dist/src/usedIn.d.ts.map +1 -0
- package/dist/src/usedIn.js +92 -0
- package/dist/src/usedIn.js.map +1 -0
- package/dist/src/viewState.d.ts +6 -10
- package/dist/src/viewState.d.ts.map +1 -1
- package/dist/src/viewState.js +20 -18
- package/dist/src/viewState.js.map +1 -1
- package/dist/src/viewWords.d.ts +26 -0
- package/dist/src/viewWords.d.ts.map +1 -0
- package/dist/src/viewWords.js +29 -0
- package/dist/src/viewWords.js.map +1 -0
- package/dist/src/vite/adapter.d.ts +13 -4
- package/dist/src/vite/adapter.d.ts.map +1 -1
- package/dist/src/vite/adapter.js +4 -2
- package/dist/src/vite/adapter.js.map +1 -1
- package/dist/src/vite/agent.types.d.ts +32 -2
- package/dist/src/vite/agent.types.d.ts.map +1 -1
- package/dist/src/vite/agentApi.d.ts +15 -3
- package/dist/src/vite/agentApi.d.ts.map +1 -1
- package/dist/src/vite/agentApi.js +63 -9
- package/dist/src/vite/agentApi.js.map +1 -1
- package/dist/src/vite/agentRoutes.d.ts +8 -3
- package/dist/src/vite/agentRoutes.d.ts.map +1 -1
- package/dist/src/vite/agentRoutes.js +84 -23
- package/dist/src/vite/agentRoutes.js.map +1 -1
- package/dist/src/vite/configFile.d.ts +2 -1
- package/dist/src/vite/configFile.d.ts.map +1 -1
- package/dist/src/vite/configFile.js +29 -11
- package/dist/src/vite/configFile.js.map +1 -1
- package/dist/src/vite/docsExtractor.d.ts +26 -2
- package/dist/src/vite/docsExtractor.d.ts.map +1 -1
- package/dist/src/vite/docsExtractor.js +12 -9
- package/dist/src/vite/docsExtractor.js.map +1 -1
- package/dist/src/vite/docsWorker.js +18 -2
- package/dist/src/vite/docsWorker.js.map +1 -1
- package/dist/src/vite/forgebookPlugin.d.ts.map +1 -1
- package/dist/src/vite/forgebookPlugin.js +109 -16
- package/dist/src/vite/forgebookPlugin.js.map +1 -1
- package/dist/src/vite/indexStoryFile.d.ts +14 -0
- package/dist/src/vite/indexStoryFile.d.ts.map +1 -1
- package/dist/src/vite/indexStoryFile.js +13 -4
- package/dist/src/vite/indexStoryFile.js.map +1 -1
- package/dist/src/vite/mcpProtocol.d.ts +9 -0
- package/dist/src/vite/mcpProtocol.d.ts.map +1 -1
- package/dist/src/vite/mcpProtocol.js +6 -3
- package/dist/src/vite/mcpProtocol.js.map +1 -1
- package/dist/src/vite/storyFilesModule.d.ts +28 -1
- package/dist/src/vite/storyFilesModule.d.ts.map +1 -1
- package/dist/src/vite/storyFilesModule.js +34 -14
- package/dist/src/vite/storyFilesModule.js.map +1 -1
- package/dist/src/vite/usageGraph.d.ts +45 -0
- package/dist/src/vite/usageGraph.d.ts.map +1 -0
- package/dist/src/vite/usageGraph.js +246 -0
- package/dist/src/vite/usageGraph.js.map +1 -0
- package/dist/src/vite/usageModule.d.ts +33 -0
- package/dist/src/vite/usageModule.d.ts.map +1 -0
- package/dist/src/vite/usageModule.js +135 -0
- package/dist/src/vite/usageModule.js.map +1 -0
- package/dist/src/worstCase.d.ts +16 -0
- package/dist/src/worstCase.d.ts.map +1 -0
- package/dist/src/worstCase.js +16 -0
- package/dist/src/worstCase.js.map +1 -0
- package/package.json +14 -2
- package/dist/src/shell/SchemeSwitches.d.ts +0 -24
- package/dist/src/shell/SchemeSwitches.d.ts.map +0 -1
- package/dist/src/shell/SchemeSwitches.js +0 -36
- package/dist/src/shell/SchemeSwitches.js.map +0 -1
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An example's box opened to fill the page, over it, without leaving it: the box grows from where it sits to the
|
|
3
|
+
* page's size and shrinks back into its place, animated; Escape, a press on the shade or its button brings it back.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* The box is never moved in the page: an iframe moved to another parent loads again, and the story would lose its
|
|
7
|
+
* state. It is drawn fixed over the page instead, and a slot of its height keeps its place in the list, so nothing
|
|
8
|
+
* under it moves. Its size and place are animated (not scaled), so the story lays itself out at each size as it would
|
|
9
|
+
* in a window being resized. A reduced-motion preference opens and closes it at once. The address does not remember
|
|
10
|
+
* it: it is a moment's look, not a page.
|
|
11
|
+
*
|
|
12
|
+
* @module
|
|
13
|
+
*/
|
|
14
|
+
import { useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
15
|
+
/** How long the box takes to fill the page, in ms: the shell's `$duration-medium`. */
|
|
16
|
+
const OPEN_MS = 260;
|
|
17
|
+
/** How long it takes to go back to its place, in ms. */
|
|
18
|
+
const CLOSE_MS = 200;
|
|
19
|
+
/** The page's easing for a thing that moves and settles: the shell's `$ease-slide`. */
|
|
20
|
+
const EASING = "cubic-bezier(0.32, 0.72, 0, 1)";
|
|
21
|
+
/** A rectangle as the keyframes of a fixed box write it. */
|
|
22
|
+
const frameOf = (rect) => ({
|
|
23
|
+
top: `${rect.top}px`,
|
|
24
|
+
left: `${rect.left}px`,
|
|
25
|
+
width: `${rect.width}px`,
|
|
26
|
+
height: `${rect.height}px`
|
|
27
|
+
});
|
|
28
|
+
/** Whether the person asked for less motion. */
|
|
29
|
+
const isReduced = () => window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
30
|
+
/** An example's box opened to fill the page. */
|
|
31
|
+
export const useFullPage = () => {
|
|
32
|
+
const [isFull, setIsFull] = useState(false);
|
|
33
|
+
const [isOver, setIsOver] = useState(false);
|
|
34
|
+
const [slotHeight, setSlotHeight] = useState(0);
|
|
35
|
+
const boxRef = useRef(null);
|
|
36
|
+
const slotRef = useRef(null);
|
|
37
|
+
const shadeRef = useRef(null);
|
|
38
|
+
const stageRef = useRef(null);
|
|
39
|
+
const [stageHeight, setStageHeight] = useState(undefined);
|
|
40
|
+
// where the box was before it filled the page, for its growing in
|
|
41
|
+
const from = useRef(undefined);
|
|
42
|
+
// the move back to its place, kept to its end so the box is never drawn full for a frame before it is put back
|
|
43
|
+
const closing = useRef(undefined);
|
|
44
|
+
// opened by the pointer: Escape, a key, would otherwise light the focused button's ring as if the keyboard moved
|
|
45
|
+
const isByPointer = useRef(false);
|
|
46
|
+
const open = () => {
|
|
47
|
+
const box = boxRef.current;
|
|
48
|
+
if (box === null)
|
|
49
|
+
return;
|
|
50
|
+
closing.current?.cancel();
|
|
51
|
+
closing.current = undefined;
|
|
52
|
+
const rect = box.getBoundingClientRect();
|
|
53
|
+
from.current = rect;
|
|
54
|
+
setSlotHeight(rect.height);
|
|
55
|
+
setIsFull(true);
|
|
56
|
+
setIsOver(true);
|
|
57
|
+
};
|
|
58
|
+
const close = () => {
|
|
59
|
+
const box = boxRef.current;
|
|
60
|
+
const slot = slotRef.current;
|
|
61
|
+
setIsFull(false);
|
|
62
|
+
if (box === null || slot === null || isReduced()) {
|
|
63
|
+
setIsOver(false);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const animation = box.animate([frameOf(box.getBoundingClientRect()), frameOf(slot.getBoundingClientRect())], {
|
|
67
|
+
duration: CLOSE_MS,
|
|
68
|
+
easing: EASING,
|
|
69
|
+
fill: "forwards"
|
|
70
|
+
});
|
|
71
|
+
shadeRef.current?.animate([{ opacity: 1 }, { opacity: 0 }], { duration: CLOSE_MS, fill: "forwards" });
|
|
72
|
+
closing.current = animation;
|
|
73
|
+
animation.finished
|
|
74
|
+
.then(() => {
|
|
75
|
+
if (closing.current === animation)
|
|
76
|
+
setIsOver(false);
|
|
77
|
+
})
|
|
78
|
+
// opened again while it went back: the opening takes over
|
|
79
|
+
.catch(() => undefined);
|
|
80
|
+
};
|
|
81
|
+
// it grows from where it sat to the page's size as it is first drawn over the page
|
|
82
|
+
useLayoutEffect(() => {
|
|
83
|
+
const box = boxRef.current;
|
|
84
|
+
const start = from.current;
|
|
85
|
+
if (!isFull || box === null || start === undefined || isReduced())
|
|
86
|
+
return;
|
|
87
|
+
box.animate([frameOf(start), frameOf(box.getBoundingClientRect())], {
|
|
88
|
+
duration: OPEN_MS,
|
|
89
|
+
easing: EASING
|
|
90
|
+
});
|
|
91
|
+
shadeRef.current?.animate([{ opacity: 0 }, { opacity: 1 }], { duration: OPEN_MS });
|
|
92
|
+
}, [isFull]);
|
|
93
|
+
// back in its place: the move that put it there is let go before the page is drawn
|
|
94
|
+
useLayoutEffect(() => {
|
|
95
|
+
if (isOver)
|
|
96
|
+
return;
|
|
97
|
+
closing.current?.cancel();
|
|
98
|
+
closing.current = undefined;
|
|
99
|
+
}, [isOver]);
|
|
100
|
+
// the room the story has over the page, followed as the box grows, shrinks and the window changes
|
|
101
|
+
useLayoutEffect(() => {
|
|
102
|
+
const stage = stageRef.current;
|
|
103
|
+
if (!isOver || stage === null) {
|
|
104
|
+
setStageHeight(undefined);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const measure = () => setStageHeight(stage.clientHeight);
|
|
108
|
+
measure();
|
|
109
|
+
const observer = new ResizeObserver(measure);
|
|
110
|
+
observer.observe(stage);
|
|
111
|
+
return () => observer.disconnect();
|
|
112
|
+
}, [isOver]);
|
|
113
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: close reads only refs and the states' setters
|
|
114
|
+
useEffect(() => {
|
|
115
|
+
if (!isFull)
|
|
116
|
+
return;
|
|
117
|
+
const closeOnEscape = (event) => {
|
|
118
|
+
if (event.key !== "Escape")
|
|
119
|
+
return;
|
|
120
|
+
close();
|
|
121
|
+
const focused = document.activeElement;
|
|
122
|
+
if (isByPointer.current && focused instanceof HTMLElement && boxRef.current?.contains(focused)) {
|
|
123
|
+
focused.blur();
|
|
124
|
+
focused.focus({ focusVisible: false });
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
document.addEventListener("keydown", closeOnEscape);
|
|
128
|
+
return () => document.removeEventListener("keydown", closeOnEscape);
|
|
129
|
+
}, [isFull]);
|
|
130
|
+
return {
|
|
131
|
+
isFull,
|
|
132
|
+
isOver,
|
|
133
|
+
slotHeight,
|
|
134
|
+
boxRef,
|
|
135
|
+
slotRef,
|
|
136
|
+
shadeRef,
|
|
137
|
+
stageRef,
|
|
138
|
+
stageHeight,
|
|
139
|
+
toggle: (press) => {
|
|
140
|
+
if (isFull) {
|
|
141
|
+
close();
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
isByPointer.current = (press?.detail ?? 0) > 0;
|
|
145
|
+
open();
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
//# sourceMappingURL=useFullPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFullPage.js","sourceRoot":"","sources":["../../../src/shell/useFullPage.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,15 +2,29 @@
|
|
|
2
2
|
* A button's popover: open and closed, closed by a press outside or Escape (the focus going back to the button), with
|
|
3
3
|
* the focus on its chosen option when it opens. The View and Compare menus use it.
|
|
4
4
|
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* The panel grows in from its button's corner and shrinks back into it when it closes, whatever closes it: it stays
|
|
7
|
+
* drawn until its closing has played. A reduced-motion preference opens and closes it at once.
|
|
8
|
+
*
|
|
5
9
|
* @module
|
|
6
10
|
*/
|
|
7
11
|
import { type RefObject } from "react";
|
|
8
12
|
/** What a menu wires to its button and panel. */
|
|
9
13
|
export type Popover = {
|
|
10
|
-
/** Whether the panel is
|
|
14
|
+
/** Whether the panel is open: what its button's state and a press on it read. */
|
|
11
15
|
readonly isOpen: boolean;
|
|
12
|
-
/**
|
|
13
|
-
readonly
|
|
16
|
+
/** Whether the panel is drawn: open, or still closing. */
|
|
17
|
+
readonly isDrawn: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Opens or closes the panel.
|
|
20
|
+
*
|
|
21
|
+
* @param isOpen - whether it opens.
|
|
22
|
+
* @param press - the press that asked, when one did: opened by the pointer (`detail` above 0), Escape gives the
|
|
23
|
+
* focus back to the button without its ring.
|
|
24
|
+
*/
|
|
25
|
+
readonly setIsOpen: (isOpen: boolean, press?: {
|
|
26
|
+
readonly detail: number;
|
|
27
|
+
}) => void;
|
|
14
28
|
/** The button. */
|
|
15
29
|
readonly buttonRef: RefObject<HTMLButtonElement | null>;
|
|
16
30
|
/** The panel. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePopover.d.ts","sourceRoot":"","sources":["../../../src/shell/usePopover.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"usePopover.d.ts","sourceRoot":"","sources":["../../../src/shell/usePopover.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,KAAK,SAAS,EAAuD,MAAM,OAAO,CAAC;AAE5F,iDAAiD;AACjD,MAAM,MAAM,OAAO,GAAG;IACpB,iFAAiF;IACjF,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,0DAA0D;IAC1D,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACnF,kBAAkB;IAClB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IACxD,iBAAiB;IACjB,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACpD,wDAAwD;IACxD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;AAiBF,0BAA0B;AAC1B,eAAO,MAAM,UAAU,QAAO,OA4E7B,CAAC"}
|
|
@@ -2,15 +2,75 @@
|
|
|
2
2
|
* A button's popover: open and closed, closed by a press outside or Escape (the focus going back to the button), with
|
|
3
3
|
* the focus on its chosen option when it opens. The View and Compare menus use it.
|
|
4
4
|
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* The panel grows in from its button's corner and shrinks back into it when it closes, whatever closes it: it stays
|
|
7
|
+
* drawn until its closing has played. A reduced-motion preference opens and closes it at once.
|
|
8
|
+
*
|
|
5
9
|
* @module
|
|
6
10
|
*/
|
|
7
|
-
import { useEffect, useId, useRef, useState } from "react";
|
|
11
|
+
import { useEffect, useId, useLayoutEffect, useRef, useState } from "react";
|
|
12
|
+
/** How long the panel takes to open, in ms: the shell's `$duration-quick`. */
|
|
13
|
+
const OPEN_MS = 150;
|
|
14
|
+
/** How long it takes to close, in ms: shorter, as a thing going away. */
|
|
15
|
+
const CLOSE_MS = 110;
|
|
16
|
+
/** The panel's look when it is not open: faded, a little smaller and nearer its button. */
|
|
17
|
+
const CLOSED_FRAME = { opacity: 0, transform: "translateY(-0.25rem) scale(0.97)" };
|
|
18
|
+
/** Its look when open. */
|
|
19
|
+
const OPEN_FRAME = { opacity: 1, transform: "none" };
|
|
20
|
+
/** Whether the person asked for less motion. */
|
|
21
|
+
const isReduced = () => window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
8
22
|
/** A button's popover. */
|
|
9
23
|
export const usePopover = () => {
|
|
10
|
-
const [isOpen,
|
|
24
|
+
const [isOpen, setOpen] = useState(false);
|
|
25
|
+
const [isDrawn, setIsDrawn] = useState(false);
|
|
11
26
|
const buttonRef = useRef(null);
|
|
12
27
|
const panelRef = useRef(null);
|
|
28
|
+
const closing = useRef(undefined);
|
|
29
|
+
const isByPointer = useRef(false);
|
|
13
30
|
const panelId = useId();
|
|
31
|
+
const setIsOpen = (isOpening, press) => {
|
|
32
|
+
const panel = panelRef.current;
|
|
33
|
+
if (isOpening) {
|
|
34
|
+
isByPointer.current = (press?.detail ?? 0) > 0;
|
|
35
|
+
// opened again while it closes: the closing stops and it grows in again
|
|
36
|
+
closing.current?.cancel();
|
|
37
|
+
closing.current = undefined;
|
|
38
|
+
setOpen(true);
|
|
39
|
+
setIsDrawn(true);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
setOpen(false);
|
|
43
|
+
if (panel === null || isReduced()) {
|
|
44
|
+
setIsDrawn(false);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const animation = panel.animate([OPEN_FRAME, CLOSED_FRAME], {
|
|
48
|
+
duration: CLOSE_MS,
|
|
49
|
+
easing: "cubic-bezier(0.4, 0, 1, 1)",
|
|
50
|
+
fill: "forwards"
|
|
51
|
+
});
|
|
52
|
+
closing.current = animation;
|
|
53
|
+
animation.finished
|
|
54
|
+
.then(() => {
|
|
55
|
+
if (closing.current !== animation)
|
|
56
|
+
return;
|
|
57
|
+
closing.current = undefined;
|
|
58
|
+
setIsDrawn(false);
|
|
59
|
+
})
|
|
60
|
+
// a cancelled closing (opened again) leaves the panel open
|
|
61
|
+
.catch(() => undefined);
|
|
62
|
+
};
|
|
63
|
+
// it grows in from its button's corner as it is drawn
|
|
64
|
+
useLayoutEffect(() => {
|
|
65
|
+
const panel = panelRef.current;
|
|
66
|
+
if (!isOpen || panel === null || isReduced())
|
|
67
|
+
return;
|
|
68
|
+
panel.animate([CLOSED_FRAME, OPEN_FRAME], {
|
|
69
|
+
duration: OPEN_MS,
|
|
70
|
+
easing: "cubic-bezier(0.22, 1, 0.36, 1)"
|
|
71
|
+
});
|
|
72
|
+
}, [isOpen]);
|
|
73
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: setIsOpen reads only refs and the state's setter
|
|
14
74
|
useEffect(() => {
|
|
15
75
|
if (!isOpen)
|
|
16
76
|
return;
|
|
@@ -24,8 +84,9 @@ export const usePopover = () => {
|
|
|
24
84
|
if (!isOutside && !isEscape)
|
|
25
85
|
return;
|
|
26
86
|
setIsOpen(false);
|
|
87
|
+
// the focus goes back where it came from, its ring lit only for the keyboard that opened the panel
|
|
27
88
|
if (isEscape)
|
|
28
|
-
buttonRef.current?.focus();
|
|
89
|
+
buttonRef.current?.focus({ focusVisible: !isByPointer.current });
|
|
29
90
|
};
|
|
30
91
|
document.addEventListener("pointerdown", close);
|
|
31
92
|
document.addEventListener("keydown", close);
|
|
@@ -34,6 +95,6 @@ export const usePopover = () => {
|
|
|
34
95
|
document.removeEventListener("keydown", close);
|
|
35
96
|
};
|
|
36
97
|
}, [isOpen]);
|
|
37
|
-
return { isOpen, setIsOpen, buttonRef, panelRef, panelId };
|
|
98
|
+
return { isOpen, isDrawn, setIsOpen, buttonRef, panelRef, panelId };
|
|
38
99
|
};
|
|
39
100
|
//# sourceMappingURL=usePopover.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePopover.js","sourceRoot":"","sources":["../../../src/shell/usePopover.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"usePopover.js","sourceRoot":"","sources":["../../../src/shell/usePopover.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A value this browser keeps for the next visit (the panel's height, the sidebar's width): a convenience of the
|
|
3
|
+
* person, not part of the page an address shares.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Storage may be missing or refused (a private window, blocked site data): the value then lives only as long as the
|
|
7
|
+
* page, and nothing fails.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
import { type Dispatch, type SetStateAction } from "react";
|
|
1
12
|
/**
|
|
2
13
|
* A value kept in this browser.
|
|
3
14
|
*
|
|
@@ -5,7 +16,7 @@
|
|
|
5
16
|
* catalogues on one origin keep their own.
|
|
6
17
|
* @param read - the value a stored text holds, or the default when it holds none.
|
|
7
18
|
* @param write - the text a value is stored as.
|
|
8
|
-
* @returns the value and its setter.
|
|
19
|
+
* @returns the value and its setter, which also takes a function of the current value.
|
|
9
20
|
*/
|
|
10
|
-
export declare const useStored: <TValue>(name: string, read: (stored: string | null) => TValue, write: (value: TValue) => string) => [TValue,
|
|
21
|
+
export declare const useStored: <TValue>(name: string, read: (stored: string | null) => TValue, write: (value: TValue) => string) => [TValue, Dispatch<SetStateAction<TValue>>];
|
|
11
22
|
//# sourceMappingURL=useStored.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useStored.d.ts","sourceRoot":"","sources":["../../../src/shell/useStored.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useStored.d.ts","sourceRoot":"","sources":["../../../src/shell/useStored.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,cAAc,EAAuB,MAAM,OAAO,CAAC;AA0ChF;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS,GAAI,MAAM,EAC9B,MAAM,MAAM,EACZ,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,MAAM,EACvC,OAAO,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,KAC/B,CAAC,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAM3C,CAAC"}
|
|
@@ -56,7 +56,7 @@ const movedStored = (name, key) => {
|
|
|
56
56
|
* catalogues on one origin keep their own.
|
|
57
57
|
* @param read - the value a stored text holds, or the default when it holds none.
|
|
58
58
|
* @param write - the text a value is stored as.
|
|
59
|
-
* @returns the value and its setter.
|
|
59
|
+
* @returns the value and its setter, which also takes a function of the current value.
|
|
60
60
|
*/
|
|
61
61
|
export const useStored = (name, read, write) => {
|
|
62
62
|
const key = `${useCatalogue().id}:${name}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useStored.js","sourceRoot":"","sources":["../../../src/shell/useStored.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,
|
|
1
|
+
{"version":3,"file":"useStored.js","sourceRoot":"","sources":["../../../src/shell/useStored.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAsC,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEhF,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,qFAAqF;AACrF,MAAM,UAAU,GAAG,CAAC,GAAW,EAAiB,EAAE;IAChD,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AAEF,wDAAwD;AACxD,MAAM,WAAW,GAAG,CAAC,GAAW,EAAE,KAAa,EAAQ,EAAE;IACvD,IAAI,CAAC;QACH,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,+CAA+C;IACjD,CAAC;AACH,CAAC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,WAAW,GAAG,CAAC,IAAY,EAAE,GAAW,EAAiB,EAAE;IAC/D,MAAM,GAAG,GAAG,UAAU,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;IAC5C,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC9B,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,0DAA0D;IAC5D,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CACvB,IAAY,EACZ,IAAuC,EACvC,KAAgC,EACY,EAAE;IAC9C,MAAM,GAAG,GAAG,GAAG,YAAY,EAAE,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC;IAC3C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IAC1F,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IAC1B,SAAS,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;IACrD,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AAC3B,CAAC,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The person's arrangement of the toolbar, kept in their browser per catalogue: where each control sits, in what
|
|
3
|
+
* order, whether a full bar wraps, the keys they gave the controls, and the changes the View menu and the toolbar's
|
|
4
|
+
* controls make to it.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
import { type ControlKeys } from "../controlKeys.ts";
|
|
9
|
+
import { type PlacedControl } from "../toolbarLayout.ts";
|
|
10
|
+
/** The arrangement and what changes it. */
|
|
11
|
+
export type ToolbarLayout = {
|
|
12
|
+
/** Every control and where it sits, in the person's order. */
|
|
13
|
+
readonly placed: readonly PlacedControl[];
|
|
14
|
+
/** Whether the person arranged anything: "Reset toolbar" then brings the catalogue's back. */
|
|
15
|
+
readonly isArranged: boolean;
|
|
16
|
+
/** Pins a control on the toolbar or takes it off. */
|
|
17
|
+
readonly pin: (id: string, isPinned: boolean) => void;
|
|
18
|
+
/** Hides a control in the View menu or shows it there again. */
|
|
19
|
+
readonly hide: (id: string, isHidden: boolean) => void;
|
|
20
|
+
/** Moves a control to a position among the shown ones. */
|
|
21
|
+
readonly move: (id: string, index: number) => void;
|
|
22
|
+
/** Forgets the person's arrangement and their keys. */
|
|
23
|
+
readonly reset: () => void;
|
|
24
|
+
/** Whether the bar wraps onto more lines when its pinned controls do not fit, instead of moving them into View. */
|
|
25
|
+
readonly isWrapped: boolean;
|
|
26
|
+
/** Turns the wrapping on or off. */
|
|
27
|
+
readonly setIsWrapped: (isWrapped: boolean) => void;
|
|
28
|
+
/** The keys that cycle the controls: the catalogue's, with the person's own over them. */
|
|
29
|
+
readonly keys: ControlKeys;
|
|
30
|
+
/**
|
|
31
|
+
* Gives a control another key, or takes its key away (`null`).
|
|
32
|
+
*
|
|
33
|
+
* @returns why the key cannot be given; none when it was.
|
|
34
|
+
*/
|
|
35
|
+
readonly setKey: (id: string, key: string | null) => string | undefined;
|
|
36
|
+
};
|
|
37
|
+
/** The person's arrangement of the toolbar. */
|
|
38
|
+
export declare const useToolbarLayout: () => ToolbarLayout;
|
|
39
|
+
//# sourceMappingURL=useToolbarLayout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useToolbarLayout.d.ts","sourceRoot":"","sources":["../../../src/shell/useToolbarLayout.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,KAAK,WAAW,EAA6C,MAAM,mBAAmB,CAAC;AAChG,OAAO,EAGL,KAAK,aAAa,EAMnB,MAAM,qBAAqB,CAAC;AAI7B,2CAA2C;AAC3C,MAAM,MAAM,aAAa,GAAG;IAC1B,8DAA8D;IAC9D,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,8FAA8F;IAC9F,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,qDAAqD;IACrD,QAAQ,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IACtD,gEAAgE;IAChE,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IACvD,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,uDAAuD;IACvD,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;IAC3B,mHAAmH;IACnH,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,oCAAoC;IACpC,QAAQ,CAAC,YAAY,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;IACpD,0FAA0F;IAC1F,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,KAAK,MAAM,GAAG,SAAS,CAAC;CACzE,CAAC;AAqBF,+CAA+C;AAC/C,eAAO,MAAM,gBAAgB,QAAO,aAkCnC,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The person's arrangement of the toolbar, kept in their browser per catalogue: where each control sits, in what
|
|
3
|
+
* order, whether a full bar wraps, the keys they gave the controls, and the changes the View menu and the toolbar's
|
|
4
|
+
* controls make to it.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
import { shownKeys, withReaderKey } from "../controlKeys.js";
|
|
9
|
+
import { arrangementOf, arrangementText, placedControls, readArrangement, withHidden, withPinned, withPosition } from "../toolbarLayout.js";
|
|
10
|
+
import { useCatalogue } from "./catalogueContext.js";
|
|
11
|
+
import { useStored } from "./useStored.js";
|
|
12
|
+
/** The person's keys a stored text holds; none for anything else. */
|
|
13
|
+
const readKeys = (stored) => {
|
|
14
|
+
if (stored === null || stored === "")
|
|
15
|
+
return {};
|
|
16
|
+
try {
|
|
17
|
+
const parsed = JSON.parse(stored);
|
|
18
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
|
|
19
|
+
return {};
|
|
20
|
+
return Object.fromEntries(Object.entries(parsed).filter((entry) => typeof entry[1] === "string" || entry[1] === null));
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return {};
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
/** The text the person's keys are stored as; empty for none. */
|
|
27
|
+
const keysText = (keys) => (Object.keys(keys).length === 0 ? "" : JSON.stringify(keys));
|
|
28
|
+
/** The person's arrangement of the toolbar. */
|
|
29
|
+
export const useToolbarLayout = () => {
|
|
30
|
+
const catalogue = useCatalogue();
|
|
31
|
+
const [arrangement, setArrangement] = useStored("toolbar", readArrangement, arrangementText);
|
|
32
|
+
const [isWrapped, setIsWrapped] = useStored("toolbar-wrap", (stored) => stored === "true", String);
|
|
33
|
+
const [readerKeys, setReaderKeys] = useStored("toolbar-keys", readKeys, keysText);
|
|
34
|
+
const placed = placedControls(catalogue, arrangement);
|
|
35
|
+
return {
|
|
36
|
+
placed,
|
|
37
|
+
isArranged: arrangement !== undefined || Object.keys(readerKeys).length > 0,
|
|
38
|
+
// from the arrangement as it is when the change applies: a drag moves a row several times before a new render
|
|
39
|
+
pin: (id, isPinned) => setArrangement((current) => arrangementOf(withPinned(placedControls(catalogue, current), id, isPinned))),
|
|
40
|
+
hide: (id, isHidden) => setArrangement((current) => arrangementOf(withHidden(placedControls(catalogue, current), id, isHidden))),
|
|
41
|
+
move: (id, index) => setArrangement((current) => arrangementOf(withPosition(placedControls(catalogue, current), id, index))),
|
|
42
|
+
reset: () => {
|
|
43
|
+
setArrangement(undefined);
|
|
44
|
+
setReaderKeys({});
|
|
45
|
+
},
|
|
46
|
+
isWrapped,
|
|
47
|
+
setIsWrapped,
|
|
48
|
+
keys: shownKeys(catalogue.keys, readerKeys),
|
|
49
|
+
setKey: (id, key) => {
|
|
50
|
+
const changed = withReaderKey(catalogue.keys, readerKeys, id, key);
|
|
51
|
+
if (typeof changed === "string")
|
|
52
|
+
return changed;
|
|
53
|
+
setReaderKeys(changed);
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=useToolbarLayout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useToolbarLayout.js","sourceRoot":"","sources":["../../../src/shell/useToolbarLayout.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAqC,SAAS,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAChG,OAAO,EACL,aAAa,EACb,eAAe,EAEf,cAAc,EACd,eAAe,EACf,UAAU,EACV,UAAU,EACV,YAAY,EACb,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AA8B3C,qEAAqE;AACrE,MAAM,QAAQ,GAAG,CAAC,MAAqB,EAAc,EAAE;IACrD,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,EAAE;QAAE,OAAO,EAAE,CAAC;IAChD,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC3C,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YAAE,OAAO,EAAE,CAAC;QACtF,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAC3B,CAAC,KAAK,EAAoC,EAAE,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,CAC/F,CACF,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC,CAAC;AAEF,gEAAgE;AAChE,MAAM,QAAQ,GAAG,CAAC,IAAgB,EAAU,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;AAE5G,+CAA+C;AAC/C,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAkB,EAAE;IAClD,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IACjC,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,SAAS,CAAC,SAAS,EAAE,eAAe,EAAE,eAAe,CAAC,CAAC;IAC7F,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,SAAS,CAAC,cAAc,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,MAAM,EAAE,MAAM,CAAC,CAAC;IACnG,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,SAAS,CAAC,cAAc,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAClF,MAAM,MAAM,GAAG,cAAc,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACtD,OAAO;QACL,MAAM;QACN,UAAU,EAAE,WAAW,KAAK,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC;QAC3E,8GAA8G;QAC9G,GAAG,EAAE,CAAC,EAAU,EAAE,QAAiB,EAAQ,EAAE,CAC3C,cAAc,CAAC,CAAC,OAAO,EAAE,EAAE,CACzB,aAAa,CAAC,UAAU,CAAC,cAAc,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC,CAC5E;QACH,IAAI,EAAE,CAAC,EAAU,EAAE,QAAiB,EAAQ,EAAE,CAC5C,cAAc,CAAC,CAAC,OAAO,EAAE,EAAE,CACzB,aAAa,CAAC,UAAU,CAAC,cAAc,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC,CAC5E;QACH,IAAI,EAAE,CAAC,EAAU,EAAE,KAAa,EAAQ,EAAE,CACxC,cAAc,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,aAAa,CAAC,YAAY,CAAC,cAAc,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;QACzG,KAAK,EAAE,GAAS,EAAE;YAChB,cAAc,CAAC,SAAS,CAAC,CAAC;YAC1B,aAAa,CAAC,EAAE,CAAC,CAAC;QACpB,CAAC;QACD,SAAS;QACT,YAAY;QACZ,IAAI,EAAE,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC;QAC3C,MAAM,EAAE,CAAC,EAAU,EAAE,GAAkB,EAAsB,EAAE;YAC7D,MAAM,OAAO,GAAG,aAAa,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;YACnE,IAAI,OAAO,OAAO,KAAK,QAAQ;gBAAE,OAAO,OAAO,CAAC;YAChD,aAAa,CAAC,OAAO,CAAC,CAAC;YACvB,OAAO,SAAS,CAAC;QACnB,CAAC;KACF,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pinned controls a narrow toolbar has no room for: they stay in the View menu for as long as the bar is narrow,
|
|
3
|
+
* the last pinned first, and come back when it widens, so the bar never wraps or squeezes a control.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* The pinned controls sit in a box that takes the room the rest of the bar leaves (the sidebar's button, View, the
|
|
7
|
+
* panel, Compare): that box's width is their room. Each pinned control's width is measured while it is drawn and
|
|
8
|
+
* remembered, so one moved out can be brought back when there is room for it again; a control pinned while the bar is
|
|
9
|
+
* narrow is drawn once, measured, then moved out if it does not fit.
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
import { type RefObject } from "react";
|
|
14
|
+
/**
|
|
15
|
+
* The ids of the pinned controls that do not fit, in their order: those from the first that passes the room on.
|
|
16
|
+
*
|
|
17
|
+
* @param pinned - the pinned controls' ids, in their order.
|
|
18
|
+
* @param widths - each one's measured width, in CSS px.
|
|
19
|
+
* @param room - the room they have, in CSS px.
|
|
20
|
+
* @param gap - the gap between two of them, in CSS px.
|
|
21
|
+
*/
|
|
22
|
+
export declare const overflowing: (pinned: readonly string[], widths: ReadonlyMap<string, number>, room: number, gap: number) => string[];
|
|
23
|
+
/**
|
|
24
|
+
* The pinned controls the bar has no room for.
|
|
25
|
+
*
|
|
26
|
+
* @param box - the box the pinned controls sit in.
|
|
27
|
+
* @param pinned - the pinned controls' ids, in their order.
|
|
28
|
+
* @returns the ids of those moved into the View menu.
|
|
29
|
+
*/
|
|
30
|
+
export declare const useToolbarOverflow: (box: RefObject<HTMLElement | null>, pinned: readonly string[]) => string[];
|
|
31
|
+
//# sourceMappingURL=useToolbarOverflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useToolbarOverflow.d.ts","sourceRoot":"","sources":["../../../src/shell/useToolbarOverflow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,KAAK,SAAS,EAAqC,MAAM,OAAO,CAAC;AAE1E;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,GACtB,QAAQ,SAAS,MAAM,EAAE,EACzB,QAAQ,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,MAAM,MAAM,EACZ,KAAK,MAAM,KACV,MAAM,EAOR,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,GAC7B,KAAK,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,EAClC,QAAQ,SAAS,MAAM,EAAE,KACxB,MAAM,EAuBR,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pinned controls a narrow toolbar has no room for: they stay in the View menu for as long as the bar is narrow,
|
|
3
|
+
* the last pinned first, and come back when it widens, so the bar never wraps or squeezes a control.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* The pinned controls sit in a box that takes the room the rest of the bar leaves (the sidebar's button, View, the
|
|
7
|
+
* panel, Compare): that box's width is their room. Each pinned control's width is measured while it is drawn and
|
|
8
|
+
* remembered, so one moved out can be brought back when there is room for it again; a control pinned while the bar is
|
|
9
|
+
* narrow is drawn once, measured, then moved out if it does not fit.
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
import { useLayoutEffect, useRef, useState } from "react";
|
|
14
|
+
/**
|
|
15
|
+
* The ids of the pinned controls that do not fit, in their order: those from the first that passes the room on.
|
|
16
|
+
*
|
|
17
|
+
* @param pinned - the pinned controls' ids, in their order.
|
|
18
|
+
* @param widths - each one's measured width, in CSS px.
|
|
19
|
+
* @param room - the room they have, in CSS px.
|
|
20
|
+
* @param gap - the gap between two of them, in CSS px.
|
|
21
|
+
*/
|
|
22
|
+
export const overflowing = (pinned, widths, room, gap) => {
|
|
23
|
+
let used = 0;
|
|
24
|
+
const first = pinned.findIndex((id, index) => {
|
|
25
|
+
used += (widths.get(id) ?? 0) + (index > 0 ? gap : 0);
|
|
26
|
+
return used > room;
|
|
27
|
+
});
|
|
28
|
+
return first === -1 ? [] : pinned.slice(first);
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* The pinned controls the bar has no room for.
|
|
32
|
+
*
|
|
33
|
+
* @param box - the box the pinned controls sit in.
|
|
34
|
+
* @param pinned - the pinned controls' ids, in their order.
|
|
35
|
+
* @returns the ids of those moved into the View menu.
|
|
36
|
+
*/
|
|
37
|
+
export const useToolbarOverflow = (box, pinned) => {
|
|
38
|
+
const widths = useRef(new Map());
|
|
39
|
+
const [moved, setMoved] = useState([]);
|
|
40
|
+
const key = pinned.join(",");
|
|
41
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: measured again whenever the pinned controls change
|
|
42
|
+
useLayoutEffect(() => {
|
|
43
|
+
const element = box.current;
|
|
44
|
+
if (element === null)
|
|
45
|
+
return;
|
|
46
|
+
const measure = () => {
|
|
47
|
+
for (const child of element.children) {
|
|
48
|
+
if (child instanceof HTMLElement)
|
|
49
|
+
widths.current.set(child.dataset["control"] ?? "", child.offsetWidth);
|
|
50
|
+
}
|
|
51
|
+
const gap = Number.parseFloat(getComputedStyle(element).columnGap) || 0;
|
|
52
|
+
const next = overflowing(pinned, widths.current, element.clientWidth, gap);
|
|
53
|
+
setMoved((current) => (current.join(",") === next.join(",") ? current : next));
|
|
54
|
+
};
|
|
55
|
+
measure();
|
|
56
|
+
const observer = new ResizeObserver(measure);
|
|
57
|
+
observer.observe(element);
|
|
58
|
+
return () => observer.disconnect();
|
|
59
|
+
}, [key]);
|
|
60
|
+
return moved.filter((id) => pinned.includes(id));
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=useToolbarOverflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useToolbarOverflow.js","sourceRoot":"","sources":["../../../src/shell/useToolbarOverflow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAkB,eAAe,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE1E;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,MAAyB,EACzB,MAAmC,EACnC,IAAY,EACZ,GAAW,EACD,EAAE;IACZ,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE;QAC3C,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtD,OAAO,IAAI,GAAG,IAAI,CAAC;IACrB,CAAC,CAAC,CAAC;IACH,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AACjD,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,GAAkC,EAClC,MAAyB,EACf,EAAE;IACZ,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,GAAG,EAAkB,CAAC,CAAC;IACjD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAW,EAAE,CAAC,CAAC;IACjD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7B,8GAA8G;IAC9G,eAAe,CAAC,GAAG,EAAE;QACnB,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;QAC5B,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO;QAC7B,MAAM,OAAO,GAAG,GAAS,EAAE;YACzB,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;gBACrC,IAAI,KAAK,YAAY,WAAW;oBAC9B,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;YAC1E,CAAC;YACD,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YACxE,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;YAC3E,QAAQ,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACjF,CAAC,CAAC;QACF,OAAO,EAAE,CAAC;QACV,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC;QAC7C,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC1B,OAAO,GAAS,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;IAC3C,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACV,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;AACnD,CAAC,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The stage's worst case: the args the Props tab's button sets, whether the values shown are those, and the spills the
|
|
3
|
+
* story's frames count while they are.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* The frames are asked to outline their spills only while the worst case is on (`forgebook:spills`), so a story shown
|
|
7
|
+
* with its own data never pays for the measure; a frame that loads again is asked again when it is ready (`sendTo`).
|
|
8
|
+
* The count is kept by story: in the compare view each frame measures its own, and the last to report is shown.
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
import { type RefObject } from "react";
|
|
13
|
+
import type { PanelProp } from "../argTypes.ts";
|
|
14
|
+
import type { PanelArgs } from "../messages.ts";
|
|
15
|
+
import { type WorstCaseState } from "./worstArgs.ts";
|
|
16
|
+
/** What the hook reads. */
|
|
17
|
+
export type WorstCaseInput = {
|
|
18
|
+
/** The element that holds the story's frames. */
|
|
19
|
+
readonly storyRef: RefObject<HTMLElement | null>;
|
|
20
|
+
/** The story's id. */
|
|
21
|
+
readonly storyId: string;
|
|
22
|
+
/** The props the panel can set; none before the docs arrive. */
|
|
23
|
+
readonly settable: readonly PanelProp[];
|
|
24
|
+
/** The values shown: the story's args with the panel's over them. */
|
|
25
|
+
readonly values: PanelArgs;
|
|
26
|
+
/** The panel's own values. */
|
|
27
|
+
readonly panelArgs: PanelArgs;
|
|
28
|
+
/** Sets the panel's values. */
|
|
29
|
+
readonly onPanelArgsChange: (args: PanelArgs) => void;
|
|
30
|
+
};
|
|
31
|
+
/** What the stage does with the worst case. */
|
|
32
|
+
export type WorstCase = {
|
|
33
|
+
/** The state the Props tab shows. */
|
|
34
|
+
readonly state: WorstCaseState;
|
|
35
|
+
/** Tells a frame that is ready whether to outline its spills. */
|
|
36
|
+
readonly sendTo: (frame: Window) => void;
|
|
37
|
+
/** Keeps the count a frame reported. */
|
|
38
|
+
readonly receive: (storyId: string, count: number) => void;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* The stage's worst case.
|
|
42
|
+
*
|
|
43
|
+
* @param input - the frames, the story, its settable props and its values.
|
|
44
|
+
*/
|
|
45
|
+
export declare const useWorstCase: ({ storyRef, storyId, settable, values, panelArgs, onPanelArgsChange }: WorstCaseInput) => WorstCase;
|
|
46
|
+
//# sourceMappingURL=useWorstCase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useWorstCase.d.ts","sourceRoot":"","sources":["../../../src/shell/useWorstCase.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,KAAK,SAAS,EAAgC,MAAM,OAAO,CAAC;AAErE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,SAAS,EAAgB,MAAM,gBAAgB,CAAC;AAE9D,OAAO,EAAe,KAAK,cAAc,EAAa,MAAM,gBAAgB,CAAC;AAE7E,2BAA2B;AAC3B,MAAM,MAAM,cAAc,GAAG;IAC3B,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACjD,sBAAsB;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE,SAAS,SAAS,EAAE,CAAC;IACxC,qEAAqE;IACrE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,8BAA8B;IAC9B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,+BAA+B;IAC/B,QAAQ,CAAC,iBAAiB,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;CACvD,CAAC;AAEF,+CAA+C;AAC/C,MAAM,MAAM,SAAS,GAAG;IACtB,qCAAqC;IACrC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,iEAAiE;IACjE,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,wCAAwC;IACxC,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,uEAO1B,cAAc,KAAG,SAsBnB,CAAC"}
|