From fba55c03bf05105ca3a9aa510ca4db9f47d0551e Mon Sep 17 00:00:00 2001 From: Ryan E <91684138+VikingDadMedic@users.noreply.github.com> Date: Thu, 19 Mar 2026 14:06:14 -0700 Subject: [PATCH 1/2] Fix bugs, add corner/touch resize, lifecycle callbacks, docs, and tests Bug fixes: - Fix iframeWindowClickedSubscribe unsubscribe targeting wrong map (was deleting from activeWindowSubscribers instead of iframeWindowClickedListeners, causing memory leaks) - Replace hardcoded sentinel string with exported INACTIVE_MOUSE_ID constant across utils.ts, Window.svelte, and WindowManager.svelte - Fix stale basicStyling prop and invalid style prop in playground Dead code cleanup: - Remove empty src/lib/helper.ts - Remove unused .cover CSS class from Window.svelte - Remove commented-out IE scroll code from utils.ts and WindowDragger - Remove unused WithoutChild/WithoutChildren/WithoutChildrenOrChild types - Delete static/style.css (all CSS commented out) and its app.html link Touch resize support: - Add ontouchstart + preventScroll to all four edge resize components (TopResize, BottomResize, LeftResize, RightResize) matching the existing pattern from WindowDragger Corner resize handles: - Add TopLeftResize, TopRightResize, BottomLeftResize, BottomRightResize components with both mouse and touch support - Each adjusts two axes simultaneously with minWidth/minHeight enforcement - Wire into Window.svelte alongside existing edge handles Lifecycle callbacks: - Add onDragStart, onDragEnd, onResizeStart, onResizeEnd to ActualWindowProps with WindowPosition and WindowDimensions payload types - Wire drag callbacks through WindowDragger - Wire resize callbacks through all edge and corner resize components - Detect interaction end via INACTIVE_MOUSE_ID broadcast in Window.svelte Public API expansion: - Export INACTIVE_MOUSE_ID, WindowPosition, WindowDimensions from index.ts Documentation: - Replace /docs stub with full docs page (quick start, API reference, props table, lifecycle callbacks, styling guide, exports) - Expand README with badges, install, usage, feature list, callback docs, exports, and links to docs/playground Testing infrastructure: - Add vitest, @testing-library/svelte, @testing-library/jest-dom, jsdom - Add vitest.config.ts with browser resolve conditions for Svelte 5 - Add test and test:watch scripts to package.json - Write MouseContext tests (subscription, dispatch, touch, sentinel) - Write WindowContext tests (registration, stacking, iframe unsub fix) - Write Window.svelte tests (drag regions, conditional resize handles) - Write WindowDragger tests (mousedown activation, coordinate updates) Made-with: Cursor --- README.md | 97 +- package-lock.json | 1251 ++++++++++++++++- package.json | 8 +- src/app.html | 1 - src/lib/BottomLeftResize.svelte | 105 ++ src/lib/BottomResize.svelte | 26 +- src/lib/BottomRightResize.svelte | 103 ++ src/lib/LeftResize.svelte | 22 +- src/lib/RightResize.svelte | 27 +- src/lib/TopLeftResize.svelte | 105 ++ src/lib/TopResize.svelte | 22 +- src/lib/TopRightResize.svelte | 105 ++ src/lib/Window.svelte | 109 +- src/lib/Window.svelte.test.ts | 86 ++ src/lib/WindowDragger.svelte | 14 +- src/lib/WindowDragger.svelte.test.ts | 54 + src/lib/WindowManager.svelte | 11 +- src/lib/helper.ts | 0 src/lib/index.ts | 16 +- .../WindowDraggerHarness.svelte | 36 + src/lib/utils.test.ts | 83 ++ src/lib/utils.ts | 38 +- src/routes/docs/+page.svelte | 230 ++- src/routes/playground/+page.svelte | 8 +- src/test/setup.ts | 1 + static/style.css | 38 - vitest.config.ts | 15 + 27 files changed, 2445 insertions(+), 166 deletions(-) create mode 100644 src/lib/BottomLeftResize.svelte create mode 100644 src/lib/BottomRightResize.svelte create mode 100644 src/lib/TopLeftResize.svelte create mode 100644 src/lib/TopRightResize.svelte create mode 100644 src/lib/Window.svelte.test.ts create mode 100644 src/lib/WindowDragger.svelte.test.ts delete mode 100644 src/lib/helper.ts create mode 100644 src/lib/test-harnesses/WindowDraggerHarness.svelte create mode 100644 src/lib/utils.test.ts create mode 100644 src/test/setup.ts delete mode 100644 static/style.css create mode 100644 vitest.config.ts diff --git a/README.md b/README.md index 3835132..cf06eb1 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,95 @@ -# Svelte Windows -A draggable and resizable window manager that works seamlessly in you projects. Works in scroll areas, overflow situations. Includes window stacking based on how recently it was active. \ No newline at end of file +# svelte-windows + +[](https://www.npmjs.com/package/svelte-windows) +[](./LICENSE.md) + +Draggable, resizable desktop-style windows for Svelte 5. Built for overflow layouts, touch interaction, and intelligent active-window stacking. + +## Preview + + + +## Install + +```bash +npm install svelte-windows +``` + +## Quick start + +```svelte + + +
Documentation
++ Build desktop-like interfaces in Svelte with drag, resize, stacking, mobile touch handling, and iframe-safe focus behavior. +
+Install the package, then place one or more windows inside a manager.
+{installCommand}
+ WindowManager sets up global move/up handlers and provides context.Window registers itself, manages z-order, and renders drag/resize handles.MouseContext multiplexes movement to one active drag/resize target.WindowContext tracks active window and stacking history.
+ Use snippet children to receive the manager context. Define draggable hit areas with windowDragRegions.
+
{quickStartExample}
+ + Dimensions and position props are bindable and use px strings. You can style both the shell and content layers. +
+| Prop | +Type | +Default | +Required | +Description | +
|---|---|---|---|---|
| {prop.name} | +{prop.type} | +{prop.default} | +{prop.required} | +{prop.description} | +
+ React to active state, drag events, and resize events. Useful for syncing layout state to your own stores. +
+Payload: {event.payload}
{event.description}
+{callbackExample}
+ + Dragging is opt-in. Define one or more absolute regions to control where users can grab the window. +
++ All four edges and four corners are supported. Touch and mouse are both wired through the same manager. +
+
+ Use outerStyle/outerClassName for shadows and chrome, and innerStyle/innerClassName for content.
+
+ Active windows are promoted to the front automatically. Iframe focus is detected and translated into window activation. +
+WindowManager, WindowMouseContext, WindowContextINACTIVE_MOUSE_IDWindowDragConfig, WindowPosition, WindowDimensions, ActualWindowProps