@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,318 @@
|
|
|
1
|
+
// ALL COMPONENTS (C5): the Components home, in the canvas cell while no
|
|
2
|
+
// component is open. Every component this Project has, then the ones every
|
|
3
|
+
// Project of the workspace offers, as cards:
|
|
4
|
+
//
|
|
5
|
+
// THIS PROJECT its Studio-made definitions, then the code files made for
|
|
6
|
+
// it, then the code components it uses (`componentsListOf`),
|
|
7
|
+
// and the dashed New card
|
|
8
|
+
// YOUR LIBRARY code made for no Project, Dailies Library installs, and
|
|
9
|
+
// what someone added with "In your library"
|
|
10
|
+
// (`libraryComponentsOf`)
|
|
11
|
+
//
|
|
12
|
+
// A card is a poster at rest and a live loop on hover or focus, through the
|
|
13
|
+
// board's one live preview (`ComponentStage`, with its poster cache and its
|
|
14
|
+
// `LIVE_CAP` budget), so a wall of cards costs pictures, not documents. A card
|
|
15
|
+
// the stage cannot draw (a dom component, or a library definition whose body
|
|
16
|
+
// lives in another Project) shows its kind's icon instead.
|
|
17
|
+
//
|
|
18
|
+
// The search is the canvas bar's (ComponentsPreview.tsx), and it filters the
|
|
19
|
+
// left column's list too, so one field filters both.
|
|
20
|
+
//
|
|
21
|
+
// An MCP agent writing a component's file shows its dots on that card
|
|
22
|
+
// (state/agentActivity.ts), so its work appears as it happens.
|
|
23
|
+
import { useEffect, useMemo, useState } from "react";
|
|
24
|
+
import type { ReactNode } from "react";
|
|
25
|
+
import { IconCode } from "@dailies-studio/ui";
|
|
26
|
+
import { componentUsesOf } from "@dailies-studio/shot/doc";
|
|
27
|
+
import type { Doc3D, ReferenceItem3D } from "@dailies-studio/shot/doc";
|
|
28
|
+
import { CUBE_ICON } from "../../icons.js";
|
|
29
|
+
import { useShotEditor, useStore } from "../../state/context.js";
|
|
30
|
+
import { componentsListOf, libraryComponentsOf, libraryEntryName, libraryHomeLabel } from "../../state/workspace.js";
|
|
31
|
+
import type { ComponentsListRow } from "../../state/workspace.js";
|
|
32
|
+
import { useCodeBufferGuard } from "../code/codeBufferGuard.js";
|
|
33
|
+
import { ComponentStage } from "../storyboard/ComponentStage.js";
|
|
34
|
+
import { workspaceRowTitle } from "./ComponentLibraryRail.js";
|
|
35
|
+
import { agentWriting } from "../../state/agentActivity.js";
|
|
36
|
+
import { AgentDots, useAgentActivity } from "../agent/AgentDots.js";
|
|
37
|
+
|
|
38
|
+
type CardItem = Extract<ReferenceItem3D, { type: "component" }>;
|
|
39
|
+
|
|
40
|
+
/** The two sections' rows, filtered by the search, and their full counts for
|
|
41
|
+
* the bar's "N in this project · M in your library". */
|
|
42
|
+
export function useHomeRows(doc: Doc3D, query: string) {
|
|
43
|
+
const library = useShotEditor((s) => s.library);
|
|
44
|
+
const workspace = useShotEditor((s) => s.workspaceComponents);
|
|
45
|
+
const homes = useShotEditor((s) => s.componentHomes);
|
|
46
|
+
const rows = useMemo(() => componentsListOf(doc, library), [doc, library]);
|
|
47
|
+
const mine = useMemo(
|
|
48
|
+
() => libraryComponentsOf(doc, library, workspace, homes, rows),
|
|
49
|
+
[doc, library, workspace, homes, rows],
|
|
50
|
+
);
|
|
51
|
+
const needle = query.trim().toLowerCase();
|
|
52
|
+
const matches = (name: string): boolean => needle.length === 0 || name.toLowerCase().includes(needle);
|
|
53
|
+
return {
|
|
54
|
+
project: rows.filter((r) => matches(r.name)),
|
|
55
|
+
library: mine.filter((entry) => matches(libraryEntryName(entry))),
|
|
56
|
+
projectCount: rows.length,
|
|
57
|
+
libraryCount: mine.length,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function ComponentsHome(props: { doc: Doc3D; query: string }) {
|
|
62
|
+
const store = useStore();
|
|
63
|
+
const readOnly = useShotEditor((s) => s.readOnly);
|
|
64
|
+
const { guard, dialog } = useCodeBufferGuard();
|
|
65
|
+
const rows = useHomeRows(props.doc, props.query);
|
|
66
|
+
// ONE WALK of the document for every card's where line.
|
|
67
|
+
const uses = useMemo(() => componentUsesOf(props.doc), [props.doc]);
|
|
68
|
+
const usedIn = (row: ComponentsListRow): number =>
|
|
69
|
+
uses.filter((u) => (row.sel.kind === "studio" ? u.def === row.sel.def : u.component === row.sel.module)).length;
|
|
70
|
+
const searching = props.query.trim().length > 0;
|
|
71
|
+
const activity = useAgentActivity();
|
|
72
|
+
const library = useShotEditor((s) => s.library);
|
|
73
|
+
/** The agent writing a code row's file, if one is. */
|
|
74
|
+
const writerOf = (module: string | null): string | null => {
|
|
75
|
+
const rel = module === null ? null : (library.find((r) => r.id === module)?.rel ?? null);
|
|
76
|
+
return agentWriting(activity, rel, module)?.name ?? null;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// Your library reads the workspace list and its homes once per visit, and
|
|
80
|
+
// the store reads them again as other Projects' writes arrive (`rereadHomes`).
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
void store.refreshWorkspaceComponents();
|
|
83
|
+
}, [store]);
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<div className="components-home" data-testid="components-home">
|
|
87
|
+
{dialog}
|
|
88
|
+
<section className="components-home-section" aria-label="This project">
|
|
89
|
+
<h2 className="components-section-title">This project</h2>
|
|
90
|
+
<div className="components-home-grid" data-testid="components-home-project">
|
|
91
|
+
{rows.project.map((r) => {
|
|
92
|
+
const sel = r.sel;
|
|
93
|
+
const n = usedIn(r);
|
|
94
|
+
const writer = writerOf(sel.kind === "code" ? sel.module : null);
|
|
95
|
+
return (
|
|
96
|
+
<HomeCard
|
|
97
|
+
key={sel.kind === "studio" ? sel.def : sel.module}
|
|
98
|
+
kind={sel.kind}
|
|
99
|
+
name={r.name}
|
|
100
|
+
writer={writer}
|
|
101
|
+
where={
|
|
102
|
+
r.refusal ??
|
|
103
|
+
(writer !== null ? `${writer} is writing it` : n === 0 ? "Not used yet" : `Used in ${n} ${n === 1 ? "place" : "places"}`)
|
|
104
|
+
}
|
|
105
|
+
title={r.refusal ?? `Open ${r.name}`}
|
|
106
|
+
refused={r.refusal !== null}
|
|
107
|
+
stage={(live) => (r.refusal === null ? <ProjectStage doc={props.doc} row={r} live={live} /> : null)}
|
|
108
|
+
onOpen={() => {
|
|
109
|
+
if (r.refusal !== null) {
|
|
110
|
+
store.reportError(r.refusal);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
void store.selectComponent(sel);
|
|
114
|
+
}}
|
|
115
|
+
/>
|
|
116
|
+
);
|
|
117
|
+
})}
|
|
118
|
+
{searching ? null : <NewCard readOnly={readOnly} />}
|
|
119
|
+
</div>
|
|
120
|
+
{searching && rows.project.length === 0 ? (
|
|
121
|
+
<p className="insp-empty">No component in this project matches “{props.query.trim()}”.</p>
|
|
122
|
+
) : null}
|
|
123
|
+
</section>
|
|
124
|
+
<section className="components-home-section" aria-label="Your library">
|
|
125
|
+
<h2 className="components-section-title">Your library</h2>
|
|
126
|
+
{rows.library.length === 0 ? (
|
|
127
|
+
<p className="insp-empty">
|
|
128
|
+
{searching
|
|
129
|
+
? `No component in your library matches “${props.query.trim()}”.`
|
|
130
|
+
: "Code made for no Project, Dailies Library installs and components you add to your library show here."}
|
|
131
|
+
</p>
|
|
132
|
+
) : (
|
|
133
|
+
<div className="components-home-grid" data-testid="components-home-library">
|
|
134
|
+
{rows.library.map((entry) => {
|
|
135
|
+
if (entry.kind === "studio") {
|
|
136
|
+
const c = entry.component;
|
|
137
|
+
return (
|
|
138
|
+
<HomeCard
|
|
139
|
+
key={c.id}
|
|
140
|
+
kind="studio"
|
|
141
|
+
name={c.name}
|
|
142
|
+
where={libraryHomeLabel(entry)}
|
|
143
|
+
title={workspaceRowTitle(entry)}
|
|
144
|
+
refused={false}
|
|
145
|
+
stage={() => null}
|
|
146
|
+
onOpen={() => {
|
|
147
|
+
if (readOnly) return;
|
|
148
|
+
guard(() => void store.addLibraryComponent(c.id));
|
|
149
|
+
}}
|
|
150
|
+
/>
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
const { module, refusal } = entry;
|
|
154
|
+
return (
|
|
155
|
+
<HomeCard
|
|
156
|
+
key={module}
|
|
157
|
+
kind="code"
|
|
158
|
+
name={entry.name}
|
|
159
|
+
where={libraryHomeLabel(entry)}
|
|
160
|
+
title={refusal ?? workspaceRowTitle(entry)}
|
|
161
|
+
refused={refusal !== null}
|
|
162
|
+
stage={(live) =>
|
|
163
|
+
refusal === null ? <LibraryStage doc={props.doc} module={module} name={entry.name} live={live} /> : null
|
|
164
|
+
}
|
|
165
|
+
onOpen={() => {
|
|
166
|
+
if (refusal !== null) {
|
|
167
|
+
store.reportError(refusal);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
// OPENED, NOTHING MORE: no record and no membership. It
|
|
171
|
+
// stays where it lists until someone ticks a box.
|
|
172
|
+
guard(() => void store.openCodeComponent(module));
|
|
173
|
+
}}
|
|
174
|
+
/>
|
|
175
|
+
);
|
|
176
|
+
})}
|
|
177
|
+
</div>
|
|
178
|
+
)}
|
|
179
|
+
</section>
|
|
180
|
+
</div>
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/** One card: the picture, then the name, the kind badge and the where line.
|
|
185
|
+
* The picture goes live while the pointer or focus is on the card. */
|
|
186
|
+
function HomeCard(props: {
|
|
187
|
+
kind: "studio" | "code";
|
|
188
|
+
name: string;
|
|
189
|
+
where: string;
|
|
190
|
+
title: string;
|
|
191
|
+
refused: boolean;
|
|
192
|
+
/** The agent writing it, whose dots the card shows. */
|
|
193
|
+
writer?: string | null;
|
|
194
|
+
stage: (live: boolean) => ReactNode;
|
|
195
|
+
onOpen: () => void;
|
|
196
|
+
}) {
|
|
197
|
+
const [hot, setHot] = useState(false);
|
|
198
|
+
const icon = (
|
|
199
|
+
<span className="components-home-icon" aria-hidden="true">
|
|
200
|
+
{props.kind === "code" ? <IconCode /> : CUBE_ICON}
|
|
201
|
+
</span>
|
|
202
|
+
);
|
|
203
|
+
return (
|
|
204
|
+
<button
|
|
205
|
+
type="button"
|
|
206
|
+
className="components-home-card"
|
|
207
|
+
data-testid="components-home-card"
|
|
208
|
+
aria-disabled={props.refused || undefined}
|
|
209
|
+
title={props.title}
|
|
210
|
+
onClick={props.onOpen}
|
|
211
|
+
onPointerEnter={() => setHot(true)}
|
|
212
|
+
onPointerLeave={() => setHot(false)}
|
|
213
|
+
onFocus={() => setHot(true)}
|
|
214
|
+
onBlur={() => setHot(false)}
|
|
215
|
+
>
|
|
216
|
+
<span className="components-home-poster">{props.stage(hot) ?? icon}</span>
|
|
217
|
+
<span className="components-home-foot">
|
|
218
|
+
<span className="components-home-name">{props.name}</span>
|
|
219
|
+
{props.writer === null || props.writer === undefined ? null : <AgentDots label={`${props.writer} is writing ${props.name}`} />}
|
|
220
|
+
<span className="components-item-kind">{props.kind === "code" ? "CODE" : "3D"}</span>
|
|
221
|
+
</span>
|
|
222
|
+
<span className="components-home-where">{props.where}</span>
|
|
223
|
+
</button>
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** A card of this Project: a definition's closure, or a three code component. */
|
|
228
|
+
function ProjectStage(props: { doc: Doc3D; row: ComponentsListRow; live: boolean }) {
|
|
229
|
+
const { sel, name } = props.row;
|
|
230
|
+
const module = sel.kind === "code" ? sel.module : null;
|
|
231
|
+
const item = useMemo<CardItem>(
|
|
232
|
+
() =>
|
|
233
|
+
sel.kind === "studio"
|
|
234
|
+
? { type: "component", id: `home:${sel.def}`, label: name, def: sel.def, props: {} }
|
|
235
|
+
: { type: "component", id: `home:${sel.module}`, label: name, component: sel.module, props: {} },
|
|
236
|
+
[sel, name],
|
|
237
|
+
);
|
|
238
|
+
return <CodeAwareStage doc={props.doc} item={item} module={module} live={props.live} />;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/** A Your library code card. A library definition's body lives in its home
|
|
242
|
+
* Project until Use here copies it in, so its card keeps the icon and never
|
|
243
|
+
* comes here. */
|
|
244
|
+
function LibraryStage(props: { doc: Doc3D; module: string; name: string; live: boolean }) {
|
|
245
|
+
const { module, name } = props;
|
|
246
|
+
const item = useMemo<CardItem>(
|
|
247
|
+
() => ({ type: "component", id: `home:${module}`, label: name, component: module, props: {} }),
|
|
248
|
+
[module, name],
|
|
249
|
+
);
|
|
250
|
+
return <CodeAwareStage doc={props.doc} item={item} module={module} live={props.live} />;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/** The board's preview, with what a code component needs: its registry row,
|
|
254
|
+
* its contract (loaded once the card goes live) and the catalog's length. */
|
|
255
|
+
function CodeAwareStage(props: { doc: Doc3D; item: CardItem; module: string | null; live: boolean }) {
|
|
256
|
+
const store = useStore();
|
|
257
|
+
const { module, live } = props;
|
|
258
|
+
const row = useShotEditor((s) => (module === null ? undefined : s.library.find((r) => r.id === module)));
|
|
259
|
+
const contract = useShotEditor((s) => (module === null ? undefined : s.contracts[module]));
|
|
260
|
+
const lengthFrames = useShotEditor((s) =>
|
|
261
|
+
module === null ? undefined : s.libraryCatalog.find((r) => r.installedAs === module)?.lengthFrames,
|
|
262
|
+
);
|
|
263
|
+
useEffect(() => {
|
|
264
|
+
if (live && module !== null) void store.loadContract(module);
|
|
265
|
+
}, [live, module, store]);
|
|
266
|
+
if (module !== null && row?.host !== "three") return null;
|
|
267
|
+
return (
|
|
268
|
+
<ComponentStage
|
|
269
|
+
doc={props.doc}
|
|
270
|
+
item={props.item}
|
|
271
|
+
contract={contract}
|
|
272
|
+
availability={row?.contractAvailability}
|
|
273
|
+
lengthFrames={lengthFrames}
|
|
274
|
+
live={live}
|
|
275
|
+
fallback={
|
|
276
|
+
<span className="components-home-icon" aria-hidden="true">
|
|
277
|
+
{module === null ? CUBE_ICON : <IconCode />}
|
|
278
|
+
</span>
|
|
279
|
+
}
|
|
280
|
+
/>
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/** The dashed card: a new component, Studio-made or code. It opens in
|
|
285
|
+
* Components, never in a Shot. */
|
|
286
|
+
function NewCard(props: { readOnly: boolean }) {
|
|
287
|
+
const store = useStore();
|
|
288
|
+
const { guard, dialog } = useCodeBufferGuard();
|
|
289
|
+
return (
|
|
290
|
+
<div className="components-home-card is-new" data-testid="components-home-new">
|
|
291
|
+
{dialog}
|
|
292
|
+
<span className="components-home-new-title">New component</span>
|
|
293
|
+
<span className="components-home-where">Studio-made or code</span>
|
|
294
|
+
<span className="components-home-new-verbs">
|
|
295
|
+
<button
|
|
296
|
+
type="button"
|
|
297
|
+
className="btn"
|
|
298
|
+
data-testid="components-home-new-studio"
|
|
299
|
+
disabled={props.readOnly}
|
|
300
|
+
title="A Studio-made component, built from layers"
|
|
301
|
+
onClick={() => guard(() => store.createEmptyComponent("Component"))}
|
|
302
|
+
>
|
|
303
|
+
Studio-made
|
|
304
|
+
</button>
|
|
305
|
+
<button
|
|
306
|
+
type="button"
|
|
307
|
+
className="btn"
|
|
308
|
+
data-testid="components-home-new-code"
|
|
309
|
+
disabled={props.readOnly}
|
|
310
|
+
title="A code component from the three starter"
|
|
311
|
+
onClick={() => guard(() => void store.newCodeComponent("Component"))}
|
|
312
|
+
>
|
|
313
|
+
Code
|
|
314
|
+
</button>
|
|
315
|
+
</span>
|
|
316
|
+
</div>
|
|
317
|
+
);
|
|
318
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
// COMPONENTS, ON ITS HOME AND ITS PREVIEW TAB.
|
|
2
|
+
//
|
|
3
|
+
// The Components workspace (`workspaceOf`) is every component of the Project,
|
|
4
|
+
// standalone, never inside a Shot. With nothing open it is the home, All
|
|
5
|
+
// components (C5). With a component open it has two tabs: Edit is the studio
|
|
6
|
+
// that edits it (ComponentStudio.tsx for a definition, CodeStudio.tsx for
|
|
7
|
+
// code); Preview is this file, the same cells with the studio taken out.
|
|
8
|
+
//
|
|
9
|
+
// LEFT which component (ComponentLibraryRail.tsx), both kinds
|
|
10
|
+
// CENTRE the home's cards (ComponentsHome.tsx), or the subject as a HOLE
|
|
11
|
+
// onto the stage with the loop transport (`PreviewTransport`), or
|
|
12
|
+
// Every use (C4) while the crumb's "used in N places" has it open
|
|
13
|
+
// BAR the way back (Back to Shot when a Shot door opened it, C7), then
|
|
14
|
+
// the home's count, search and New, or the breadcrumb, Preview |
|
|
15
|
+
// Edit and the zoom
|
|
16
|
+
//
|
|
17
|
+
// No timeline on this tab (`componentsHideTimeline`): the transport under the
|
|
18
|
+
// stage is the clock.
|
|
19
|
+
//
|
|
20
|
+
// The subject stays in the stage's component context across the tab swap, so
|
|
21
|
+
// the hole is the same render the studio shows, and code buffers survive it.
|
|
22
|
+
import { useEffect, useRef, useState } from "react";
|
|
23
|
+
import { instanceExportOf } from "@dailies-studio/shot/doc";
|
|
24
|
+
import type { Doc3D } from "@dailies-studio/shot/doc";
|
|
25
|
+
import { useShotEditor, useStore } from "../../state/context.js";
|
|
26
|
+
import { usesViewOf, workspaceOf } from "../../state/workspace.js";
|
|
27
|
+
import { useCodeBufferGuard } from "../code/codeBufferGuard.js";
|
|
28
|
+
import { InCell } from "../stage/cellSlots.js";
|
|
29
|
+
import { ComponentLibraryRail } from "./ComponentLibraryRail.js";
|
|
30
|
+
import { ComponentsTabSwitch, StudioZoom } from "./ComponentStudio.js";
|
|
31
|
+
import { ComponentCrumb, ComponentsBack, PreviewTransport } from "./componentParts.js";
|
|
32
|
+
import { ComponentsHome, useHomeRows } from "./ComponentsHome.js";
|
|
33
|
+
import { EveryUse } from "./EveryUse.js";
|
|
34
|
+
|
|
35
|
+
export function ComponentsPreview() {
|
|
36
|
+
const store = useStore();
|
|
37
|
+
const doc = useShotEditor((s) => s.doc);
|
|
38
|
+
const editingDef = useShotEditor((s) => s.editingDef);
|
|
39
|
+
const codeComponent = useShotEditor((s) => s.codeComponent);
|
|
40
|
+
const library = useShotEditor((s) => s.library);
|
|
41
|
+
const usesOpen = useShotEditor((s) => usesViewOf(s) !== null);
|
|
42
|
+
// THIS FILE'S CELLS: Components with nothing open (the home), or with a
|
|
43
|
+
// subject on the Preview tab.
|
|
44
|
+
const shown = useShotEditor(
|
|
45
|
+
(s) =>
|
|
46
|
+
workspaceOf(s) === "components" &&
|
|
47
|
+
(s.componentsTab === "preview" || (s.codeComponent === null && s.editingDef === null)),
|
|
48
|
+
);
|
|
49
|
+
// Leaving drops a code component's buffers, so unsaved text asks first.
|
|
50
|
+
const { guard, dialog } = useCodeBufferGuard();
|
|
51
|
+
// ONE SEARCH for the home's cards and the left column's list. On the home
|
|
52
|
+
// its field is the bar's, and the column draws none.
|
|
53
|
+
const [query, setQuery] = useState("");
|
|
54
|
+
|
|
55
|
+
// AN ESCAPE FOR CODE ON THIS TAB: the keymap's code rung hands it here
|
|
56
|
+
// (`codeBackRequest`), as it does to CodeStudio on the Edit tab. A request
|
|
57
|
+
// made while this tab is not up is marked seen, so swapping tabs never
|
|
58
|
+
// answers a stale one.
|
|
59
|
+
const backRequest = useShotEditor((s) => s.codeBackRequest);
|
|
60
|
+
const seen = useRef<object | null>(null);
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
if (backRequest === seen.current) return;
|
|
63
|
+
seen.current = backRequest;
|
|
64
|
+
if (!shown || backRequest === null || store.getState().codeComponent === null) return;
|
|
65
|
+
guard(() => (store.getState().componentsOrigin !== null ? void store.backToShot() : store.leaveComponents()));
|
|
66
|
+
}, [shown, backRequest, guard, store]);
|
|
67
|
+
|
|
68
|
+
if (!shown || doc === null) return null;
|
|
69
|
+
|
|
70
|
+
const def = editingDef === null ? undefined : doc.components?.[editingDef];
|
|
71
|
+
const subject =
|
|
72
|
+
codeComponent !== null
|
|
73
|
+
? { kind: "code" as const, module: codeComponent }
|
|
74
|
+
: def !== undefined
|
|
75
|
+
? { kind: "studio" as const, def: def.id }
|
|
76
|
+
: null;
|
|
77
|
+
const name =
|
|
78
|
+
codeComponent !== null
|
|
79
|
+
? (library.find((r) => r.id === codeComponent)?.name ?? instanceExportOf(codeComponent))
|
|
80
|
+
: (def?.name ?? "Components");
|
|
81
|
+
|
|
82
|
+
return (
|
|
83
|
+
<>
|
|
84
|
+
{dialog}
|
|
85
|
+
<InCell name="left">
|
|
86
|
+
<ComponentLibraryRail doc={doc} current={subject} query={query} onQuery={setQuery} />
|
|
87
|
+
</InCell>
|
|
88
|
+
|
|
89
|
+
<InCell name="centre">
|
|
90
|
+
{subject === null ? (
|
|
91
|
+
<ComponentsHome doc={doc} query={query} />
|
|
92
|
+
) : usesOpen ? (
|
|
93
|
+
<EveryUse />
|
|
94
|
+
) : (
|
|
95
|
+
// THE COMPONENT ITSELF, a hole like the studios' (`.stage-window`):
|
|
96
|
+
// no paint, no pointer, so a drag on the subject orbits the stage.
|
|
97
|
+
// The transport under it paints and takes its own pointer.
|
|
98
|
+
<>
|
|
99
|
+
<div className="stage-window components-preview-hole" aria-hidden="true" data-testid="components-preview-hole" />
|
|
100
|
+
<PreviewTransport />
|
|
101
|
+
</>
|
|
102
|
+
)}
|
|
103
|
+
</InCell>
|
|
104
|
+
|
|
105
|
+
<InCell name="bar">
|
|
106
|
+
<div className="component-studio-bar" role="group" aria-label={name} data-testid="components-preview">
|
|
107
|
+
<ComponentsBack testId="components-back" guard={guard} />
|
|
108
|
+
{subject === null ? (
|
|
109
|
+
<HomeBar query={query} onQuery={setQuery} />
|
|
110
|
+
) : (
|
|
111
|
+
<ComponentCrumb
|
|
112
|
+
sel={subject}
|
|
113
|
+
name={
|
|
114
|
+
<span className="component-studio-name is-label" title={name}>
|
|
115
|
+
{name}
|
|
116
|
+
</span>
|
|
117
|
+
}
|
|
118
|
+
/>
|
|
119
|
+
)}
|
|
120
|
+
{subject === null ? null : (
|
|
121
|
+
<div className="component-studio-tools">
|
|
122
|
+
<ComponentsTabSwitch />
|
|
123
|
+
<StudioZoom />
|
|
124
|
+
</div>
|
|
125
|
+
)}
|
|
126
|
+
</div>
|
|
127
|
+
</InCell>
|
|
128
|
+
|
|
129
|
+
</>
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** The home's bar (C5): "All components", the two counts, the search and
|
|
134
|
+
* New component. New makes an empty master and opens it here, on its Edit
|
|
135
|
+
* tab, never in a Shot. */
|
|
136
|
+
function HomeBar(props: { query: string; onQuery: (q: string) => void }) {
|
|
137
|
+
const store = useStore();
|
|
138
|
+
const doc = useShotEditor((s) => s.doc);
|
|
139
|
+
const readOnly = useShotEditor((s) => s.readOnly);
|
|
140
|
+
if (doc === null) return null;
|
|
141
|
+
return (
|
|
142
|
+
<>
|
|
143
|
+
<span className="component-studio-name is-label">All components</span>
|
|
144
|
+
<HomeCounts doc={doc} />
|
|
145
|
+
<div className="component-studio-tools">
|
|
146
|
+
<label className="components-home-search">
|
|
147
|
+
<input
|
|
148
|
+
type="search"
|
|
149
|
+
value={props.query}
|
|
150
|
+
placeholder="Search components"
|
|
151
|
+
aria-label="Search components"
|
|
152
|
+
data-testid="components-home-search"
|
|
153
|
+
onChange={(e) => props.onQuery(e.target.value)}
|
|
154
|
+
/>
|
|
155
|
+
</label>
|
|
156
|
+
<button
|
|
157
|
+
type="button"
|
|
158
|
+
className="btn is-primary"
|
|
159
|
+
data-testid="components-new"
|
|
160
|
+
disabled={readOnly}
|
|
161
|
+
title="A new Studio-made component, opened here"
|
|
162
|
+
onClick={() => store.createEmptyComponent("Component")}
|
|
163
|
+
>
|
|
164
|
+
+ New component
|
|
165
|
+
</button>
|
|
166
|
+
</div>
|
|
167
|
+
</>
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function HomeCounts(props: { doc: Doc3D }) {
|
|
172
|
+
const rows = useHomeRows(props.doc, "");
|
|
173
|
+
return (
|
|
174
|
+
<span className="components-home-counts" data-testid="components-home-counts">
|
|
175
|
+
{rows.projectCount} in this project · {rows.libraryCount} in your library
|
|
176
|
+
</span>
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|