Fix regression with the color picker in the Properties panel being broken

This commit is contained in:
Keavon Chambers 2026-05-01 19:55:50 -07:00
parent eeb1f85e25
commit 485bac89e5
5 changed files with 42 additions and 54 deletions

View File

@ -1,15 +1,12 @@
<script lang="ts">
import { getContext } from "svelte";
import LayoutCol from "/src/components/layout/LayoutCol.svelte";
import WidgetLayout from "/src/components/widgets/WidgetLayout.svelte";
import type { PortfolioStore } from "/src/stores/portfolio";
const portfolio = getContext<PortfolioStore>("portfolio");
import { dataPanelLayout } from "/src/stores/portfolio";
</script>
<LayoutCol class="data-panel">
<LayoutCol class="body" scrollableY={true}>
<WidgetLayout layout={$portfolio.dataPanelLayout} layoutTarget="DataPanel" />
<WidgetLayout layout={$dataPanelLayout} layoutTarget="DataPanel" />
</LayoutCol>
</LayoutCol>

View File

@ -7,6 +7,7 @@
import Separator from "/src/components/widgets/labels/Separator.svelte";
import WidgetLayout from "/src/components/widgets/WidgetLayout.svelte";
import type { NodeGraphStore } from "/src/stores/node-graph";
import { layersPanelControlBarLeftLayout, layersPanelControlBarRightLayout, layersPanelBottomBarLayout } from "/src/stores/portfolio";
import type { PortfolioStore } from "/src/stores/portfolio";
import type { TooltipStore } from "/src/stores/tooltip";
import { pasteFile } from "/src/utility-functions/files";
@ -509,11 +510,11 @@
<LayoutCol class="layers" on:dragleave={() => (dragInPanel = false)}>
<LayoutRow class="control-bar" scrollableX={true}>
<WidgetLayout layout={$portfolio.layersPanelControlBarLeftLayout} layoutTarget="LayersPanelControlLeftBar" />
{#if $portfolio.layersPanelControlBarLeftLayout?.length > 0 && $portfolio.layersPanelControlBarRightLayout?.length > 0}
<WidgetLayout layout={$layersPanelControlBarLeftLayout} layoutTarget="LayersPanelControlLeftBar" />
{#if $layersPanelControlBarLeftLayout?.length > 0 && $layersPanelControlBarRightLayout?.length > 0}
<Separator />
{/if}
<WidgetLayout layout={$portfolio.layersPanelControlBarRightLayout} layoutTarget="LayersPanelControlRightBar" />
<WidgetLayout layout={$layersPanelControlBarRightLayout} layoutTarget="LayersPanelControlRightBar" />
</LayoutRow>
<LayoutRow class="list-area" classes={{ "drag-ongoing": Boolean(internalDragState?.active && draggingData) }} scrollableY={true}>
<LayoutCol
@ -633,7 +634,7 @@
{/if}
</LayoutRow>
<LayoutRow class="bottom-bar" scrollableX={true}>
<WidgetLayout layout={$portfolio.layersPanelBottomBarLayout} layoutTarget="LayersPanelBottomBar" />
<WidgetLayout layout={$layersPanelBottomBarLayout} layoutTarget="LayersPanelBottomBar" />
</LayoutRow>
</LayoutCol>

View File

@ -1,15 +1,12 @@
<script lang="ts">
import { getContext } from "svelte";
import LayoutCol from "/src/components/layout/LayoutCol.svelte";
import WidgetLayout from "/src/components/widgets/WidgetLayout.svelte";
import type { PortfolioStore } from "/src/stores/portfolio";
const portfolio = getContext<PortfolioStore>("portfolio");
import { propertiesPanelLayout } from "/src/stores/portfolio";
</script>
<LayoutCol class="properties">
<LayoutCol class="sections" scrollableY={true}>
<WidgetLayout layout={$portfolio.propertiesPanelLayout} layoutTarget="PropertiesPanel" />
<WidgetLayout layout={$propertiesPanelLayout} layoutTarget="PropertiesPanel" />
</LayoutCol>
</LayoutCol>

View File

@ -5,12 +5,11 @@
import IconLabel from "/src/components/widgets/labels/IconLabel.svelte";
import TextLabel from "/src/components/widgets/labels/TextLabel.svelte";
import WidgetLayout from "/src/components/widgets/WidgetLayout.svelte";
import type { PortfolioStore } from "/src/stores/portfolio";
import { welcomeScreenButtonsLayout } from "/src/stores/portfolio";
import { pasteFile } from "/src/utility-functions/files";
import type { EditorWrapper } from "/wrapper/pkg/graphite_wasm_wrapper";
const editor = getContext<EditorWrapper>("editor");
const portfolio = getContext<PortfolioStore>("portfolio");
function dropFile(e: DragEvent) {
if (!e.dataTransfer) return;
@ -29,7 +28,7 @@
<IconLabel icon="GraphiteLogotypeSolid" />
</LayoutRow>
<LayoutRow class="actions">
<WidgetLayout layout={$portfolio.welcomeScreenButtonsLayout} layoutTarget="WelcomeScreenButtons" />
<WidgetLayout layout={$welcomeScreenButtonsLayout} layoutTarget="WelcomeScreenButtons" />
</LayoutRow>
</LayoutCol>
</LayoutCol>

View File

@ -15,12 +15,6 @@ type PortfolioStoreState = {
documents: DocumentInfo[];
activeDocumentIndex: number;
panelLayout: WorkspacePanelLayout;
welcomeScreenButtonsLayout: Layout;
propertiesPanelLayout: Layout;
dataPanelLayout: Layout;
layersPanelControlBarLeftLayout: Layout;
layersPanelControlBarRightLayout: Layout;
layersPanelBottomBarLayout: Layout;
layerCache: SvelteMap<string, LayerPanelEntry>;
layerStructure: LayerStructureEntry[];
};
@ -29,12 +23,6 @@ const initialState: PortfolioStoreState = {
documents: [],
activeDocumentIndex: 0,
panelLayout: {},
welcomeScreenButtonsLayout: [],
propertiesPanelLayout: [],
dataPanelLayout: [],
layersPanelControlBarLeftLayout: [],
layersPanelControlBarRightLayout: [],
layersPanelBottomBarLayout: [],
layerCache: new SvelteMap<string, LayerPanelEntry>(),
layerStructure: [],
};
@ -46,6 +34,30 @@ const store: Writable<PortfolioStoreState> = import.meta.hot?.data?.store || wri
if (import.meta.hot) import.meta.hot.data.store = store;
const { subscribe, update } = store;
export const welcomeScreenButtonsLayout = makeLayoutStore("welcomeScreenButtonsLayout");
export const propertiesPanelLayout = makeLayoutStore("propertiesPanelLayout");
export const dataPanelLayout = makeLayoutStore("dataPanelLayout");
export const layersPanelControlBarLeftLayout = makeLayoutStore("layersPanelControlBarLeftLayout");
export const layersPanelControlBarRightLayout = makeLayoutStore("layersPanelControlBarRightLayout");
export const layersPanelBottomBarLayout = makeLayoutStore("layersPanelBottomBarLayout");
// Each panel layout has its own dedicated store so a layout update only re-renders that panel's consumers.
// Putting them at module scope (not inside the component) lets them survive a Svelte remount during a
// panel-tree restructure, since the backend's diff-based updates aren't re-sent on subscribe.
function makeLayoutStore(name: string): Writable<Layout> {
const persisted = import.meta.hot?.data?.[name];
const layoutStore: Writable<Layout> = persisted || writable<Layout>([]);
if (import.meta.hot) import.meta.hot.data[name] = layoutStore;
return layoutStore;
}
function patchLayoutStore(layoutStore: Writable<Layout>, data: Parameters<typeof patchLayout>[1]) {
layoutStore.update((layout) => {
patchLayout(layout, data);
return layout;
});
}
export function createPortfolioStore(subscriptions: SubscriptionsRouter, editor: EditorWrapper) {
destroyPortfolioStore();
@ -123,53 +135,35 @@ export function createPortfolioStore(subscriptions: SubscriptionsRouter, editor:
});
});
// All panel layouts below live in this store so panels that remount during a panel-tree change keep their contents
// Each panel layout uses its own store so updates only re-render that panel's consumers
subscriptions.subscribeLayoutUpdate("WelcomeScreenButtons", async (data) => {
await tick();
update((state) => {
patchLayout(state.welcomeScreenButtonsLayout, data);
return state;
});
patchLayoutStore(welcomeScreenButtonsLayout, data);
});
subscriptions.subscribeLayoutUpdate("PropertiesPanel", async (data) => {
await tick();
update((state) => {
patchLayout(state.propertiesPanelLayout, data);
return state;
});
patchLayoutStore(propertiesPanelLayout, data);
});
subscriptions.subscribeLayoutUpdate("DataPanel", async (data) => {
await tick();
update((state) => {
patchLayout(state.dataPanelLayout, data);
return state;
});
patchLayoutStore(dataPanelLayout, data);
});
subscriptions.subscribeLayoutUpdate("LayersPanelControlLeftBar", async (data) => {
await tick();
update((state) => {
patchLayout(state.layersPanelControlBarLeftLayout, data);
return state;
});
patchLayoutStore(layersPanelControlBarLeftLayout, data);
});
subscriptions.subscribeLayoutUpdate("LayersPanelControlRightBar", async (data) => {
await tick();
update((state) => {
patchLayout(state.layersPanelControlBarRightLayout, data);
return state;
});
patchLayoutStore(layersPanelControlBarRightLayout, data);
});
subscriptions.subscribeLayoutUpdate("LayersPanelBottomBar", async (data) => {
await tick();
update((state) => {
patchLayout(state.layersPanelBottomBarLayout, data);
return state;
});
patchLayoutStore(layersPanelBottomBarLayout, data);
});
subscriptions.subscribeFrontendMessage("UpdateDocumentLayerStructure", (data) => {