layerpro 3.0.1 → 3.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
@@ -136,12 +136,13 @@ The `body` property accepts different content types:
136
136
 
137
137
  ```typescript
138
138
  {
139
- id: string, // Unique ID
139
+ id: string, // Unique ID (auto-generated as popup_1, popup_2, ... if omitted)
140
140
  body: any, // Content (text, HTML, or React)
141
141
  name: string, // Modal title
142
- icon: string, // Icon (HTML entity)
142
+ icon: string, // Icon glyph — HTML entity (e.g. "⚠") or an HTML
143
+ // string (e.g. '<i class="fa fa-star"></i>')
143
144
 
144
- // Dimensions
145
+ // Dimensions (defaults: width 340, height 220; minWidth 340, minHeight 220)
145
146
  width: number,
146
147
  height: number,
147
148
  minWidth: number,
@@ -149,25 +150,32 @@ The `body` property accepts different content types:
149
150
  maxWidth: number,
150
151
  maxHeight: number,
151
152
 
152
- // Position
153
+ // Remote content (same-origin only for security)
154
+ source: string, // URL to fetch HTML content from (same-origin enforced)
155
+
156
+ // Position (numbers are px; strings applied as-is, e.g. "10%")
153
157
  top: number | string,
154
158
  left: number | string,
155
159
  right: number | string,
156
160
  bottom: number | string,
161
+ center: boolean, // Center the popup in the viewport (adds a small
162
+ // cascade offset per open window so stacks don't overlap)
157
163
 
158
164
  // Animation
159
- fadeIn: number,
160
- fadeOut: number,
161
- timer: number,
165
+ fadeIn: number, // open fade duration (ms, default 100)
166
+ fadeOut: number, // close fade duration (ms, default 100)
167
+ timer: number, // auto-close after N ms
162
168
 
163
169
  // Features
164
- movable: boolean,
165
- resizable: boolean,
166
- maximize: boolean,
167
- iconize: boolean,
168
- dockable: boolean,
169
- close: boolean,
170
- raised: boolean,
170
+ movable: boolean, // draggable by the title bar
171
+ resizable: boolean, // resize handles
172
+ maximize: boolean, // double-click title bar to maximize
173
+ iconize: boolean, // allow minimize to dock
174
+ dockable: boolean, // show an icon in the dock bar
175
+ close: boolean, // show the close button
176
+ raised: boolean, // alias: modal — show a full-screen overlay that blocks
177
+ // pointer events to the page underneath
178
+ modal: boolean, // alias of raised
171
179
 
172
180
  // Buttons
173
181
  buttons: {
@@ -177,6 +185,86 @@ The `body` property accepts different content types:
177
185
  }
178
186
  ```
179
187
 
