Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .changeset/modern-owl-dance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
'@projectstorm/react-workspaces-core': minor
'@projectstorm/react-workspaces-behavior-panel-dropzone': minor
'@projectstorm/react-workspaces-dropzone-plugin-tabs': minor
'@projectstorm/react-workspaces-dropzone-plugin-tray': minor
'@projectstorm/react-workspaces-behavior-divider-dropzone': patch
'@projectstorm/react-workspaces-behavior-resize': patch
'@projectstorm/react-workspaces-defaults': patch
'@projectstorm/react-workspaces-model-floating-window': patch
'@projectstorm/react-workspaces-model-tabs': patch
'@projectstorm/react-workspaces-model-tray': patch
---

Upgrade the workspace to the latest TypeScript, React, Storybook, and build-tool dependencies.

Add improved panel drop targets, including reliable transform-zone activation, root-level tab and tray splitting, and gap-free directional layouts while preserving boundary drop zones.
9 changes: 7 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ on:

concurrency: ${{ github.workflow }}-${{ github.ref }}

permissions:
contents: write
pull-requests: write
id-token: write

jobs:
release:
name: Release
Expand All @@ -23,6 +28,7 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: "${{ steps.nvm.outputs.NVMRC }}"
registry-url: 'https://registry.npmjs.org'

