@window-splitter/svelte 0.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.storybook/main.ts +33 -0
- package/.storybook/preview.ts +14 -0
- package/.tshy/build.json +8 -0
- package/.tshy/commonjs.json +19 -0
- package/.tshy/esm.json +18 -0
- package/.turbo/turbo-build.log +6 -0
- package/CHANGELOG.md +20 -0
- package/README.md +58 -0
- package/dist/Panel.svelte +178 -0
- package/dist/Panel.svelte.d.ts +19 -0
- package/dist/Panel.svelte.d.ts.map +1 -0
- package/dist/PanelGroup.svelte +159 -0
- package/dist/PanelGroup.svelte.d.ts +18 -0
- package/dist/PanelGroup.svelte.d.ts.map +1 -0
- package/dist/PanelResizer.svelte +171 -0
- package/dist/PanelResizer.svelte.d.ts +8 -0
- package/dist/PanelResizer.svelte.d.ts.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/eslint.config.js +24 -0
- package/package.json +92 -0
- package/src/SvelteWindowSplitter.test.svelte.ts +283 -0
- package/src/__snapshots__/SvelteWindowSplitter.test.svelte.ts.snap +56 -0
- package/src/__snapshots__/SvelteWindowSplitter.test.ts.snap +54 -0
- package/src/lib/Panel.svelte +178 -0
- package/src/lib/PanelGroup.svelte +159 -0
- package/src/lib/PanelResizer.svelte +171 -0
- package/src/lib/index.ts +3 -0
- package/src/stories/Autosave.svelte +52 -0
- package/src/stories/AutosaveCollapsible.svelte +65 -0
- package/src/stories/AutosaveCookie.svelte +63 -0
- package/src/stories/Collapsible.svelte +112 -0
- package/src/stories/Conditional.svelte +70 -0
- package/src/stories/DynamicConstraints.svelte +73 -0
- package/src/stories/Simple.svelte +48 -0
- package/src/stories/SvelteWindowSplitter.stories.svelte +468 -0
- package/src/stories/VerticalLayout.svelte +58 -0
- package/svelte.config.js +7 -0
- package/tsconfig.json +6 -0
- package/vite.config.js +7 -0
- package/vitest.config.js +19 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { StorybookConfig } from "@storybook/svelte-vite";
|
|
2
|
+
|
|
3
|
+
import { join, dirname } from "path";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* This function is used to resolve the absolute path of a package.
|
|
7
|
+
* It is needed in projects that use Yarn PnP or are set up within a monorepo.
|
|
8
|
+
*/
|
|
9
|
+
function getAbsolutePath(value: string) {
|
|
10
|
+
return dirname(require.resolve(join(value, "package.json")));
|
|
11
|
+
}
|
|
12
|
+
const config: StorybookConfig = {
|
|
13
|
+
stories: [
|
|
14
|
+
"../stories/**/*.mdx",
|
|
15
|
+
"../src/**/*.stories.@(js|ts|svelte)",
|
|
16
|
+
"../stories/**/*.stories.@(js|ts|svelte)",
|
|
17
|
+
],
|
|
18
|
+
addons: [
|
|
19
|
+
{
|
|
20
|
+
name: getAbsolutePath("@storybook/addon-essentials"),
|
|
21
|
+
options: {
|
|
22
|
+
docs: false,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
getAbsolutePath("@storybook/addon-svelte-csf"),
|
|
26
|
+
getAbsolutePath("@storybook/addon-interactions"),
|
|
27
|
+
],
|
|
28
|
+
framework: {
|
|
29
|
+
name: getAbsolutePath("@storybook/svelte-vite"),
|
|
30
|
+
options: {},
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
export default config;
|
package/.tshy/build.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./build.json",
|
|
3
|
+
"include": [
|
|
4
|
+
"../src/**/*.ts",
|
|
5
|
+
"../src/**/*.cts",
|
|
6
|
+
"../src/**/*.tsx",
|
|
7
|
+
"../src/**/*.json"
|
|
8
|
+
],
|
|
9
|
+
"exclude": [
|
|
10
|
+
"../node_modules",
|
|
11
|
+
"../src/**/*.test.svelte.ts",
|
|
12
|
+
"../**/*stories*",
|
|
13
|
+
"../src/**/*.mts",
|
|
14
|
+
"../src/package.json"
|
|
15
|
+
],
|
|
16
|
+
"compilerOptions": {
|
|
17
|
+
"outDir": "../.tshy-build/commonjs"
|
|
18
|
+
}
|
|
19
|
+
}
|
package/.tshy/esm.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./build.json",
|
|
3
|
+
"include": [
|
|
4
|
+
"../src/**/*.ts",
|
|
5
|
+
"../src/**/*.mts",
|
|
6
|
+
"../src/**/*.tsx",
|
|
7
|
+
"../src/**/*.json"
|
|
8
|
+
],
|
|
9
|
+
"exclude": [
|
|
10
|
+
"../node_modules",
|
|
11
|
+
"../src/**/*.test.svelte.ts",
|
|
12
|
+
"../**/*stories*",
|
|
13
|
+
"../src/package.json"
|
|
14
|
+
],
|
|
15
|
+
"compilerOptions": {
|
|
16
|
+
"outDir": "../.tshy-build/esm"
|
|
17
|
+
}
|
|
18
|
+
}
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# v0.8.4 (Sat May 03 2025)
|
|
2
|
+
|
|
3
|
+
#### 🐛 Bug Fix
|
|
4
|
+
|
|
5
|
+
- Svelte Adapter [#55](https://github.com/hipstersmoothie/window-splitter/pull/55) ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
|
6
|
+
- fix test ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
|
7
|
+
- builds ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
|
8
|
+
- test it ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
|
9
|
+
- fix warning ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
|
10
|
+
- fix types ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
|
11
|
+
- clean up type errors ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
|
12
|
+
- constraints and imperative api ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
|
13
|
+
- conditional ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
|
14
|
+
- collapse ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
|
15
|
+
- working ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
|
16
|
+
- startin ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
|
17
|
+
|
|
18
|
+
#### Authors: 1
|
|
19
|
+
|
|
20
|
+
- Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
package/README.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# @window-splitter/svelte
|
|
2
|
+
|
|
3
|
+
A full featured window splitter for Svelte.
|
|
4
|
+
|
|
5
|
+
- Support for the full [window splitter](https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/) ARIA spec
|
|
6
|
+
- Support for percentage and pixel based constraints
|
|
7
|
+
- Collapsible panels
|
|
8
|
+
- Controlled panels
|
|
9
|
+
- Layout Persistance - LocalStorage and Cookie
|
|
10
|
+
|
|
11
|
+
[Read the full docs](https://react-window-splitter-six.vercel.app)
|
|
12
|
+
|
|
13
|
+
> NOTE: Docs are currently on react but it's the same API. Refer the the stories for usage examples.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @window-splitter/svelte
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
```svelte
|
|
24
|
+
<script>
|
|
25
|
+
import { PanelGroup } from '@window-splitter/svelte';
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<PanelGroup>
|
|
29
|
+
<Panel min="130px" max="400px" />
|
|
30
|
+
<PanelResizer />
|
|
31
|
+
<Panel min="130px" />
|
|
32
|
+
</PanelGroup>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Features
|
|
36
|
+
|
|
37
|
+
- WAI-ARIA compliant
|
|
38
|
+
- Keyboard accessible
|
|
39
|
+
- Touch friendly
|
|
40
|
+
- Customizable
|
|
41
|
+
- TypeScript support
|
|
42
|
+
|
|
43
|
+
## Server Side Rendering + Strict Mode
|
|
44
|
+
|
|
45
|
+
While not required for the simple case, for anything more complex you will
|
|
46
|
+
need to add an `id` prop to your panels and handles.
|
|
47
|
+
This is so that the component can tell all of the components apart during layout and rendering.
|
|
48
|
+
|
|
49
|
+
Features that require `id`:
|
|
50
|
+
|
|
51
|
+
- Conditional Panels
|
|
52
|
+
- Server Side Rendering
|
|
53
|
+
|
|
54
|
+
## Prior Art
|
|
55
|
+
|
|
56
|
+
This library is heavily inspired by the following libraries:
|
|
57
|
+
|
|
58
|
+
- [react-resizable-panels](https://github.com/bvaughn/react-resizable-panels)
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { SharedPanelProps } from "@window-splitter/interface";
|
|
3
|
+
import { getContext } from "svelte";
|
|
4
|
+
import {
|
|
5
|
+
initializePanel,
|
|
6
|
+
isPanelData,
|
|
7
|
+
haveConstraintsChangedForPanel,
|
|
8
|
+
getPanelPercentageSize,
|
|
9
|
+
getPanelPixelSize,
|
|
10
|
+
} from "@window-splitter/state";
|
|
11
|
+
import type {
|
|
12
|
+
PanelData,
|
|
13
|
+
GroupMachineContextValue,
|
|
14
|
+
SendFn,
|
|
15
|
+
Unit,
|
|
16
|
+
} from "@window-splitter/state";
|
|
17
|
+
import { getPanelDomAttributes } from "@window-splitter/interface";
|
|
18
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
19
|
+
|
|
20
|
+
export { PanelHandle } from "@window-splitter/interface";
|
|
21
|
+
|
|
22
|
+
interface Props
|
|
23
|
+
extends SharedPanelProps<boolean>,
|
|
24
|
+
HTMLAttributes<HTMLDivElement> {}
|
|
25
|
+
|
|
26
|
+
let {
|
|
27
|
+
children,
|
|
28
|
+
min,
|
|
29
|
+
max,
|
|
30
|
+
id: _id,
|
|
31
|
+
collapsible,
|
|
32
|
+
collapsed,
|
|
33
|
+
collapsedSize,
|
|
34
|
+
onCollapseChange,
|
|
35
|
+
collapseAnimation,
|
|
36
|
+
onResize,
|
|
37
|
+
defaultCollapsed,
|
|
38
|
+
default: defaultSize,
|
|
39
|
+
isStaticAtRest,
|
|
40
|
+
...attrs
|
|
41
|
+
}: Props = $props();
|
|
42
|
+
|
|
43
|
+
const defaultId = $props.id();
|
|
44
|
+
const id = _id || defaultId;
|
|
45
|
+
const send = getContext<SendFn>("send");
|
|
46
|
+
const state = getContext<GroupMachineContextValue>("state");
|
|
47
|
+
|
|
48
|
+
const initPanel = (): PanelData =>
|
|
49
|
+
initializePanel({
|
|
50
|
+
id,
|
|
51
|
+
min,
|
|
52
|
+
max,
|
|
53
|
+
collapsible,
|
|
54
|
+
collapsed,
|
|
55
|
+
collapsedSize,
|
|
56
|
+
onCollapseChange: { current: onCollapseChange },
|
|
57
|
+
collapseAnimation,
|
|
58
|
+
onResize: { current: onResize },
|
|
59
|
+
defaultCollapsed,
|
|
60
|
+
default: defaultSize,
|
|
61
|
+
isStaticAtRest,
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const isPrerender = getContext<{ current: boolean }>("isPrerender");
|
|
65
|
+
const panelData = () => {
|
|
66
|
+
const item = state?.items.find((i) => i.id === id);
|
|
67
|
+
if (!item || !isPanelData(item)) return undefined;
|
|
68
|
+
return item;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
let dynamicPanelIsMounting = false;
|
|
72
|
+
|
|
73
|
+
if (panelData()) {
|
|
74
|
+
send({
|
|
75
|
+
type: "rebindPanelCallbacks",
|
|
76
|
+
data: {
|
|
77
|
+
id,
|
|
78
|
+
onCollapseChange: { current: onCollapseChange },
|
|
79
|
+
onResize: { current: onResize },
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
} else {
|
|
83
|
+
if (isPrerender.current) {
|
|
84
|
+
send({ type: "registerPanel", data: initPanel() });
|
|
85
|
+
} else {
|
|
86
|
+
dynamicPanelIsMounting = true;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const contraintChanged = $derived(
|
|
91
|
+
!dynamicPanelIsMounting &&
|
|
92
|
+
haveConstraintsChangedForPanel(initPanel(), panelData())
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
$effect(() => {
|
|
96
|
+
if (!contraintChanged) return;
|
|
97
|
+
send({ type: "updateConstraints", data: initPanel() });
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
const dynamicPanelData = initPanel();
|
|
101
|
+
|
|
102
|
+
$effect(() => {
|
|
103
|
+
if (!dynamicPanelIsMounting) return;
|
|
104
|
+
|
|
105
|
+
const groupElement = document.getElementById(state.groupId);
|
|
106
|
+
if (!groupElement) return;
|
|
107
|
+
|
|
108
|
+
const panelElement = document.getElementById(id);
|
|
109
|
+
if (!panelElement) return;
|
|
110
|
+
|
|
111
|
+
const order = Array.from(groupElement.children).indexOf(panelElement);
|
|
112
|
+
if (typeof order !== "number") return;
|
|
113
|
+
|
|
114
|
+
send({
|
|
115
|
+
type: "registerDynamicPanel",
|
|
116
|
+
data: { ...dynamicPanelData, order },
|
|
117
|
+
});
|
|
118
|
+
dynamicPanelIsMounting = false;
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
$effect(() => () => {
|
|
122
|
+
requestAnimationFrame(() => {
|
|
123
|
+
send({ type: "unregisterPanel", id });
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
const isControlledCollapse = $derived(panelData()?.collapseIsControlled);
|
|
128
|
+
|
|
129
|
+
$effect(() => {
|
|
130
|
+
if (!isControlledCollapse) return;
|
|
131
|
+
|
|
132
|
+
if (collapsed) {
|
|
133
|
+
send?.({ type: "collapsePanel", panelId: id, controlled: true });
|
|
134
|
+
} else {
|
|
135
|
+
send?.({ type: "expandPanel", panelId: id, controlled: true });
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
const domAttributes = () => {
|
|
140
|
+
const currentPanel = panelData();
|
|
141
|
+
|
|
142
|
+
return getPanelDomAttributes({
|
|
143
|
+
groupId: state.groupId,
|
|
144
|
+
id,
|
|
145
|
+
collapsible: currentPanel?.collapsible,
|
|
146
|
+
collapsed: currentPanel?.collapsed,
|
|
147
|
+
});
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
export const getId = () => id;
|
|
151
|
+
export const collapse = () => {
|
|
152
|
+
if (!panelData()?.collapsible) return;
|
|
153
|
+
send({ type: "collapsePanel", panelId: id, controlled: true });
|
|
154
|
+
};
|
|
155
|
+
export const isCollapsed = () =>
|
|
156
|
+
Boolean(panelData()?.collapsible && panelData()?.collapsed);
|
|
157
|
+
export const expand = () => {
|
|
158
|
+
if (!panelData()?.collapsible) return;
|
|
159
|
+
send({ type: "expandPanel", panelId: id, controlled: true });
|
|
160
|
+
};
|
|
161
|
+
export const isExpanded = () =>
|
|
162
|
+
Boolean(panelData()?.collapsible && !panelData()?.collapsed);
|
|
163
|
+
export const getPixelSize = () => getPanelPixelSize(state, id);
|
|
164
|
+
export const setSize = (size: Unit) => {
|
|
165
|
+
send({ type: "setPanelPixelSize", panelId: id, size });
|
|
166
|
+
};
|
|
167
|
+
export const getPercentageSize = () => getPanelPercentageSize(state, id);
|
|
168
|
+
</script>
|
|
169
|
+
|
|
170
|
+
<div
|
|
171
|
+
{...attrs}
|
|
172
|
+
{...domAttributes()}
|
|
173
|
+
style:min-width={0}
|
|
174
|
+
style:min-height={0}
|
|
175
|
+
style:overflow="hidden"
|
|
176
|
+
>
|
|
177
|
+
{@render children?.()}
|
|
178
|
+
</div>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { SharedPanelProps } from "@window-splitter/interface";
|
|
2
|
+
import type { Unit } from "@window-splitter/state";
|
|
3
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
4
|
+
interface Props extends SharedPanelProps<boolean>, HTMLAttributes<HTMLDivElement> {
|
|
5
|
+
}
|
|
6
|
+
declare const Panel: import("svelte").Component<Props, {
|
|
7
|
+
PanelHandle: typeof PanelHandle;
|
|
8
|
+
getId: () => string;
|
|
9
|
+
collapse: () => void;
|
|
10
|
+
isCollapsed: () => boolean;
|
|
11
|
+
expand: () => void;
|
|
12
|
+
isExpanded: () => boolean;
|
|
13
|
+
getPixelSize: () => number;
|
|
14
|
+
setSize: (size: Unit) => void;
|
|
15
|
+
getPercentageSize: () => number;
|
|
16
|
+
}, "">;
|
|
17
|
+
type Panel = ReturnType<typeof Panel>;
|
|
18
|
+
export default Panel;
|
|
19
|
+
//# sourceMappingURL=Panel.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Panel.svelte.d.ts","sourceRoot":"","sources":["../src/lib/Panel.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AASnE,OAAO,KAAK,EAIR,IAAI,EACL,MAAM,wBAAwB,CAAC;AAElC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGpD,UAAU,KACR,SAAQ,gBAAgB,CAAC,OAAO,CAAC,EAC/B,cAAc,CAAC,cAAc,CAAC;CAAG;AAkKvC,QAAA,MAAM,KAAK;iBADsQ,OAAO,WAAW;;;;;;;oBAXzQ,IAAI;;MAYqB,CAAC;AACpD,KAAK,KAAK,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC;AACtC,eAAe,KAAK,CAAC"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { SharedPanelGroupProps } from "@window-splitter/interface";
|
|
3
|
+
import { measureGroupChildren } from "@window-splitter/interface";
|
|
4
|
+
import {
|
|
5
|
+
buildTemplate,
|
|
6
|
+
groupMachine,
|
|
7
|
+
prepareSnapshot,
|
|
8
|
+
prepareItems,
|
|
9
|
+
getPanelGroupPixelSizes,
|
|
10
|
+
getPanelGroupPercentageSizes,
|
|
11
|
+
isPanelData,
|
|
12
|
+
} from "@window-splitter/state";
|
|
13
|
+
import type { GroupMachineContextValue, Unit } from "@window-splitter/state";
|
|
14
|
+
import { setContext } from "svelte";
|
|
15
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
16
|
+
|
|
17
|
+
export { PanelGroupHandle } from "@window-splitter/interface";
|
|
18
|
+
|
|
19
|
+
interface Props
|
|
20
|
+
extends SharedPanelGroupProps,
|
|
21
|
+
HTMLAttributes<HTMLDivElement> {
|
|
22
|
+
id: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let {
|
|
26
|
+
children,
|
|
27
|
+
orientation = "horizontal",
|
|
28
|
+
autosaveStrategy = "localStorage",
|
|
29
|
+
autosaveId,
|
|
30
|
+
snapshot,
|
|
31
|
+
...attrs
|
|
32
|
+
}: Props = $props();
|
|
33
|
+
|
|
34
|
+
if (
|
|
35
|
+
!snapshot &&
|
|
36
|
+
typeof window !== "undefined" &&
|
|
37
|
+
autosaveId &&
|
|
38
|
+
autosaveStrategy === "localStorage"
|
|
39
|
+
) {
|
|
40
|
+
const localSnapshot = localStorage.getItem(autosaveId);
|
|
41
|
+
|
|
42
|
+
if (localSnapshot) {
|
|
43
|
+
snapshot = JSON.parse(localSnapshot) as GroupMachineContextValue;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const defaultId = $props.id();
|
|
48
|
+
const id = autosaveId || defaultId;
|
|
49
|
+
|
|
50
|
+
const [initialState, send, machineState] = groupMachine(
|
|
51
|
+
{
|
|
52
|
+
orientation,
|
|
53
|
+
groupId: id,
|
|
54
|
+
autosaveStrategy,
|
|
55
|
+
...(snapshot ? prepareSnapshot(snapshot) : undefined),
|
|
56
|
+
},
|
|
57
|
+
(s) => {
|
|
58
|
+
if (!context) return;
|
|
59
|
+
updateContext(s);
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
const context = $state<GroupMachineContextValue>(initialState);
|
|
64
|
+
function updateContext(s: GroupMachineContextValue) {
|
|
65
|
+
for (const key in s) {
|
|
66
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
67
|
+
(context as any)[key] = (s as any)[key];
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
setContext("send", send);
|
|
72
|
+
setContext("state", context);
|
|
73
|
+
setContext("id", machineState);
|
|
74
|
+
|
|
75
|
+
const isPrerender = $state({ current: true });
|
|
76
|
+
setContext("isPrerender", isPrerender);
|
|
77
|
+
$effect(() => {
|
|
78
|
+
isPrerender.current = false;
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
let elementRef = $state<HTMLDivElement>();
|
|
82
|
+
|
|
83
|
+
$effect(() => {
|
|
84
|
+
const observer = new ResizeObserver(([entry]) => {
|
|
85
|
+
if (!entry) return;
|
|
86
|
+
if (entry.contentRect.width > 0 && entry.contentRect.height > 0) {
|
|
87
|
+
send({ type: "setSize", size: entry.contentRect });
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
if (elementRef) {
|
|
92
|
+
observer.observe(elementRef);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return () => observer.disconnect();
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
let childIds = $derived(context.items.map((i) => i.id).join(","));
|
|
99
|
+
|
|
100
|
+
$effect(() => {
|
|
101
|
+
// re-render when the childIds change
|
|
102
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
103
|
+
childIds;
|
|
104
|
+
measureGroupChildren(id, (childrenSizes) => {
|
|
105
|
+
send({ type: "setActualItemsSize", childrenSizes });
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
let template = $derived(buildTemplate(context));
|
|
110
|
+
|
|
111
|
+
$effect(() => {
|
|
112
|
+
send({ type: "unlockGroup" });
|
|
113
|
+
return () => send({ type: "lockGroup" });
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
export const getId = () => id;
|
|
117
|
+
export const getPixelSizes = () => getPanelGroupPixelSizes(context);
|
|
118
|
+
export const getPercentageSizes = () => getPanelGroupPercentageSizes(context);
|
|
119
|
+
export const getTemplate = () =>
|
|
120
|
+
buildTemplate({ ...context, items: prepareItems(context) });
|
|
121
|
+
export const getState = () =>
|
|
122
|
+
machineState.current === "idle" ? "idle" : "dragging";
|
|
123
|
+
export const setSizes = (updates: Array<Unit>) => {
|
|
124
|
+
for (let index = 0; index < updates.length; index++) {
|
|
125
|
+
const item = context.items[index];
|
|
126
|
+
const update = updates[index];
|
|
127
|
+
|
|
128
|
+
if (item && isPanelData(item) && update) {
|
|
129
|
+
send({
|
|
130
|
+
type: "setPanelPixelSize",
|
|
131
|
+
panelId: item.id,
|
|
132
|
+
size: update,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
</script>
|
|
138
|
+
|
|
139
|
+
<div
|
|
140
|
+
{...attrs}
|
|
141
|
+
data-panel-group-wrapper
|
|
142
|
+
bind:this={elementRef}
|
|
143
|
+
style:display="grid"
|
|
144
|
+
style:grid-template-columns={context.orientation === "horizontal"
|
|
145
|
+
? template
|
|
146
|
+
: undefined}
|
|
147
|
+
style:grid-template-rows={context.orientation === "vertical"
|
|
148
|
+
? template
|
|
149
|
+
: undefined}
|
|
150
|
+
{id}
|
|
151
|
+
>
|
|
152
|
+
{@render children?.()}
|
|
153
|
+
</div>
|
|
154
|
+
|
|
155
|
+
<style>
|
|
156
|
+
:where([data-panel-group-wrapper]) {
|
|
157
|
+
height: 100%;
|
|
158
|
+
}
|
|
159
|
+
</style>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { SharedPanelGroupProps } from "@window-splitter/interface";
|
|
2
|
+
import type { Unit } from "@window-splitter/state";
|
|
3
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
4
|
+
interface Props extends SharedPanelGroupProps, HTMLAttributes<HTMLDivElement> {
|
|
5
|
+
id: string;
|
|
6
|
+
}
|
|
7
|
+
declare const PanelGroup: import("svelte").Component<Props, {
|
|
8
|
+
PanelGroupHandle: typeof PanelGroupHandle;
|
|
9
|
+
getId: () => string;
|
|
10
|
+
getPixelSizes: () => number[];
|
|
11
|
+
getPercentageSizes: () => number[];
|
|
12
|
+
getTemplate: () => string;
|
|
13
|
+
getState: () => "idle" | "dragging";
|
|
14
|
+
setSizes: (updates: Array<Unit>) => void;
|
|
15
|
+
}, "">;
|
|
16
|
+
type PanelGroup = ReturnType<typeof PanelGroup>;
|
|
17
|
+
export default PanelGroup;
|
|
18
|
+
//# sourceMappingURL=PanelGroup.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PanelGroup.svelte.d.ts","sourceRoot":"","sources":["../src/lib/PanelGroup.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAWxE,OAAO,KAAK,EAA4B,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAE7E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGpD,UAAU,KACR,SAAQ,qBAAqB,EAC3B,cAAc,CAAC,cAAc,CAAC;IAChC,EAAE,EAAE,MAAM,CAAC;CACZ;AA0IH,QAAA,MAAM,UAAU;sBADgP,OAAO,gBAAgB;;;;;;wBA3BzP,KAAK,CAAC,IAAI,CAAC;MA4Be,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
|