188
+ > **`raised` / `modal`** injects a full-viewport overlay (`popup_raised_<id>`) that
189
+ > intercepts every pointer event — the page underneath becomes unclickable until the
190
+ > popup closes. This is modal behavior; both names are accepted.
191
+
192
+ > **Duplicate id** — opening a popup whose `id` already exists brings that window to
193
+ > the front and refreshes its `body`/`buttons` instead of doing nothing.
194
+
195
+ ---
196
+
197
+ ## Global Overrides
198
+
199
+ Importing LayerPro replaces the native `alert`, `confirm`, and `prompt` globals with
200
+ callback-based versions, and adds a `message` global:
201
+
202
+ ```javascript
203
+ import "layerpro";
204
+
205
+ alert("Hello World!"); // LayerPro alert
206
+ confirm("Sure?", yes => {...}); // LayerPro confirm (callback, not a boolean return!)
207
+ prompt("Name?", name => {...}); // LayerPro prompt (callback, not a string return!)
208
+ message("Done!"); // LayerPro message
209
+ ```
210
+
211
+ > **⚠️ Important:** the overridden `confirm()` no longer returns a `boolean` and
212
+ > `prompt()` no longer returns a `string`. They are callback-based and return
213
+ > `undefined`. Any third-party code that does `if (confirm("..."))` will silently
214
+ > fall into the falsy branch. If your codebase depends on the native synchronous
215
+ > return values, call **`layerpro.noGlobals()`** right after importing LayerPro to
216
+ > restore the originals:
217
+ >
218
+ > ```javascript
219
+ > import "layerpro";
220
+ > layerpro.noGlobals(); // restores native alert/confirm/prompt, drops `message`
221
+ > ```
222
+
223
+ ---
224
+
225
+ ## Methods
226
+
227
+ | Method | Description |
228
+ |--------|-------------|
229
+ | `layerpro.popup.open(props)` | Open a modal; returns the props. Re-opens a same-id window to front + refreshes body |
230
+ | `layerpro.popup.close(id)` | Close (and unmount) a modal |
231
+ | `layerpro.popup.center(id, offset?)` | Center a modal in the viewport; optional pixel offset |
232
+ | `layerpro.popup.maximize(props)` | Toggle maximize (pure CSS) |
233
+ | `layerpro.popup.iconize(id)` | Toggle minimize to the dock |
234
+ | `layerpro.popup.index(id)` | Bring a modal to the front (select) |
235
+ | `layerpro.popup.zIndex()` | Get the next z-index counter value |
236
+ | `layerpro.popup.movable(props)` | Enable dragging |
237
+ | `layerpro.popup.resizable(props)` | Enable resizing |
238
+ | `layerpro.noGlobals()` | Restore native `alert`/`confirm`/`prompt`; remove `message` |
239
+
240
+ ---
241
+
242
+ ## Styling & z-index
243
+
244
+ Popups live in a `#popup` container whose base z-index comes from the
245
+ `--popup-z-index` CSS variable (default `1000`). Apps with their own stacking
246
+ contexts can override it to shift the whole stack:
247
+
248
+ ```scss
249
+ :root { --popup-z-index: 100000; }
250
+ ```
251
+
252
+ The title bar, window surface, internal area, and body all read from CSS custom
253
+ properties, so theming needs no `!important` or `[class^=popup_…]` selectors:
254
+
255
+ | Variable | Applies to |
256
+ |----------|-----------|
257
+ | `--bar-background` | title bar |
258
+ | `--bar-selected-background` | active/selected title bar |
259
+ | `--bar-color` | title bar text |
260
+ | `--window-background` | popup surface |
261
+ | `--window-shadow` | popup shadow |
262
+ | `--window-border-radius` | popup border radius |
263
+ | `--internal-background` | body wrapper |
264
+ | `--body-color` | body text color |
265
+ | `--raised-background` | modal overlay |
266
+ | `--popup-z-index` | base z-index for the stack |
267
+
180
268
  ---
181
269
 
182
270
  ## Methods
@@ -199,6 +287,20 @@ Chrome 80+ • Firefox 75+ • Safari 13+ • Edge 80+
199
287
 
200
288
  ---
201
289
 
290
+ ## Security
291
+
292
+ LayerPro includes several security measures:
293
+
294
+ - **Same-origin fetch guard**: The `source` prop only accepts same-origin URLs. Cross-origin requests are rejected before any network call is made, preventing SSRF and data exfiltration.
295
+
296
+ - **HTML escaping**: All user-provided text content (button labels, body content, titles) is automatically escaped via `escapeHtml()` to prevent XSS. HTML entities like `<`, `>`, `&`, `"` are converted to their safe equivalents.
297
+
298
+ - **Content Security Policy friendly**: No inline scripts or `eval()` are used. React components are rendered via `createRoot()` with proper sanitization.
299
+
300
+ - **No global pollution option**: Call `layerpro.noGlobals()` after import to restore native `alert`, `confirm`, `prompt` and remove the `message` global if your codebase depends on synchronous return values.
301
+
302
+ ---
303
+
202
304
  ## Contributing
203
305
 
204
306
  LayerPro is **open source** and free for everyone. The current source is private,