- name: Install PNPM
uses: pnpm/action-setup@v4
Expand All @@ -40,8 +46,7 @@ jobs:
publish: pnpm release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: publish storybook
if: steps.changesets.outputs.published == 'true'
run: pnpm release:storybook
run: pnpm release:storybook
6 changes: 6 additions & 0 deletions demo/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ import type { StorybookConfig } from '@storybook/react-webpack5';
const config: StorybookConfig = {
stories: ['../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: ['@storybook/addon-webpack5-compiler-swc'],
core: {
disableWhatsNewNotifications: true
},
features: {
sidebarOnboardingChecklist: false
},
framework: {
name: '@storybook/react-webpack5',
options: {}
Expand Down
20 changes: 10 additions & 10 deletions demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,20 @@
"@projectstorm/react-workspaces-model-floating-window": "workspace:*",
"@projectstorm/react-workspaces-model-tabs": "workspace:*",
"@projectstorm/react-workspaces-model-tray": "workspace:*",
"lodash": "^4.17.23",
"react": "^19.2.4",
"lodash": "^4.18.1",
"react": "^19.2.7",
"typeface-open-sans": "^1.1.13"
},
"devDependencies": {
"@types/lodash": "^4.17.23",
"@types/node": "^25.2.3",
"@types/react": "19.2.14",
"@types/lodash": "^4.17.24",
"@types/node": "^26.1.1",
"@types/react": "19.2.17",
"@types/react-dom": "^19.2.3",
"react-dom": "19.2.4",
"react-dom": "19.2.7",
"source-map-loader": "^5.0.0",
"storybook": "^10.2.9",
"@storybook/react-webpack5": "^10.2.9",
"@storybook/addon-webpack5-compiler-swc": "^4.0.2",
"webpack": "^5.105.2"
"storybook": "^10.4.6",
"@storybook/react-webpack5": "^10.4.6",
"@storybook/addon-webpack5-compiler-swc": "^4.0.3",
"webpack": "^5.108.4"
}
}
41 changes: 21 additions & 20 deletions demo/stories/Affinity.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,29 @@ import * as React from 'react';
import { useState } from 'react';
import 'typeface-open-sans';
import { WorkspaceNodeModel } from '@projectstorm/react-workspaces-core';
import { CompInternal, SharedArgs, useEngine } from './helpers/tools';
import { CompInternal, SharedArgs, StoryArgs, useEngine } from './helpers/tools';
import { DefaultWorkspacePanelModel } from '@projectstorm/react-workspaces-defaults';

export const AffinityStories = function (args) {
const engine = useEngine(args);
const [model] = useState(() => {
let model = new WorkspaceNodeModel();
model.setHorizontal(true);
model
.addModel(new DefaultWorkspacePanelModel('left'))
.addModel(new DefaultWorkspacePanelModel('left'))
.addModel(new DefaultWorkspacePanelModel('left'))
.addModel(new DefaultWorkspacePanelModel('expand').setExpand(true, true))
.addModel(new DefaultWorkspacePanelModel('right'))
.addModel(new DefaultWorkspacePanelModel('right'))
.addModel(new DefaultWorkspacePanelModel('right'));
return model;
});
return <CompInternal model={model} engine={engine} />;
}.bind({});

AffinityStories.args = SharedArgs;
export const AffinityStories = Object.assign(
function AffinityStories(args: StoryArgs) {
const engine = useEngine(args);
const [model] = useState(() => {
let model = new WorkspaceNodeModel();
model.setHorizontal(true);
model
.addModel(new DefaultWorkspacePanelModel('left'))
.addModel(new DefaultWorkspacePanelModel('left'))
.addModel(new DefaultWorkspacePanelModel('left'))
.addModel(new DefaultWorkspacePanelModel('expand').setExpand(true, true))
.addModel(new DefaultWorkspacePanelModel('right'))
.addModel(new DefaultWorkspacePanelModel('right'))
.addModel(new DefaultWorkspacePanelModel('right'));
return model;
});
return <CompInternal model={model} engine={engine} />;
},
{ args: SharedArgs }
);

export default {
title: 'Workspace',
Expand Down
21 changes: 11 additions & 10 deletions demo/stories/Basic.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import * as React from 'react';
import { useState } from 'react';
import 'typeface-open-sans';
import { CompInternal, SharedArgs, useEngine } from './helpers/tools';
import { CompInternal, SharedArgs, StoryArgs, useEngine } from './helpers/tools';
import { createSimpleModel } from './helpers/simpleModel';

export const Basic = function (args) {
const engine = useEngine(args);
const [model] = useState(() => {
return createSimpleModel();
});
return <CompInternal model={model} engine={engine} />;
}.bind({});

Basic.args = SharedArgs;
export const Basic = Object.assign(
function Basic(args: StoryArgs) {
const engine = useEngine(args);
const [model] = useState(() => {
return createSimpleModel();
});
return <CompInternal model={model} engine={engine} />;
},
{ args: SharedArgs }
);

export default {
title: 'Workspace',
Expand Down
55 changes: 28 additions & 27 deletions demo/stories/Complex.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,39 @@
import * as React from 'react';
import { useEffect, useState } from 'react';
import 'typeface-open-sans';
import { Buttons, CompInternal, SharedArgs, useEngine, useRootModel } from './helpers/tools';
import { Buttons, CompInternal, SharedArgs, StoryArgs, useEngine, useRootModel } from './helpers/tools';
import { createComplexModel } from './helpers/complexModel';
import { useForceUpdate } from '@projectstorm/react-workspaces-core';

export const ComplexLayout = function (args) {
const forceUpdate = useForceUpdate();
const engine = useEngine(args);
const [model] = useState(() => {
return createComplexModel(engine);
});
useEffect(() => {
return engine.registerListener({
lockUpdated: () => {
forceUpdate();
}
export const ComplexLayout = Object.assign(
function ComplexLayout(args: StoryArgs) {
const forceUpdate = useForceUpdate();
const engine = useEngine(args);
const [model] = useState(() => {
return createComplexModel(engine);
});
}, []);
useRootModel(model, args);
return (
<Buttons
btns={{
[engine.locked ? 'Unlock' : 'Lock']: () => {
engine.setLocked(!engine.locked);
useEffect(() => {
return engine.registerListener({
lockUpdated: () => {
forceUpdate();
}
}}
>
<CompInternal model={model} engine={engine} />
</Buttons>
);
}.bind({});

ComplexLayout.args = SharedArgs;
});
}, []);
useRootModel(model, args);
return (
<Buttons
btns={{
[engine.locked ? 'Unlock' : 'Lock']: () => {
engine.setLocked(!engine.locked);
}
}}
>
<CompInternal model={model} engine={engine} />
</Buttons>
);
},
{ args: SharedArgs }
);

export default {
title: 'Workspace',
Expand Down
95 changes: 48 additions & 47 deletions demo/stories/FloatingWindows.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,55 +4,56 @@ import 'typeface-open-sans';
import { DefaultWindowModel, DefaultWorkspacePanelModel } from '@projectstorm/react-workspaces-defaults';
import { WorkspaceTabModel } from '@projectstorm/react-workspaces-model-tabs';
import { RootWorkspaceModel } from '@projectstorm/react-workspaces-model-floating-window';
import { CompInternal, genVerticalNode, SharedArgs, useEngine, useRootModel } from './helpers/tools';

export const FloatingWindows = function (args) {
const engine = useEngine(args);
const [model] = useState(() => {
let model = new RootWorkspaceModel(engine, false);
model.setHorizontal(true);
model

//left panel
.addModel(genVerticalNode())

//tab panel
.addModel(
new WorkspaceTabModel()

.addModel(new DefaultWorkspacePanelModel('Tab 4'))
.addModel(new DefaultWorkspacePanelModel('Tab 5'))
.addModel(new DefaultWorkspacePanelModel('Tab 6'))
)

.addModel(genVerticalNode());

const window1 = new DefaultWindowModel(new DefaultWorkspacePanelModel('Floating window 1'));
window1.position.update({
top: 100,
left: 100
});
window1.setWidth(400);
window1.setHeight(400);
model.addFloatingWindow(window1);

const window2 = new DefaultWindowModel(new DefaultWorkspacePanelModel('Floating window 2'));
window2.position.update({
top: 100,
left: 600
import { CompInternal, genVerticalNode, SharedArgs, StoryArgs, useEngine, useRootModel } from './helpers/tools';

export const FloatingWindows = Object.assign(
function FloatingWindows(args: StoryArgs) {
const engine = useEngine(args);
const [model] = useState(() => {
let model = new RootWorkspaceModel(engine, false);
model.setHorizontal(true);
model

//left panel
.addModel(genVerticalNode())

//tab panel
.addModel(
new WorkspaceTabModel()

.addModel(new DefaultWorkspacePanelModel('Tab 4'))
.addModel(new DefaultWorkspacePanelModel('Tab 5'))
.addModel(new DefaultWorkspacePanelModel('Tab 6'))
)

.addModel(genVerticalNode());

const window1 = new DefaultWindowModel(new DefaultWorkspacePanelModel('Floating window 1'));
window1.position.update({
top: 100,
left: 100
});
window1.setWidth(400);
window1.setHeight(400);
model.addFloatingWindow(window1);

const window2 = new DefaultWindowModel(new DefaultWorkspacePanelModel('Floating window 2'));
window2.position.update({
top: 100,
left: 600
});
window2.setWidth(400);
window2.setHeight(400);
model.addFloatingWindow(window2);

return model;
});
window2.setWidth(400);
window2.setHeight(400);
model.addFloatingWindow(window2);

return model;
});
useRootModel(model, args);

return <CompInternal model={model} engine={engine} />;
}.bind({});
useRootModel(model, args);

FloatingWindows.args = SharedArgs;
return <CompInternal model={model} engine={engine} />;
},
{ args: SharedArgs }
);

export default {
title: 'Workspace',
Expand Down
Loading
Loading