@simplysm/core-browser 13.0.69 → 13.0.71
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 +14 -224
- package/dist/extensions/element-ext.d.ts +36 -36
- package/dist/extensions/element-ext.d.ts.map +1 -1
- package/dist/extensions/element-ext.js +1 -1
- package/dist/extensions/element-ext.js.map +1 -1
- package/dist/extensions/html-element-ext.d.ts +22 -22
- package/dist/utils/download.d.ts +3 -3
- package/dist/utils/fetch.d.ts +1 -1
- package/dist/utils/file-dialog.d.ts +1 -1
- package/package.json +6 -5
- package/src/extensions/element-ext.ts +41 -41
- package/src/extensions/html-element-ext.ts +24 -24
- package/src/index.ts +1 -1
- package/src/utils/download.ts +3 -3
- package/src/utils/fetch.ts +4 -4
- package/src/utils/file-dialog.ts +1 -1
- package/tests/extensions/element-ext.spec.ts +737 -0
- package/tests/extensions/html-element-ext.spec.ts +190 -0
- package/tests/utils/download.spec.ts +66 -0
package/README.md
CHANGED
|
@@ -1,239 +1,29 @@
|
|
|
1
1
|
# @simplysm/core-browser
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
This package includes both APIs that can be called directly as instance methods by extending `Element` and `HTMLElement` prototypes, and utilities in the form of static functions.
|
|
3
|
+
Simplysm package - Core module (browser)
|
|
6
4
|
|
|
7
5
|
## Installation
|
|
8
6
|
|
|
9
|
-
```bash
|
|
10
|
-
npm install @simplysm/core-browser
|
|
11
|
-
# or
|
|
12
7
|
pnpm add @simplysm/core-browser
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## Main Modules
|
|
16
|
-
|
|
17
|
-
### Element Extension Methods
|
|
18
|
-
|
|
19
|
-
Instance methods automatically added to `Element.prototype` when importing `"@simplysm/core-browser"`. Works as a side-effect import.
|
|
20
|
-
|
|
21
|
-
| Method | Return Type | Description |
|
|
22
|
-
|--------|-----------|------|
|
|
23
|
-
| `findAll<T>(selector: string)` | `T[]` | Search all descendant elements by selector. Returns empty array for empty selector. |
|
|
24
|
-
| `findFirst<T>(selector: string)` | `T \| undefined` | Search first matching element by selector. Returns `undefined` for empty selector. |
|
|
25
|
-
| `prependChild<T>(child: T)` | `T` | Insert element as first child |
|
|
26
|
-
| `getParents()` | `Element[]` | Return list of all parent elements (closest first) |
|
|
27
|
-
| `findFocusableParent()` | `HTMLElement \| undefined` | Search for first focusable element among parents (uses tabbable) |
|
|
28
|
-
| `findFirstFocusableChild()` | `HTMLElement \| undefined` | Search for first focusable element among children (uses tabbable) |
|
|
29
|
-
| `isOffsetElement()` | `boolean` | Check if element has `position: relative`, `absolute`, `fixed`, or `sticky` |
|
|
30
|
-
| `isVisible()` | `boolean` | Check element visibility (clientRects exist, not `visibility: hidden`, not `opacity: 0`) |
|
|
31
|
-
|
|
32
|
-
### HTMLElement Extension Methods
|
|
33
|
-
|
|
34
|
-
Instance methods automatically added to `HTMLElement.prototype`.
|
|
35
|
-
|
|
36
|
-
| Method | Return Type | Description |
|
|
37
|
-
|--------|-----------|------|
|
|
38
|
-
| `repaint()` | `void` | Trigger forced repaint by causing forced synchronous layout |
|
|
39
|
-
| `getRelativeOffset(parent: HTMLElement \| string)` | `{ top: number; left: number }` | Calculate document-based position relative to a parent element or CSS selector, suitable for CSS `top`/`left` (includes `window.scrollX/Y`, parent scroll, border widths, and CSS transforms) |
|
|
40
|
-
| `scrollIntoViewIfNeeded(target: { top: number; left: number }, offset?: { top: number; left: number })` | `void` | Adjust scroll so that target position is visible past any fixed offset regions (top/left only) |
|
|
41
|
-
|
|
42
|
-
### Static Functions
|
|
43
|
-
|
|
44
|
-
| Function | Return Type | Description |
|
|
45
|
-
|------|-----------|------|
|
|
46
|
-
| `copyElement(event: ClipboardEvent)` | `void` | Copy value of first `input`/`textarea` within the event target element to clipboard |
|
|
47
|
-
| `pasteToElement(event: ClipboardEvent)` | `void` | Paste clipboard text into the first `input`/`textarea` within the event target element |
|
|
48
|
-
| `getBounds(els: Element[], timeout?: number)` | `Promise<ElementBounds[]>` | Query element bounds using `IntersectionObserver`. Results are returned in input order. Default timeout: 5000ms. |
|
|
49
|
-
|
|
50
|
-
### Download Utilities
|
|
51
|
-
|
|
52
|
-
| Function | Return Type | Description |
|
|
53
|
-
|------|-----------|------|
|
|
54
|
-
| `downloadBlob(blob: Blob, fileName: string)` | `void` | Download a Blob as a file |
|
|
55
|
-
| `fetchUrlBytes(url: string, options?: { onProgress?: (progress: DownloadProgress) => void })` | `Promise<Uint8Array>` | Download binary data from a URL with optional progress callback |
|
|
56
|
-
|
|
57
|
-
### File Dialog
|
|
58
|
-
|
|
59
|
-
| Function | Return Type | Description |
|
|
60
|
-
|------|-----------|------|
|
|
61
|
-
| `openFileDialog(options?: { accept?: string; multiple?: boolean })` | `Promise<File[] \| undefined>` | Open a file selection dialog. Returns `undefined` if the user cancels without selecting. |
|
|
62
|
-
|
|
63
|
-
### Types
|
|
64
|
-
|
|
65
|
-
| Type | Description |
|
|
66
|
-
|------|------|
|
|
67
|
-
| `ElementBounds` | Element bounds information: `target: Element`, `top: number`, `left: number`, `width: number`, `height: number` |
|
|
68
|
-
| `DownloadProgress` | Download progress: `receivedLength: number`, `contentLength: number` |
|
|
69
|
-
|
|
70
|
-
## Usage Examples
|
|
71
|
-
|
|
72
|
-
### Element Extension Methods
|
|
73
|
-
|
|
74
|
-
```typescript
|
|
75
|
-
import "@simplysm/core-browser";
|
|
76
|
-
|
|
77
|
-
// Search descendant elements
|
|
78
|
-
const buttons = container.findAll<HTMLButtonElement>("button.primary");
|
|
79
|
-
const firstInput = container.findFirst<HTMLInputElement>("input[type='text']");
|
|
80
|
-
|
|
81
|
-
// Insert element as first child
|
|
82
|
-
const newEl = document.createElement("div");
|
|
83
|
-
container.prependChild(newEl);
|
|
84
|
-
|
|
85
|
-
// Query all parent elements (closest parent first)
|
|
86
|
-
const parents = element.getParents();
|
|
87
|
-
|
|
88
|
-
// Search focusable elements (based on tabbable library)
|
|
89
|
-
const focusableParent = element.findFocusableParent();
|
|
90
|
-
const focusableChild = element.findFirstFocusableChild();
|
|
91
|
-
|
|
92
|
-
// Check element state
|
|
93
|
-
if (element.isOffsetElement()) {
|
|
94
|
-
// position is one of relative, absolute, fixed, sticky
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (element.isVisible()) {
|
|
98
|
-
// Element is visible on screen (clientRects exist, visibility !== "hidden", opacity !== "0")
|
|
99
|
-
}
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
### HTMLElement Extension Methods
|
|
103
|
-
|
|
104
|
-
```typescript
|
|
105
|
-
import "@simplysm/core-browser";
|
|
106
|
-
|
|
107
|
-
// Forced repaint (useful for restarting CSS animations)
|
|
108
|
-
element.repaint();
|
|
109
|
-
|
|
110
|
-
// Calculate document-based position relative to a parent element (can be used directly for CSS top/left)
|
|
111
|
-
const offset = element.getRelativeOffset(document.body);
|
|
112
|
-
popup.style.top = `${offset.top}px`;
|
|
113
|
-
popup.style.left = `${offset.left}px`;
|
|
114
|
-
|
|
115
|
-
// Parent can also be specified by CSS selector (uses closest())
|
|
116
|
-
const offset2 = element.getRelativeOffset(".scroll-container");
|
|
117
|
-
|
|
118
|
-
// Adjust scroll position in table with fixed header/columns
|
|
119
|
-
const scrollContainer = document.getElementById("table-body") as HTMLElement;
|
|
120
|
-
const targetRow = document.getElementById("row-42") as HTMLElement;
|
|
121
|
-
|
|
122
|
-
scrollContainer.scrollIntoViewIfNeeded(
|
|
123
|
-
{ top: targetRow.offsetTop, left: targetRow.offsetLeft },
|
|
124
|
-
{ top: 50, left: 120 }, // Fixed header height 50px, fixed column width 120px
|
|
125
|
-
);
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
### Clipboard Handling
|
|
129
|
-
|
|
130
|
-
```typescript
|
|
131
|
-
import { copyElement, pasteToElement } from "@simplysm/core-browser";
|
|
132
|
-
|
|
133
|
-
// Use in copy event handler
|
|
134
|
-
// Copies value of the first input/textarea within the target element to clipboard
|
|
135
|
-
element.addEventListener("copy", (e) => copyElement(e));
|
|
136
|
-
|
|
137
|
-
// Use in paste event handler
|
|
138
|
-
// Pastes clipboard content into the first input/textarea within the target element
|
|
139
|
-
element.addEventListener("paste", (e) => pasteToElement(e));
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
### Asynchronous Element Bounds Query
|
|
143
|
-
|
|
144
|
-
```typescript
|
|
145
|
-
import { getBounds } from "@simplysm/core-browser";
|
|
146
|
-
import type { ElementBounds } from "@simplysm/core-browser";
|
|
147
|
-
|
|
148
|
-
const el1 = document.getElementById("item1")!;
|
|
149
|
-
const el2 = document.getElementById("item2")!;
|
|
150
|
-
|
|
151
|
-
// Query bounds information asynchronously using IntersectionObserver
|
|
152
|
-
const bounds: ElementBounds[] = await getBounds([el1, el2]);
|
|
153
|
-
|
|
154
|
-
for (const b of bounds) {
|
|
155
|
-
console.log(b.target); // Target element being measured
|
|
156
|
-
console.log(b.top); // Top position relative to viewport
|
|
157
|
-
console.log(b.left); // Left position relative to viewport
|
|
158
|
-
console.log(b.width); // Element width
|
|
159
|
-
console.log(b.height); // Element height
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// Specify custom timeout (default: 5000ms)
|
|
163
|
-
// TimeoutError is thrown if timeout is exceeded
|
|
164
|
-
const bounds2 = await getBounds([el1], 3000);
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
### Blob Download
|
|
168
|
-
|
|
169
|
-
```typescript
|
|
170
|
-
import { downloadBlob } from "@simplysm/core-browser";
|
|
171
|
-
|
|
172
|
-
// Download Blob object as file
|
|
173
|
-
const blob = new Blob(["Hello, World!"], { type: "text/plain" });
|
|
174
|
-
downloadBlob(blob, "hello.txt");
|
|
175
|
-
|
|
176
|
-
// Download binary data such as Excel files
|
|
177
|
-
const excelBlob = new Blob([excelData], {
|
|
178
|
-
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
179
|
-
});
|
|
180
|
-
downloadBlob(excelBlob, "report.xlsx");
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### Binary Download (with Progress Support)
|
|
184
|
-
|
|
185
|
-
```typescript
|
|
186
|
-
import { fetchUrlBytes } from "@simplysm/core-browser";
|
|
187
|
-
import type { DownloadProgress } from "@simplysm/core-browser";
|
|
188
|
-
|
|
189
|
-
// Basic usage
|
|
190
|
-
const data: Uint8Array = await fetchUrlBytes("https://example.com/file.bin");
|
|
191
|
-
|
|
192
|
-
// Using progress callback
|
|
193
|
-
const data2 = await fetchUrlBytes("https://example.com/large-file.zip", {
|
|
194
|
-
onProgress: (progress: DownloadProgress) => {
|
|
195
|
-
const percent = progress.contentLength > 0
|
|
196
|
-
? Math.round((progress.receivedLength / progress.contentLength) * 100)
|
|
197
|
-
: 0;
|
|
198
|
-
console.log(`Download progress: ${percent}%`);
|
|
199
|
-
},
|
|
200
|
-
});
|
|
201
|
-
```
|
|
202
8
|
|
|
203
|
-
|
|
9
|
+
**Peer Dependencies:** none
|
|
204
10
|
|
|
205
|
-
|
|
206
|
-
import { openFileDialog } from "@simplysm/core-browser";
|
|
11
|
+
## Source Index
|
|
207
12
|
|
|
208
|
-
|
|
209
|
-
const files = await openFileDialog({
|
|
210
|
-
accept: "image/*", // Optional: specify accepted file types
|
|
211
|
-
});
|
|
212
|
-
if (files) {
|
|
213
|
-
console.log("Selected file:", files[0].name);
|
|
214
|
-
}
|
|
13
|
+
### Extensions
|
|
215
14
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
});
|
|
221
|
-
if (selectedFiles) {
|
|
222
|
-
selectedFiles.forEach((file) => {
|
|
223
|
-
console.log("File:", file.name, "Size:", file.size);
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
|
-
```
|
|
15
|
+
| Source | Exports | Description | Test |
|
|
16
|
+
|--------|---------|-------------|------|
|
|
17
|
+
| `src/extensions/element-ext.ts` | `ElementBounds`, `copyElement`, `pasteToElement`, `getBounds` | DOM clipboard operations and element bounds utilities | `element-ext.spec.ts` |
|
|
18
|
+
| `src/extensions/html-element-ext.ts` | _(HTMLElement prototype augmentation only)_ | Repaint, relative offset, and scroll-into-view helpers | `html-element-ext.spec.ts` |
|
|
227
19
|
|
|
228
|
-
|
|
20
|
+
### Utils
|
|
229
21
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
-
|
|
235
|
-
- The `fetchUrlBytes()` function improves memory efficiency by pre-allocating a buffer when the `Content-Length` header is available, and collects and merges chunks for chunked encoding. Throws an `Error` if the response status is not ok or if the response body is not readable.
|
|
236
|
-
- The `pasteToElement()` function replaces the entire value of the target input/textarea. It does not consider cursor position or selection range. It dispatches an `input` event after the value is set.
|
|
22
|
+
| Source | Exports | Description | Test |
|
|
23
|
+
|--------|---------|-------------|------|
|
|
24
|
+
| `src/utils/download.ts` | `downloadBlob` | Trigger browser file download from a Blob | `download.spec.ts` |
|
|
25
|
+
| `src/utils/fetch.ts` | `DownloadProgress`, `fetchUrlBytes` | Fetch URL as Uint8Array with progress callback | - |
|
|
26
|
+
| `src/utils/file-dialog.ts` | `openFileDialog` | Open native file selection dialog programmatically | - |
|
|
237
27
|
|
|
238
28
|
## License
|
|
239
29
|
|
|
@@ -1,98 +1,98 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Element bounds information type
|
|
3
3
|
*/
|
|
4
4
|
export interface ElementBounds {
|
|
5
|
-
/**
|
|
5
|
+
/** Element to be measured */
|
|
6
6
|
target: Element;
|
|
7
|
-
/**
|
|
7
|
+
/** Top position relative to viewport */
|
|
8
8
|
top: number;
|
|
9
|
-
/**
|
|
9
|
+
/** Left position relative to viewport */
|
|
10
10
|
left: number;
|
|
11
|
-
/**
|
|
11
|
+
/** Element width */
|
|
12
12
|
width: number;
|
|
13
|
-
/**
|
|
13
|
+
/** Element height */
|
|
14
14
|
height: number;
|
|
15
15
|
}
|
|
16
16
|
declare global {
|
|
17
17
|
interface Element {
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
19
|
+
* Find all child elements matching selector
|
|
20
20
|
*
|
|
21
|
-
* @param selector - CSS
|
|
22
|
-
* @returns
|
|
21
|
+
* @param selector - CSS selector
|
|
22
|
+
* @returns Array of matching elements (empty selector returns empty array)
|
|
23
23
|
*/
|
|
24
24
|
findAll<T extends Element = Element>(selector: string): T[];
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
26
|
+
* Find first element matching selector
|
|
27
27
|
*
|
|
28
|
-
* @param selector - CSS
|
|
29
|
-
* @returns
|
|
28
|
+
* @param selector - CSS selector
|
|
29
|
+
* @returns First matching element or undefined (empty selector returns undefined)
|
|
30
30
|
*/
|
|
31
31
|
findFirst<T extends Element = Element>(selector: string): T | undefined;
|
|
32
32
|
/**
|
|
33
|
-
*
|
|
33
|
+
* Insert element as first child
|
|
34
34
|
*
|
|
35
|
-
* @param child -
|
|
36
|
-
* @returns
|
|
35
|
+
* @param child - Child element to insert
|
|
36
|
+
* @returns Inserted child element
|
|
37
37
|
*/
|
|
38
38
|
prependChild<T extends Element>(child: T): T;
|
|
39
39
|
/**
|
|
40
|
-
*
|
|
40
|
+
* Get all parent elements (in order of proximity)
|
|
41
41
|
*
|
|
42
|
-
* @returns
|
|
42
|
+
* @returns Array of parent elements (from closest to farthest)
|
|
43
43
|
*/
|
|
44
44
|
getParents(): Element[];
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
46
|
+
* Find first focusable parent element (using tabbable)
|
|
47
47
|
*
|
|
48
|
-
* @returns
|
|
48
|
+
* @returns First focusable parent element or undefined
|
|
49
49
|
*/
|
|
50
50
|
findFocusableParent(): HTMLElement | undefined;
|
|
51
51
|
/**
|
|
52
|
-
*
|
|
52
|
+
* Find first focusable child element (using tabbable)
|
|
53
53
|
*
|
|
54
|
-
* @returns
|
|
54
|
+
* @returns First focusable child element or undefined
|
|
55
55
|
*/
|
|
56
56
|
findFirstFocusableChild(): HTMLElement | undefined;
|
|
57
57
|
/**
|
|
58
|
-
*
|
|
58
|
+
* Check if element is an offset parent (position: relative/absolute/fixed/sticky)
|
|
59
59
|
*
|
|
60
|
-
* @returns position
|
|
60
|
+
* @returns true if position property is one of relative, absolute, fixed, or sticky
|
|
61
61
|
*/
|
|
62
62
|
isOffsetElement(): boolean;
|
|
63
63
|
/**
|
|
64
|
-
*
|
|
64
|
+
* Check if element is visible on screen
|
|
65
65
|
*
|
|
66
66
|
* @remarks
|
|
67
|
-
*
|
|
67
|
+
* Checks existence of clientRects, visibility: hidden, and opacity: 0.
|
|
68
68
|
*
|
|
69
|
-
* @returns
|
|
69
|
+
* @returns true if element is visible on screen
|
|
70
70
|
*/
|
|
71
71
|
isVisible(): boolean;
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
/**
|
|
75
|
-
*
|
|
75
|
+
* Copy element content to clipboard (use with copy event handler)
|
|
76
76
|
*
|
|
77
|
-
* @param event - copy
|
|
77
|
+
* @param event - copy event object
|
|
78
78
|
*/
|
|
79
79
|
export declare function copyElement(event: ClipboardEvent): void;
|
|
80
80
|
/**
|
|
81
|
-
*
|
|
81
|
+
* Paste clipboard content to element (use with paste event handler)
|
|
82
82
|
*
|
|
83
83
|
* @remarks
|
|
84
|
-
*
|
|
85
|
-
*
|
|
84
|
+
* Finds the first input/textarea within the target element and replaces its entire value with clipboard content.
|
|
85
|
+
* Does not consider cursor position or selection.
|
|
86
86
|
*
|
|
87
|
-
* @param event - paste
|
|
87
|
+
* @param event - paste event object
|
|
88
88
|
*/
|
|
89
89
|
export declare function pasteToElement(event: ClipboardEvent): void;
|
|
90
90
|
/**
|
|
91
|
-
*
|
|
91
|
+
* Get bounds information for elements using IntersectionObserver
|
|
92
92
|
*
|
|
93
|
-
* @param els -
|
|
94
|
-
* @param timeout -
|
|
95
|
-
* @throws {TimeoutError}
|
|
93
|
+
* @param els - Array of target elements
|
|
94
|
+
* @param timeout - Timeout in milliseconds (default: 5000)
|
|
95
|
+
* @throws {TimeoutError} If no response within timeout duration
|
|
96
96
|
*/
|
|
97
97
|
export declare function getBounds(els: Element[], timeout?: number): Promise<ElementBounds[]>;
|
|
98
98
|
//# sourceMappingURL=element-ext.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"element-ext.d.ts","sourceRoot":"","sources":["..\\..\\src\\extensions\\element-ext.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,
|
|
1
|
+
{"version":3,"file":"element-ext.d.ts","sourceRoot":"","sources":["..\\..\\src\\extensions\\element-ext.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,6BAA6B;IAC7B,MAAM,EAAE,OAAO,CAAC;IAChB,wCAAwC;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,qBAAqB;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,OAAO;QACf;;;;;WAKG;QACH,OAAO,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC;QAE5D;;;;;WAKG;QACH,SAAS,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAAC;QAExE;;;;;WAKG;QACH,YAAY,CAAC,CAAC,SAAS,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC;QAE7C;;;;WAIG;QACH,UAAU,IAAI,OAAO,EAAE,CAAC;QAExB;;;;WAIG;QACH,mBAAmB,IAAI,WAAW,GAAG,SAAS,CAAC;QAE/C;;;;WAIG;QACH,uBAAuB,IAAI,WAAW,GAAG,SAAS,CAAC;QAEnD;;;;WAIG;QACH,eAAe,IAAI,OAAO,CAAC;QAE3B;;;;;;;WAOG;QACH,SAAS,IAAI,OAAO,CAAC;KACtB;CACF;AAkED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAYvD;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAa1D;AAED;;;;;;GAMG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,OAAO,GAAE,MAAa,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAoDhG"}
|
|
@@ -111,7 +111,7 @@ async function getBounds(els, timeout = 5e3) {
|
|
|
111
111
|
}
|
|
112
112
|
}),
|
|
113
113
|
new Promise(
|
|
114
|
-
(_, reject) => setTimeout(() => reject(new TimeoutError(void 0, `${timeout}ms
|
|
114
|
+
(_, reject) => setTimeout(() => reject(new TimeoutError(void 0, `${timeout}ms timeout`)), timeout)
|
|
115
115
|
)
|
|
116
116
|
]);
|
|
117
117
|
} finally {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/extensions/element-ext.ts"],
|
|
4
|
-
"mappings": "AAAA,SAAS,mBAAmB;AAC5B,SAAS,oBAAoB;AAoF7B,QAAQ,UAAU,UAAU,SAAuC,UAAuB;AACxF,QAAM,UAAU,SAAS,KAAK;AAC9B,MAAI,YAAY,GAAI,QAAO,CAAC;AAC5B,SAAO,MAAM,KAAK,KAAK,iBAAoB,OAAO,CAAC;AACrD;AAEA,QAAQ,UAAU,YAAY,SAC5B,UACe;AACf,QAAM,UAAU,SAAS,KAAK;AAC9B,MAAI,YAAY,GAAI,QAAO;AAC3B,SAAO,KAAK,cAAiB,OAAO,KAAK;AAC3C;AAEA,QAAQ,UAAU,eAAe,SAA6B,OAAa;AACzE,SAAO,KAAK,aAAa,OAAO,KAAK,iBAAiB;AACxD;AAEA,QAAQ,UAAU,aAAa,WAAuB;AACpD,QAAM,SAAoB,CAAC;AAC3B,MAAI,SAAS,KAAK;AAClB,SAAO,WAAW,QAAQ,kBAAkB,SAAS;AACnD,WAAO,KAAK,MAAM;AAClB,aAAS,OAAO;AAAA,EAClB;AACA,SAAO;AACT;AAEA,QAAQ,UAAU,sBAAsB,WAAqC;AAC3E,MAAI,WAAW,KAAK;AACpB,SAAO,aAAa,MAAM;AACxB,QAAI,YAAY,QAAQ,GAAG;AACzB,aAAO;AAAA,IACT;AACA,eAAW,SAAS;AAAA,EACtB;AACA,SAAO;AACT;AAEA,QAAQ,UAAU,0BAA0B,WAAqC;AAC/E,QAAM,SAAS,SAAS,iBAAiB,MAAM,WAAW,YAAY;AACtE,MAAI,OAAO,OAAO,SAAS;AAC3B,SAAO,SAAS,MAAM;AACpB,QAAI,gBAAgB,eAAe,YAAY,IAAI,GAAG;AACpD,aAAO;AAAA,IACT;AACA,WAAO,OAAO,SAAS;AAAA,EACzB;AACA,SAAO;AACT;AAEA,QAAQ,UAAU,kBAAkB,WAAqB;AACvD,SAAO,CAAC,YAAY,YAAY,SAAS,QAAQ,EAAE,SAAS,iBAAiB,IAAI,EAAE,QAAQ;AAC7F;AAEA,QAAQ,UAAU,YAAY,WAAqB;AACjD,QAAM,QAAQ,iBAAiB,IAAI;AACnC,SAAO,KAAK,eAAe,EAAE,SAAS,KAAK,MAAM,eAAe,YAAY,MAAM,YAAY;AAChG;AAWO,SAAS,YAAY,OAA6B;AACvD,QAAM,gBAAgB,MAAM;AAC5B,QAAM,SAAS,MAAM;AACrB,MAAI,iBAAiB,QAAQ,EAAE,kBAAkB,SAAU;AAE3D,QAAM,eAAe,OAAO;AAAA,IAC1B;AAAA,EACF;AACA,MAAI,gBAAgB,MAAM;AACxB,kBAAc,QAAQ,cAAc,aAAa,KAAK;AACtD,UAAM,eAAe;AAAA,EACvB;AACF;AAWO,SAAS,eAAe,OAA6B;AAC1D,QAAM,gBAAgB,MAAM;AAC5B,QAAM,SAAS,MAAM;AACrB,MAAI,iBAAiB,QAAQ,EAAE,kBAAkB,SAAU;AAE3D,QAAM,cAAc,cAAc,QAAQ,YAAY;AAEtD,QAAM,eAAe,OAAO,UAAkD,iBAAiB;AAC/F,MAAI,iBAAiB,QAAW;AAC9B,iBAAa,QAAQ;AACrB,iBAAa,cAAc,IAAI,MAAM,SAAS,EAAE,SAAS,KAAK,CAAC,CAAC;AAChE,UAAM,eAAe;AAAA,EACvB;AACF;AASA,eAAsB,UAAU,KAAgB,UAAkB,KAAgC;AAEhG,QAAM,WAAW,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAU,CAAC;AAC7D,MAAI,SAAS,SAAS,GAAG;AACvB,WAAO,CAAC;AAAA,EACV;AAGA,QAAM,eAAe,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAU,CAAC;AAEjE,MAAI;AAEJ,MAAI;AACF,WAAO,MAAM,QAAQ,KAAK;AAAA,MACxB,IAAI,QAAyB,CAAC,YAAY;AACxC,cAAM,UAA2B,CAAC;AAElC,mBAAW,IAAI,qBAAqB,CAAC,YAAY;AAC/C,qBAAW,SAAS,SAAS;AAC3B,kBAAM,SAAS,MAAM;AACrB,gBAAI,SAAS,IAAI,MAAM,GAAG;AACxB,uBAAS,OAAO,MAAM;AACtB,sBAAQ,KAAK;AAAA,gBACX;AAAA,gBACA,KAAK,MAAM,mBAAmB;AAAA,gBAC9B,MAAM,MAAM,mBAAmB;AAAA,gBAC/B,OAAO,MAAM,mBAAmB;AAAA,gBAChC,QAAQ,MAAM,mBAAmB;AAAA,cACnC,CAAC;AAAA,YACH;AAAA,UACF;AAEA,cAAI,SAAS,SAAS,GAAG;AACvB,iDAAU;AAEV;AAAA,cACE,QAAQ,KAAK,CAAC,GAAG,MAAM,aAAa,IAAI,EAAE,MAAM,IAAK,aAAa,IAAI,EAAE,MAAM,CAAE;AAAA,YAClF;AAAA,UACF;AAAA,QACF,CAAC;AAED,mBAAW,MAAM,SAAS,KAAK,GAAG;AAChC,mBAAS,QAAQ,EAAE;AAAA,QACrB;AAAA,MACF,CAAC;AAAA,MACD,IAAI;AAAA,QAAyB,CAAC,GAAG,WAC/B,WAAW,MAAM,OAAO,IAAI,aAAa,QAAW,GAAG,OAAO,
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -1,45 +1,45 @@
|
|
|
1
1
|
declare global {
|
|
2
2
|
interface HTMLElement {
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Force repaint (triggers reflow)
|
|
5
5
|
*/
|
|
6
6
|
repaint(): void;
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Calculate relative position based on parent element (for CSS positioning)
|
|
9
9
|
*
|
|
10
10
|
* @remarks
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* Calculates element position relative to parent element, returning document-based coordinates
|
|
12
|
+
* including `window.scrollX/Y` that can be directly used in CSS `top`/`left` properties.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
* -
|
|
16
|
-
* -
|
|
14
|
+
* Common use cases:
|
|
15
|
+
* - Position dropdowns, popups after appending to `document.body`
|
|
16
|
+
* - Works correctly on scrolled pages
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
* -
|
|
20
|
-
* -
|
|
21
|
-
* -
|
|
22
|
-
* -
|
|
23
|
-
* - CSS transform
|
|
18
|
+
* Factors included in calculation:
|
|
19
|
+
* - Viewport-relative position (getBoundingClientRect)
|
|
20
|
+
* - Document scroll position (window.scrollX/Y)
|
|
21
|
+
* - Parent element internal scroll (parentEl.scrollTop/Left)
|
|
22
|
+
* - Border thickness of intermediate elements
|
|
23
|
+
* - CSS transform transformations
|
|
24
24
|
*
|
|
25
|
-
* @param parent -
|
|
26
|
-
* @returns CSS top/left
|
|
27
|
-
* @throws {ArgumentError}
|
|
25
|
+
* @param parent - Parent element or selector to use as reference (e.g., document.body, ".container")
|
|
26
|
+
* @returns Coordinates usable in CSS top/left properties
|
|
27
|
+
* @throws {ArgumentError} If parent element cannot be found
|
|
28
28
|
*/
|
|
29
29
|
getRelativeOffset(parent: HTMLElement | string): {
|
|
30
30
|
top: number;
|
|
31
31
|
left: number;
|
|
32
32
|
};
|
|
33
33
|
/**
|
|
34
|
-
*
|
|
34
|
+
* Scroll to make target visible if hidden by offset area (e.g., fixed header/column)
|
|
35
35
|
*
|
|
36
36
|
* @remarks
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
37
|
+
* Only handles cases where target extends beyond top/left boundaries of scroll area.
|
|
38
|
+
* For scrolling needed downward/rightward, relies on browser's default focus scroll behavior.
|
|
39
|
+
* Typically used with focus events on tables with fixed headers or columns.
|
|
40
40
|
*
|
|
41
|
-
* @param target -
|
|
42
|
-
* @param offset -
|
|
41
|
+
* @param target - Target position within container (offsetTop, offsetLeft)
|
|
42
|
+
* @param offset - Size of area that must not be obscured (e.g., fixed header height, fixed column width)
|
|
43
43
|
*/
|
|
44
44
|
scrollIntoViewIfNeeded(target: {
|
|
45
45
|
top: number;
|
package/dist/utils/download.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Blob
|
|
2
|
+
* Download Blob as file
|
|
3
3
|
*
|
|
4
|
-
* @param blob -
|
|
5
|
-
* @param fileName -
|
|
4
|
+
* @param blob - Blob object to download
|
|
5
|
+
* @param fileName - File name to save as
|
|
6
6
|
*/
|
|
7
7
|
export declare function downloadBlob(blob: Blob, fileName: string): void;
|
|
8
8
|
//# sourceMappingURL=download.d.ts.map
|
package/dist/utils/fetch.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export interface DownloadProgress {
|
|
|
3
3
|
contentLength: number;
|
|
4
4
|
}
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* Download binary data from URL (with progress callback support)
|
|
7
7
|
*/
|
|
8
8
|
export declare function fetchUrlBytes(url: string, options?: {
|
|
9
9
|
onProgress?: (progress: DownloadProgress) => void;
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/core-browser",
|
|
3
|
-
"version": "13.0.
|
|
4
|
-
"description": "
|
|
5
|
-
"author": "
|
|
3
|
+
"version": "13.0.71",
|
|
4
|
+
"description": "Simplysm package - Core module (browser)",
|
|
5
|
+
"author": "simplysm",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"types": "./dist/index.d.ts",
|
|
15
15
|
"files": [
|
|
16
16
|
"dist",
|
|
17
|
-
"src"
|
|
17
|
+
"src",
|
|
18
|
+
"tests"
|
|
18
19
|
],
|
|
19
20
|
"sideEffects": [
|
|
20
21
|
"./dist/extensions/element-ext.js",
|
|
@@ -22,7 +23,7 @@
|
|
|
22
23
|
],
|
|
23
24
|
"dependencies": {
|
|
24
25
|
"tabbable": "^6.4.0",
|
|
25
|
-
"@simplysm/core-common": "13.0.
|
|
26
|
+
"@simplysm/core-common": "13.0.71"
|
|
26
27
|
},
|
|
27
28
|
"devDependencies": {
|
|
28
29
|
"happy-dom": "^20.7.0"
|