@dailies-studio/shot-editor 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.vite/manifest.json +382 -0
- package/dist/assets/AgentPanel-CQejLbiX.js +2 -0
- package/dist/assets/AgentPanel-DJEphah0.css +1 -0
- package/dist/assets/AgentQuestionDialog-BqkD0kXF.js +1 -0
- package/dist/assets/CodeStudio-Dv4ihHpz.js +23 -0
- package/dist/assets/CommentsPanel-B4yhhT1T.js +1 -0
- package/dist/assets/ComponentLibraryRail-Ch_dsAru.js +1 -0
- package/dist/assets/ComponentStage-BRhRotyH.js +1 -0
- package/dist/assets/CurvePane-BjFVabKX.css +1 -0
- package/dist/assets/CurvePane-R22WzllJ.js +1 -0
- package/dist/assets/ExportDialog-CWLQWTmG.js +2 -0
- package/dist/assets/FontPicker-DWKaYL7F.js +1 -0
- package/dist/assets/FontPicker-v0IOIArM.css +1 -0
- package/dist/assets/GenerateDrawer-Bh3SqDKt.js +2 -0
- package/dist/assets/InsertDrawer-Ce1fod1L.js +1 -0
- package/dist/assets/LibraryBrowser-D9sEGz5w.js +2 -0
- package/dist/assets/MakeItYoursSection-CMO4319_.js +2 -0
- package/dist/assets/MaterialGraphCanvas-BFzl4wWR.js +23 -0
- package/dist/assets/MaterialGraphCanvas-BIUD59ik.css +1 -0
- package/dist/assets/MaterialWorkspace-CqTWqaRA.js +14 -0
- package/dist/assets/PreferencesDialog-CBf9_OoD.js +1 -0
- package/dist/assets/PresetsSection-CUEaoCVU.js +1 -0
- package/dist/assets/SoundHistory-BeS8EW1h.js +1 -0
- package/dist/assets/SoundMode-BmcZru3i.js +3 -0
- package/dist/assets/StockSounds-DdAUGRYK.js +1 -0
- package/dist/assets/TemplateFieldSection-CaeXpLFo.js +1 -0
- package/dist/assets/VersionHistoryPanel-CxG6XhNP.js +1 -0
- package/dist/assets/board-B88EPuLO.css +1 -0
- package/dist/assets/board-CL-he7SL.js +3 -0
- package/dist/assets/components-0oOSPN0l.js +1 -0
- package/dist/assets/googleFontRanges-gp32wJMo.js +1 -0
- package/dist/assets/googleFonts-BNon6M7X.js +1 -0
- package/dist/assets/iconsAndAliases-DL7gXP5j.js +1863 -0
- package/dist/assets/index-4F5NQmI8.css +1 -0
- package/dist/assets/index-BGHQGV5z.js +117 -0
- package/dist/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
- package/dist/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
- package/dist/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
- package/dist/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
- package/dist/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
- package/dist/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
- package/dist/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
- package/dist/assets/libraryModel-CpIwfFha.js +1 -0
- package/dist/assets/lucide-6iK64tTB.js +9319 -0
- package/dist/assets/motionStamp-CH-Hew4E.js +1 -0
- package/dist/assets/takeMeasure-Tdg0TxEi.js +1 -0
- package/dist/assets/webmcp-BsB9gxWC.js +2 -0
- package/dist/index.html +34 -3
- package/package.json +12 -9
- package/src/addFamilies.ts +66 -0
- package/src/api.ts +1631 -55
- package/src/app/App.tsx +977 -198
- package/src/app/lazyPanel.tsx +137 -0
- package/src/app/lazySurfaces.tsx +203 -0
- package/src/audio/index.tsx +41 -10
- package/src/audio/meter.ts +485 -0
- package/src/audio/meterMath.ts +273 -0
- package/src/audio/meterStore.ts +155 -0
- package/src/audio/offlineMix.ts +289 -0
- package/src/audio/preview.ts +928 -118
- package/src/bridge.ts +15 -5
- package/src/bridgeTypes.ts +1611 -36
- package/src/channels.ts +17 -32
- package/src/fonts/googleFonts.ts +4 -0
- package/src/hostApi.ts +174 -0
- package/src/icons.tsx +770 -0
- package/src/layerWords.ts +61 -0
- package/src/main.tsx +56 -4
- package/src/panels/ResizeHandle.tsx +33 -43
- package/src/panels/agent/AgentDots.tsx +36 -0
- package/src/panels/agent/AgentPanel.tsx +119 -43
- package/src/panels/agent/AgentQuestionDialog.tsx +202 -0
- package/src/panels/agent/agent.css +113 -97
- package/src/panels/agent/agentGate.ts +35 -0
- package/src/panels/code/CodeDefaultsPanel.tsx +345 -0
- package/src/panels/code/CodeStudio.tsx +373 -0
- package/src/panels/code/FileTree.tsx +265 -0
- package/src/panels/code/codeBufferGuard.ts +52 -0
- package/src/panels/code/codeParts.tsx +321 -0
- package/src/panels/comments/CommentComposer.tsx +239 -0
- package/src/panels/comments/CommentThread.tsx +346 -0
- package/src/panels/comments/CommentsPanel.tsx +336 -0
- package/src/panels/comments/InboxButton.tsx +131 -0
- package/src/panels/comments/MentionMenu.tsx +98 -0
- package/src/panels/comments/parts.tsx +171 -0
- package/src/panels/export/ExportDialog.tsx +919 -96
- package/src/panels/export/ExportScrim.tsx +57 -0
- package/src/panels/files/AssetsTab.tsx +656 -0
- package/src/panels/files/FilePanel.tsx +1466 -216
- package/src/panels/files/LayerMarks.tsx +40 -0
- package/src/panels/files/LeftColumn.tsx +37 -0
- package/src/panels/files/McpSection.tsx +690 -47
- package/src/panels/files/MissingAssetsNotice.tsx +60 -0
- package/src/panels/files/assetDrag.ts +79 -0
- package/src/panels/files/resourceParts.tsx +255 -0
- package/src/panels/fonts/FontPicker.tsx +762 -0
- package/src/panels/fonts/faceCache.ts +207 -0
- package/src/panels/fonts/fontPicker.css +271 -0
- package/src/panels/fonts/pickerModel.ts +265 -0
- package/src/panels/fonts/pickerRequest.ts +46 -0
- package/src/panels/header/AccountAvatar.tsx +76 -0
- package/src/panels/header/AgentChip.tsx +77 -0
- package/src/panels/header/AppMenu.tsx +213 -0
- package/src/panels/header/Header.tsx +564 -84
- package/src/panels/header/HistoryControls.tsx +31 -5
- package/src/panels/header/PresenceStack.tsx +329 -0
- package/src/panels/header/ProjectTitle.tsx +232 -0
- package/src/panels/header/ShareButton.tsx +59 -0
- package/src/panels/header/StatusBadges.tsx +358 -27
- package/src/panels/header/SyncDeletedDialog.tsx +88 -0
- package/src/panels/header/ZoomControls.tsx +46 -15
- package/src/panels/header/agentHandoff.ts +52 -0
- package/src/panels/header/leave.ts +26 -0
- package/src/panels/help/HelpSection.tsx +189 -163
- package/src/panels/insert/InsertDrawer.tsx +723 -0
- package/src/panels/insert/iconSet.ts +109 -0
- package/src/panels/inspector/ExposeDot.tsx +117 -0
- package/src/panels/inspector/FramingRows.tsx +314 -44
- package/src/panels/inspector/InspectorFooter.tsx +91 -0
- package/src/panels/inspector/InspectorHead.tsx +425 -0
- package/src/panels/inspector/InspectorPanel.tsx +408 -124
- package/src/panels/inspector/KeyframeDot.tsx +373 -0
- package/src/panels/inspector/KeyframeSection.tsx +257 -0
- package/src/panels/inspector/MarkerSection.tsx +55 -11
- package/src/panels/inspector/ParamRow.tsx +84 -53
- package/src/panels/inspector/RightColumn.tsx +152 -0
- package/src/panels/inspector/TimeSection.tsx +866 -0
- package/src/panels/inspector/animate/EaseControl.tsx +244 -0
- package/src/panels/inspector/animate/PresetsSection.tsx +135 -0
- package/src/panels/inspector/animate/ShotSection.tsx +562 -48
- package/src/panels/inspector/design/AlignRow.tsx +95 -31
- package/src/panels/inspector/design/AppearanceSection.tsx +118 -9
- package/src/panels/inspector/design/ClonerSection.tsx +323 -62
- package/src/panels/inspector/design/ComponentSection.tsx +50 -43
- package/src/panels/inspector/design/CornerSection.tsx +45 -14
- package/src/panels/inspector/design/DefinitionProps.tsx +315 -0
- package/src/panels/inspector/design/DefinitionSection.tsx +136 -0
- package/src/panels/inspector/design/DeviceSection.tsx +210 -0
- package/src/panels/inspector/design/FillSection.tsx +83 -51
- package/src/panels/inspector/design/FontField.tsx +196 -0
- package/src/panels/inspector/design/HtmlSection.tsx +23 -12
- package/src/panels/inspector/design/InstanceSection.tsx +373 -154
- package/src/panels/inspector/design/MaskSection.tsx +84 -0
- package/src/panels/inspector/design/MaterialSection.tsx +177 -0
- package/src/panels/inspector/design/MediaSection.tsx +273 -120
- package/src/panels/inspector/design/MeshSection.tsx +910 -82
- package/src/panels/inspector/design/PaintRows.tsx +550 -0
- package/src/panels/inspector/design/PlateStyleSection.tsx +177 -0
- package/src/panels/inspector/design/ShadowSection.tsx +221 -48
- package/src/panels/inspector/design/SplineFollowSection.tsx +235 -0
- package/src/panels/inspector/design/StrokeSection.tsx +228 -43
- package/src/panels/inspector/design/TemplateFieldSection.tsx +57 -0
- package/src/panels/inspector/design/TransformSection.tsx +244 -50
- package/src/panels/inspector/design/TypographySection.tsx +679 -110
- package/src/panels/inspector/layout.ts +295 -0
- package/src/panels/inspector/propValue.ts +199 -0
- package/src/panels/inspector/scene/CameraSection.tsx +232 -22
- package/src/panels/inspector/scene/EffectsSection.tsx +722 -71
- package/src/panels/inspector/scene/MakeItYoursSection.tsx +180 -0
- package/src/panels/inspector/scene/SceneDocSection.tsx +191 -0
- package/src/panels/inspector/scene/SceneSection.tsx +219 -44
- package/src/panels/inspector/scene/TransitionSection.tsx +523 -72
- package/src/panels/inspector/storyboard/StoryboardReferenceSection.tsx +593 -0
- package/src/panels/inspector/storyboard/VideoStill.tsx +120 -0
- package/src/panels/inspector/timeModel.ts +190 -0
- package/src/panels/inspector/useDocWrite.ts +438 -146
- package/src/panels/library/LibraryBrowser.tsx +435 -0
- package/src/panels/library/LibraryGrid.tsx +190 -0
- package/src/panels/library/LibraryPreviewPanel.tsx +349 -0
- package/src/panels/library/LibraryRail.tsx +84 -0
- package/src/panels/library/LibrarySoundPanel.tsx +293 -0
- package/src/panels/library/SoundHistory.tsx +245 -0
- package/src/panels/library/StockSounds.tsx +390 -0
- package/src/panels/library/libraryModel.ts +147 -0
- package/src/panels/library/stockSearch.ts +77 -0
- package/src/panels/maskMarks.tsx +117 -0
- package/src/panels/material/MaterialCommentNode.tsx +54 -0
- package/src/panels/material/MaterialGraphCanvas.tsx +861 -0
- package/src/panels/material/MaterialGraphMenu.tsx +45 -0
- package/src/panels/material/MaterialGroupNode.tsx +56 -0
- package/src/panels/material/MaterialLibrary.tsx +253 -0
- package/src/panels/material/MaterialNode.tsx +453 -0
- package/src/panels/material/MaterialNodePalette.tsx +349 -0
- package/src/panels/material/MaterialParameterControls.tsx +525 -0
- package/src/panels/material/MaterialRerouteNode.tsx +42 -0
- package/src/panels/material/MaterialWorkspace.tsx +501 -0
- package/src/panels/material/NodePreview.tsx +70 -0
- package/src/panels/material/flowModel.ts +441 -0
- package/src/panels/material/parameterValues.ts +231 -0
- package/src/panels/material/previewScheduler.ts +235 -0
- package/src/panels/material/reactFlow.css +6 -0
- package/src/panels/material/socketGlyph.ts +85 -0
- package/src/panels/material/viewportMemory.ts +58 -0
- package/src/panels/preferences/PreferencesDialog.tsx +215 -0
- package/src/panels/share/ShareComponentDialog.tsx +247 -0
- package/src/panels/stage/StageMenu.tsx +35 -5
- package/src/panels/stage/StagePanel.tsx +338 -23
- package/src/panels/stage/cellSlots.tsx +70 -0
- package/src/panels/storyboard/BoardCanvas.tsx +739 -0
- package/src/panels/storyboard/BoardCursors.tsx +158 -0
- package/src/panels/storyboard/BoardDropDialog.tsx +161 -0
- package/src/panels/storyboard/BoardPlan.tsx +42 -0
- package/src/panels/storyboard/ComponentSheet.tsx +187 -0
- package/src/panels/storyboard/ComponentStage.tsx +235 -0
- package/src/panels/storyboard/MiniSketch.tsx +173 -0
- package/src/panels/storyboard/PartPicker.tsx +64 -0
- package/src/panels/storyboard/PlanPanel.tsx +617 -0
- package/src/panels/storyboard/ReferencePreview.tsx +217 -0
- package/src/panels/storyboard/ShotBrief.tsx +360 -0
- package/src/panels/storyboard/ShotCard.tsx +251 -0
- package/src/panels/storyboard/StagePreview.tsx +348 -0
- package/src/panels/storyboard/StillThumbs.tsx +162 -0
- package/src/panels/storyboard/StoryboardView.tsx +79 -0
- package/src/panels/storyboard/board.css +1065 -0
- package/src/panels/storyboard/board.ts +12 -0
- package/src/panels/storyboard/boardClipboard.ts +111 -0
- package/src/panels/storyboard/boardOrder.ts +68 -0
- package/src/panels/storyboard/boardRows.tsx +425 -0
- package/src/panels/storyboard/liveCap.ts +90 -0
- package/src/panels/storyboard/plan.css +295 -0
- package/src/panels/storyboard/posterCache.ts +133 -0
- package/src/panels/storyboard/shotboard/ComponentPicker.tsx +373 -0
- package/src/panels/storyboard/shotboard/ImagePicker.tsx +145 -0
- package/src/panels/storyboard/shotboard/ShotBoard.tsx +292 -0
- package/src/panels/storyboard/shotboard/SketchCanvas.tsx +443 -0
- package/src/panels/storyboard/shotboard/SketchInspector.tsx +471 -0
- package/src/panels/storyboard/shotboard/SketchItem.tsx +240 -0
- package/src/panels/storyboard/shotboard/SketchLayers.tsx +130 -0
- package/src/panels/storyboard/shotboard/SketchPlay.tsx +108 -0
- package/src/panels/storyboard/shotboard/SketchStrip.tsx +178 -0
- package/src/panels/storyboard/shotboard/SketchToolFooter.tsx +99 -0
- package/src/panels/storyboard/shotboard/sketch.css +1392 -0
- package/src/panels/storyboard/shotboard/sketchModel.ts +219 -0
- package/src/panels/storyboard/storyboardDrop.ts +164 -0
- package/src/panels/studio/ComponentLibraryRail.tsx +346 -0
- package/src/panels/studio/ComponentSidePanel.tsx +355 -0
- package/src/panels/studio/ComponentStudio.tsx +243 -0
- package/src/panels/studio/ComponentsHome.tsx +318 -0
- package/src/panels/studio/ComponentsPreview.tsx +179 -0
- package/src/panels/studio/EveryUse.tsx +244 -0
- package/src/panels/studio/ThisUsePanel.tsx +679 -0
- package/src/panels/studio/componentParts.tsx +341 -0
- package/src/panels/studio/components.ts +6 -0
- package/src/panels/studio/newCodeComponent.ts +66 -0
- package/src/panels/timeline/AudioFxButton.tsx +290 -0
- package/src/panels/timeline/AudioLane.tsx +674 -85
- package/src/panels/timeline/BlockRow.tsx +154 -85
- package/src/panels/timeline/ChannelRow.tsx +378 -129
- package/src/panels/timeline/CurvePane.tsx +508 -0
- package/src/panels/timeline/Filmstrip.tsx +361 -0
- package/src/panels/timeline/GenerateDrawer.tsx +407 -0
- package/src/panels/timeline/KeyStretch.tsx +115 -0
- package/src/panels/timeline/LifespanRow.tsx +730 -47
- package/src/panels/timeline/MarkerLane.tsx +46 -8
- package/src/panels/timeline/PlayButton.tsx +91 -0
- package/src/panels/timeline/PropertyPicker.tsx +254 -0
- package/src/panels/timeline/ShotRow.tsx +400 -0
- package/src/panels/timeline/SoundMode.tsx +1406 -0
- package/src/panels/timeline/TimelineDock.tsx +2338 -272
- package/src/panels/timeline/TransportVolume.tsx +163 -0
- package/src/panels/timeline/beatRuler.ts +74 -0
- package/src/panels/timeline/curveModel.ts +500 -0
- package/src/panels/timeline/duckUnderVoice.ts +68 -0
- package/src/panels/timeline/keyframeMenu.ts +138 -0
- package/src/panels/timeline/labelWidth.ts +49 -0
- package/src/panels/timeline/marquee.ts +155 -0
- package/src/panels/timeline/model.ts +1860 -199
- package/src/panels/timeline/snap.ts +125 -43
- package/src/panels/timeline/staggerPreview.tsx +92 -0
- package/src/panels/timeline/takeMeasure.ts +72 -0
- package/src/panels/timeline/useLive.ts +48 -0
- package/src/panels/timeline/viewport.ts +234 -0
- package/src/panels/toolbar/BackChip.tsx +116 -0
- package/src/panels/toolbar/CameraViewBar.tsx +118 -49
- package/src/panels/toolbar/CanvasBar.tsx +117 -0
- package/src/panels/toolbar/InsertButton.tsx +38 -0
- package/src/panels/toolbar/IsolationTrail.tsx +156 -0
- package/src/panels/toolbar/PanelToggles.tsx +86 -0
- package/src/panels/toolbar/ShadingBar.tsx +119 -26
- package/src/panels/toolbar/ToolDockBar.tsx +329 -80
- package/src/panels/toolbar/ToolFooter.tsx +102 -0
- package/src/panels/toolbar/ViewModeBar.tsx +247 -38
- package/src/panels/toolbar/WorkPlaneBar.tsx +94 -0
- package/src/panels/toolbar/useAddRows.tsx +326 -0
- package/src/panels/toolbar/useDismiss.ts +122 -0
- package/src/panels/versions/VersionHistoryPanel.tsx +274 -0
- package/src/panels/versions/versionModel.ts +103 -0
- package/src/panels/virtualWindow.ts +271 -0
- package/src/shotTokens.css +151 -60
- package/src/stage/FrustumGizmo.tsx +504 -84
- package/src/stage/GridPlane.tsx +225 -16
- package/src/stage/NodePreviews.tsx +628 -0
- package/src/stage/PerfHud.tsx +437 -47
- package/src/stage/SplitRenderer.tsx +816 -169
- package/src/stage/StageApp.tsx +4274 -486
- package/src/stage/StageRootBoundary.tsx +114 -0
- package/src/stage/StageTools.tsx +651 -151
- package/src/stage/TransformGizmo.tsx +696 -0
- package/src/stage/adaptivePresentation.ts +145 -0
- package/src/stage/bridgeClient.ts +2522 -41
- package/src/stage/exportWorker.ts +9 -0
- package/src/stage/feed.ts +305 -14
- package/src/stage/fontPreview.ts +176 -0
- package/src/stage/frustumGeometry.ts +319 -1
- package/src/stage/furnitureTokens.ts +33 -0
- package/src/stage/gizmoMath.ts +508 -16
- package/src/stage/gpuTimer.ts +276 -0
- package/src/stage/instanceModules.ts +194 -33
- package/src/stage/interactions/move.ts +24 -5
- package/src/stage/isolation.ts +291 -33
- package/src/stage/jsSelfProfiler.ts +325 -0
- package/src/stage/main.tsx +116 -16
- package/src/stage/modalState.ts +222 -23
- package/src/stage/moduleEpoch.ts +60 -0
- package/src/stage/motionPathStage.ts +279 -0
- package/src/stage/motionPreview.ts +74 -0
- package/src/stage/overlays/Overlays.tsx +1112 -159
- package/src/stage/overlays/Rulers.tsx +495 -0
- package/src/stage/panes.ts +159 -10
- package/src/stage/project.ts +68 -3
- package/src/stage/renderScaleController.ts +730 -0
- package/src/stage/rulers.ts +129 -0
- package/src/stage/sceneExtent.ts +75 -0
- package/src/stage/shading.ts +20 -0
- package/src/stage/splineStage.ts +632 -0
- package/src/stage/stagePerformanceTelemetry.ts +717 -0
- package/src/stage/stageTheme.ts +36 -0
- package/src/stage/stageWarmup.ts +11 -0
- package/src/stage/textAutoSize.ts +124 -0
- package/src/stage/tier1Export.ts +641 -0
- package/src/stage/tokenColor.ts +14 -9
- package/src/stage/view.ts +56 -9
- package/src/stage/workingView.ts +277 -33
- package/src/state/accountPrefs.ts +261 -0
- package/src/state/agentActions.ts +173 -15
- package/src/state/agentActivity.ts +198 -0
- package/src/state/agentQuestion.ts +239 -0
- package/src/state/bootOpen.ts +42 -0
- package/src/state/cameraVerbs.ts +139 -0
- package/src/state/clientId.ts +6 -1
- package/src/state/comments.ts +1099 -0
- package/src/state/context.tsx +19 -1
- package/src/state/editorPrefs.ts +220 -0
- package/src/state/errorReports.ts +121 -0
- package/src/state/fieldWrite.ts +161 -0
- package/src/state/fontRecents.ts +70 -0
- package/src/state/fonts.ts +656 -0
- package/src/state/graphClipboard.ts +414 -0
- package/src/state/imageThumbs.ts +216 -0
- package/src/state/insert.ts +444 -67
- package/src/state/isolationTrail.ts +92 -0
- package/src/state/keyMoves.ts +134 -0
- package/src/state/keyframeClipboard.ts +177 -0
- package/src/state/keymap.ts +1153 -117
- package/src/state/layoutPrefs.ts +272 -0
- package/src/state/layouts.ts +205 -0
- package/src/state/measureMedia.ts +167 -0
- package/src/state/menu.ts +2341 -28
- package/src/state/motionStamp.ts +7 -0
- package/src/state/panelSize.ts +375 -5
- package/src/state/pendingChanges.ts +119 -0
- package/src/state/playHold.ts +78 -0
- package/src/state/playbackPreparation.ts +562 -0
- package/src/state/posterCapture.ts +242 -0
- package/src/state/presence.ts +254 -0
- package/src/state/projectComponents.ts +160 -0
- package/src/state/renderEvents.ts +298 -18
- package/src/state/runtimeErrors.ts +46 -0
- package/src/state/selection.ts +12 -0
- package/src/state/shortcuts.ts +1606 -0
- package/src/state/sketchGuide.ts +51 -0
- package/src/state/splineRefs.ts +87 -0
- package/src/state/stageHealth.ts +259 -0
- package/src/state/stageWatchdog.ts +47 -0
- package/src/state/stillStage.ts +330 -0
- package/src/state/stillThumbs.ts +474 -0
- package/src/state/store.ts +23591 -2982
- package/src/state/storyboardModel.ts +528 -0
- package/src/state/sync.ts +1257 -0
- package/src/state/syncCache.ts +159 -0
- package/src/state/triangles.ts +13 -0
- package/src/state/types.ts +1698 -55
- package/src/state/unsavedGuard.ts +49 -0
- package/src/state/viewMode.ts +200 -0
- package/src/state/webmcp.ts +1128 -0
- package/src/state/workspace.ts +1147 -0
- package/src/styles/assets-tab.css +304 -0
- package/src/styles/canvas.css +545 -0
- package/src/styles/comments.css +1435 -0
- package/src/styles/controls.css +162 -0
- package/src/styles/dialogs.css +390 -0
- package/src/styles/insert-drawer.css +586 -0
- package/src/styles/inspector-board.css +207 -0
- package/src/styles/inspector-object.css +486 -0
- package/src/styles/inspector-shot.css +252 -0
- package/src/styles/inspector.css +360 -0
- package/src/styles/left-column.css +1628 -0
- package/src/styles/library-preview.css +575 -0
- package/src/styles/library.css +512 -0
- package/src/styles/modes/code.css +569 -0
- package/src/styles/modes/component.css +1561 -0
- package/src/styles/modes/material.css +1201 -0
- package/src/styles/modes/storyboard.css +518 -0
- package/src/styles/share-component.css +49 -0
- package/src/styles/shell.css +653 -0
- package/src/styles/shot-brief.css +360 -0
- package/src/styles/states.css +76 -0
- package/src/styles/sync.css +380 -0
- package/src/styles/timeline-graph.css +384 -0
- package/src/styles/timeline-meters.css +89 -0
- package/src/styles/timeline-rows.css +1959 -0
- package/src/styles/timeline-sound.css +1003 -0
- package/src/styles/timeline.css +754 -0
- package/src/styles/tool-footer.css +525 -0
- package/src/styles/topbar.css +886 -0
- package/src/styles/versions.css +262 -0
- package/src/styles.css +72 -2921
- package/src/tools.ts +108 -23
- package/dist/assets/index-B7notge7.css +0 -1
- package/dist/assets/index-BBE6Ta9L.js +0 -52
- package/src/panels/files/icons.tsx +0 -118
- package/src/panels/header/DocSwitcher.tsx +0 -85
- package/src/panels/header/TransportBar.tsx +0 -86
- package/src/panels/inspector/animate/BlockTiming.tsx +0 -341
- package/src/panels/inspector/animate/DuringBlocks.tsx +0 -85
- package/src/panels/inspector/animate/InOutPresets.tsx +0 -57
- package/src/panels/inspector/animate/ResolvedChannels.tsx +0 -150
- package/src/panels/inspector/animate/useBlocks.ts +0 -43
- package/src/panels/material/MaterialPicker.tsx +0 -172
- package/src/panels/timeline/SceneStrip.tsx +0 -145
- package/src/panels/toolbar/AddMenu.tsx +0 -230
- package/src/stage/MoveGizmo.tsx +0 -411
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// THE DOCK'S + : it opens and closes the Insert drawer (InsertDrawer.tsx),
|
|
2
|
+
// which lists every insert a drag cannot express (a file, a registry choice,
|
|
3
|
+
// an operation on the selection) beside the icons, shaders and backgrounds.
|
|
4
|
+
//
|
|
5
|
+
// It also hosts the media tool's file claim. The media tool draws its box on
|
|
6
|
+
// the stage and only then needs a file, so its geometry parks in the store
|
|
7
|
+
// (`imagePick`) and a mounted `useAddRows` with the claim opens the dialog for
|
|
8
|
+
// it. The dock is mounted whenever the media tool can be armed, so the claim
|
|
9
|
+
// lives here and not in the drawer, which is often closed.
|
|
10
|
+
//
|
|
11
|
+
// A VIEWER sees no +: there is no insert for them to make. The claim's input
|
|
12
|
+
// stays mounted, since it costs nothing and a read-only flip mid-pick must not
|
|
13
|
+
// strand the dialog's answer.
|
|
14
|
+
import { useShotEditor, useStore } from "../../state/context.js";
|
|
15
|
+
import { ADD_ICON } from "../../icons.js";
|
|
16
|
+
import { ToolButton } from "./ToolDockBar.js";
|
|
17
|
+
import { useAddRows } from "./useAddRows.js";
|
|
18
|
+
|
|
19
|
+
export function InsertButton() {
|
|
20
|
+
const store = useStore();
|
|
21
|
+
const inserting = useShotEditor((s) => s.insertDrawer !== null);
|
|
22
|
+
const viewer = useShotEditor((s) => s.readOnly);
|
|
23
|
+
const { busy, fileInput } = useAddRows({ wantLibrary: false });
|
|
24
|
+
return (
|
|
25
|
+
<>
|
|
26
|
+
{viewer ? null : (
|
|
27
|
+
<ToolButton
|
|
28
|
+
armed={inserting}
|
|
29
|
+
refusal={busy ? "Waiting for the last file to finish importing" : null}
|
|
30
|
+
title="Insert: shapes, icons, shaders and backgrounds"
|
|
31
|
+
icon={ADD_ICON}
|
|
32
|
+
onClick={() => store.toggleInsertDrawer()}
|
|
33
|
+
/>
|
|
34
|
+
)}
|
|
35
|
+
{fileInput}
|
|
36
|
+
</>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
// Where the author is while isolated, over the canvas they are looking at.
|
|
2
|
+
//
|
|
3
|
+
// It replaces the stage's old "INSIDE X. ESC TO LEAVE" strip (a 22px accent
|
|
4
|
+
// bar across the top of the pane) and the canvas bar's one-level back chip.
|
|
5
|
+
// One trail says the mode, the path, and every way out:
|
|
6
|
+
//
|
|
7
|
+
// Shot › … › Group › [icon] line Not on screen Done
|
|
8
|
+
//
|
|
9
|
+
// - The shot crumb and Done leave isolation entirely (`exitIsolationAll`).
|
|
10
|
+
// - An ancestor crumb climbs to that level with the store's one-level verb,
|
|
11
|
+
// once per level. `enterIsolation(ancestor)` only looks like it: it selects
|
|
12
|
+
// the ancestor instead of the group just left.
|
|
13
|
+
// - The current crumb does nothing on click: it is where the author is.
|
|
14
|
+
// - Past two ancestors, all but the nearest fold into a `…` menu, so the bar
|
|
15
|
+
// keeps its width at any depth.
|
|
16
|
+
//
|
|
17
|
+
// Done names no key on purpose: Escape deselects first and climbs one level,
|
|
18
|
+
// while Done leaves every level at once. See BackChip.tsx for the same call.
|
|
19
|
+
import { useContextMenu } from "@dailies-studio/ui";
|
|
20
|
+
import { useRef } from "react";
|
|
21
|
+
import { CHEVRON_RIGHT_ICON, iconFor, isComponentGlyph } from "../../icons.js";
|
|
22
|
+
import { useShotEditor, useShotEditorHot, useStore } from "../../state/context.js";
|
|
23
|
+
import { crumbsFor, isolationOffscreen } from "../../state/isolationTrail.js";
|
|
24
|
+
|
|
25
|
+
/** Ancestors shown inline before the rest fold into the `…` menu. */
|
|
26
|
+
const INLINE_ANCESTORS = 2;
|
|
27
|
+
|
|
28
|
+
export function IsolationTrail() {
|
|
29
|
+
const store = useStore();
|
|
30
|
+
// The doc reference moves on edits only, never on playback frames, so this
|
|
31
|
+
// re-renders when a label or the tree changes and not 60 times a second.
|
|
32
|
+
const doc = useShotEditor((s) => s.doc);
|
|
33
|
+
const sceneId = useShotEditor((s) => s.sceneId);
|
|
34
|
+
const isolation = useShotEditor((s) => (s.editingDef === null ? s.isolation : null));
|
|
35
|
+
const { open, menu } = useContextMenu();
|
|
36
|
+
const moreRef = useRef<HTMLButtonElement | null>(null);
|
|
37
|
+
|
|
38
|
+
const scene = doc === null || sceneId === null ? undefined : doc.scenesById[sceneId];
|
|
39
|
+
const layer = isolation === null ? undefined : scene?.layersById[isolation];
|
|
40
|
+
if (scene === undefined || layer === undefined || isolation === null) return null;
|
|
41
|
+
|
|
42
|
+
const trail = crumbsFor(scene, isolation);
|
|
43
|
+
const ancestors = trail.slice(0, -1);
|
|
44
|
+
const folded = ancestors.length > INLINE_ANCESTORS ? ancestors.slice(0, -1) : [];
|
|
45
|
+
const inline = folded.length > 0 ? ancestors.slice(-1) : ancestors;
|
|
46
|
+
const labelOf = (id: string): string => scene.layersById[id]?.label ?? id;
|
|
47
|
+
/** Up to `id`, one level per call, the way Escape climbs. */
|
|
48
|
+
const climbTo = (id: string): void => {
|
|
49
|
+
const levels = trail.length - 1 - trail.indexOf(id);
|
|
50
|
+
for (let n = 0; n < levels; n += 1) store.exitIsolation();
|
|
51
|
+
};
|
|
52
|
+
const showFolded = (): void => {
|
|
53
|
+
const el = moreRef.current;
|
|
54
|
+
if (el === null) return;
|
|
55
|
+
const r = el.getBoundingClientRect();
|
|
56
|
+
open(
|
|
57
|
+
{ x: r.left, y: r.bottom + 6 },
|
|
58
|
+
folded.map((id) => ({
|
|
59
|
+
kind: "action" as const,
|
|
60
|
+
id: `isolation.crumb.${id}`,
|
|
61
|
+
label: labelOf(id),
|
|
62
|
+
onSelect: () => climbTo(id),
|
|
63
|
+
})),
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
const sep = (
|
|
67
|
+
<span className="iso-trail-sep" aria-hidden="true">
|
|
68
|
+
{CHEVRON_RIGHT_ICON}
|
|
69
|
+
</span>
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<>
|
|
74
|
+
<nav className="iso-trail" aria-label="Isolation path" data-testid="isolation-trail">
|
|
75
|
+
<button
|
|
76
|
+
type="button"
|
|
77
|
+
className="iso-crumb"
|
|
78
|
+
data-testid="trail-shot"
|
|
79
|
+
title={`Back to ${scene.name}`}
|
|
80
|
+
onClick={() => store.exitIsolationAll()}
|
|
81
|
+
>
|
|
82
|
+
{scene.name}
|
|
83
|
+
</button>
|
|
84
|
+
{folded.length === 0 ? null : (
|
|
85
|
+
<span className="iso-trail-step">
|
|
86
|
+
{sep}
|
|
87
|
+
<button
|
|
88
|
+
ref={moreRef}
|
|
89
|
+
type="button"
|
|
90
|
+
className={`iso-crumb is-more${menu !== null ? " is-open" : ""}`}
|
|
91
|
+
aria-haspopup="menu"
|
|
92
|
+
aria-expanded={menu !== null}
|
|
93
|
+
aria-label={`${folded.length} more levels`}
|
|
94
|
+
title={folded.map(labelOf).join(" › ")}
|
|
95
|
+
data-testid="trail-more"
|
|
96
|
+
onClick={showFolded}
|
|
97
|
+
>
|
|
98
|
+
…
|
|
99
|
+
</button>
|
|
100
|
+
{menu}
|
|
101
|
+
</span>
|
|
102
|
+
)}
|
|
103
|
+
{inline.map((id) => (
|
|
104
|
+
<span key={id} className="iso-trail-step">
|
|
105
|
+
{sep}
|
|
106
|
+
<button
|
|
107
|
+
type="button"
|
|
108
|
+
className="iso-crumb"
|
|
109
|
+
title={`Back to ${labelOf(id)}`}
|
|
110
|
+
onClick={() => climbTo(id)}
|
|
111
|
+
>
|
|
112
|
+
{labelOf(id)}
|
|
113
|
+
</button>
|
|
114
|
+
</span>
|
|
115
|
+
))}
|
|
116
|
+
{sep}
|
|
117
|
+
<span className="iso-crumb is-current" aria-current="location" data-testid="trail-current">
|
|
118
|
+
<span
|
|
119
|
+
className={`iso-crumb-icon${isComponentGlyph(layer) ? " is-component" : ""}`}
|
|
120
|
+
aria-hidden="true"
|
|
121
|
+
>
|
|
122
|
+
{iconFor(layer)}
|
|
123
|
+
</span>
|
|
124
|
+
<span className="iso-crumb-label">{layer.label}</span>
|
|
125
|
+
</span>
|
|
126
|
+
<OffscreenChip />
|
|
127
|
+
</nav>
|
|
128
|
+
<button
|
|
129
|
+
type="button"
|
|
130
|
+
className="btn is-ghost iso-done"
|
|
131
|
+
data-testid="isolation-done"
|
|
132
|
+
title={`Leave isolation, back to ${scene.name}`}
|
|
133
|
+
onClick={() => store.exitIsolationAll()}
|
|
134
|
+
>
|
|
135
|
+
Done
|
|
136
|
+
</button>
|
|
137
|
+
</>
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** The playhead moves on the clock tick, which `useShotEditor` is deaf to, so
|
|
142
|
+
* this leaf alone subscribes hot. The selector is a boolean: it re-renders
|
|
143
|
+
* only when the answer flips, never per frame. */
|
|
144
|
+
function OffscreenChip() {
|
|
145
|
+
const offscreen = useShotEditorHot(isolationOffscreen);
|
|
146
|
+
if (!offscreen) return null;
|
|
147
|
+
return (
|
|
148
|
+
<span
|
|
149
|
+
className="status-chip status-chip-quiet iso-offscreen"
|
|
150
|
+
data-testid="trail-offscreen"
|
|
151
|
+
title="Nothing in this layer is drawing at the playhead"
|
|
152
|
+
>
|
|
153
|
+
Not on screen
|
|
154
|
+
</span>
|
|
155
|
+
);
|
|
156
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// Show and hide the three panels, from the canvas bar.
|
|
2
|
+
//
|
|
3
|
+
// ON THE CANVAS BAR, not on the panels themselves: a control that lives on the
|
|
4
|
+
// thing it hides disappears with it. The canvas cell never collapses, so the
|
|
5
|
+
// bar is the one place that can always bring a panel back.
|
|
6
|
+
//
|
|
7
|
+
// ONE TRIGGER, NOT THREE BUTTONS (Paper 27, "7 · Canvas bar"). Three glyph
|
|
8
|
+
// toggles cost the bar ~92px it needed for the plane and shading controls,
|
|
9
|
+
// and their state was a fill the eye had to decode. The menu says it in words
|
|
10
|
+
// with a check per panel, plus "Every panel", and shows each row's key, read
|
|
11
|
+
// off the shortcut table like every other accelerator in the chrome.
|
|
12
|
+
//
|
|
13
|
+
// The rows are built at OPEN time from `getState()` (StageMenu's rule), so a
|
|
14
|
+
// key pressed while the menu is closed is reflected the next time it opens.
|
|
15
|
+
import { useContextMenu, type MenuEntry } from "@dailies-studio/ui";
|
|
16
|
+
import { useRef } from "react";
|
|
17
|
+
import { CHEVRON_DOWN_ICON, PANELS_ICON } from "../../icons.js";
|
|
18
|
+
import { useShotEditor, useStore } from "../../state/context.js";
|
|
19
|
+
import { shortcutFor, shortcutHint } from "../../state/shortcuts.js";
|
|
20
|
+
|
|
21
|
+
export function PanelToggles() {
|
|
22
|
+
const store = useStore();
|
|
23
|
+
const docOpen = useShotEditor((s) => s.name !== null);
|
|
24
|
+
const { open, menu } = useContextMenu();
|
|
25
|
+
const buttonRef = useRef<HTMLButtonElement | null>(null);
|
|
26
|
+
// DERIVED from `menu`, never mirrored: see AppMenu.
|
|
27
|
+
const isOpen = menu !== null;
|
|
28
|
+
if (!docOpen) return null;
|
|
29
|
+
|
|
30
|
+
const row = (menuId: string, label: string, on: boolean, run: () => void): MenuEntry => ({
|
|
31
|
+
kind: "action",
|
|
32
|
+
id: menuId,
|
|
33
|
+
label,
|
|
34
|
+
checked: on,
|
|
35
|
+
shortcut: shortcutFor(menuId),
|
|
36
|
+
onSelect: run,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const show = (): void => {
|
|
40
|
+
const el = buttonRef.current;
|
|
41
|
+
if (el === null) return;
|
|
42
|
+
const s = store.getState();
|
|
43
|
+
const r = el.getBoundingClientRect();
|
|
44
|
+
open(
|
|
45
|
+
{ x: r.left, y: r.bottom + 6 },
|
|
46
|
+
[
|
|
47
|
+
{ kind: "separator", heading: "Panels" },
|
|
48
|
+
row("view.panel.rail", "Layers", !s.railCollapsed, () => store.setRailCollapsed(!s.railCollapsed)),
|
|
49
|
+
row("view.panel.dock", "Timeline", !s.dockCollapsed, () => store.setDockCollapsed(!s.dockCollapsed)),
|
|
50
|
+
row("view.panel.inspector", "Inspector", !s.inspectorCollapsed, () =>
|
|
51
|
+
store.setInspectorCollapsed(!s.inspectorCollapsed),
|
|
52
|
+
),
|
|
53
|
+
{ kind: "separator" },
|
|
54
|
+
row(
|
|
55
|
+
"view.panel.all",
|
|
56
|
+
"Every panel",
|
|
57
|
+
!s.railCollapsed && !s.dockCollapsed && !s.inspectorCollapsed,
|
|
58
|
+
() => store.togglePanels(),
|
|
59
|
+
),
|
|
60
|
+
],
|
|
61
|
+
{ lanes: "always" },
|
|
62
|
+
);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<div className="panel-toggles">
|
|
67
|
+
<button
|
|
68
|
+
ref={buttonRef}
|
|
69
|
+
type="button"
|
|
70
|
+
className={`tool-button panel-menu-trigger${isOpen ? " is-open" : ""}`}
|
|
71
|
+
aria-haspopup="menu"
|
|
72
|
+
aria-expanded={isOpen}
|
|
73
|
+
aria-label="Panels"
|
|
74
|
+
title={`Panels${shortcutHint("view.panel.all")}`}
|
|
75
|
+
data-testid="panel-menu-trigger"
|
|
76
|
+
onClick={show}
|
|
77
|
+
>
|
|
78
|
+
{PANELS_ICON}
|
|
79
|
+
<span className="panel-menu-caret" aria-hidden="true">
|
|
80
|
+
{CHEVRON_DOWN_ICON}
|
|
81
|
+
</span>
|
|
82
|
+
</button>
|
|
83
|
+
{menu}
|
|
84
|
+
</div>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
@@ -1,42 +1,135 @@
|
|
|
1
1
|
// How the WORKING pane draws: solid clay, wireframe, real materials, or the
|
|
2
2
|
// graded render from the working camera.
|
|
3
3
|
//
|
|
4
|
-
// A
|
|
5
|
-
//
|
|
6
|
-
// NOTHING when the layout is camera-only — the camera pane is always the
|
|
7
|
-
//
|
|
8
|
-
//
|
|
4
|
+
// A table of GLYPHS, and nothing else: the words and the cycle order come from
|
|
5
|
+
// `stage/shading.ts`, which is where the App menu reads them too. It renders
|
|
6
|
+
// NOTHING when the layout is camera-only — the camera pane is always the graded
|
|
7
|
+
// render, so with no working pane on screen there is nothing this bar addresses
|
|
8
|
+
// and an armed button over an invisible pane would be a lie. It sits in the
|
|
9
|
+
// canvas bar's "3D" group (CanvasBar.tsx), which names the pane.
|
|
10
|
+
//
|
|
11
|
+
// ── ONE BUTTON, NOT FOUR, AND ITS OWN CLASS ─────────────────────────────
|
|
12
|
+
//
|
|
13
|
+
// This used to be four 36px glyph buttons wearing `view-mode-bar`, the
|
|
14
|
+
// view-mode segmented control's own class, borrowed for its layout and
|
|
15
|
+
// carrying that control's track and surface with it. It also cost 160px of a
|
|
16
|
+
// bar that does not wrap.
|
|
17
|
+
//
|
|
18
|
+
// So: one trigger showing what the pane is doing now, and the other three a
|
|
19
|
+
// press away. A mode picker IS one control reporting one value, and four
|
|
20
|
+
// mutually exclusive glyphs only read as four choices to someone who already
|
|
21
|
+
// knows the vocabulary. Every mode keeps its own title text, so "Z cycles"
|
|
22
|
+
// stays discoverable on the rows where the modes are.
|
|
23
|
+
//
|
|
24
|
+
// ── THE MENU PORTALS, IT DOES NOT FLY OUT ───────────────────────────────
|
|
25
|
+
//
|
|
26
|
+
// The reason used to be that `.control-strip` carried `overflow: clip` and
|
|
27
|
+
// would clip an absolutely-positioned child. IT NO LONGER DOES — that rule is
|
|
28
|
+
// gone, because it was clipping the dock's own shapes flyout and the whole Add
|
|
29
|
+
// menu into invisible, unclickable boxes. So `.tool-flyout` would work here.
|
|
30
|
+
//
|
|
31
|
+
// It still portals, and the reason is now the one that was always the better
|
|
32
|
+
// one: `.tool-flyout` is CSS and nothing else — it opens where its anchor is,
|
|
33
|
+
// stays there, and closes only from inside itself (its trigger again, or one
|
|
34
|
+
// of its own rows). Nothing outside it can dismiss it. This menu
|
|
35
|
+
// sits mid-strip over the stage, so it needs the behaviours `Popover` brings
|
|
36
|
+
// and the flyout has none of: it closes on an outside pointerdown and on
|
|
37
|
+
// Escape; it flips above the trigger when the window is short; and it clamps
|
|
38
|
+
// its LEFT EDGE on-screen. Not on blur — `Popover.tsx`'s own header says
|
|
39
|
+
// "outside pointerdown / Escape / blur" and the file registers two listeners,
|
|
40
|
+
// neither of them blur; and the clamp is horizontal only, which is what the
|
|
41
|
+
// flip is for. A menu left open under the author's next click on
|
|
42
|
+
// the picture is the failure the dock's flyout still has and this one does not.
|
|
43
|
+
import { useRef, useState } from "react";
|
|
44
|
+
import { Popover } from "@dailies-studio/ui";
|
|
9
45
|
import { useShotEditor, useStore } from "../../state/context.js";
|
|
10
|
-
import {
|
|
46
|
+
import { inDefinition, shownLayoutMode } from "../../state/viewMode.js";
|
|
47
|
+
// `shadingLabel` and not four labels of our own: this bar hand-wrote the same
|
|
48
|
+
// words the App menu prints, so renaming a mode moved one and left the other.
|
|
49
|
+
import { SHADING_MODES, shadingLabel } from "../../stage/shading.js";
|
|
11
50
|
import type { ShadingMode } from "../../bridgeTypes.js";
|
|
12
51
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
52
|
+
/** The face for each mode. The drawing is this file's; the word is not. */
|
|
53
|
+
const SHADING_GLYPHS: Readonly<Record<ShadingMode, string>> = {
|
|
54
|
+
solid: "◯",
|
|
55
|
+
wireframe: "◇",
|
|
56
|
+
material: "◑",
|
|
57
|
+
rendered: "✦",
|
|
18
58
|
};
|
|
19
59
|
|
|
60
|
+
/** One hover string for a mode, worn by the trigger and by that mode's row. */
|
|
61
|
+
function titleFor(mode: ShadingMode): string {
|
|
62
|
+
return `${shadingLabel(mode)}: working pane (Z cycles)`;
|
|
63
|
+
}
|
|
64
|
+
|
|
20
65
|
export function ShadingBar() {
|
|
21
66
|
const store = useStore();
|
|
22
67
|
const shading = useShotEditor((s) => s.shadingMode);
|
|
23
|
-
|
|
68
|
+
// ON SCREEN, not chosen: see CameraViewBar.
|
|
69
|
+
const layoutMode = useShotEditor(shownLayoutMode);
|
|
70
|
+
// A definition always draws the working pane alone (StageApp forces it),
|
|
71
|
+
// whatever layout the shot left stashed. WorkPlaneBar keeps the same rule.
|
|
72
|
+
const inDef = useShotEditor(inDefinition);
|
|
24
73
|
const open = useShotEditor((s) => s.name !== null);
|
|
25
|
-
|
|
74
|
+
const anchor = useRef<HTMLButtonElement>(null);
|
|
75
|
+
const [menuOpen, setMenuOpen] = useState(false);
|
|
76
|
+
if (!open || (layoutMode === "camera" && !inDef)) {
|
|
77
|
+
// ── AND THE GATE CLOSES THE MENU ──────────────────────────────────
|
|
78
|
+
//
|
|
79
|
+
// Returning null is not an unmount: React keeps this component and its
|
|
80
|
+
// state, so a menu left open when the layout went camera-only came back
|
|
81
|
+
// OPEN the next time the working pane did — a popover over the picture
|
|
82
|
+
// that nobody pressed, reporting `aria-expanded="true"` nobody set.
|
|
83
|
+
// Setting state during this component's own render is React's documented
|
|
84
|
+
// answer to "reset state when an input changes": it re-renders before
|
|
85
|
+
// anything is committed, so there is no extra paint and no effect.
|
|
86
|
+
if (menuOpen) setMenuOpen(false);
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
26
89
|
return (
|
|
27
|
-
<div className="
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
90
|
+
<div className="shading-bar" role="group" aria-label="Working-pane shading" data-testid="shading-bar">
|
|
91
|
+
<button
|
|
92
|
+
ref={anchor}
|
|
93
|
+
type="button"
|
|
94
|
+
className="tool-button has-caret"
|
|
95
|
+
aria-haspopup="menu"
|
|
96
|
+
aria-expanded={menuOpen}
|
|
97
|
+
// THE NAME CARRIES THE VALUE. A bare glyph has no accessible name at
|
|
98
|
+
// all, and `title` alone is the last resort the accname spec reaches
|
|
99
|
+
// for — the one control here whose face changes with its state is the
|
|
100
|
+
// one that must say so out loud.
|
|
101
|
+
aria-label={`Shading: ${shadingLabel(shading)}`}
|
|
102
|
+
title={titleFor(shading)}
|
|
103
|
+
onClick={() => setMenuOpen((v) => !v)}
|
|
104
|
+
>
|
|
105
|
+
{SHADING_GLYPHS[shading]}
|
|
106
|
+
<span className="tool-caret" aria-hidden="true" />
|
|
107
|
+
</button>
|
|
108
|
+
<Popover open={menuOpen} anchor={anchor} onClose={() => setMenuOpen(false)}>
|
|
109
|
+
{/* `menuitemradio` and not `menuitem`: the four rows ARE the whole
|
|
110
|
+
menu, so the `role="menu"` element is the group the radio semantics
|
|
111
|
+
need — which is what the old bar's four `aria-pressed` buttons
|
|
112
|
+
said, kept rather than dropped on the way into a menu. */}
|
|
113
|
+
<div className="shading-menu" role="menu" data-testid="shading-menu">
|
|
114
|
+
{SHADING_MODES.map((mode) => (
|
|
115
|
+
<button
|
|
116
|
+
key={mode}
|
|
117
|
+
type="button"
|
|
118
|
+
role="menuitemradio"
|
|
119
|
+
aria-checked={shading === mode}
|
|
120
|
+
className={`tool-button${shading === mode ? " is-armed" : ""}`}
|
|
121
|
+
title={titleFor(mode)}
|
|
122
|
+
onClick={() => {
|
|
123
|
+
setMenuOpen(false);
|
|
124
|
+
store.setShadingMode(mode);
|
|
125
|
+
}}
|
|
126
|
+
>
|
|
127
|
+
<span aria-hidden="true">{SHADING_GLYPHS[mode]}</span>
|
|
128
|
+
{shadingLabel(mode)}
|
|
129
|
+
</button>
|
|
130
|
+
))}
|
|
131
|
+
</div>
|
|
132
|
+
</Popover>
|
|
40
133
|
</div>
|
|
41
134
|
);
|
|
42
135
|
}
|