layerpro 4.0.1 → 4.1.0

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/README.md CHANGED
@@ -35,6 +35,7 @@ LayerPro is **not only** a replacement for `alert`/`prompt`/`confirm`: the same
35
35
  - [OS-style Windows](#os-style-windows)
36
36
  - [React Components](#react-components)
37
37
  - [The `body` Parameter](#the-body-parameter)
38
+ - [Targeting a window](#targeting-a-window)
38
39
  - [Options](#options)
39
40
  - [Global Overrides](#global-overrides)
40
41
  - [Methods](#methods)
@@ -52,6 +53,7 @@ LayerPro is **not only** a replacement for `alert`/`prompt`/`confirm`: the same
52
53
  ## Features
53
54
 
54
55
  - **Zero runtime dependencies** - no jQuery, pure vanilla DOM helpers; `react`/`react-dom` are peer dependencies, only loaded when React bodies are used, powered by [`reattach`](https://npmjs.com/package/reattach)
56
+ - **Native `<dialog>` windows** - every popup is a real `<dialog>` element, so the platform owns the window semantics (open state, implicit dialog role) while LayerPro keeps the geometry, the drag and the stacking order
55
57
  - **OS-style window engine** - not just modals: every popup is a real window with a title bar, drag handle, resize handles, maximize/restore, minimize-to-dock, focus stacking, and a z-order you control
56
58
  - **Hosts any content** - plain text, HTML strings, or **full React components** (with Context bridging and DOM auto-healing), rendered inside the window body
57
59
  - **Multiple modal types** - alert, confirm, prompt, message - built on top of the same window engine, so they inherit the same styling, dock, and accessibility features
@@ -215,6 +217,33 @@ popup.open({
215
217
 
216
218
  > **Note**: in React, always use elements (`<Component />`), not function calls (`Component()`).
217
219
 
220
+ ### Targeting a window
221
+
222
+ A layer is drawn in the document of the page that loaded LayerPro. The
223
+ `target` option names the window a layer belongs to, so a window opened with
224
+ `native: true` can host its own layers instead of seeing them land on the
225
+ opener:
226
+
227
+ ```javascript
228
+ // Open a real browser window
229
+ await layerpro.popup.open({ id: 'desk', name: 'Desktop', native: true })
230
+
231
+ // Open a layer inside that window
232
+ await layerpro.popup.open({ id: 'detail', body: 'Inside the desk', target: 'desk' })
233
+
234
+ // The same thing, through the handle bound to that window
235
+ const desk = layerpro.window('desk')
236
+ await desk.popup.open({ id: 'detail2', body: 'Also inside' })
237
+
238
+ // The modals accept a target too
239
+ await layerpro.confirm('Save the changes?', { target: 'desk' })
240
+ ```
241
+
242
+ A target is the id of a native window, a `Window` object, or a
243
+ `{ win, doc }` scope. A target that cannot be reached (unknown id, closed
244
+ window, another origin) produces a warning and the layer is drawn in the
245
+ current document.
246
+
218
247
  ## Options
219
248
 
220
249
  ```typescript
@@ -266,12 +295,17 @@ popup.open({
266
295
  confirm?: { text: string; cb?: () => void },
267
296
  cancel?: { text: string; cb?: () => void }
268
297
  }
298
+
299
+ // The window the layer is drawn in: the id of a native window, a Window
300
+ // object, or a { win, doc } scope. Without it the layer is drawn in the
301
+ // document of the page that loaded LayerPro.
302
+ target?: string | number | Window | LayerScope
269
303
  }
270
304
  ```
271
305
 
272
306
  > **`modal`** injects a full-viewport overlay (`popup_modal_<id>`) that intercepts every pointer event - the page underneath becomes unclickable until the popup closes. Use `modal: true` for alert/confirm/prompt/message pop ups.
273
307
 
274
- > **Duplicate id** - opening a popup whose `id` already exists brings that window to the front and refreshes its `body`/`buttons` instead of doing nothing.
308
+ > **Duplicate id** - opening a popup whose `id` already exists brings that window to the front and refreshes its `body`/`buttons` instead of doing nothing. The refresh reuses the existing button row: the row is emptied and refilled, never stacked.
275
309
 
276
310
  ## Global Overrides (Opt-in in 4.0)
277
311
 
@@ -321,6 +355,7 @@ const val = await prompt("Name?"); // Promise<string>
321
355
  | `popup.movable(props)` | Enable dragging. |
322
356
  | `popup.resizable(props)` | Enable resizing. |
323
357
  | `layerpro.installGlobals()` | Override `window.alert/confirm/prompt/message` with LayerPro's Promise-based versions. |
358
+ | `layerpro.window(target)` | A handle bound to one window: `win`, `doc` and a `popup` API whose layers are drawn in that window. |
324
359
  | `layerpro.version()` | Returns the current LayerPro version string (read from `app.json`). |
325
360
  | `layerpro.config(opts)` | Runtime config. Currently supports `{ nonce: string }` for CSP; sets `window.__layerproNonce` consumed by the injected `<style>`. Call before importing LayerPro for the nonce to be present at injection. |
326
361
 
@@ -401,7 +436,7 @@ Every element LayerPro creates carries a **stable class alias** next to its id-s
401
436
 
402
437
  | Element | Stable class | Id-suffixed class |
403
438
  |---------|--------------|-------------------|
404
- | Window surface | `.popup_window` | `.popup_window_<id>` |
439
+ | Window surface (`<dialog>`) | `.popup_window` | `.popup_window_<id>` |
405
440
  | Title bar | `.popup_bar` | `.popup_bar_<id>` |
406
441
  | Drag handle (title) | `.popup_drag` | `.popup_drag_<id>` |
407
442
  | Icon slot | `.popup_icon` | `.popup_icon_<id>` |
@@ -413,6 +448,15 @@ Every element LayerPro creates carries a **stable class alias** next to its id-s
413
448
  | Confirm/cancel row | `.buttons` | - |
414
449
  | Selected/focused window | `.zHigh`, `.popup_bar_selected` | - |
415
450
 
451
+ The confirm/cancel row built from the `buttons` option lives in the **internal
452
+ area** (`.popup_internal`), next to the body, and not inside the body itself:
453
+ a body renderer (React) owns the body container and empties it when it
454
+ commits, so a row kept inside the body would be wiped by the first render.
455
+ The built-in `alert`/`confirm`/`prompt`/`message` modals carry their own row
456
+ inside their body markup, as part of the modal content. Target the row with
457
+ `.buttons` (or `.lp_confirm` / `.lp_cancel` for the single buttons), never
458
+ with `.popup_body .buttons`.
459
+
416
460
  ```css
417
461
  /* square windows, no rounded corners */
418
462
  #popup .popup_window {