@simplysm/core-browser 13.0.98 → 13.0.100
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 +21 -137
- package/docs/classes.md +184 -0
- package/docs/element-extensions.md +134 -0
- package/docs/html-element-extensions.md +56 -0
- package/docs/utilities.md +71 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @simplysm/core-browser
|
|
2
2
|
|
|
3
|
-
Core module (browser)
|
|
3
|
+
Simplysm package - Core module (browser). Browser-only utilities including DOM extensions, file downloads, IndexedDB storage, and virtual file system.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -12,21 +12,18 @@ npm install @simplysm/core-browser
|
|
|
12
12
|
|
|
13
13
|
This package includes side-effect imports that augment global prototypes when the module is loaded:
|
|
14
14
|
|
|
15
|
-
- `
|
|
16
|
-
- `
|
|
15
|
+
- `Element.prototype` -- Adds `findAll`, `findFirst`, `prependChild`, `getParents`, `findFocusableParent`, `findFirstFocusableChild`, `isOffsetElement`, `isVisible`.
|
|
16
|
+
- `HTMLElement.prototype` -- Adds `repaint`, `getRelativeOffset`, `scrollIntoViewIfNeeded`.
|
|
17
17
|
|
|
18
18
|
These side effects run automatically when you import from `@simplysm/core-browser`.
|
|
19
19
|
|
|
20
20
|
## API Overview
|
|
21
21
|
|
|
22
|
-
### Extensions
|
|
22
|
+
### Element Extensions
|
|
23
23
|
|
|
24
24
|
| API | Type | Description |
|
|
25
25
|
|-----|------|-------------|
|
|
26
26
|
| `ElementBounds` | interface | Element bounds info (`target`, `top`, `left`, `width`, `height`) |
|
|
27
|
-
| `copyElement` | function | Copy element content to clipboard via ClipboardEvent |
|
|
28
|
-
| `pasteToElement` | function | Paste clipboard content to element via ClipboardEvent |
|
|
29
|
-
| `getBounds` | function | Get bounds for multiple elements using IntersectionObserver |
|
|
30
27
|
| `Element.findAll` | prototype method | Find all child elements matching a CSS selector |
|
|
31
28
|
| `Element.findFirst` | prototype method | Find first element matching a CSS selector |
|
|
32
29
|
| `Element.prependChild` | prototype method | Insert element as first child |
|
|
@@ -35,8 +32,13 @@ These side effects run automatically when you import from `@simplysm/core-browse
|
|
|
35
32
|
| `Element.findFirstFocusableChild` | prototype method | Find first focusable child element |
|
|
36
33
|
| `Element.isOffsetElement` | prototype method | Check if element has offset positioning |
|
|
37
34
|
| `Element.isVisible` | prototype method | Check if element is visible on screen |
|
|
35
|
+
| `copyElement` | function | Copy element content to clipboard via ClipboardEvent |
|
|
36
|
+
| `pasteToElement` | function | Paste clipboard content to element via ClipboardEvent |
|
|
37
|
+
| `getBounds` | function | Get bounds for multiple elements using IntersectionObserver |
|
|
38
|
+
|
|
39
|
+
-> See [docs/element-extensions.md](./docs/element-extensions.md) for details.
|
|
38
40
|
|
|
39
|
-
### Extensions
|
|
41
|
+
### HTMLElement Extensions
|
|
40
42
|
|
|
41
43
|
| API | Type | Description |
|
|
42
44
|
|-----|------|-------------|
|
|
@@ -44,7 +46,9 @@ These side effects run automatically when you import from `@simplysm/core-browse
|
|
|
44
46
|
| `HTMLElement.getRelativeOffset` | prototype method | Calculate position relative to a parent element |
|
|
45
47
|
| `HTMLElement.scrollIntoViewIfNeeded` | prototype method | Scroll to make target visible if obscured |
|
|
46
48
|
|
|
47
|
-
|
|
49
|
+
-> See [docs/html-element-extensions.md](./docs/html-element-extensions.md) for details.
|
|
50
|
+
|
|
51
|
+
### Utilities
|
|
48
52
|
|
|
49
53
|
| API | Type | Description |
|
|
50
54
|
|-----|------|-------------|
|
|
@@ -52,139 +56,19 @@ These side effects run automatically when you import from `@simplysm/core-browse
|
|
|
52
56
|
| `DownloadProgress` | interface | Download progress info (`receivedLength`, `contentLength`) |
|
|
53
57
|
| `fetchUrlBytes` | function | Download binary data from URL with progress callback |
|
|
54
58
|
| `openFileDialog` | function | Programmatically open file selection dialog |
|
|
59
|
+
|
|
60
|
+
-> See [docs/utilities.md](./docs/utilities.md) for details.
|
|
61
|
+
|
|
62
|
+
### Classes
|
|
63
|
+
|
|
64
|
+
| API | Type | Description |
|
|
65
|
+
|-----|------|-------------|
|
|
55
66
|
| `StoreConfig` | interface | IndexedDB store configuration (`name`, `keyPath`) |
|
|
56
67
|
| `IndexedDbStore` | class | IndexedDB wrapper for key-value storage |
|
|
57
68
|
| `VirtualFsEntry` | interface | Virtual file system entry (`kind`, `dataBase64`) |
|
|
58
69
|
| `IndexedDbVirtualFs` | class | IndexedDB-backed virtual file system |
|
|
59
70
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
```typescript
|
|
63
|
-
interface ElementBounds {
|
|
64
|
-
target: Element;
|
|
65
|
-
top: number;
|
|
66
|
-
left: number;
|
|
67
|
-
width: number;
|
|
68
|
-
height: number;
|
|
69
|
-
}
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
## `copyElement`
|
|
73
|
-
|
|
74
|
-
```typescript
|
|
75
|
-
function copyElement(event: ClipboardEvent): void;
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
Copy element content to clipboard. Use as a copy event handler.
|
|
79
|
-
|
|
80
|
-
## `pasteToElement`
|
|
81
|
-
|
|
82
|
-
```typescript
|
|
83
|
-
function pasteToElement(event: ClipboardEvent): void;
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
Paste clipboard content to element. Finds the first `input`/`textarea` within the target and replaces its value.
|
|
87
|
-
|
|
88
|
-
## `getBounds`
|
|
89
|
-
|
|
90
|
-
```typescript
|
|
91
|
-
async function getBounds(els: Element[], timeout?: number): Promise<ElementBounds[]>;
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
Get bounds information for elements using IntersectionObserver. Throws `TimeoutError` if no response within `timeout` ms (default: 5000).
|
|
95
|
-
|
|
96
|
-
## `downloadBlob`
|
|
97
|
-
|
|
98
|
-
```typescript
|
|
99
|
-
function downloadBlob(blob: Blob, fileName: string): void;
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
Download a Blob as a file by creating a temporary object URL and clicking a link.
|
|
103
|
-
|
|
104
|
-
## `DownloadProgress`
|
|
105
|
-
|
|
106
|
-
```typescript
|
|
107
|
-
interface DownloadProgress {
|
|
108
|
-
receivedLength: number;
|
|
109
|
-
contentLength: number;
|
|
110
|
-
}
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
## `fetchUrlBytes`
|
|
114
|
-
|
|
115
|
-
```typescript
|
|
116
|
-
async function fetchUrlBytes(
|
|
117
|
-
url: string,
|
|
118
|
-
options?: { onProgress?: (progress: DownloadProgress) => void },
|
|
119
|
-
): Promise<Uint8Array>;
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
Download binary data from URL with optional progress callback. Pre-allocates memory when Content-Length is known.
|
|
123
|
-
|
|
124
|
-
## `openFileDialog`
|
|
125
|
-
|
|
126
|
-
```typescript
|
|
127
|
-
function openFileDialog(options?: {
|
|
128
|
-
accept?: string;
|
|
129
|
-
multiple?: boolean;
|
|
130
|
-
}): Promise<File[] | undefined>;
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
Programmatically open a file selection dialog. Returns `undefined` if cancelled.
|
|
134
|
-
|
|
135
|
-
## `StoreConfig`
|
|
136
|
-
|
|
137
|
-
```typescript
|
|
138
|
-
interface StoreConfig {
|
|
139
|
-
name: string;
|
|
140
|
-
keyPath: string;
|
|
141
|
-
}
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
## `IndexedDbStore`
|
|
145
|
-
|
|
146
|
-
```typescript
|
|
147
|
-
class IndexedDbStore {
|
|
148
|
-
constructor(dbName: string, dbVersion: number, storeConfigs: StoreConfig[]);
|
|
149
|
-
async open(): Promise<IDBDatabase>;
|
|
150
|
-
async withStore<TResult>(
|
|
151
|
-
storeName: string,
|
|
152
|
-
mode: IDBTransactionMode,
|
|
153
|
-
fn: (store: IDBObjectStore) => Promise<TResult>,
|
|
154
|
-
): Promise<TResult>;
|
|
155
|
-
async get<TValue>(storeName: string, key: IDBValidKey): Promise<TValue | undefined>;
|
|
156
|
-
async put(storeName: string, value: unknown): Promise<void>;
|
|
157
|
-
async delete(storeName: string, key: IDBValidKey): Promise<void>;
|
|
158
|
-
async getAll<TItem>(storeName: string): Promise<TItem[]>;
|
|
159
|
-
close(): void;
|
|
160
|
-
}
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
IndexedDB wrapper that manages database connections, schema upgrades, and transactional CRUD operations.
|
|
164
|
-
|
|
165
|
-
## `VirtualFsEntry`
|
|
166
|
-
|
|
167
|
-
```typescript
|
|
168
|
-
interface VirtualFsEntry {
|
|
169
|
-
kind: "file" | "dir";
|
|
170
|
-
dataBase64?: string;
|
|
171
|
-
}
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
## `IndexedDbVirtualFs`
|
|
175
|
-
|
|
176
|
-
```typescript
|
|
177
|
-
class IndexedDbVirtualFs {
|
|
178
|
-
constructor(db: IndexedDbStore, storeName: string, keyField: string);
|
|
179
|
-
async getEntry(fullKey: string): Promise<VirtualFsEntry | undefined>;
|
|
180
|
-
async putEntry(fullKey: string, kind: "file" | "dir", dataBase64?: string): Promise<void>;
|
|
181
|
-
async deleteByPrefix(keyPrefix: string): Promise<boolean>;
|
|
182
|
-
async listChildren(prefix: string): Promise<{ name: string; isDirectory: boolean }[]>;
|
|
183
|
-
async ensureDir(fullKeyBuilder: (path: string) => string, dirPath: string): Promise<void>;
|
|
184
|
-
}
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
Virtual file system backed by IndexedDB. Stores files and directories as key-value entries with hierarchical path support.
|
|
71
|
+
-> See [docs/classes.md](./docs/classes.md) for details.
|
|
188
72
|
|
|
189
73
|
## Usage Examples
|
|
190
74
|
|
package/docs/classes.md
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# Classes
|
|
2
|
+
|
|
3
|
+
IndexedDB-based storage classes for browser-side data persistence.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
import { IndexedDbStore, IndexedDbVirtualFs } from "@simplysm/core-browser";
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## `StoreConfig`
|
|
10
|
+
|
|
11
|
+
Configuration for an IndexedDB object store.
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
interface StoreConfig {
|
|
15
|
+
name: string;
|
|
16
|
+
keyPath: string;
|
|
17
|
+
}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
| Field | Type | Description |
|
|
21
|
+
|-------|------|-------------|
|
|
22
|
+
| `name` | `string` | Object store name |
|
|
23
|
+
| `keyPath` | `string` | Key path for the object store |
|
|
24
|
+
|
|
25
|
+
## `IndexedDbStore`
|
|
26
|
+
|
|
27
|
+
IndexedDB wrapper that manages database connections, schema upgrades, and transactional CRUD operations. Handles version changes and connection blocking gracefully.
|
|
28
|
+
|
|
29
|
+
### Constructor
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
constructor(dbName: string, dbVersion: number, storeConfigs: StoreConfig[])
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Parameters:**
|
|
36
|
+
- `dbName` -- Database name
|
|
37
|
+
- `dbVersion` -- Database version (triggers upgrade when increased)
|
|
38
|
+
- `storeConfigs` -- Array of object store configurations
|
|
39
|
+
|
|
40
|
+
### Methods
|
|
41
|
+
|
|
42
|
+
#### `open`
|
|
43
|
+
|
|
44
|
+
Open or reuse the database connection. Creates object stores defined in `storeConfigs` during upgrade. Handles `onversionchange` and `onclose` events to clear internal references.
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
async open(): Promise<IDBDatabase>;
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
#### `withStore`
|
|
51
|
+
|
|
52
|
+
Execute a function within an IndexedDB transaction. Handles transaction completion and error propagation.
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
async withStore<TResult>(
|
|
56
|
+
storeName: string,
|
|
57
|
+
mode: IDBTransactionMode,
|
|
58
|
+
fn: (store: IDBObjectStore) => Promise<TResult>,
|
|
59
|
+
): Promise<TResult>;
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
#### `get`
|
|
63
|
+
|
|
64
|
+
Get a value by key from a store.
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
async get<TValue>(storeName: string, key: IDBValidKey): Promise<TValue | undefined>;
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
#### `put`
|
|
71
|
+
|
|
72
|
+
Put a value into a store (insert or update).
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
async put(storeName: string, value: unknown): Promise<void>;
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
#### `delete`
|
|
79
|
+
|
|
80
|
+
Delete a value by key from a store.
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
async delete(storeName: string, key: IDBValidKey): Promise<void>;
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
#### `getAll`
|
|
87
|
+
|
|
88
|
+
Get all values from a store.
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
async getAll<TItem>(storeName: string): Promise<TItem[]>;
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
#### `close`
|
|
95
|
+
|
|
96
|
+
Close the database connection and clear internal references.
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
close(): void;
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## `VirtualFsEntry`
|
|
105
|
+
|
|
106
|
+
Entry in the virtual file system.
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
interface VirtualFsEntry {
|
|
110
|
+
kind: "file" | "dir";
|
|
111
|
+
dataBase64?: string;
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
| Field | Type | Description |
|
|
116
|
+
|-------|------|-------------|
|
|
117
|
+
| `kind` | `"file" \| "dir"` | Entry type |
|
|
118
|
+
| `dataBase64` | `string \| undefined` | Base64-encoded file data (files only) |
|
|
119
|
+
|
|
120
|
+
## `IndexedDbVirtualFs`
|
|
121
|
+
|
|
122
|
+
Virtual file system backed by IndexedDB. Stores files and directories as key-value entries with hierarchical path support. Built on top of `IndexedDbStore`.
|
|
123
|
+
|
|
124
|
+
### Constructor
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
constructor(db: IndexedDbStore, storeName: string, keyField: string)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Parameters:**
|
|
131
|
+
- `db` -- `IndexedDbStore` instance
|
|
132
|
+
- `storeName` -- Name of the object store to use
|
|
133
|
+
- `keyField` -- Key field name for entries
|
|
134
|
+
|
|
135
|
+
### Methods
|
|
136
|
+
|
|
137
|
+
#### `getEntry`
|
|
138
|
+
|
|
139
|
+
Get a virtual file system entry by its full key.
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
async getEntry(fullKey: string): Promise<VirtualFsEntry | undefined>;
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
#### `putEntry`
|
|
146
|
+
|
|
147
|
+
Put an entry into the virtual file system.
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
async putEntry(fullKey: string, kind: "file" | "dir", dataBase64?: string): Promise<void>;
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
#### `deleteByPrefix`
|
|
154
|
+
|
|
155
|
+
Delete all entries matching a key prefix (the entry with the exact prefix key and all children).
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
async deleteByPrefix(keyPrefix: string): Promise<boolean>;
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**Returns:** `true` if any entries were deleted.
|
|
162
|
+
|
|
163
|
+
#### `listChildren`
|
|
164
|
+
|
|
165
|
+
List immediate children under a prefix path.
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
async listChildren(prefix: string): Promise<{ name: string; isDirectory: boolean }[]>;
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
#### `ensureDir`
|
|
172
|
+
|
|
173
|
+
Ensure a directory path exists by creating all missing parent directories.
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
async ensureDir(
|
|
177
|
+
fullKeyBuilder: (path: string) => string,
|
|
178
|
+
dirPath: string,
|
|
179
|
+
): Promise<void>;
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
**Parameters:**
|
|
183
|
+
- `fullKeyBuilder` -- Function to convert a path segment to a full key
|
|
184
|
+
- `dirPath` -- Directory path to ensure (e.g., `"/a/b/c"`)
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Element Extensions
|
|
2
|
+
|
|
3
|
+
Extensions added to the `Element.prototype` via side-effect import. These methods are available on all `Element` instances when `@simplysm/core-browser` is imported.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
import "@simplysm/core-browser";
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## `ElementBounds`
|
|
10
|
+
|
|
11
|
+
Element bounds information type returned by `getBounds`.
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
interface ElementBounds {
|
|
15
|
+
/** Element to be measured */
|
|
16
|
+
target: Element;
|
|
17
|
+
/** Top position relative to viewport */
|
|
18
|
+
top: number;
|
|
19
|
+
/** Left position relative to viewport */
|
|
20
|
+
left: number;
|
|
21
|
+
/** Element width */
|
|
22
|
+
width: number;
|
|
23
|
+
/** Element height */
|
|
24
|
+
height: number;
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
| Field | Type | Description |
|
|
29
|
+
|-------|------|-------------|
|
|
30
|
+
| `target` | `Element` | Element to be measured |
|
|
31
|
+
| `top` | `number` | Top position relative to viewport |
|
|
32
|
+
| `left` | `number` | Left position relative to viewport |
|
|
33
|
+
| `width` | `number` | Element width |
|
|
34
|
+
| `height` | `number` | Element height |
|
|
35
|
+
|
|
36
|
+
## `Element.findAll`
|
|
37
|
+
|
|
38
|
+
Find all child elements matching a CSS selector.
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
findAll<TEl extends Element = Element>(selector: string): TEl[];
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Returns an empty array if the selector is empty.
|
|
45
|
+
|
|
46
|
+
## `Element.findFirst`
|
|
47
|
+
|
|
48
|
+
Find first element matching a CSS selector.
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
findFirst<TEl extends Element = Element>(selector: string): TEl | undefined;
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Returns `undefined` if the selector is empty or no match is found.
|
|
55
|
+
|
|
56
|
+
## `Element.prependChild`
|
|
57
|
+
|
|
58
|
+
Insert element as first child.
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
prependChild<TEl extends Element>(child: TEl): TEl;
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## `Element.getParents`
|
|
65
|
+
|
|
66
|
+
Get all parent elements in order of proximity (from closest to farthest).
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
getParents(): Element[];
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## `Element.findFocusableParent`
|
|
73
|
+
|
|
74
|
+
Find first focusable parent element (using tabbable library).
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
findFocusableParent(): HTMLElement | undefined;
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## `Element.findFirstFocusableChild`
|
|
81
|
+
|
|
82
|
+
Find first focusable child element (using tabbable library). Uses a TreeWalker for traversal.
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
findFirstFocusableChild(): HTMLElement | undefined;
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## `Element.isOffsetElement`
|
|
89
|
+
|
|
90
|
+
Check if element is an offset parent (`position: relative | absolute | fixed | sticky`).
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
isOffsetElement(): boolean;
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## `Element.isVisible`
|
|
97
|
+
|
|
98
|
+
Check if element is visible on screen. Checks existence of clientRects, `visibility: hidden`, and `opacity: 0`.
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
isVisible(): boolean;
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## `copyElement`
|
|
105
|
+
|
|
106
|
+
Copy element content to clipboard. Use as a copy event handler. Finds the first `input`/`textarea` within the target element and copies its value.
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
function copyElement(event: ClipboardEvent): void;
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## `pasteToElement`
|
|
113
|
+
|
|
114
|
+
Paste clipboard content to element. Use as a paste event handler. Finds the first `input`/`textarea` within the target element and replaces its entire value with clipboard content. Does not consider cursor position or selection.
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
function pasteToElement(event: ClipboardEvent): void;
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## `getBounds`
|
|
121
|
+
|
|
122
|
+
Get bounds information for multiple elements using IntersectionObserver.
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
async function getBounds(els: Element[], timeout?: number): Promise<ElementBounds[]>;
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**Parameters:**
|
|
129
|
+
- `els` -- Array of target elements
|
|
130
|
+
- `timeout` -- Timeout in milliseconds (default: `5000`)
|
|
131
|
+
|
|
132
|
+
**Throws:** `TimeoutError` if no response within the timeout duration.
|
|
133
|
+
|
|
134
|
+
Results are returned sorted in input order, with duplicates removed.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# HTMLElement Extensions
|
|
2
|
+
|
|
3
|
+
Extensions added to the `HTMLElement.prototype` via side-effect import. These methods are available on all `HTMLElement` instances when `@simplysm/core-browser` is imported.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
import "@simplysm/core-browser";
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## `HTMLElement.repaint`
|
|
10
|
+
|
|
11
|
+
Force repaint by triggering reflow. Internally accesses `offsetHeight` which triggers forced synchronous layout in the browser.
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
repaint(): void;
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## `HTMLElement.getRelativeOffset`
|
|
18
|
+
|
|
19
|
+
Calculate relative position based on a parent element for CSS positioning.
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
getRelativeOffset(parent: HTMLElement | string): { top: number; left: number };
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Returns document-based coordinates including `window.scrollX/Y` that can be directly used in CSS `top`/`left` properties.
|
|
26
|
+
|
|
27
|
+
**Parameters:**
|
|
28
|
+
- `parent` -- Parent element or CSS selector to use as reference (e.g., `document.body`, `".container"`)
|
|
29
|
+
|
|
30
|
+
**Throws:** `ArgumentError` if parent element cannot be found.
|
|
31
|
+
|
|
32
|
+
**Factors included in calculation:**
|
|
33
|
+
- Viewport-relative position (`getBoundingClientRect`)
|
|
34
|
+
- Document scroll position (`window.scrollX/Y`)
|
|
35
|
+
- Parent element internal scroll (`parentEl.scrollTop/Left`)
|
|
36
|
+
- Border thickness of intermediate elements
|
|
37
|
+
- CSS transform transformations
|
|
38
|
+
|
|
39
|
+
**Common use cases:**
|
|
40
|
+
- Position dropdowns, popups after appending to `document.body`
|
|
41
|
+
- Works correctly on scrolled pages
|
|
42
|
+
|
|
43
|
+
## `HTMLElement.scrollIntoViewIfNeeded`
|
|
44
|
+
|
|
45
|
+
Scroll to make target visible if hidden by offset area (e.g., fixed header/column). Only handles cases where target extends beyond top/left boundaries of the scroll area. For downward/rightward scrolling, relies on browser's default focus scroll behavior. Typically used with focus events on tables with fixed headers or columns.
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
scrollIntoViewIfNeeded(
|
|
49
|
+
target: { top: number; left: number },
|
|
50
|
+
offset?: { top: number; left: number },
|
|
51
|
+
): void;
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Parameters:**
|
|
55
|
+
- `target` -- Target position within container (`offsetTop`, `offsetLeft`)
|
|
56
|
+
- `offset` -- Size of area that must not be obscured (e.g., fixed header height, fixed column width). Defaults to `{ top: 0, left: 0 }`.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Utilities
|
|
2
|
+
|
|
3
|
+
Standalone utility functions for browser-side operations.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
import { downloadBlob, fetchUrlBytes, openFileDialog } from "@simplysm/core-browser";
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## `downloadBlob`
|
|
10
|
+
|
|
11
|
+
Download a Blob as a file by creating a temporary object URL and clicking a hidden link.
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
function downloadBlob(blob: Blob, fileName: string): void;
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**Parameters:**
|
|
18
|
+
- `blob` -- Blob object to download
|
|
19
|
+
- `fileName` -- File name to save as
|
|
20
|
+
|
|
21
|
+
## `DownloadProgress`
|
|
22
|
+
|
|
23
|
+
Download progress information used by `fetchUrlBytes`.
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
interface DownloadProgress {
|
|
27
|
+
receivedLength: number;
|
|
28
|
+
contentLength: number;
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
| Field | Type | Description |
|
|
33
|
+
|-------|------|-------------|
|
|
34
|
+
| `receivedLength` | `number` | Number of bytes received so far |
|
|
35
|
+
| `contentLength` | `number` | Total content length from `Content-Length` header |
|
|
36
|
+
|
|
37
|
+
## `fetchUrlBytes`
|
|
38
|
+
|
|
39
|
+
Download binary data from a URL with optional progress callback support.
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
async function fetchUrlBytes(
|
|
43
|
+
url: string,
|
|
44
|
+
options?: { onProgress?: (progress: DownloadProgress) => void },
|
|
45
|
+
): Promise<Uint8Array>;
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Parameters:**
|
|
49
|
+
- `url` -- URL to download from
|
|
50
|
+
- `options.onProgress` -- Progress callback function
|
|
51
|
+
|
|
52
|
+
When `Content-Length` is known, pre-allocates memory for efficiency. For chunked encoding (unknown length), collects chunks and merges them.
|
|
53
|
+
|
|
54
|
+
**Throws:** `Error` if the download fails or the response body is not readable.
|
|
55
|
+
|
|
56
|
+
## `openFileDialog`
|
|
57
|
+
|
|
58
|
+
Programmatically open a file selection dialog.
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
function openFileDialog(options?: {
|
|
62
|
+
accept?: string;
|
|
63
|
+
multiple?: boolean;
|
|
64
|
+
}): Promise<File[] | undefined>;
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Parameters:**
|
|
68
|
+
- `options.accept` -- File type filter (e.g., `".csv"`, `"image/*"`)
|
|
69
|
+
- `options.multiple` -- Allow multiple file selection (default: `false`)
|
|
70
|
+
|
|
71
|
+
**Returns:** Array of selected files, or `undefined` if the dialog is cancelled.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/core-browser",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.100",
|
|
4
4
|
"description": "Simplysm package - Core module (browser)",
|
|
5
5
|
"author": "simplysm",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
],
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"tabbable": "^6.4.0",
|
|
27
|
-
"@simplysm/core-common": "13.0.
|
|
27
|
+
"@simplysm/core-common": "13.0.100"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"happy-dom": "^20.8.4"
|