diff --git a/.changeset/early-monkeys-learn.md b/.changeset/early-monkeys-learn.md
new file mode 100644
index 0000000..89dda24
--- /dev/null
+++ b/.changeset/early-monkeys-learn.md
@@ -0,0 +1,5 @@
+---
+"paneforge": patch
+---
+
+feat: reactive minSize prop
diff --git a/docs/src/content/examples/collapsible-panes.md b/docs/src/content/examples/collapsible-panes.md
index a7d5b22..5c59ce8 100644
--- a/docs/src/content/examples/collapsible-panes.md
+++ b/docs/src/content/examples/collapsible-panes.md
@@ -32,21 +32,9 @@ Here's the high-level structure of the example above:
{#if collapsed}
-
+
{:else}
-
+
{/if}
+ import { ReactiveSizeDemo } from '$lib/components/demos'
+ import ViewExampleCode from '$lib/components/view-example-code.svelte'
+
+
+
+
+
+
+## Anatomy
+
+Here's the high-level structure of the example above:
+
+```svelte
+
+
+
+
+ Left
+
+ Right
+
+```
diff --git a/docs/src/lib/components/demos/index.ts b/docs/src/lib/components/demos/index.ts
index 1303ab5..64a5745 100644
--- a/docs/src/lib/components/demos/index.ts
+++ b/docs/src/lib/components/demos/index.ts
@@ -6,3 +6,4 @@ export { default as CollapsibleDemo } from "./collapsible-demo.svelte";
export { default as ConditionalDemo } from "./conditional-demo.svelte";
export { default as CookieDemo } from "./cookie-demo.svelte";
export { default as StorageDemo } from "./storage-demo.svelte";
+export { default as ReactiveSizeDemo } from "./reactive-size-demo.svelte";
diff --git a/docs/src/lib/components/demos/reactive-size-demo.svelte b/docs/src/lib/components/demos/reactive-size-demo.svelte
new file mode 100644
index 0000000..32ebd5b
--- /dev/null
+++ b/docs/src/lib/components/demos/reactive-size-demo.svelte
@@ -0,0 +1,32 @@
+
+
+
+
+
Panel Min: {panelMin}
+
+
+
+
+ Left
+
+
+
+
+
+
+
+
+
+ Right
+
+
+
+
diff --git a/docs/src/routes/(docs)/docs/sink/+page.svelte b/docs/src/routes/(docs)/docs/sink/+page.svelte
new file mode 100644
index 0000000..fd65b0d
--- /dev/null
+++ b/docs/src/routes/(docs)/docs/sink/+page.svelte
@@ -0,0 +1,32 @@
+
+
+
+
+
Panel Min: {panelMin}
+
+
+
+
+ Left
+
+
+
+
+
+
+
+
+
+ Right
+
+
+
+
diff --git a/packages/paneforge/package.json b/packages/paneforge/package.json
index 1438515..0026861 100644
--- a/packages/paneforge/package.json
+++ b/packages/paneforge/package.json
@@ -36,7 +36,7 @@
},
"devDependencies": {
"@sveltejs/kit": "^2.17.2",
- "@sveltejs/package": "^2.3.0",
+ "@sveltejs/package": "^2.3.10",
"@sveltejs/vite-plugin-svelte": "4.0.0",
"@testing-library/dom": "^10.2.0",
"@testing-library/jest-dom": "^6.4.6",
@@ -46,7 +46,7 @@
"jsdom": "^24.0.0",
"publint": "^0.1.9",
"resize-observer-polyfill": "^1.5.1",
- "svelte": "^5.20.1",
+ "svelte": "^5.20.2",
"svelte-check": "^4.1.4",
"tslib": "^2.4.1",
"typescript": "^5.0.0",
@@ -57,6 +57,7 @@
"types": "./dist/index.d.ts",
"type": "module",
"dependencies": {
+ "runed": "^0.23.4",
"svelte-toolbelt": "^0.7.1"
}
}
diff --git a/packages/paneforge/src/lib/components/pane-group.svelte b/packages/paneforge/src/lib/components/pane-group.svelte
index d67b273..f28231e 100644
--- a/packages/paneforge/src/lib/components/pane-group.svelte
+++ b/packages/paneforge/src/lib/components/pane-group.svelte
@@ -33,7 +33,7 @@
export const getLayout = () => paneGroupState.layout;
export const setLayout = paneGroupState.setLayout;
- export const getId = () => paneGroupState.id.current;
+ export const getId = () => paneGroupState.opts.id.current;
const mergedProps = $derived(mergeProps(restProps, paneGroupState.props));
diff --git a/packages/paneforge/src/lib/internal/helpers.ts b/packages/paneforge/src/lib/internal/helpers.ts
index 4827a58..2862c18 100644
--- a/packages/paneforge/src/lib/internal/helpers.ts
+++ b/packages/paneforge/src/lib/internal/helpers.ts
@@ -1,4 +1,5 @@
-import type { Direction, DragState, PaneConstraints, PaneData, ResizeEvent } from "./types.js";
+import type { PaneState } from "$lib/paneforge.svelte.js";
+import type { Direction, DragState, PaneConstraints, ResizeEvent } from "./types.js";
import { calculateAriaValues } from "./utils/aria.js";
import { assert } from "./utils/assert.js";
import { areNumbersAlmostEqual } from "./utils/compare.js";
@@ -10,27 +11,26 @@ export function noop() {}
export function updateResizeHandleAriaValues({
groupId,
layout,
- paneDataArray,
+ panesArray,
}: {
groupId: string;
layout: number[];
- paneDataArray: PaneData[];
+ panesArray: PaneState[];
}) {
const resizeHandleElements = getResizeHandleElementsForGroup(groupId);
- for (let index = 0; index < paneDataArray.length - 1; index++) {
+ for (let index = 0; index < panesArray.length - 1; index++) {
const { valueMax, valueMin, valueNow } = calculateAriaValues({
layout,
- panesArray: paneDataArray,
+ panesArray: panesArray,
pivotIndices: [index, index + 1],
});
const resizeHandleEl = resizeHandleElements[index];
if (isHTMLElement(resizeHandleEl)) {
- const paneData = paneDataArray[index];
-
- resizeHandleEl.setAttribute("aria-controls", paneData.id);
+ const paneData = panesArray[index];
+ resizeHandleEl.setAttribute("aria-controls", paneData.opts.id.current);
resizeHandleEl.setAttribute("aria-valuemax", `${Math.round(valueMax)}`);
resizeHandleEl.setAttribute("aria-valuemin", `${Math.round(valueMin)}`);
resizeHandleEl.setAttribute(
@@ -73,13 +73,13 @@ export function getPivotIndices(
return index != null ? [index, index + 1] : [-1, -1];
}
-export function paneDataHelper(paneDataArray: PaneData[], paneData: PaneData, layout: number[]) {
- const paneConstraintsArray = paneDataArray.map((paneData) => paneData.constraints);
+export function paneDataHelper(panesArray: PaneState[], pane: PaneState, layout: number[]) {
+ const paneConstraintsArray = panesArray.map((paneData) => paneData.constraints);
- const paneIndex = findPaneDataIndex(paneDataArray, paneData);
+ const paneIndex = findPaneDataIndex(panesArray, pane);
const paneConstraints = paneConstraintsArray[paneIndex];
- const isLastPane = paneIndex === paneDataArray.length - 1;
+ const isLastPane = paneIndex === panesArray.length - 1;
const pivotIndices = isLastPane ? [paneIndex - 1, paneIndex] : [paneIndex, paneIndex + 1];
const paneSize = layout[paneIndex];
@@ -91,30 +91,31 @@ export function paneDataHelper(paneDataArray: PaneData[], paneData: PaneData, la
};
}
-export function findPaneDataIndex(paneDataArray: readonly PaneData[], paneData: PaneData) {
- return paneDataArray.findIndex((prevPaneData) => prevPaneData.id === paneData.id);
+export function findPaneDataIndex(panesArray: readonly PaneState[], pane: PaneState) {
+ return panesArray.findIndex(
+ (prevPaneData) => prevPaneData.opts.id.current === pane.opts.id.current
+ );
}
// Layout should be pre-converted into percentages
export function callPaneCallbacks(
- paneArray: PaneData[],
+ panesArray: PaneState[],
layout: number[],
paneIdToLastNotifiedSizeMap: Record
) {
for (let index = 0; index < layout.length; index++) {
const size = layout[index];
- const paneData = paneArray[index];
+ const paneData = panesArray[index];
assert(paneData);
- const { callbacks, constraints, id: paneId } = paneData;
- const { collapsedSize = 0, collapsible } = constraints;
+ const { collapsedSize = 0, collapsible } = paneData.constraints;
- const lastNotifiedSize = paneIdToLastNotifiedSizeMap[paneId];
+ const lastNotifiedSize = paneIdToLastNotifiedSizeMap[paneData.opts.id.current];
// invert the logic from below
if (!(lastNotifiedSize == null || size !== lastNotifiedSize)) continue;
- paneIdToLastNotifiedSizeMap[paneId] = size;
+ paneIdToLastNotifiedSizeMap[paneData.opts.id.current] = size;
- const { onCollapse, onExpand, onResize } = callbacks;
+ const { onCollapse, onExpand, onResize } = paneData.callbacks;
onResize?.(size, lastNotifiedSize);
@@ -138,16 +139,16 @@ export function callPaneCallbacks(
}
}
-export function getUnsafeDefaultLayout({ paneDataArray }: { paneDataArray: PaneData[] }): number[] {
- const layout = Array(paneDataArray.length);
+export function getUnsafeDefaultLayout({ panesArray }: { panesArray: PaneState[] }): number[] {
+ const layout = Array(panesArray.length);
- const paneConstraintsArray = paneDataArray.map((paneData) => paneData.constraints);
+ const paneConstraintsArray = panesArray.map((paneData) => paneData.constraints);
let numPanesWithSizes = 0;
let remainingSize = 100;
// Distribute default sizes first
- for (let index = 0; index < paneDataArray.length; index++) {
+ for (let index = 0; index < panesArray.length; index++) {
const paneConstraints = paneConstraintsArray[index];
assert(paneConstraints);
const { defaultSize } = paneConstraints;
@@ -160,7 +161,7 @@ export function getUnsafeDefaultLayout({ paneDataArray }: { paneDataArray: PaneD
}
// Remaining size should be distributed evenly between panes without default sizes
- for (let index = 0; index < paneDataArray.length; index++) {
+ for (let index = 0; index < panesArray.length; index++) {
const paneConstraints = paneConstraintsArray[index];
assert(paneConstraints);
const { defaultSize } = paneConstraints;
@@ -169,7 +170,7 @@ export function getUnsafeDefaultLayout({ paneDataArray }: { paneDataArray: PaneD
continue;
}
- const numRemainingPanes = paneDataArray.length - numPanesWithSizes;
+ const numRemainingPanes = panesArray.length - numPanesWithSizes;
const size = remainingSize / numRemainingPanes;
numPanesWithSizes++;
@@ -373,14 +374,14 @@ export function getResizeEventCursorPosition(dir: Direction, e: ResizeEvent): nu
export function getResizeHandlePaneIds(
groupId: string,
handleId: string,
- panesArray: PaneData[]
+ panesArray: PaneState[]
): [idBefore: string | null, idAfter: string | null] {
const handle = getResizeHandleElement(handleId);
const handles = getResizeHandleElementsForGroup(groupId);
const index = handle ? handles.indexOf(handle) : -1;
- const idBefore: string | null = panesArray[index]?.id ?? null;
- const idAfter: string | null = panesArray[index + 1]?.id ?? null;
+ const idBefore: string | null = panesArray[index]?.opts.id.current ?? null;
+ const idAfter: string | null = panesArray[index + 1]?.opts.id.current ?? null;
return [idBefore, idAfter];
}
diff --git a/packages/paneforge/src/lib/internal/utils/aria.ts b/packages/paneforge/src/lib/internal/utils/aria.ts
index d17092b..797f329 100644
--- a/packages/paneforge/src/lib/internal/utils/aria.ts
+++ b/packages/paneforge/src/lib/internal/utils/aria.ts
@@ -1,4 +1,4 @@
-import type { PaneData } from "../types.js";
+import type { PaneState } from "$lib/paneforge.svelte.js";
/**
* A utility function that calculates the `aria-valuemax`, `aria-valuemin`,
@@ -10,7 +10,7 @@ export function calculateAriaValues({
pivotIndices,
}: {
layout: number[];
- panesArray: PaneData[];
+ panesArray: PaneState[];
pivotIndices: number[];
}) {
let currentMinSize = 0;
@@ -22,7 +22,7 @@ export function calculateAriaValues({
// A pane's effective min/max sizes also need to account for other pane's sizes.
for (let i = 0; i < panesArray.length; i++) {
- const { constraints } = panesArray[i];
+ const constraints = panesArray[i].constraints;
const { maxSize = 100, minSize = 0 } = constraints;
if (i === firstIndex) {
diff --git a/packages/paneforge/src/lib/internal/utils/createContext.ts b/packages/paneforge/src/lib/internal/utils/createContext.ts
deleted file mode 100644
index 5ad7202..0000000
--- a/packages/paneforge/src/lib/internal/utils/createContext.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-import { getContext as getSvelteContext, hasContext, setContext as setSvelteContext } from "svelte";
-
-function setContext(key: symbol | string, value: T): T {
- return setSvelteContext(key, value);
-}
-
-function getContext(key: symbol | string, fallback?: T): T {
- const trueKey = typeof key === "symbol" ? key : key;
- const description = typeof key === "symbol" ? key.description : key;
-
- if (!hasContext(trueKey)) {
- if (fallback === undefined) {
- throw new Error(
- `Missing context dependency: ${description} and no fallback was provided.`
- );
- }
- return fallback as T;
- }
- return getSvelteContext(key);
-}
-
-function getSymbolDescription(providerComponentName: string | string[], contextName?: string) {
- if (contextName !== undefined) return contextName;
- if (typeof providerComponentName === "string" && contextName === undefined) {
- return `${providerComponentName}Context`;
- } else if (Array.isArray(providerComponentName) && contextName === undefined) {
- return `${providerComponentName[0]}Context`;
- } else {
- if (contextName !== undefined) return contextName;
- return `${providerComponentName}Context`;
- }
-}
-
-export function createContext(
- providerComponentName: string | string[],
- contextName?: string,
- useSymbol = true
-) {
- const symbolDescription = getSymbolDescription(providerComponentName, contextName);
- const symbol = Symbol(symbolDescription);
- const key = symbolDescription;
-
- function getCtx(
- fallback?: T
- ): T extends null ? ContextValue | null : ContextValue {
- const context = getContext(useSymbol ? symbol : key, fallback);
- if (context === undefined) {
- throw new Error(
- `Context \`${symbolDescription}\` not found. Component must be used within ${
- Array.isArray(providerComponentName)
- ? `one of the following components: ${providerComponentName.join(", ")}`
- : `\`${providerComponentName}\``
- }`
- );
- }
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- if (context === null) return context as any;
- return context;
- }
-
- function setCtx(value: ContextValue): ContextValue {
- if (useSymbol) {
- return setContext(symbol, value);
- } else {
- return setContext(key, value);
- }
- }
-
- return [setCtx, getCtx] as const;
-}
diff --git a/packages/paneforge/src/lib/internal/utils/storage.ts b/packages/paneforge/src/lib/internal/utils/storage.ts
index 6feb2a6..71eedc7 100644
--- a/packages/paneforge/src/lib/internal/utils/storage.ts
+++ b/packages/paneforge/src/lib/internal/utils/storage.ts
@@ -1,5 +1,5 @@
-import type { PaneData } from "../types.js";
import { LOCAL_STORAGE_DEBOUNCE_INTERVAL } from "../constants.js";
+import type { PaneState } from "$lib/paneforge.svelte.js";
export type PaneConfigState = {
expandToSizes: { [paneId: string]: number };
@@ -45,15 +45,12 @@ function getPaneGroupKey(autoSaveId: string): string {
* Returns a key to use for storing the pane state in local storage.
* The key is based on the pane order and constraints.
*/
-function getPaneKey(panes: PaneData[]): string {
+function getPaneKey(panes: PaneState[]): string {
const sortedPaneIds = panes
.map((pane) => {
- const { constraints, id, idIsFromProps, order } = pane;
- return idIsFromProps
- ? id
- : order
- ? `${order}:${JSON.stringify(constraints)}`
- : JSON.stringify(constraints);
+ return pane.opts.order.current
+ ? `${pane.opts.order.current}:${JSON.stringify(pane.constraints)}`
+ : JSON.stringify(pane.constraints);
})
.sort()
.join(",");
@@ -88,11 +85,11 @@ function loadSerializedPaneGroupState(
*/
export function loadPaneGroupState(
autoSaveId: string,
- panes: PaneData[],
+ panesArray: PaneState[],
storage: PaneGroupStorage
): PaneConfigState | null {
const state = loadSerializedPaneGroupState(autoSaveId, storage) || {};
- const paneKey = getPaneKey(panes);
+ const paneKey = getPaneKey(panesArray);
return state[paneKey] || null;
}
@@ -101,13 +98,13 @@ export function loadPaneGroupState(
*/
export function savePaneGroupState(
autoSaveId: string,
- panes: PaneData[],
+ panesArray: PaneState[],
paneSizesBeforeCollapse: Map,
sizes: number[],
storage: PaneGroupStorage
): void {
const paneGroupKey = getPaneGroupKey(autoSaveId);
- const paneKey = getPaneKey(panes);
+ const paneKey = getPaneKey(panesArray);
const state = loadSerializedPaneGroupState(autoSaveId, storage) || {};
state[paneKey] = {
expandToSizes: Object.fromEntries(paneSizesBeforeCollapse.entries()),
@@ -155,19 +152,19 @@ export function updateStorageValues({
autoSaveId,
layout,
storage,
- paneDataArray,
+ panesArray,
paneSizeBeforeCollapse,
}: {
autoSaveId: string;
layout: number[];
storage: PaneGroupStorage;
- paneDataArray: PaneData[];
+ panesArray: PaneState[];
paneSizeBeforeCollapse: Map;
}) {
// If this pane has been configured to persist sizing
// information, save sizes to local storage.
- if (layout.length === 0 || layout.length !== paneDataArray.length) return;
+ if (layout.length === 0 || layout.length !== panesArray.length) return;
let debouncedSave = debounceMap[autoSaveId];
@@ -179,8 +176,8 @@ export function updateStorageValues({
// Clone mutable data before passing to the debounced function,
// else we run the risk of saving an incorrect combination of mutable and immutable values to state.
- const clonedPaneDataArray = [...paneDataArray];
+ const clonedPanesArray = [...panesArray];
const clonedPaneSizesBeforeCollapse = new Map(paneSizeBeforeCollapse);
- debouncedSave(autoSaveId, clonedPaneDataArray, clonedPaneSizesBeforeCollapse, layout, storage);
+ debouncedSave(autoSaveId, clonedPanesArray, clonedPaneSizesBeforeCollapse, layout, storage);
}
diff --git a/packages/paneforge/src/lib/internal/utils/style.ts b/packages/paneforge/src/lib/internal/utils/style.ts
index 16efef9..b507138 100644
--- a/packages/paneforge/src/lib/internal/utils/style.ts
+++ b/packages/paneforge/src/lib/internal/utils/style.ts
@@ -1,4 +1,5 @@
-import type { DragState, PaneData } from "../types.js";
+import type { PaneState } from "$lib/paneforge.svelte.js";
+import type { DragState } from "../types.js";
type CursorState =
| "horizontal"
@@ -71,14 +72,14 @@ export function computePaneFlexBoxStyle({
defaultSize,
dragState,
layout,
- paneData,
+ panesArray,
paneIndex,
precision = 3,
}: {
defaultSize: number | undefined;
layout: number[];
dragState: DragState | null;
- paneData: PaneData[];
+ panesArray: PaneState[];
paneIndex: number;
precision?: number;
}): Record {
@@ -89,7 +90,7 @@ export function computePaneFlexBoxStyle({
// Initial render (before panes have registered themselves)
// To support server rendering, fallback to default size
flexGrow = defaultSize ?? "1";
- } else if (paneData.length === 1) {
+ } else if (panesArray.length === 1) {
// Single pane group should always fill full width/height
flexGrow = "1";
} else {
diff --git a/packages/paneforge/src/lib/paneforge.svelte.ts b/packages/paneforge/src/lib/paneforge.svelte.ts
index f67a020..670d0fa 100644
--- a/packages/paneforge/src/lib/paneforge.svelte.ts
+++ b/packages/paneforge/src/lib/paneforge.svelte.ts
@@ -6,7 +6,7 @@ import {
useRefById,
} from "svelte-toolbelt";
import { onMount, untrack } from "svelte";
-import { createContext } from "$lib/internal/utils/createContext.js";
+import { Context, watch } from "runed";
import {
callPaneCallbacks,
findPaneDataIndex,
@@ -36,7 +36,6 @@ import { assert } from "$lib/internal/utils/assert.js";
import type {
Direction,
DragState,
- PaneData,
PaneOnCollapse,
PaneOnExpand,
PaneOnResize,
@@ -50,6 +49,7 @@ import {
loadPaneGroupState,
updateStorageValues,
} from "$lib/internal/utils/storage.js";
+import { on } from "svelte/events";
type PaneGroupStateProps = WithRefProps<
ReadableBoxedValues<{
@@ -73,90 +73,67 @@ export const defaultStorage: PaneGroupStorage = {
};
class PaneGroupState {
- id: PaneGroupStateProps["id"];
- #ref: PaneGroupStateProps["ref"];
- #autoSaveId: PaneGroupStateProps["autoSaveId"];
- direction: PaneGroupStateProps["direction"];
- #keyboardResizeBy: PaneGroupStateProps["keyboardResizeBy"];
- #onLayout: PaneGroupStateProps["onLayout"];
- #storage: PaneGroupStateProps["storage"];
dragState = $state.raw(null);
layout = $state.raw([]);
- paneDataArray = $state.raw([]);
- paneDataArrayChanged = $state(false);
-
+ panesArray = $state.raw([]);
+ panesArrayChanged = $state(false);
paneIdToLastNotifiedSizeMap = $state>({});
paneSizeBeforeCollapseMap = new Map();
prevDelta = $state(0);
- constructor(props: PaneGroupStateProps) {
- this.id = props.id;
- this.#ref = props.ref;
- this.#autoSaveId = props.autoSaveId;
- this.direction = props.direction;
- this.#keyboardResizeBy = props.keyboardResizeBy;
- this.#onLayout = props.onLayout;
- this.#storage = props.storage;
-
- useRefById({
- id: this.id,
- ref: this.#ref,
- });
-
- $effect(() => {
- const groupId = this.id.current;
- const layout = this.layout;
- const paneDataArray = this.paneDataArray;
-
- untrack(() => {
- const unsub = updateResizeHandleAriaValues({
- groupId,
- layout,
- paneDataArray,
- });
+ constructor(readonly opts: PaneGroupStateProps) {
+ useRefById(opts);
- return unsub;
+ watch([() => this.opts.id.current, () => this.layout, () => this.panesArray], () => {
+ return updateResizeHandleAriaValues({
+ groupId: this.opts.id.current,
+ layout: this.layout,
+ panesArray: this.panesArray,
});
});
$effect(() => {
- untrack(() => {
- const unsub = this.#setResizeHandlerEventListeners();
- return unsub;
+ return untrack(() => {
+ return this.#setResizeHandlerEventListeners();
});
});
- $effect(() => {
- const autoSaveId = this.#autoSaveId.current;
- const layout = this.layout;
- const storage = this.#storage.current;
- if (!autoSaveId) return;
-
- untrack(() => {
+ watch(
+ [
+ () => this.opts.autoSaveId.current,
+ () => this.layout,
+ () => this.opts.storage.current,
+ ],
+ () => {
+ if (!this.opts.autoSaveId.current) return;
updateStorageValues({
- autoSaveId,
- layout,
- storage,
- paneDataArray: this.paneDataArray,
+ autoSaveId: this.opts.autoSaveId.current,
+ layout: this.layout,
+ storage: this.opts.storage.current,
+ panesArray: this.panesArray,
paneSizeBeforeCollapse: this.paneSizeBeforeCollapseMap,
});
- });
- });
-
- $effect(() => {
- const paneDataArrayChanged = this.paneDataArrayChanged;
- if (!paneDataArrayChanged) return;
- untrack(() => {
- this.paneDataArrayChanged = false;
- const autoSaveId = this.#autoSaveId.current;
- const storage = this.#storage.current;
+ }
+ );
+
+ watch(
+ () => this.panesArrayChanged,
+ () => {
+ if (!this.panesArrayChanged) return;
+ this.panesArrayChanged = false;
+ // const autoSaveId = this.opts.autoSaveId.current;
+ // const storage = this.opts.storage.current;
const prevLayout = this.layout;
- const paneDataArray = this.paneDataArray;
+ // const paneDataArray = this.panesArray;
let unsafeLayout: number[] | null = null;
- if (autoSaveId) {
- const state = loadPaneGroupState(autoSaveId, paneDataArray, storage);
+ if (this.opts.autoSaveId.current) {
+ const state = loadPaneGroupState(
+ this.opts.autoSaveId.current,
+ this.panesArray,
+ this.opts.storage.current
+ );
if (state) {
this.paneSizeBeforeCollapseMap = new Map(
Object.entries(state.expandToSizes)
@@ -167,23 +144,23 @@ class PaneGroupState {
if (unsafeLayout == null) {
unsafeLayout = getUnsafeDefaultLayout({
- paneDataArray,
+ panesArray: this.panesArray,
});
}
const nextLayout = validatePaneGroupLayout({
layout: unsafeLayout,
- paneConstraints: paneDataArray.map((paneData) => paneData.constraints),
+ paneConstraints: this.panesArray.map((paneData) => paneData.constraints),
});
if (areArraysEqual(prevLayout, nextLayout)) return;
this.layout = nextLayout;
- this.#onLayout.current?.(nextLayout);
+ this.opts.onLayout.current?.(nextLayout);
- callPaneCallbacks(paneDataArray, nextLayout, this.paneIdToLastNotifiedSizeMap);
- });
- });
+ callPaneCallbacks(this.panesArray, nextLayout, this.paneIdToLastNotifiedSizeMap);
+ }
+ );
}
setLayout = (newLayout: number[]) => {
@@ -194,13 +171,13 @@ class PaneGroupState {
return (e: ResizeEvent) => {
e.preventDefault();
- const direction = this.direction.current;
+ const direction = this.opts.direction.current;
const dragState = this.dragState;
- const groupId = this.id.current;
- const keyboardResizeBy = this.#keyboardResizeBy.current;
+ const groupId = this.opts.id.current;
+ const keyboardResizeBy = this.opts.keyboardResizeBy.current;
const prevLayout = this.layout;
- const paneDataArray = this.paneDataArray;
+ const paneDataArray = this.panesArray;
const { initialLayout } = dragState ?? {};
@@ -253,23 +230,23 @@ class PaneGroupState {
}
if (layoutChanged) {
this.setLayout(nextLayout);
- this.#onLayout.current?.(nextLayout);
+ this.opts.onLayout.current?.(nextLayout);
callPaneCallbacks(paneDataArray, nextLayout, this.paneIdToLastNotifiedSizeMap);
}
};
};
- resizePane = (paneData: PaneData, unsafePaneSize: number) => {
+ resizePane = (paneState: PaneState, unsafePaneSize: number) => {
const prevLayout = this.layout;
- const paneDataArray = this.paneDataArray;
+ const panesArray = this.panesArray;
- const paneConstraintsArr = paneDataArray.map((paneData) => paneData.constraints);
+ const paneConstraintsArr = panesArray.map((paneData) => paneData.constraints);
- const { paneSize, pivotIndices } = paneDataHelper(paneDataArray, paneData, prevLayout);
+ const { paneSize, pivotIndices } = paneDataHelper(panesArray, paneState, prevLayout);
assert(paneSize != null);
- const isLastPane = findPaneDataIndex(paneDataArray, paneData) === paneDataArray.length - 1;
+ const isLastPane = findPaneDataIndex(panesArray, paneState) === panesArray.length - 1;
const delta = isLastPane ? paneSize - unsafePaneSize : unsafePaneSize - paneSize;
@@ -285,13 +262,13 @@ class PaneGroupState {
this.setLayout(nextLayout);
- this.#onLayout.current?.(nextLayout);
+ this.opts.onLayout.current?.(nextLayout);
- callPaneCallbacks(paneDataArray, nextLayout, this.paneIdToLastNotifiedSizeMap);
+ callPaneCallbacks(panesArray, nextLayout, this.paneIdToLastNotifiedSizeMap);
};
startDragging = (dragHandleId: string, e: ResizeEvent) => {
- const direction = this.direction.current;
+ const direction = this.opts.direction.current;
const layout = this.layout;
const handleElement = getResizeHandleElement(dragHandleId);
@@ -313,34 +290,23 @@ class PaneGroupState {
this.dragState = null;
};
- unregisterPane = (paneData: PaneData) => {
- const paneDataArray = [...this.paneDataArray];
- const index = findPaneDataIndex(paneDataArray, paneData);
-
- if (index < 0) return;
- paneDataArray.splice(index, 1);
- this.paneDataArray = paneDataArray;
- delete this.paneIdToLastNotifiedSizeMap[paneData.id];
- this.paneDataArrayChanged = true;
- };
-
- isPaneCollapsed = (paneData: PaneData) => {
- const paneDataArray = this.paneDataArray;
+ isPaneCollapsed = (pane: PaneState) => {
+ const paneDataArray = this.panesArray;
const layout = this.layout;
const {
collapsedSize = 0,
collapsible,
paneSize,
- } = paneDataHelper(paneDataArray, paneData, layout);
+ } = paneDataHelper(paneDataArray, pane, layout);
return collapsible === true && paneSize === collapsedSize;
};
- expandPane = (paneData: PaneData) => {
+ expandPane = (pane: PaneState) => {
const prevLayout = this.layout;
- const paneDataArray = this.paneDataArray;
+ const paneDataArray = this.panesArray;
- if (!paneData.constraints.collapsible) return;
+ if (!pane.constraints.collapsible) return;
const paneConstraintsArray = paneDataArray.map((paneData) => paneData.constraints);
const {
@@ -348,14 +314,14 @@ class PaneGroupState {
paneSize,
minSize = 0,
pivotIndices,
- } = paneDataHelper(paneDataArray, paneData, prevLayout);
+ } = paneDataHelper(paneDataArray, pane, prevLayout);
if (paneSize !== collapsedSize) return;
// restore this pane to the size it was before it was collapsed, if possible.
- const prevPaneSize = this.paneSizeBeforeCollapseMap.get(paneData.id);
+ const prevPaneSize = this.paneSizeBeforeCollapseMap.get(pane.opts.id.current);
const baseSize = prevPaneSize != null && prevPaneSize >= minSize ? prevPaneSize : minSize;
- const isLastPane = findPaneDataIndex(paneDataArray, paneData) === paneDataArray.length - 1;
+ const isLastPane = findPaneDataIndex(paneDataArray, pane) === paneDataArray.length - 1;
const delta = isLastPane ? paneSize - baseSize : baseSize - paneSize;
const nextLayout = adjustLayoutByDelta({
@@ -370,16 +336,16 @@ class PaneGroupState {
this.setLayout(nextLayout);
- this.#onLayout.current?.(nextLayout);
+ this.opts.onLayout.current?.(nextLayout);
callPaneCallbacks(paneDataArray, nextLayout, this.paneIdToLastNotifiedSizeMap);
};
- collapsePane = (paneData: PaneData) => {
+ collapsePane = (pane: PaneState) => {
const prevLayout = this.layout;
- const paneDataArray = this.paneDataArray;
+ const paneDataArray = this.panesArray;
- if (!paneData.constraints.collapsible) return;
+ if (!pane.constraints.collapsible) return;
const paneConstraintsArray = paneDataArray.map((paneData) => paneData.constraints);
@@ -387,16 +353,16 @@ class PaneGroupState {
collapsedSize = 0,
paneSize,
pivotIndices,
- } = paneDataHelper(paneDataArray, paneData, prevLayout);
+ } = paneDataHelper(paneDataArray, pane, prevLayout);
assert(paneSize != null);
if (paneSize === collapsedSize) return;
// Store the size before collapse, which is returned when `expand()` is called
- this.paneSizeBeforeCollapseMap.set(paneData.id, paneSize);
+ this.paneSizeBeforeCollapseMap.set(pane.opts.id.current, paneSize);
- const isLastPane = findPaneDataIndex(paneDataArray, paneData) === paneDataArray.length - 1;
+ const isLastPane = findPaneDataIndex(paneDataArray, pane) === paneDataArray.length - 1;
const delta = isLastPane ? paneSize - collapsedSize : collapsedSize - paneSize;
const nextLayout = adjustLayoutByDelta({
@@ -410,45 +376,44 @@ class PaneGroupState {
if (areArraysEqual(prevLayout, nextLayout)) return;
this.layout = nextLayout;
- this.#onLayout.current?.(nextLayout);
+ this.opts.onLayout.current?.(nextLayout);
callPaneCallbacks(paneDataArray, nextLayout, this.paneIdToLastNotifiedSizeMap);
};
- getPaneSize = (paneData: PaneData) => {
- const { paneSize } = paneDataHelper(this.paneDataArray, paneData, this.layout);
- return paneSize;
+ getPaneSize = (pane: PaneState) => {
+ return paneDataHelper(this.panesArray, pane, this.layout).paneSize;
};
- getPaneStyle = (paneData: PaneData, defaultSize: number | undefined) => {
- const paneDataArray = this.paneDataArray;
+ getPaneStyle = (pane: PaneState, defaultSize: number | undefined) => {
+ const paneDataArray = this.panesArray;
const layout = this.layout;
const dragState = this.dragState;
- const paneIndex = findPaneDataIndex(paneDataArray, paneData);
+ const paneIndex = findPaneDataIndex(paneDataArray, pane);
return computePaneFlexBoxStyle({
defaultSize,
dragState,
layout,
- paneData: paneDataArray,
+ panesArray: paneDataArray,
paneIndex,
});
};
- isPaneExpanded = (paneData: PaneData) => {
+ isPaneExpanded = (pane: PaneState) => {
const {
collapsedSize = 0,
collapsible,
paneSize,
- } = paneDataHelper(this.paneDataArray, paneData, this.layout);
+ } = paneDataHelper(this.panesArray, pane, this.layout);
return !collapsible || paneSize > collapsedSize;
};
- registerPane = (paneData: PaneData) => {
- const newPaneDataArray = [...this.paneDataArray, paneData];
+ registerPane = (pane: PaneState) => {
+ const newPaneDataArray = [...this.panesArray, pane];
newPaneDataArray.sort((paneA, paneB) => {
- const orderA = paneA.order;
- const orderB = paneB.order;
+ const orderA = paneA.opts.order.current;
+ const orderB = paneB.opts.order.current;
if (orderA == null && orderB == null) {
return 0;
@@ -460,14 +425,25 @@ class PaneGroupState {
return orderA - orderB;
}
});
- this.paneDataArray = newPaneDataArray;
- this.paneDataArrayChanged = true;
+ this.panesArray = newPaneDataArray;
+ this.panesArrayChanged = true;
+
+ return () => {
+ const paneDataArray = [...this.panesArray];
+ const index = findPaneDataIndex(this.panesArray, pane);
+
+ if (index < 0) return;
+ paneDataArray.splice(index, 1);
+ this.panesArray = paneDataArray;
+ delete this.paneIdToLastNotifiedSizeMap[pane.opts.id.current];
+ this.panesArrayChanged = true;
+ };
};
#setResizeHandlerEventListeners = () => {
- const groupId = this.id.current;
+ const groupId = this.opts.id.current;
const handles = getResizeHandleElementsForGroup(groupId);
- const paneDataArray = this.paneDataArray;
+ const paneDataArray = this.panesArray;
const unsubHandlers = handles.map((handle) => {
const handleId = handle.getAttribute("data-pane-resizer-id");
@@ -481,8 +457,10 @@ class PaneGroupState {
if (e.defaultPrevented || e.key !== "Enter") return;
e.preventDefault();
- const paneDataArray = this.paneDataArray;
- const index = paneDataArray.findIndex((paneData) => paneData.id === idBefore);
+ const paneDataArray = this.panesArray;
+ const index = paneDataArray.findIndex(
+ (paneData) => paneData.opts.id.current === idBefore
+ );
if (index < 0) return;
@@ -525,27 +503,22 @@ class PaneGroupState {
};
};
- props = $derived.by(() => ({
- id: this.id.current,
- "data-pane-group": "",
- "data-direction": this.direction.current,
- "data-pane-group-id": this.id.current,
- style: {
- display: "flex",
- flexDirection: this.direction.current === "horizontal" ? "row" : "column",
- height: "100%",
- overflow: "hidden",
- width: "100%",
- },
- }));
-
- createResizer = (props: PaneResizerStateProps) => {
- return new PaneResizerState(props, this);
- };
-
- createPane = (props: PaneStateProps) => {
- return new PaneState(props, this);
- };
+ props = $derived.by(
+ () =>
+ ({
+ id: this.opts.id.current,
+ "data-pane-group": "",
+ "data-direction": this.opts.direction.current,
+ "data-pane-group-id": this.opts.id.current,
+ style: {
+ display: "flex",
+ flexDirection: this.opts.direction.current === "horizontal" ? "row" : "column",
+ height: "100%",
+ overflow: "hidden",
+ width: "100%",
+ },
+ }) as const
+ );
}
type PaneResizerStateProps = WithRefProps<
@@ -559,41 +532,28 @@ type PaneResizerStateProps = WithRefProps<
const resizeKeys = ["ArrowDown", "ArrowLeft", "ArrowRight", "ArrowUp", "End", "Home"];
class PaneResizerState {
- #id: PaneResizerStateProps["id"];
- #ref: PaneResizerStateProps["ref"];
- #onDraggingChange: PaneResizerStateProps["onDraggingChange"];
- #disabled: PaneResizerStateProps["disabled"];
- #tabIndex: PaneResizerStateProps["tabIndex"];
- #group: PaneGroupState;
- #isDragging = $derived.by(() => this.#group.dragState?.dragHandleId === this.#id.current);
+ #isDragging = $derived.by(() => this.group.dragState?.dragHandleId === this.opts.id.current);
#isFocused = $state(false);
resizeHandler: ResizeHandler | null = null;
- constructor(props: PaneResizerStateProps, group: PaneGroupState) {
- this.#id = props.id;
- this.#ref = props.ref;
- this.#group = group;
- this.#onDraggingChange = props.onDraggingChange;
- this.#disabled = props.disabled;
- this.#tabIndex = props.tabIndex;
-
- useRefById({
- id: this.#id,
- ref: this.#ref,
- });
+ constructor(
+ readonly opts: PaneResizerStateProps,
+ readonly group: PaneGroupState
+ ) {
+ useRefById(opts);
$effect(() => {
- if (this.#disabled.current) {
+ if (this.opts.disabled.current) {
this.resizeHandler = null;
} else {
- this.resizeHandler = this.#group.registerResizeHandle(this.#id.current);
+ this.resizeHandler = this.group.registerResizeHandle(this.opts.id.current);
}
});
$effect(() => {
- const node = this.#ref.current;
+ const node = this.opts.ref.current;
if (!node) return;
- const disabled = this.#disabled.current;
+ const disabled = this.opts.disabled.current;
const resizeHandler = this.resizeHandler;
const isDragging = this.#isDragging;
if (disabled || resizeHandler === null || !isDragging) return;
@@ -608,41 +568,39 @@ class PaneResizerState {
const stopDraggingAndBlur = () => {
node.blur();
- this.#group.stopDragging();
- this.#onDraggingChange.current(false);
+ this.group.stopDragging();
+ this.opts.onDraggingChange.current(false);
};
- const unsub = executeCallbacks(
- addEventListener(document.body, "contextmenu", stopDraggingAndBlur),
- addEventListener(document.body, "mousemove", onMove),
- addEventListener(document.body, "touchmove", onMove, { passive: false }),
- addEventListener(document.body, "mouseleave", onMouseLeave),
- addEventListener(window, "mouseup", stopDraggingAndBlur),
- addEventListener(window, "touchend", stopDraggingAndBlur)
+ return executeCallbacks(
+ on(document.body, "contextmenu", stopDraggingAndBlur),
+ on(document.body, "mousemove", onMove),
+ on(document.body, "touchmove", onMove, { passive: false }),
+ on(document.body, "mouseleave", onMouseLeave),
+ on(window, "mouseup", stopDraggingAndBlur),
+ on(window, "touchend", stopDraggingAndBlur)
);
-
- return unsub;
});
}
#startDragging = (e: MouseEvent | TouchEvent) => {
e.preventDefault();
- if (this.#disabled.current) return;
- this.#group.startDragging(this.#id.current, e);
- this.#onDraggingChange.current(true);
+ if (this.opts.disabled.current) return;
+ this.group.startDragging(this.opts.id.current, e);
+ this.opts.onDraggingChange.current(true);
};
#stopDraggingAndBlur = () => {
- const node = this.#ref.current;
+ const node = this.opts.ref.current;
if (!node) return;
node.blur();
- this.#group.stopDragging();
- this.#onDraggingChange.current(false);
+ this.group.stopDragging();
+ this.opts.onDraggingChange.current(false);
};
#onkeydown = (e: KeyboardEvent) => {
- if (this.#disabled.current || !this.resizeHandler || e.defaultPrevented) return;
+ if (this.opts.disabled.current || !this.resizeHandler || e.defaultPrevented) return;
if (resizeKeys.includes(e.key)) {
e.preventDefault();
@@ -654,8 +612,8 @@ class PaneResizerState {
e.preventDefault();
- const handles = getResizeHandleElementsForGroup(this.#group.id.current);
- const index = getResizeHandleElementIndex(this.#group.id.current, this.#id.current);
+ const handles = getResizeHandleElementsForGroup(this.group.opts.id.current);
+ const index = getResizeHandleElementIndex(this.group.opts.id.current, this.opts.id.current);
if (index === null) return;
@@ -712,21 +670,21 @@ class PaneResizerState {
props = $derived.by(
() =>
({
- id: this.#id.current,
+ id: this.opts.id.current,
role: "separator",
- "data-direction": this.#group.direction.current,
- "data-pane-group-id": this.#group.id.current,
+ "data-direction": this.group.opts.direction.current,
+ "data-pane-group-id": this.group.opts.id.current,
"data-active": this.#isDragging
? "pointer"
: this.#isFocused
? "keyboard"
: undefined,
- "data-enabled": !this.#disabled.current,
- "data-pane-resizer-id": this.#id.current,
+ "data-enabled": !this.opts.disabled.current,
+ "data-pane-resizer-id": this.opts.id.current,
"data-pane-resizer": "",
- tabIndex: this.#tabIndex.current,
+ tabIndex: this.opts.tabIndex.current,
style: {
- cursor: getCursorStyle(this.#group.direction.current),
+ cursor: getCursorStyle(this.group.opts.direction.current),
touchAction: "none",
userSelect: "none",
"-webkit-user-select": "none",
@@ -758,101 +716,77 @@ type PaneStateProps = WithRefProps<
}>
>;
-class PaneState {
- #id: PaneStateProps["id"];
- #ref: PaneStateProps["ref"];
- #collapsedSize: PaneStateProps["collapsedSize"];
- #collapsible: PaneStateProps["collapsible"];
- #defaultSize: PaneStateProps["defaultSize"];
- #maxSize: PaneStateProps["maxSize"];
- #minSize: PaneStateProps["minSize"];
- #order: PaneStateProps["order"];
- #onCollapse: PaneStateProps["onCollapse"];
- #onExpand: PaneStateProps["onExpand"];
- #onResize: PaneStateProps["onResize"];
- #group: PaneGroupState;
-
- #paneData = $derived.by(() => ({
- callbacks: {
- onCollapse: this.#onCollapse.current,
- onExpand: this.#onExpand.current,
- onResize: this.#onResize.current,
- },
- constraints: {
- collapsedSize: this.#collapsedSize.current,
- collapsible: this.#collapsible.current,
- defaultSize: this.#defaultSize.current,
- maxSize: this.#maxSize.current,
- minSize: this.#minSize.current,
- },
- id: this.#id.current,
- idIsFromProps: false,
- order: this.#order.current,
+export class PaneState {
+ callbacks = $derived.by(() => ({
+ onCollapse: this.opts.onCollapse.current,
+ onExpand: this.opts.onExpand.current,
+ onResize: this.opts.onResize.current,
+ }));
+
+ constraints = $derived.by(() => ({
+ collapsedSize: this.opts.collapsedSize.current,
+ collapsible: this.opts.collapsible.current,
+ defaultSize: this.opts.defaultSize.current,
+ maxSize: this.opts.maxSize.current,
+ minSize: this.opts.minSize.current,
}));
pane = {
collapse: () => {
- this.#group.collapsePane(this.#paneData);
+ this.group.collapsePane(this);
},
- expand: () => this.#group.expandPane(this.#paneData),
- getSize: () => this.#group.getPaneSize(this.#paneData),
- isCollapsed: () => this.#group.isPaneCollapsed(this.#paneData),
- isExpanded: () => this.#group.isPaneExpanded(this.#paneData),
- resize: (size: number) => this.#group.resizePane(this.#paneData, size),
- getId: () => this.#id.current,
+ expand: () => this.group.expandPane(this),
+ getSize: () => this.group.getPaneSize(this),
+ isCollapsed: () => this.group.isPaneCollapsed(this),
+ isExpanded: () => this.group.isPaneExpanded(this),
+ resize: (size: number) => this.group.resizePane(this, size),
+ getId: () => this.opts.id.current,
};
- constructor(props: PaneStateProps, group: PaneGroupState) {
- this.#id = props.id;
- this.#ref = props.ref;
- this.#collapsedSize = props.collapsedSize;
- this.#collapsible = props.collapsible;
- this.#defaultSize = props.defaultSize;
- this.#maxSize = props.maxSize;
- this.#minSize = props.minSize;
- this.#order = props.order;
- this.#onCollapse = props.onCollapse;
- this.#onExpand = props.onExpand;
- this.#onResize = props.onResize;
- this.#group = group;
-
- useRefById({
- id: this.#id,
- ref: this.#ref,
- });
+ constructor(
+ readonly opts: PaneStateProps,
+ readonly group: PaneGroupState
+ ) {
+ useRefById(opts);
onMount(() => {
- this.#group.registerPane(this.#paneData);
-
- return () => {
- this.#group.unregisterPane(this.#paneData);
- };
+ return this.group.registerPane(this);
});
+
+ watch(
+ () => $state.snapshot(this.constraints),
+ () => {
+ this.group.panesArrayChanged = true;
+ }
+ );
}
- #isCollapsed = $derived.by(() => this.#group.isPaneCollapsed(this.#paneData));
+ #isCollapsed = $derived.by(() => this.group.isPaneCollapsed(this));
- props = $derived.by(() => ({
- id: this.#id.current,
- style: this.#group.getPaneStyle(this.#paneData, this.#defaultSize.current),
- "data-pane": "",
- "data-pane-id": this.#id.current,
- "data-pane-group-id": this.#group.id.current,
- "data-collapsed": this.#isCollapsed ? "" : undefined,
- "data-expanded": this.#isCollapsed ? undefined : "",
- }));
+ props = $derived.by(
+ () =>
+ ({
+ id: this.opts.id.current,
+ style: this.group.getPaneStyle(this, this.opts.defaultSize.current),
+ "data-pane": "",
+ "data-pane-id": this.opts.id.current,
+ "data-pane-group-id": this.group.opts.id.current,
+ "data-collapsed": this.#isCollapsed ? "" : undefined,
+ "data-expanded": this.#isCollapsed ? undefined : "",
+ }) as const
+ );
}
-const [setPaneGroupContext, getPaneGroupContext] = createContext("PaneGroup");
+const PaneGroupContext = new Context("PaneGroup");
export function usePaneGroup(props: PaneGroupStateProps) {
- return setPaneGroupContext(new PaneGroupState(props));
+ return PaneGroupContext.set(new PaneGroupState(props));
}
export function usePaneResizer(props: PaneResizerStateProps) {
- return getPaneGroupContext().createResizer(props);
+ return new PaneResizerState(props, PaneGroupContext.get());
}
export function usePane(props: PaneStateProps) {
- return getPaneGroupContext().createPane(props);
+ return new PaneState(props, PaneGroupContext.get());
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 4375f63..7f5cf1b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -113,19 +113,22 @@ importers:
packages/paneforge:
dependencies:
+ runed:
+ specifier: ^0.23.4
+ version: 0.23.4(svelte@5.20.2)
svelte-toolbelt:
specifier: ^0.7.1
- version: 0.7.1(svelte@5.20.1)
+ version: 0.7.1(svelte@5.20.2)
devDependencies:
'@sveltejs/kit':
specifier: ^2.17.2
- version: 2.17.2(@sveltejs/vite-plugin-svelte@4.0.0(svelte@5.20.1)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0)))(svelte@5.20.1)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0))
+ version: 2.17.2(@sveltejs/vite-plugin-svelte@4.0.0(svelte@5.20.2)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0)))(svelte@5.20.2)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0))
'@sveltejs/package':
- specifier: ^2.3.0
- version: 2.3.7(svelte@5.20.1)(typescript@5.7.2)
+ specifier: ^2.3.10
+ version: 2.3.10(svelte@5.20.2)(typescript@5.7.2)
'@sveltejs/vite-plugin-svelte':
specifier: 4.0.0
- version: 4.0.0(svelte@5.20.1)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0))
+ version: 4.0.0(svelte@5.20.2)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0))
'@testing-library/dom':
specifier: ^10.2.0
version: 10.4.0
@@ -134,7 +137,7 @@ importers:
version: 6.6.3
'@testing-library/svelte':
specifier: ^5.2.0
- version: 5.2.6(svelte@5.20.1)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0))(vitest@1.6.0(@types/node@20.17.10)(jsdom@24.1.3)(lightningcss@1.28.2)(terser@5.37.0))
+ version: 5.2.6(svelte@5.20.2)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0))(vitest@1.6.0(@types/node@20.17.10)(jsdom@24.1.3)(lightningcss@1.28.2)(terser@5.37.0))
'@testing-library/user-event':
specifier: ^14.5.2
version: 14.5.2(@testing-library/dom@10.4.0)
@@ -151,11 +154,11 @@ importers:
specifier: ^1.5.1
version: 1.5.1
svelte:
- specifier: ^5.20.1
- version: 5.20.1
+ specifier: ^5.20.2
+ version: 5.20.2
svelte-check:
specifier: ^4.1.4
- version: 4.1.4(svelte@5.20.1)(typescript@5.7.2)
+ version: 4.1.4(svelte@5.20.2)(typescript@5.7.2)
tslib:
specifier: ^2.4.1
version: 2.8.1
@@ -1079,8 +1082,8 @@ packages:
svelte: ^4.0.0 || ^5.0.0-next.0
vite: ^5.0.3 || ^6.0.0
- '@sveltejs/package@2.3.7':
- resolution: {integrity: sha512-LYgUkde5GUYqOpXbcoCGUpEH4Ctl3Wj4u4CVZBl56dEeLW5fGHE037ZL1qlK0Ky+QD5uUfwONSeGwIOIighFMQ==}
+ '@sveltejs/package@2.3.10':
+ resolution: {integrity: sha512-A4fQacgjJ7C/7oSmxR61/TdB14u6ecyMZ8V9JCR5Lol0bLj/PdJPU4uFodFBsKzO3iFiJMpNTgZZ+zYsYZNpUg==}
engines: {node: ^16.14 || >=18}
hasBin: true
peerDependencies:
@@ -1485,6 +1488,10 @@ packages:
resolution: {integrity: sha512-/b57FK+bblSU+dfewfFe0rT1YjVDfOmeLQwCAuC+vwvgLkXboATqqmy+Ipux6JrF6L5joe5CBnFOw+gLWH6yKg==}
engines: {node: '>= 14.16.0'}
+ chokidar@4.0.3:
+ resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
+ engines: {node: '>= 14.16.0'}
+
ci-info@3.9.0:
resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==}
engines: {node: '>=8'}
@@ -3114,8 +3121,8 @@ packages:
peerDependencies:
svelte: ^5.0.0
- svelte2tsx@0.7.31:
- resolution: {integrity: sha512-exrN1o9mdCLAA7hTCudz731FIxomH/0SN9ZIX+WrY/XnlLuno/NNC1PF6JXPZVqp/4sMMDKteqyKoG44hliljQ==}
+ svelte2tsx@0.7.34:
+ resolution: {integrity: sha512-WTMhpNhFf8/h3SMtR5dkdSy2qfveomkhYei/QW9gSPccb0/b82tjHvLop6vT303ZkGswU/da1s6XvrLgthQPCw==}
peerDependencies:
svelte: ^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0
typescript: ^4.9.4 || ^5.0.0
@@ -3128,6 +3135,10 @@ packages:
resolution: {integrity: sha512-aCARru2WTdzJl55Ws8SK27+kvQwd8tijl4kY7NoDUXUHtTHhxMa8Lf6QNZKmU7cuPu3jjFloDO1j5HgYJNIIWg==}
engines: {node: '>=18'}
+ svelte@5.20.2:
+ resolution: {integrity: sha512-aYXJreNUiyTob0QOzRZeBXZMGeFZDch6SrSRV8QTncZb6zj0O3BEdUzPpojuHQ1pTvk+KX7I6rZCXPUf8pTPxA==}
+ engines: {node: '>=18'}
+
symbol-tree@3.2.4:
resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
@@ -4256,9 +4267,9 @@ snapshots:
worktop: 0.8.0-next.18
wrangler: 3.96.0(@cloudflare/workers-types@4.20241218.0)
- '@sveltejs/kit@2.17.2(@sveltejs/vite-plugin-svelte@4.0.0(svelte@5.20.1)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0)))(svelte@5.20.1)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0))':
+ '@sveltejs/kit@2.17.2(@sveltejs/vite-plugin-svelte@4.0.0(svelte@5.20.1)(vite@5.4.11(@types/node@22.10.2)(lightningcss@1.28.2)(terser@5.37.0)))(svelte@5.20.1)(vite@5.4.11(@types/node@22.10.2)(lightningcss@1.28.2)(terser@5.37.0))':
dependencies:
- '@sveltejs/vite-plugin-svelte': 4.0.0(svelte@5.20.1)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0))
+ '@sveltejs/vite-plugin-svelte': 4.0.0(svelte@5.20.1)(vite@5.4.11(@types/node@22.10.2)(lightningcss@1.28.2)(terser@5.37.0))
'@types/cookie': 0.6.0
cookie: 0.6.0
devalue: 5.1.1
@@ -4271,11 +4282,11 @@ snapshots:
set-cookie-parser: 2.7.1
sirv: 3.0.0
svelte: 5.20.1
- vite: 5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0)
+ vite: 5.4.11(@types/node@22.10.2)(lightningcss@1.28.2)(terser@5.37.0)
- '@sveltejs/kit@2.17.2(@sveltejs/vite-plugin-svelte@4.0.0(svelte@5.20.1)(vite@5.4.11(@types/node@22.10.2)(lightningcss@1.28.2)(terser@5.37.0)))(svelte@5.20.1)(vite@5.4.11(@types/node@22.10.2)(lightningcss@1.28.2)(terser@5.37.0))':
+ '@sveltejs/kit@2.17.2(@sveltejs/vite-plugin-svelte@4.0.0(svelte@5.20.2)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0)))(svelte@5.20.2)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0))':
dependencies:
- '@sveltejs/vite-plugin-svelte': 4.0.0(svelte@5.20.1)(vite@5.4.11(@types/node@22.10.2)(lightningcss@1.28.2)(terser@5.37.0))
+ '@sveltejs/vite-plugin-svelte': 4.0.0(svelte@5.20.2)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0))
'@types/cookie': 0.6.0
cookie: 0.6.0
devalue: 5.1.1
@@ -4287,29 +4298,20 @@ snapshots:
sade: 1.8.1
set-cookie-parser: 2.7.1
sirv: 3.0.0
- svelte: 5.20.1
- vite: 5.4.11(@types/node@22.10.2)(lightningcss@1.28.2)(terser@5.37.0)
+ svelte: 5.20.2
+ vite: 5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0)
- '@sveltejs/package@2.3.7(svelte@5.20.1)(typescript@5.7.2)':
+ '@sveltejs/package@2.3.10(svelte@5.20.2)(typescript@5.7.2)':
dependencies:
- chokidar: 4.0.2
+ chokidar: 4.0.3
kleur: 4.1.5
sade: 1.8.1
semver: 7.6.3
- svelte: 5.20.1
- svelte2tsx: 0.7.31(svelte@5.20.1)(typescript@5.7.2)
+ svelte: 5.20.2
+ svelte2tsx: 0.7.34(svelte@5.20.2)(typescript@5.7.2)
transitivePeerDependencies:
- typescript
- '@sveltejs/vite-plugin-svelte-inspector@3.0.1(@sveltejs/vite-plugin-svelte@4.0.0(svelte@5.20.1)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0)))(svelte@5.20.1)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0))':
- dependencies:
- '@sveltejs/vite-plugin-svelte': 4.0.0(svelte@5.20.1)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0))
- debug: 4.4.0
- svelte: 5.20.1
- vite: 5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0)
- transitivePeerDependencies:
- - supports-color
-
'@sveltejs/vite-plugin-svelte-inspector@3.0.1(@sveltejs/vite-plugin-svelte@4.0.0(svelte@5.20.1)(vite@5.4.11(@types/node@22.10.2)(lightningcss@1.28.2)(terser@5.37.0)))(svelte@5.20.1)(vite@5.4.11(@types/node@22.10.2)(lightningcss@1.28.2)(terser@5.37.0))':
dependencies:
'@sveltejs/vite-plugin-svelte': 4.0.0(svelte@5.20.1)(vite@5.4.11(@types/node@22.10.2)(lightningcss@1.28.2)(terser@5.37.0))
@@ -4319,16 +4321,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@sveltejs/vite-plugin-svelte@4.0.0(svelte@5.20.1)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0))':
+ '@sveltejs/vite-plugin-svelte-inspector@3.0.1(@sveltejs/vite-plugin-svelte@4.0.0(svelte@5.20.2)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0)))(svelte@5.20.2)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0))':
dependencies:
- '@sveltejs/vite-plugin-svelte-inspector': 3.0.1(@sveltejs/vite-plugin-svelte@4.0.0(svelte@5.20.1)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0)))(svelte@5.20.1)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0))
+ '@sveltejs/vite-plugin-svelte': 4.0.0(svelte@5.20.2)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0))
debug: 4.4.0
- deepmerge: 4.3.1
- kleur: 4.1.5
- magic-string: 0.30.17
- svelte: 5.20.1
+ svelte: 5.20.2
vite: 5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0)
- vitefu: 1.0.4(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0))
transitivePeerDependencies:
- supports-color
@@ -4345,6 +4343,19 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ '@sveltejs/vite-plugin-svelte@4.0.0(svelte@5.20.2)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0))':
+ dependencies:
+ '@sveltejs/vite-plugin-svelte-inspector': 3.0.1(@sveltejs/vite-plugin-svelte@4.0.0(svelte@5.20.2)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0)))(svelte@5.20.2)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0))
+ debug: 4.4.0
+ deepmerge: 4.3.1
+ kleur: 4.1.5
+ magic-string: 0.30.17
+ svelte: 5.20.2
+ vite: 5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0)
+ vitefu: 1.0.4(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0))
+ transitivePeerDependencies:
+ - supports-color
+
'@svitejs/changesets-changelog-github-compact@1.2.0':
dependencies:
'@changesets/get-github-info': 0.6.0
@@ -4438,10 +4449,10 @@ snapshots:
lodash: 4.17.21
redent: 3.0.0
- '@testing-library/svelte@5.2.6(svelte@5.20.1)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0))(vitest@1.6.0(@types/node@20.17.10)(jsdom@24.1.3)(lightningcss@1.28.2)(terser@5.37.0))':
+ '@testing-library/svelte@5.2.6(svelte@5.20.2)(vite@5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0))(vitest@1.6.0(@types/node@20.17.10)(jsdom@24.1.3)(lightningcss@1.28.2)(terser@5.37.0))':
dependencies:
'@testing-library/dom': 10.4.0
- svelte: 5.20.1
+ svelte: 5.20.2
optionalDependencies:
vite: 5.4.11(@types/node@20.17.10)(lightningcss@1.28.2)(terser@5.37.0)
vitest: 1.6.0(@types/node@20.17.10)(jsdom@24.1.3)(lightningcss@1.28.2)(terser@5.37.0)
@@ -4753,6 +4764,10 @@ snapshots:
dependencies:
readdirp: 4.0.2
+ chokidar@4.0.3:
+ dependencies:
+ readdirp: 4.0.2
+
ci-info@3.9.0: {}
clsx@2.1.1: {}
@@ -6612,10 +6627,10 @@ snapshots:
esm-env: 1.2.2
svelte: 5.20.1
- runed@0.23.4(svelte@5.20.1):
+ runed@0.23.4(svelte@5.20.2):
dependencies:
esm-env: 1.2.2
- svelte: 5.20.1
+ svelte: 5.20.2
sade@1.8.1:
dependencies:
@@ -6775,6 +6790,18 @@ snapshots:
transitivePeerDependencies:
- picomatch
+ svelte-check@4.1.4(svelte@5.20.2)(typescript@5.7.2):
+ dependencies:
+ '@jridgewell/trace-mapping': 0.3.25
+ chokidar: 4.0.2
+ fdir: 6.4.2
+ picocolors: 1.1.1
+ sade: 1.8.1
+ svelte: 5.20.2
+ typescript: 5.7.2
+ transitivePeerDependencies:
+ - picomatch
+
svelte-eslint-parser@0.43.0(svelte@5.14.4):
dependencies:
eslint-scope: 7.2.2
@@ -6791,18 +6818,18 @@ snapshots:
style-to-object: 1.0.8
svelte: 5.20.1
- svelte-toolbelt@0.7.1(svelte@5.20.1):
+ svelte-toolbelt@0.7.1(svelte@5.20.2):
dependencies:
clsx: 2.1.1
- runed: 0.23.4(svelte@5.20.1)
+ runed: 0.23.4(svelte@5.20.2)
style-to-object: 1.0.8
- svelte: 5.20.1
+ svelte: 5.20.2
- svelte2tsx@0.7.31(svelte@5.20.1)(typescript@5.7.2):
+ svelte2tsx@0.7.34(svelte@5.20.2)(typescript@5.7.2):
dependencies:
dedent-js: 1.0.1
pascal-case: 3.1.2
- svelte: 5.20.1
+ svelte: 5.20.2
typescript: 5.7.2
svelte@5.14.4:
@@ -6838,6 +6865,23 @@ snapshots:
magic-string: 0.30.17
zimmerframe: 1.1.2
+ svelte@5.20.2:
+ dependencies:
+ '@ampproject/remapping': 2.3.0
+ '@jridgewell/sourcemap-codec': 1.5.0
+ '@types/estree': 1.0.6
+ acorn: 8.14.0
+ acorn-typescript: 1.4.13(acorn@8.14.0)
+ aria-query: 5.3.2
+ axobject-query: 4.1.0
+ clsx: 2.1.1
+ esm-env: 1.2.2
+ esrap: 1.4.4
+ is-reference: 3.0.3
+ locate-character: 3.0.0
+ magic-string: 0.30.17
+ zimmerframe: 1.1.2
+
symbol-tree@3.2.4: {}
tailwind-merge@2.5.5: {}