@blcklab/freedom 0.1.1
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 +240 -0
- package/dist/index.cjs +798 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +791 -0
- package/dist/index.js.map +1 -0
- package/dist/manager.cjs +94 -0
- package/dist/manager.cjs.map +1 -0
- package/dist/manager.d.cts +6 -0
- package/dist/manager.d.ts +6 -0
- package/dist/manager.js +91 -0
- package/dist/manager.js.map +1 -0
- package/dist/snap.cjs +34 -0
- package/dist/snap.cjs.map +1 -0
- package/dist/snap.d.cts +10 -0
- package/dist/snap.d.ts +10 -0
- package/dist/snap.js +32 -0
- package/dist/snap.js.map +1 -0
- package/dist/types-tH0wv_P8.d.cts +121 -0
- package/dist/types-tH0wv_P8.d.ts +121 -0
- package/dist/window.cjs +788 -0
- package/dist/window.cjs.map +1 -0
- package/dist/window.d.cts +6 -0
- package/dist/window.d.ts +6 -0
- package/dist/window.js +785 -0
- package/dist/window.js.map +1 -0
- package/package.json +65 -0
package/README.md
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# freeDOM
|
|
2
|
+
|
|
3
|
+
A lightweight, framework-agnostic TypeScript library for draggable and resizable DOM windows.
|
|
4
|
+
|
|
5
|
+
- Draggable windows
|
|
6
|
+
- Optional resizing from edges and corners
|
|
7
|
+
- Safe first-render positioning, including centered windows
|
|
8
|
+
- Position-agnostic initialization: CSS `top/right`, `bottom/left`, `absolute`, `fixed`, `relative`, and normal-flow elements can be used as the starting point
|
|
9
|
+
- Zero runtime dependencies
|
|
10
|
+
- Pointer Events support: mouse, touch, and pen
|
|
11
|
+
- Works with any framework or vanilla JavaScript
|
|
12
|
+
- SSR-safe imports: DOM access only happens when you create a window
|
|
13
|
+
- Tree-shaking friendly subpath exports
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @blcklab/freedom
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick start
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { freedom } from '@blcklab/freedom'
|
|
25
|
+
|
|
26
|
+
const element = document.getElementById('window')!
|
|
27
|
+
|
|
28
|
+
const win = freedom.window(element, {
|
|
29
|
+
resizable: false
|
|
30
|
+
})
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Center without first-render flicker
|
|
34
|
+
|
|
35
|
+
Use `initialPosition: 'center'` to place the window in the center synchronously during initialization.
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { freedom } from '@blcklab/freedom'
|
|
39
|
+
|
|
40
|
+
const win = freedom.window(element, {
|
|
41
|
+
initialPosition: 'center',
|
|
42
|
+
initialSize: {
|
|
43
|
+
width: 500,
|
|
44
|
+
height: 320
|
|
45
|
+
},
|
|
46
|
+
resizable: false
|
|
47
|
+
})
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
For the strongest zero-flicker setup, hide the element before JavaScript runs:
|
|
51
|
+
|
|
52
|
+
```css
|
|
53
|
+
.my-window {
|
|
54
|
+
position: fixed;
|
|
55
|
+
visibility: hidden;
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Then initialize it:
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
freedom.window(element, {
|
|
63
|
+
initialPosition: 'center',
|
|
64
|
+
initialSize: { width: 500, height: 320 }
|
|
65
|
+
})
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
By default, freeDOM will reveal an element that starts with `visibility: hidden` after it has synchronously written the initial size and position. Disable that behavior with `autoReveal: false`.
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
freedom.window(element, {
|
|
72
|
+
initialPosition: 'center',
|
|
73
|
+
autoReveal: false
|
|
74
|
+
})
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Custom initial position and size
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
freedom.window(element, {
|
|
81
|
+
initialPosition: { x: 100, y: 100 },
|
|
82
|
+
initialSize: { width: 500, height: 320 }
|
|
83
|
+
})
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Drag only
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
const win = freedom.window(element, {
|
|
90
|
+
resizable: false
|
|
91
|
+
})
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Drag and resize
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
const win = freedom.window(element, {
|
|
98
|
+
draggable: true,
|
|
99
|
+
resizable: true,
|
|
100
|
+
minWidth: 200,
|
|
101
|
+
minHeight: 150,
|
|
102
|
+
maxWidth: 800,
|
|
103
|
+
maxHeight: 600
|
|
104
|
+
})
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Drag handle
|
|
108
|
+
|
|
109
|
+
Restrict dragging to a title bar or any child element.
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
freedom.window(element, {
|
|
113
|
+
dragHandle: '.window-titlebar',
|
|
114
|
+
resizable: true
|
|
115
|
+
})
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Position-agnostic initialization
|
|
119
|
+
|
|
120
|
+
freeDOM does not require your CSS to use `top` and `left`. It can start from CSS such as `top/right`, `bottom/left`, an existing `fixed` or `absolute` panel, or even a normal-flow element. During initialization it reads the current rendered location, normalizes the managed window, and then uses transform deltas for smooth movement.
|
|
121
|
+
|
|
122
|
+
This works:
|
|
123
|
+
|
|
124
|
+
```css
|
|
125
|
+
.my-window {
|
|
126
|
+
position: fixed;
|
|
127
|
+
top: 20px;
|
|
128
|
+
right: 20px;
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
const win = freedom.window(element, {
|
|
134
|
+
dragHandle: '.header',
|
|
135
|
+
resizable: true
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
console.log(win.getPosition()) // the real visual x/y after CSS is resolved
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Normal-flow elements are preserved by switching them to `position: relative` and moving with transform deltas, so the library does not need to force everything to `top: 0; left: 0`.
|
|
142
|
+
|
|
143
|
+
You can still force a mode when needed:
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
freedom.window(element, {
|
|
147
|
+
positioning: 'fixed', // 'fixed' | 'absolute' | 'relative'
|
|
148
|
+
initialPosition: 'center'
|
|
149
|
+
})
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Available modes are `fixed`, `absolute`, and `relative`.
|
|
153
|
+
|
|
154
|
+
## Public imports
|
|
155
|
+
|
|
156
|
+
Root import for the main window API:
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
import { freedom, createWindow } from '@blcklab/freedom'
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Tree-shaking friendly subpath import:
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
import { createWindow } from '@blcklab/freedom/window'
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Optional manager:
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
import { createManager } from '@blcklab/freedom/manager'
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Optional snap plugin:
|
|
175
|
+
|
|
176
|
+
```ts
|
|
177
|
+
import { snapPlugin } from '@blcklab/freedom/plugins/snap'
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## API
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
const win = freedom.window(element)
|
|
184
|
+
|
|
185
|
+
win.setPosition({ x: 100, y: 100 })
|
|
186
|
+
win.setSize({ width: 400, height: 300 })
|
|
187
|
+
|
|
188
|
+
win.getPosition()
|
|
189
|
+
win.getSize()
|
|
190
|
+
|
|
191
|
+
win.enableDrag()
|
|
192
|
+
win.disableDrag()
|
|
193
|
+
|
|
194
|
+
win.enableResize()
|
|
195
|
+
win.disableResize()
|
|
196
|
+
|
|
197
|
+
win.destroy()
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Options
|
|
201
|
+
|
|
202
|
+
```ts
|
|
203
|
+
freedom.window(element, {
|
|
204
|
+
id: 'settings-panel',
|
|
205
|
+
|
|
206
|
+
draggable: true,
|
|
207
|
+
resizable: true,
|
|
208
|
+
|
|
209
|
+
initialPosition: 'center',
|
|
210
|
+
initialSize: { width: 500, height: 320 },
|
|
211
|
+
|
|
212
|
+
positioning: 'fixed', // 'fixed' | 'absolute' | 'relative'
|
|
213
|
+
autoReveal: true,
|
|
214
|
+
|
|
215
|
+
minWidth: 200,
|
|
216
|
+
minHeight: 150,
|
|
217
|
+
maxWidth: 800,
|
|
218
|
+
maxHeight: 600,
|
|
219
|
+
|
|
220
|
+
dragHandle: '.titlebar',
|
|
221
|
+
bounds: 'viewport'
|
|
222
|
+
})
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Browser support
|
|
226
|
+
|
|
227
|
+
Modern browsers supporting the Pointer Events API.
|
|
228
|
+
|
|
229
|
+
## Notes
|
|
230
|
+
|
|
231
|
+
- Importing the package is SSR-safe.
|
|
232
|
+
- Creating a window must happen in the browser.
|
|
233
|
+
- freeDOM does not inject global CSS.
|
|
234
|
+
- Runtime styles are applied only to the controlled element and generated resize handles.
|
|
235
|
+
- Existing CSS positioning can be used as the initial source of truth; after initialization, freeDOM owns the managed position.
|
|
236
|
+
- Resize handles win over dragging, so resizing does not accidentally start a drag.
|
|
237
|
+
|
|
238
|
+
## License
|
|
239
|
+
|
|
240
|
+
MIT
|