@oscarpalmer/oui 0.26.1 → 0.27.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/dist/css/floatable.css +0 -2
- package/dist/css/message.css +1 -0
- package/dist/css/reset.css +1 -0
- package/dist/js/dialog.d.mts +2 -0
- package/dist/js/dialog.mjs +16 -1
- package/dist/js/draggable-zszaW1qS.d.mts +155 -0
- package/dist/js/floatable/floatable.embedded.d.mts +2 -0
- package/dist/js/floatable/{embedded.mjs → floatable.embedded.mjs} +16 -11
- package/dist/js/floatable/floatable.standalone.d.mts +2 -0
- package/dist/js/floatable/floatable.standalone.mjs +2 -0
- package/dist/js/{embedded-CSOh5njI.d.mts → floatable.embedded-YxGwzgbE.d.mts} +5 -2
- package/dist/js/focus-trap/focus-trap.embedded.d.mts +2 -0
- package/dist/js/focus-trap/{embedded.mjs → focus-trap.embedded.mjs} +17 -15
- package/dist/js/focus-trap/focus-trap.standalone.d.mts +2 -0
- package/dist/js/focus-trap/focus-trap.standalone.mjs +2 -0
- package/dist/js/{embedded-CHK82Uh5.d.mts → focus-trap.embedded-DR8NpZfr.d.mts} +18 -18
- package/dist/js/index.d.mts +4 -3
- package/dist/js/index.mjs +8 -7
- package/dist/js/internal/draggable.d.mts +2 -2
- package/dist/js/internal/draggable.mjs +146 -94
- package/dist/js/movable/movable.embedded.d.mts +2 -0
- package/dist/js/movable/movable.embedded.mjs +184 -0
- package/dist/js/movable/movable.standalone.d.mts +2 -0
- package/dist/js/movable/movable.standalone.mjs +2 -0
- package/dist/js/popover.d.mts +2 -2
- package/dist/js/popover.mjs +4 -3
- package/dist/js/sortable/sortable.embedded.d.mts +2 -0
- package/dist/js/{sortable.mjs → sortable/sortable.embedded.mjs} +88 -63
- package/dist/js/sortable/sortable.standalone.d.mts +2 -0
- package/dist/js/sortable/sortable.standalone.mjs +2 -0
- package/dist/js/splitter.mjs +5 -5
- package/dist/js/toolbar.mjs +6 -6
- package/dist/js/tooltip.d.mts +2 -2
- package/dist/js/tooltip.mjs +36 -33
- package/package.json +11 -11
- package/src/css/floatable.scss +0 -2
- package/src/css/message.scss +1 -0
- package/src/css/reset.scss +1 -0
- package/src/js/dialog.ts +31 -1
- package/src/js/floatable/{embedded.ts → floatable.embedded.ts} +18 -10
- package/src/js/floatable/floatable.standalone.ts +6 -0
- package/src/js/focus-trap/{embedded.ts → focus-trap.embedded.ts} +20 -17
- package/src/js/focus-trap/focus-trap.standalone.ts +1 -0
- package/src/js/index.ts +4 -4
- package/src/js/internal/draggable.ts +309 -168
- package/src/js/movable/movable.embedded.ts +328 -0
- package/src/js/movable/movable.standalone.ts +2 -0
- package/src/js/popover.ts +3 -2
- package/src/js/{sortable.ts → sortable/sortable.embedded.ts} +170 -103
- package/src/js/sortable/sortable.standalone.ts +2 -0
- package/src/js/tooltip.ts +49 -43
- package/dist/js/floatable/embedded.d.mts +0 -2
- package/dist/js/floatable/standalone.d.mts +0 -2
- package/dist/js/floatable/standalone.mjs +0 -2
- package/dist/js/focus-trap/embedded.d.mts +0 -2
- package/dist/js/focus-trap/standalone.d.mts +0 -2
- package/dist/js/focus-trap/standalone.mjs +0 -6
- package/dist/js/movable-dNqBctx3.d.mts +0 -101
- package/dist/js/movable.d.mts +0 -2
- package/dist/js/movable.mjs +0 -152
- package/dist/js/sortable.d.mts +0 -2
- package/src/js/floatable/standalone.ts +0 -1
- package/src/js/focus-trap/standalone.ts +0 -6
- package/src/js/movable.ts +0 -260
|
@@ -1,52 +1,84 @@
|
|
|
1
1
|
import { getPosition, on } from "@oscarpalmer/toretto/event";
|
|
2
|
+
import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
|
|
2
3
|
import { clamp } from "@oscarpalmer/atoms/number";
|
|
3
4
|
import { findAncestor } from "@oscarpalmer/toretto/find";
|
|
4
5
|
import { toggleStyles } from "@oscarpalmer/toretto/style";
|
|
5
6
|
import supportsTouch from "@oscarpalmer/toretto/touch";
|
|
6
7
|
//#region src/js/internal/draggable.ts
|
|
7
8
|
var OuiDraggable = class {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
this
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
9
|
+
#destroyed = false;
|
|
10
|
+
#name;
|
|
11
|
+
#state;
|
|
12
|
+
get element() {
|
|
13
|
+
return this.#state.element;
|
|
14
|
+
}
|
|
15
|
+
constructor(name, event, attribute, element, options, extras) {
|
|
16
|
+
this.#name = name;
|
|
17
|
+
this.#state = {
|
|
18
|
+
...extras,
|
|
19
|
+
attribute,
|
|
20
|
+
element,
|
|
21
|
+
event,
|
|
22
|
+
options,
|
|
23
|
+
horizontal: true,
|
|
24
|
+
vertical: true,
|
|
25
|
+
styling: toggleStyles(element, styles)
|
|
26
|
+
};
|
|
27
|
+
const item = {
|
|
28
|
+
instance: this,
|
|
29
|
+
state: this.#state
|
|
30
|
+
};
|
|
31
|
+
setContainer(item);
|
|
32
|
+
setDirection(item);
|
|
33
|
+
element.setAttribute(attribute, "");
|
|
34
|
+
let states = globals.states.get(element);
|
|
35
|
+
states ??= {};
|
|
36
|
+
states[this.#name] = this.#state;
|
|
37
|
+
globals.states.set(element, states);
|
|
21
38
|
}
|
|
22
39
|
destroy() {
|
|
23
|
-
|
|
24
|
-
this
|
|
25
|
-
this
|
|
26
|
-
this.options = void 0;
|
|
40
|
+
if (this.#destroyed) return;
|
|
41
|
+
this.#destroyed = true;
|
|
42
|
+
destroyInstance(this, this.#state);
|
|
27
43
|
}
|
|
28
44
|
};
|
|
29
|
-
function addDraggable(element) {
|
|
30
|
-
let instances =
|
|
45
|
+
function addDraggable(element, options) {
|
|
46
|
+
let instances = globals.instances.get(element);
|
|
31
47
|
if (instances == null) {
|
|
32
48
|
instances = {};
|
|
33
|
-
|
|
49
|
+
globals.instances.set(element, instances);
|
|
34
50
|
}
|
|
35
|
-
instances[this.property] ??= new this.constructor(element);
|
|
51
|
+
instances[this.property] ??= new this.constructor(element, options);
|
|
52
|
+
return instances[this.property];
|
|
53
|
+
}
|
|
54
|
+
function destroyInstance(instance, state) {
|
|
55
|
+
unsetContainer({
|
|
56
|
+
instance,
|
|
57
|
+
state
|
|
58
|
+
});
|
|
59
|
+
state.element.removeAttribute(state.attribute);
|
|
60
|
+
state.styling.remove();
|
|
61
|
+
state.container = void 0;
|
|
62
|
+
state.element = void 0;
|
|
63
|
+
state.options = void 0;
|
|
64
|
+
state.styling = void 0;
|
|
65
|
+
}
|
|
66
|
+
function getDraggableStates(element) {
|
|
67
|
+
return globals.states.get(element);
|
|
36
68
|
}
|
|
37
69
|
function getHandle(event, isMovable) {
|
|
38
70
|
return findAncestor(event, isMovable ? SELECTOR_MOVABLE_HANDLE : SELECTOR_SORTABLE_HANDLE);
|
|
39
71
|
}
|
|
40
|
-
function getNextPosition(
|
|
41
|
-
let x =
|
|
42
|
-
let y =
|
|
43
|
-
if (
|
|
44
|
-
x = position.x - (
|
|
45
|
-
if (
|
|
72
|
+
function getNextPosition(item, position) {
|
|
73
|
+
let x = globals.original?.x ?? 0;
|
|
74
|
+
let y = globals.original?.y ?? 0;
|
|
75
|
+
if (item.state.horizontal) {
|
|
76
|
+
x = position.x - (globals.offset?.x ?? 0);
|
|
77
|
+
if (globals.container != null && globals.element != null) x = clamp(x, globals.container.left, globals.container.right - globals.element.rectangle.width);
|
|
46
78
|
}
|
|
47
|
-
if (
|
|
48
|
-
y = position.y - (
|
|
49
|
-
if (
|
|
79
|
+
if (item.state.vertical) {
|
|
80
|
+
y = position.y - (globals.offset?.y ?? 0);
|
|
81
|
+
if (globals.container != null && globals.element != null) y = clamp(y, globals.container.top, globals.container.bottom - globals.element.rectangle.height);
|
|
50
82
|
}
|
|
51
83
|
return {
|
|
52
84
|
x,
|
|
@@ -55,19 +87,22 @@ function getNextPosition(draggable, position) {
|
|
|
55
87
|
}
|
|
56
88
|
function onKeydown(event) {
|
|
57
89
|
if (current == null || event.key !== KEY_ESCAPE) return;
|
|
58
|
-
|
|
59
|
-
current.
|
|
60
|
-
current.element.dispatchEvent(new CustomEvent(`${current.prefix}:cancel`, { detail: { element: origin } }));
|
|
90
|
+
current.state.options.drag.onCancel?.(globals, current);
|
|
91
|
+
current.state.element.dispatchEvent(new CustomEvent(`${current.state.event}:cancel`, { detail: { element: current.state.options.getOrigin() } }));
|
|
61
92
|
reset();
|
|
62
93
|
}
|
|
63
94
|
function onPointerdown(event) {
|
|
64
95
|
if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey || (supportsTouch.value ? event.type === "mousedown" : event.type === "touchstart" || event.button !== 0)) return;
|
|
65
96
|
const container = findAncestor(event, SELECTOR);
|
|
66
|
-
const instances =
|
|
67
|
-
|
|
97
|
+
const instances = globals.instances.get(container);
|
|
98
|
+
const states = globals.states.get(container);
|
|
99
|
+
if (instances == null || states == null) return;
|
|
68
100
|
const isMovable = container.hasAttribute(ATTRIBUTE_MOVABLE);
|
|
69
|
-
const
|
|
70
|
-
|
|
101
|
+
const item = {
|
|
102
|
+
instance: isMovable ? instances.movable : instances.sortable,
|
|
103
|
+
state: isMovable ? states.movable : states.sortable
|
|
104
|
+
};
|
|
105
|
+
if (item.instance == null || item.state == null) return;
|
|
71
106
|
if (supportsTouch.value) event.preventDefault();
|
|
72
107
|
let element = container;
|
|
73
108
|
if (!isMovable) {
|
|
@@ -75,41 +110,43 @@ function onPointerdown(event) {
|
|
|
75
110
|
if (element == null || element.parentElement !== container) return;
|
|
76
111
|
}
|
|
77
112
|
let handle = element;
|
|
78
|
-
|
|
79
|
-
if (
|
|
113
|
+
item.state.hasHandles ??= element.querySelector(SELECTOR_SORTABLE_HANDLE) != null;
|
|
114
|
+
if (item.state.hasHandles) handle = getHandle(event, isMovable);
|
|
80
115
|
if (handle == null) return;
|
|
81
|
-
const
|
|
116
|
+
const dragged = item.state.options.getDragged();
|
|
82
117
|
const rectangle = dragged.getBoundingClientRect();
|
|
83
118
|
const position = getPosition(event) ?? {
|
|
84
119
|
x: 0,
|
|
85
120
|
y: 0
|
|
86
121
|
};
|
|
87
|
-
current =
|
|
88
|
-
|
|
89
|
-
|
|
122
|
+
current = item;
|
|
123
|
+
globals.container = item.state.container?.getBoundingClientRect();
|
|
124
|
+
globals.element = {
|
|
90
125
|
rectangle,
|
|
91
126
|
node: dragged
|
|
92
127
|
};
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const begin = new CustomEvent(`${
|
|
128
|
+
globals.offset = item.state.options.position.getOffset(globals, item, element, position);
|
|
129
|
+
globals.original = item.state.options.position.getOriginal(globals, item, position);
|
|
130
|
+
const begin = new CustomEvent(`${item.state.event}:begin`, {
|
|
96
131
|
detail: {
|
|
97
132
|
element,
|
|
98
|
-
position: { ...
|
|
133
|
+
position: { ...globals.original }
|
|
99
134
|
},
|
|
100
135
|
cancelable: true
|
|
101
136
|
});
|
|
102
|
-
|
|
137
|
+
item.state.element.dispatchEvent(begin);
|
|
103
138
|
setTimeout(() => {
|
|
104
139
|
if (begin.defaultPrevented) {
|
|
105
|
-
|
|
140
|
+
item.state.options.drag.onCancel?.(globals, item);
|
|
106
141
|
reset();
|
|
107
142
|
return;
|
|
108
143
|
}
|
|
109
|
-
const next = getNextPosition(
|
|
144
|
+
const next = getNextPosition(item, position);
|
|
110
145
|
dragged.style.position = "fixed";
|
|
111
146
|
dragged.style.inset = `${next.y}px auto auto ${next.x}px`;
|
|
112
|
-
|
|
147
|
+
dragged.style.transform = "translate3d(0, 0, 0)";
|
|
148
|
+
item.state.options.drag.onBegin?.(event, globals, item, element, handle, next);
|
|
149
|
+
item.state.styling.set();
|
|
113
150
|
styleToggler.set();
|
|
114
151
|
});
|
|
115
152
|
}
|
|
@@ -118,61 +155,74 @@ function onPointermove(event) {
|
|
|
118
155
|
const position = getPosition(event);
|
|
119
156
|
if (position == null) return;
|
|
120
157
|
const next = getNextPosition(current, position);
|
|
121
|
-
if (
|
|
122
|
-
const detail = current.options.drag.onMove(event,
|
|
158
|
+
if (globals.element != null) globals.element.node.style.inset = `${next.y}px auto auto ${next.x}px`;
|
|
159
|
+
const detail = current.state.options.drag.onMove(event, globals, current, {
|
|
123
160
|
calculated: next,
|
|
124
161
|
original: position
|
|
125
162
|
});
|
|
126
|
-
current.element.dispatchEvent(new CustomEvent(`${current.
|
|
163
|
+
current.state.element.dispatchEvent(new CustomEvent(`${current.state.event}:move`, { detail }));
|
|
127
164
|
}
|
|
128
165
|
function onPointerup(event) {
|
|
129
|
-
current?.options.drag.onEnd?.(event,
|
|
166
|
+
current?.state.options.drag.onEnd?.(event, globals, current, reset);
|
|
130
167
|
}
|
|
131
168
|
function removeDraggable(element) {
|
|
132
169
|
const { property } = this;
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
170
|
+
removeInstance(globals.instances, property, element);
|
|
171
|
+
removeInstance(globals.states, property, element);
|
|
172
|
+
}
|
|
173
|
+
function removeInstance(map, name, element) {
|
|
174
|
+
const instances = map.get(element);
|
|
175
|
+
if (instances == null || instances[name] == null) return;
|
|
176
|
+
if (typeof instances[name].destroy === "function") instances[name].destroy();
|
|
177
|
+
instances[name] = void 0;
|
|
178
|
+
if (instances[properties[name]] == null) map.delete(element);
|
|
138
179
|
}
|
|
139
180
|
function reset() {
|
|
140
|
-
current
|
|
141
|
-
state.container = void 0;
|
|
142
|
-
state.element = void 0;
|
|
143
|
-
state.offset = void 0;
|
|
144
|
-
state.original = void 0;
|
|
181
|
+
current?.state.styling.remove();
|
|
145
182
|
styleToggler.remove();
|
|
183
|
+
current = void 0;
|
|
184
|
+
globals.container = void 0;
|
|
185
|
+
globals.element = void 0;
|
|
186
|
+
globals.offset = void 0;
|
|
187
|
+
globals.original = void 0;
|
|
146
188
|
}
|
|
147
|
-
function setContainer(
|
|
148
|
-
const
|
|
189
|
+
function setContainer(item) {
|
|
190
|
+
const { container } = item.state.options.input ?? {};
|
|
191
|
+
if (isHTMLOrSVGElement(container)) {
|
|
192
|
+
setContainerElement(item, container);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
const selector = container ?? item.instance.element.getAttribute(item.state.options.container.attribute);
|
|
149
196
|
if (typeof selector !== "string") return;
|
|
150
|
-
|
|
151
|
-
if (
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
options.container.
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
options.direction.
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
197
|
+
const element = containers.has(selector) ? item.state.element.ownerDocument.body : document.querySelector(selector) ?? void 0;
|
|
198
|
+
if (isHTMLOrSVGElement(element)) setContainerElement(item, element);
|
|
199
|
+
}
|
|
200
|
+
function setContainerElement(item, element) {
|
|
201
|
+
item.state.container = element;
|
|
202
|
+
const set = item.state.options.container.map.get(element);
|
|
203
|
+
if (set == null) item.state.options.container.map.set(element, /* @__PURE__ */ new Set([item.instance]));
|
|
204
|
+
else set.add(item.instance);
|
|
205
|
+
item.state.options.container.onInitialize?.(item);
|
|
206
|
+
}
|
|
207
|
+
function setDirection(item) {
|
|
208
|
+
const direction = item.state.element.getAttribute(item.state.options.direction.attribute);
|
|
209
|
+
if (horizontals.has(direction)) item.state.vertical = false;
|
|
210
|
+
else if (verticals.has(direction)) item.state.horizontal = false;
|
|
211
|
+
item.state.options.direction.onAfter?.(item);
|
|
212
|
+
}
|
|
213
|
+
function unsetContainer(item) {
|
|
214
|
+
const { container } = item.state;
|
|
165
215
|
if (container == null) return;
|
|
166
|
-
const set = options.container.map.get(container);
|
|
216
|
+
const set = item.state.options.container.map.get(container);
|
|
167
217
|
let empty = false;
|
|
168
218
|
if (set != null) {
|
|
169
|
-
set.delete(
|
|
219
|
+
set.delete(item.instance);
|
|
170
220
|
if (set.size === 0) {
|
|
171
221
|
empty = true;
|
|
172
|
-
options.container.map.delete(container);
|
|
222
|
+
item.state.options.container.map.delete(container);
|
|
173
223
|
}
|
|
174
224
|
}
|
|
175
|
-
options.container.onDestroy?.(
|
|
225
|
+
item.state.options.container.onDestroy?.(item, container, empty);
|
|
176
226
|
}
|
|
177
227
|
const ATTRIBUTE_MOVABLE = "oui-movable";
|
|
178
228
|
const ATTRIBUTE_SORTABLE = "oui-sortable";
|
|
@@ -181,29 +231,31 @@ const SELECTOR = `[${ATTRIBUTE_MOVABLE}], [${ATTRIBUTE_SORTABLE}]`;
|
|
|
181
231
|
const SELECTOR_MOVABLE_HANDLE = `[${ATTRIBUTE_MOVABLE}-handle]`;
|
|
182
232
|
const SELECTOR_SORTABLE_HANDLE = `[${ATTRIBUTE_SORTABLE}-handle]`;
|
|
183
233
|
const SELECTOR_SORTABLE_ITEM = `[${ATTRIBUTE_SORTABLE}] > *`;
|
|
184
|
-
const
|
|
234
|
+
const containers = /* @__PURE__ */ new Set([
|
|
185
235
|
"body",
|
|
186
236
|
"document",
|
|
187
237
|
"window"
|
|
188
238
|
]);
|
|
189
|
-
const horizontals = new Set(["horizontal", "x"]);
|
|
239
|
+
const horizontals = /* @__PURE__ */ new Set(["horizontal", "x"]);
|
|
190
240
|
const properties = {
|
|
191
241
|
movable: "sortable",
|
|
192
242
|
sortable: "movable"
|
|
193
243
|
};
|
|
194
|
-
const
|
|
244
|
+
const globals = {
|
|
195
245
|
container: void 0,
|
|
196
246
|
element: void 0,
|
|
197
247
|
instances: /* @__PURE__ */ new WeakMap(),
|
|
198
248
|
offset: void 0,
|
|
199
|
-
original: void 0
|
|
249
|
+
original: void 0,
|
|
250
|
+
states: /* @__PURE__ */ new WeakMap()
|
|
200
251
|
};
|
|
201
|
-
const
|
|
252
|
+
const styles = {
|
|
202
253
|
touchAction: "none",
|
|
203
254
|
userSelect: "none",
|
|
204
255
|
webkitUserSelect: "none"
|
|
205
|
-
}
|
|
206
|
-
const
|
|
256
|
+
};
|
|
257
|
+
const styleToggler = toggleStyles(document.body, styles);
|
|
258
|
+
const verticals = /* @__PURE__ */ new Set(["vertical", "y"]);
|
|
207
259
|
let current;
|
|
208
260
|
on(document, "keydown", onKeydown);
|
|
209
261
|
on(document, "mousedown", onPointerdown);
|
|
@@ -212,4 +264,4 @@ on(document, "pointerup", onPointerup);
|
|
|
212
264
|
on(document, "touchcancel", onPointerup, { passive: false });
|
|
213
265
|
on(document, "touchstart", onPointerdown, { passive: false });
|
|
214
266
|
//#endregion
|
|
215
|
-
export { OuiDraggable, addDraggable, removeDraggable };
|
|
267
|
+
export { OuiDraggable, addDraggable, getDraggableStates, removeDraggable };
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { attributable } from "../internal/attributable.mjs";
|
|
2
|
+
import { OuiDraggable, addDraggable, getDraggableStates, removeDraggable } from "../internal/draggable.mjs";
|
|
3
|
+
import { getPosition, on } from "@oscarpalmer/toretto/event";
|
|
4
|
+
import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
|
|
5
|
+
//#region src/js/movable/movable.embedded.ts
|
|
6
|
+
var OuiMovable = class extends OuiDraggable {
|
|
7
|
+
#element;
|
|
8
|
+
#style;
|
|
9
|
+
constructor(element, options) {
|
|
10
|
+
const style = {
|
|
11
|
+
inset: element.style.inset,
|
|
12
|
+
position: element.style.position
|
|
13
|
+
};
|
|
14
|
+
super("movable", "move", ATTRIBUTE_MOVABLE, element, {
|
|
15
|
+
container: {
|
|
16
|
+
attribute: ATTRIBUTE_CONTAINER,
|
|
17
|
+
map: CONTAINERS,
|
|
18
|
+
onDestroy: destroyContainer,
|
|
19
|
+
onInitialize: initializeContainer
|
|
20
|
+
},
|
|
21
|
+
direction: {
|
|
22
|
+
attribute: ATTRIBUTE_DIRECTION,
|
|
23
|
+
onAfter: afterDirection
|
|
24
|
+
},
|
|
25
|
+
drag: {
|
|
26
|
+
onBegin,
|
|
27
|
+
onCancel,
|
|
28
|
+
onEnd,
|
|
29
|
+
onMove
|
|
30
|
+
},
|
|
31
|
+
input: options,
|
|
32
|
+
position: {
|
|
33
|
+
getOffset: getOffsetPosition,
|
|
34
|
+
getOriginal: getOriginalPosition
|
|
35
|
+
},
|
|
36
|
+
getDragged() {
|
|
37
|
+
return element;
|
|
38
|
+
},
|
|
39
|
+
getOrigin() {
|
|
40
|
+
return element;
|
|
41
|
+
}
|
|
42
|
+
}, {
|
|
43
|
+
style,
|
|
44
|
+
hasHandles: element.querySelector(SELECTOR_HANDLE) != null,
|
|
45
|
+
moved: false
|
|
46
|
+
});
|
|
47
|
+
this.#element = element;
|
|
48
|
+
this.#style = style;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Destroys the _Movable_
|
|
52
|
+
*/
|
|
53
|
+
destroy() {
|
|
54
|
+
MOVED.delete(this);
|
|
55
|
+
this.#element.style.inset = this.#style.inset;
|
|
56
|
+
this.#element.style.position = this.#style.position;
|
|
57
|
+
this.#element = void 0;
|
|
58
|
+
this.#style = void 0;
|
|
59
|
+
super.destroy();
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
function afterDirection(item) {
|
|
63
|
+
const container = item.state.container?.getBoundingClientRect();
|
|
64
|
+
if (container != null) setOffset(item.state, container);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Creates _(or retrieves)_ a _OuiMovable_ instance for an element
|
|
68
|
+
*
|
|
69
|
+
* @param element Element to make movable
|
|
70
|
+
* @returns _OuiMovable_ instance
|
|
71
|
+
*/
|
|
72
|
+
function createMovable(element, options) {
|
|
73
|
+
if (!isHTMLOrSVGElement(element)) throw new TypeError(MESSAGE);
|
|
74
|
+
return addMovable(element, options);
|
|
75
|
+
}
|
|
76
|
+
function destroyContainer(_, container, empty) {
|
|
77
|
+
if (empty) resizer.unobserve(container);
|
|
78
|
+
}
|
|
79
|
+
function getOffsetPosition(globals, _, __, position) {
|
|
80
|
+
return {
|
|
81
|
+
x: position.x - (globals.element?.rectangle.left ?? 0),
|
|
82
|
+
y: position.y - (globals.element?.rectangle.top ?? 0)
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function getOriginalPosition(globals) {
|
|
86
|
+
return {
|
|
87
|
+
x: globals.element?.rectangle.left ?? 0,
|
|
88
|
+
y: globals.element?.rectangle.top ?? 0
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function initializeContainer(item) {
|
|
92
|
+
resizer.observe(item.state.container);
|
|
93
|
+
}
|
|
94
|
+
function onBegin() {}
|
|
95
|
+
function onCancel(globals, item) {
|
|
96
|
+
const { element, moved, style } = item.state;
|
|
97
|
+
const { x, y } = globals.original ?? {
|
|
98
|
+
x: 0,
|
|
99
|
+
y: 0
|
|
100
|
+
};
|
|
101
|
+
if (moved) element.style.inset = `${y}px auto auto ${x}px`;
|
|
102
|
+
else {
|
|
103
|
+
element.style.position = style.position;
|
|
104
|
+
element.style.inset = style.inset;
|
|
105
|
+
}
|
|
106
|
+
element.removeAttribute(ATTRIBUTE_MOVING);
|
|
107
|
+
}
|
|
108
|
+
function onEnd(event, globals, item, reset) {
|
|
109
|
+
const movable = item.instance;
|
|
110
|
+
const state = item.state;
|
|
111
|
+
state.element.removeAttribute(ATTRIBUTE_MOVING);
|
|
112
|
+
if (!state.moved) {
|
|
113
|
+
state.moved = true;
|
|
114
|
+
if (state.container != null) MOVED.add(movable);
|
|
115
|
+
}
|
|
116
|
+
const container = state.container?.getBoundingClientRect();
|
|
117
|
+
if (container != null) setOffset(state, container);
|
|
118
|
+
const end = new CustomEvent(EVENT_END, {
|
|
119
|
+
detail: {
|
|
120
|
+
from: { ...globals.original },
|
|
121
|
+
to: getPosition(event)
|
|
122
|
+
},
|
|
123
|
+
cancelable: true
|
|
124
|
+
});
|
|
125
|
+
state.element.dispatchEvent(end);
|
|
126
|
+
setTimeout(() => {
|
|
127
|
+
if (end.defaultPrevented) onCancel(globals, item);
|
|
128
|
+
reset();
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
function onMove(_, globals, __, position) {
|
|
132
|
+
globals.element?.node.setAttribute(ATTRIBUTE_MOVING, "");
|
|
133
|
+
return {
|
|
134
|
+
from: { ...globals.original },
|
|
135
|
+
to: { ...position.calculated }
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
function onResize(entries) {
|
|
139
|
+
const { length } = entries;
|
|
140
|
+
for (let index = 0; index < length; index += 1) {
|
|
141
|
+
const entry = entries[index];
|
|
142
|
+
const set = CONTAINERS.get(entry.target);
|
|
143
|
+
if (set == null) continue;
|
|
144
|
+
for (const movable of set) reposition(movable);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
function onScroll() {
|
|
148
|
+
for (const moved of MOVED) reposition(moved);
|
|
149
|
+
}
|
|
150
|
+
function reposition(movable) {
|
|
151
|
+
const state = getDraggableStates(movable.element)?.movable;
|
|
152
|
+
if (state == null || !state.moved || state.container == null) return;
|
|
153
|
+
const container = state.container.getBoundingClientRect();
|
|
154
|
+
const x = container.left + (state.offset?.x ?? 0);
|
|
155
|
+
const y = container.top + (state.offset?.y ?? 0);
|
|
156
|
+
state.element.style.inset = `${y}px auto auto ${x}px`;
|
|
157
|
+
}
|
|
158
|
+
function setOffset(state, container) {
|
|
159
|
+
state.offset = {};
|
|
160
|
+
const element = state.element.getBoundingClientRect();
|
|
161
|
+
state.offset.y = element.top - container.top;
|
|
162
|
+
state.offset.x = element.left - container.left;
|
|
163
|
+
}
|
|
164
|
+
const ATTRIBUTE_MOVABLE = "oui-movable";
|
|
165
|
+
const ATTRIBUTE_CONTAINER = `${ATTRIBUTE_MOVABLE}-container`;
|
|
166
|
+
const ATTRIBUTE_DIRECTION = `${ATTRIBUTE_MOVABLE}-direction`;
|
|
167
|
+
const ATTRIBUTE_MOVABLE_HANDLE = `${ATTRIBUTE_MOVABLE}-handle`;
|
|
168
|
+
const ATTRIBUTE_MOVING = `${ATTRIBUTE_MOVABLE}-moving`;
|
|
169
|
+
const CONTAINERS = /* @__PURE__ */ new Map();
|
|
170
|
+
const EVENT_END = "move:end";
|
|
171
|
+
const MESSAGE = "The element must be an instance of HTMLElement or SVGElement";
|
|
172
|
+
const MOVED = /* @__PURE__ */ new Set();
|
|
173
|
+
const SELECTOR_HANDLE = `[${ATTRIBUTE_MOVABLE_HANDLE}]`;
|
|
174
|
+
const bound = {
|
|
175
|
+
constructor: OuiMovable,
|
|
176
|
+
property: "movable"
|
|
177
|
+
};
|
|
178
|
+
const resizer = new ResizeObserver(onResize);
|
|
179
|
+
const addMovable = addDraggable.bind(bound);
|
|
180
|
+
const removeMovable = removeDraggable.bind(bound);
|
|
181
|
+
on(document, "scroll", onScroll);
|
|
182
|
+
attributable(ATTRIBUTE_MOVABLE, addMovable, removeMovable);
|
|
183
|
+
//#endregion
|
|
184
|
+
export { ATTRIBUTE_MOVABLE, ATTRIBUTE_MOVABLE_HANDLE, OuiMovable, createMovable };
|
package/dist/js/popover.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { i as OuiFocusTrap } from "./embedded-
|
|
1
|
+
import { i as OuiFloatable } from "./floatable.embedded-YxGwzgbE.mjs";
|
|
2
|
+
import { i as OuiFocusTrap } from "./focus-trap.embedded-DR8NpZfr.mjs";
|
|
3
3
|
import { RemovableEventListener } from "@oscarpalmer/toretto/models";
|
|
4
4
|
|
|
5
5
|
//#region src/js/popover.d.ts
|
package/dist/js/popover.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { createEmbeddedFloatable, getOnBeforeToggleListener } from "./floatable/embedded.mjs";
|
|
1
|
+
import { createEmbeddedFloatable, getOnBeforeToggleListener } from "./floatable/floatable.embedded.mjs";
|
|
2
2
|
import { attributable } from "./internal/attributable.mjs";
|
|
3
|
-
import { createFocusTrap } from "./focus-trap/embedded.mjs";
|
|
3
|
+
import { createFocusTrap } from "./focus-trap/focus-trap.embedded.mjs";
|
|
4
4
|
import { on } from "@oscarpalmer/toretto/event";
|
|
5
5
|
import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
|
|
6
6
|
//#region src/js/popover.ts
|
|
@@ -97,7 +97,8 @@ const STATE_OPEN = "open";
|
|
|
97
97
|
const TRUE = "true";
|
|
98
98
|
const options = {
|
|
99
99
|
attribute: `${ATTRIBUTE}position`,
|
|
100
|
-
position: "below-start"
|
|
100
|
+
position: "below-start",
|
|
101
|
+
reusable: false
|
|
101
102
|
};
|
|
102
103
|
const states = /* @__PURE__ */ new WeakMap();
|
|
103
104
|
let ignoreFocus = false;
|