@oscarpalmer/oui 0.27.0 → 0.29.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 +9 -0
- package/dist/js/dialog.d.mts +3 -1
- package/dist/js/dialog.mjs +35 -19
- package/dist/js/{draggable-zszaW1qS.d.mts → draggable-fIYXd8eO.d.mts} +3 -3
- package/dist/js/floatable/floatable.embedded.d.mts +2 -2
- package/dist/js/floatable/floatable.embedded.mjs +17 -16
- package/dist/js/floatable/floatable.standalone.d.mts +1 -1
- package/dist/js/{floatable.embedded-YxGwzgbE.d.mts → floatable.embedded-DUR8bQBK.d.mts} +1 -2
- package/dist/js/focus-trap/focus-trap.embedded.mjs +6 -5
- package/dist/js/index.d.mts +4 -3
- package/dist/js/index.mjs +6 -2
- package/dist/js/internal/attributable.mjs +3 -4
- package/dist/js/internal/draggable.d.mts +1 -1
- package/dist/js/internal/draggable.mjs +12 -9
- package/dist/js/internal/navigable.d.mts +32 -0
- package/dist/js/internal/navigable.mjs +107 -0
- package/dist/js/menu.d.mts +1 -0
- package/dist/js/menu.mjs +168 -0
- package/dist/js/movable/movable.embedded.d.mts +1 -1
- package/dist/js/movable/movable.embedded.mjs +8 -13
- package/dist/js/movable/movable.standalone.d.mts +1 -1
- package/dist/js/popover.d.mts +1 -1
- package/dist/js/popover.mjs +27 -12
- package/dist/js/resizable/resizable.embedded.d.mts +2 -0
- package/dist/js/resizable/resizable.embedded.mjs +191 -0
- package/dist/js/resizable/resizable.standalone.d.mts +2 -0
- package/dist/js/resizable/resizable.standalone.mjs +2 -0
- package/dist/js/resizable.embedded-CXrUVPzR.d.mts +35 -0
- package/dist/js/sortable/sortable.embedded.d.mts +1 -1
- package/dist/js/sortable/sortable.embedded.mjs +15 -13
- package/dist/js/sortable/sortable.standalone.d.mts +1 -1
- package/dist/js/splitter.mjs +30 -26
- package/dist/js/toolbar.mjs +12 -88
- package/dist/js/tooltip.d.mts +1 -1
- package/dist/js/tooltip.mjs +12 -17
- package/package.json +11 -3
- package/src/css/floatable.scss +9 -0
- package/src/css/form.scss +6 -6
- package/src/js/dialog.ts +50 -24
- package/src/js/floatable/floatable.embedded.ts +19 -18
- package/src/js/focus-trap/focus-trap.embedded.ts +6 -5
- package/src/js/index.ts +3 -1
- package/src/js/internal/attributable.ts +3 -5
- package/src/js/internal/draggable.ts +13 -10
- package/src/js/internal/navigable.ts +247 -0
- package/src/js/menu.ts +345 -0
- package/src/js/movable/movable.embedded.ts +10 -13
- package/src/js/popover.ts +41 -15
- package/src/js/resizable/resizable.embedded.ts +390 -0
- package/src/js/resizable/resizable.standalone.ts +5 -0
- package/src/js/sortable/sortable.embedded.ts +17 -22
- package/src/js/splitter.ts +41 -36
- package/src/js/toolbar.ts +27 -178
- package/src/js/tooltip.ts +18 -30
package/dist/js/menu.mjs
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { createEmbeddedFloatable, getOnBeforeToggleListener } from "./floatable/floatable.embedded.mjs";
|
|
2
|
+
import { attributable } from "./internal/attributable.mjs";
|
|
3
|
+
import { NAVIGABLE_KEYS_HORIZONTAL, NAVIGABLE_KEYS_VERTICAL, getNavigable, updateNavigableFocus } from "./internal/navigable.mjs";
|
|
4
|
+
import { setAria, setRole } from "@oscarpalmer/toretto/aria";
|
|
5
|
+
import { on } from "@oscarpalmer/toretto/event";
|
|
6
|
+
import { setAttribute } from "@oscarpalmer/toretto/attribute";
|
|
7
|
+
import { findAncestor } from "@oscarpalmer/toretto/find";
|
|
8
|
+
//#region src/js/menu.ts
|
|
9
|
+
var OuiMenu = class {
|
|
10
|
+
content;
|
|
11
|
+
element;
|
|
12
|
+
floatable;
|
|
13
|
+
navigable;
|
|
14
|
+
toggle;
|
|
15
|
+
get open() {
|
|
16
|
+
return this.floatable.open;
|
|
17
|
+
}
|
|
18
|
+
constructor(element, navigable) {
|
|
19
|
+
this.element = element;
|
|
20
|
+
this.navigable = navigable;
|
|
21
|
+
this.content = navigable.element;
|
|
22
|
+
this.toggle = element.querySelector(SELECTOR_MENU_TOGGLE);
|
|
23
|
+
this.floatable = createEmbeddedFloatable(this.toggle, this.content, {
|
|
24
|
+
attribute: ATTRIBUTE_MENU_POSITION,
|
|
25
|
+
position: findAncestor(element.parentElement, SELECTOR_MENU_CONTENT) == null ? "below-start" : "end-top",
|
|
26
|
+
reusable: false
|
|
27
|
+
});
|
|
28
|
+
this.navigable.listeners.push(getOnBeforeToggleListener(this.content), on(this.content, "click", (event) => {
|
|
29
|
+
event.stopPropagation();
|
|
30
|
+
if (findAncestor(event, SELECTOR_MENU_TOGGLE) != null) return;
|
|
31
|
+
const elements = document.querySelectorAll(SELECTOR_MENU_CONTENT);
|
|
32
|
+
for (const element of elements) menus.get(element)?.floatable.hide();
|
|
33
|
+
const menu = menus.get(elements[0]);
|
|
34
|
+
if (menu != null && event.pointerId === -1) updateNavigableFocus(menu.navigable, true);
|
|
35
|
+
}), on(this.content, "toggle", (event) => {
|
|
36
|
+
const expanded = event.newState === "open";
|
|
37
|
+
if (expanded) {
|
|
38
|
+
this.floatable?.update();
|
|
39
|
+
updateNavigableFocus(this.navigable, true);
|
|
40
|
+
}
|
|
41
|
+
setAria(this.toggle, "expanded", expanded);
|
|
42
|
+
}));
|
|
43
|
+
this.floatable.update();
|
|
44
|
+
initializeMenu(this);
|
|
45
|
+
updateNavigableFocus(this.navigable, false);
|
|
46
|
+
}
|
|
47
|
+
destroy() {
|
|
48
|
+
this.floatable.destroy();
|
|
49
|
+
this.navigable.destroy();
|
|
50
|
+
this.floatable = void 0;
|
|
51
|
+
this.navigable = void 0;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
var OuiMenubar = class {
|
|
55
|
+
element;
|
|
56
|
+
navigable;
|
|
57
|
+
constructor(element, navigable) {
|
|
58
|
+
this.element = element;
|
|
59
|
+
this.navigable = navigable;
|
|
60
|
+
updateNavigableFocus(this.navigable, false);
|
|
61
|
+
}
|
|
62
|
+
destroy() {
|
|
63
|
+
this.navigable.destroy();
|
|
64
|
+
this.navigable = void 0;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
function addInstance(instances, ctor, element, content, options) {
|
|
68
|
+
if (!instances.has(content)) instances.set(content, new ctor(element, getNavigable(content, {
|
|
69
|
+
...options,
|
|
70
|
+
onDeactivate,
|
|
71
|
+
onPreventNavigation,
|
|
72
|
+
onShouldActivate,
|
|
73
|
+
onShouldDeactivate
|
|
74
|
+
})));
|
|
75
|
+
}
|
|
76
|
+
function addMenu(element) {
|
|
77
|
+
const content = element.querySelector(SELECTOR_MENU_CONTENT);
|
|
78
|
+
const toggle = element.querySelector(SELECTOR_MENU_TOGGLE);
|
|
79
|
+
if (content != null && toggle != null) addInstance(menus, OuiMenu, element, content, {
|
|
80
|
+
selector: SELECTOR_MENU_ITEM,
|
|
81
|
+
vertical: true
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
function addMenubar(element) {
|
|
85
|
+
addInstance(menubars, OuiMenubar, element, element, {
|
|
86
|
+
role: "menubar",
|
|
87
|
+
selector: SELECTOR_MENUBAR_ITEM,
|
|
88
|
+
vertical: false
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
function getId(element, value) {
|
|
92
|
+
let { id } = element;
|
|
93
|
+
if (id == null || id.trim().length === 0) {
|
|
94
|
+
id = value == null ? `oui_menu_${++index}` : `${value}_toggle`;
|
|
95
|
+
element.id = id;
|
|
96
|
+
}
|
|
97
|
+
return id;
|
|
98
|
+
}
|
|
99
|
+
function initializeMenu(menu) {
|
|
100
|
+
const id = getId(menu.content);
|
|
101
|
+
setAttribute(menu.toggle, "popovertarget", id);
|
|
102
|
+
setAria(menu.toggle, {
|
|
103
|
+
controls: id,
|
|
104
|
+
expanded: "false",
|
|
105
|
+
haspopup: "menu"
|
|
106
|
+
});
|
|
107
|
+
setAttribute(menu.content, "tabindex", "-1");
|
|
108
|
+
setRole(menu.content, "menu");
|
|
109
|
+
}
|
|
110
|
+
function onDeactivate(_, navigable) {
|
|
111
|
+
const menu = menus.get(navigable.element);
|
|
112
|
+
if (menu == null) return;
|
|
113
|
+
menu.floatable.hide();
|
|
114
|
+
const element = findAncestor(menu.element.parentElement, SELECTORS);
|
|
115
|
+
if (element == null) return;
|
|
116
|
+
const instance = menubars.get(element) ?? menus.get(element);
|
|
117
|
+
if (instance != null) updateNavigableFocus(instance.navigable, true);
|
|
118
|
+
}
|
|
119
|
+
function onPreventNavigation(_, navigable) {
|
|
120
|
+
return findAncestor((menubars.get(navigable.element) ?? menus.get(navigable.element))?.element.parentElement, SELECTORS) != null;
|
|
121
|
+
}
|
|
122
|
+
function onShouldActivate(event, navigable) {
|
|
123
|
+
let activate = false;
|
|
124
|
+
if (menubars.has(navigable.element)) activate = navigable.orientation === "horizontal" ? NAVIGABLE_KEYS_VERTICAL.has(event.key) : NAVIGABLE_KEYS_HORIZONTAL.has(event.key);
|
|
125
|
+
else if (menus.has(navigable.element)) activate = navigable.orientation === "horizontal" ? NAVIGABLE_KEYS_VERTICAL.has(event.key) : event.key === "ArrowRight";
|
|
126
|
+
if (activate) {
|
|
127
|
+
const target = event.target instanceof HTMLElement && event.target.matches(SELECTOR_MENU_TOGGLE) ? event.target : void 0;
|
|
128
|
+
if (target == null) activate = false;
|
|
129
|
+
else target.click();
|
|
130
|
+
}
|
|
131
|
+
return activate;
|
|
132
|
+
}
|
|
133
|
+
function onShouldDeactivate(event, navigable) {
|
|
134
|
+
if (menubars.has(navigable.element)) return;
|
|
135
|
+
const menu = menus.get(navigable.element);
|
|
136
|
+
if (menu == null) return;
|
|
137
|
+
const horizontal = navigable.orientation === "horizontal";
|
|
138
|
+
const altKey = horizontal ? "ArrowDown" : "ArrowRight";
|
|
139
|
+
const baseKey = horizontal ? "ArrowUp" : "ArrowLeft";
|
|
140
|
+
if (event.key === baseKey) return findAncestor(menu.element.parentElement, SELECTOR_MENU_CONTENT) != null;
|
|
141
|
+
if (event.key === altKey && event.target instanceof HTMLElement && !event.target.hasAttribute("popovertarget")) return false;
|
|
142
|
+
}
|
|
143
|
+
function removeInstance(instances, element) {
|
|
144
|
+
instances.get(element)?.destroy();
|
|
145
|
+
instances.delete(element);
|
|
146
|
+
}
|
|
147
|
+
function removeMenu(element) {
|
|
148
|
+
removeInstance(menus, element);
|
|
149
|
+
}
|
|
150
|
+
function removeMenubar(element) {
|
|
151
|
+
removeInstance(menubars, element);
|
|
152
|
+
}
|
|
153
|
+
const ATTRIBUTE_MENU = "oui-menu";
|
|
154
|
+
const ATTRIBUTE_MENU_POSITION = "oui-menu-position";
|
|
155
|
+
const ATTRIBUTE_MENUBAR = "oui-menubar";
|
|
156
|
+
const SELECTOR_MENUBAR = `[${ATTRIBUTE_MENUBAR}]`;
|
|
157
|
+
const SELECTOR_MENUBAR_ITEM = `:scope > [${ATTRIBUTE_MENUBAR}-item], :scope > * > [${ATTRIBUTE_MENUBAR}-item]`;
|
|
158
|
+
const SELECTOR_MENU_CONTENT = `[${ATTRIBUTE_MENU}-content]`;
|
|
159
|
+
const SELECTOR_MENU_ITEM = `:scope > [${ATTRIBUTE_MENU}-item], :scope > * > [${ATTRIBUTE_MENU}-item]`;
|
|
160
|
+
const SELECTOR_MENU_TOGGLE = `[${ATTRIBUTE_MENU}-toggle]`;
|
|
161
|
+
const SELECTORS = `${SELECTOR_MENUBAR}, ${SELECTOR_MENU_CONTENT}`;
|
|
162
|
+
const menubars = /* @__PURE__ */ new WeakMap();
|
|
163
|
+
const menus = /* @__PURE__ */ new WeakMap();
|
|
164
|
+
let index = 0;
|
|
165
|
+
attributable(ATTRIBUTE_MENU, addMenu, removeMenu);
|
|
166
|
+
attributable(ATTRIBUTE_MENUBAR, addMenubar, removeMenubar);
|
|
167
|
+
//#endregion
|
|
168
|
+
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { g as createMovable, h as OuiMovable, m as ATTRIBUTE_MOVABLE_HANDLE, p as ATTRIBUTE_MOVABLE } from "../draggable-
|
|
1
|
+
import { g as createMovable, h as OuiMovable, m as ATTRIBUTE_MOVABLE_HANDLE, p as ATTRIBUTE_MOVABLE } from "../draggable-fIYXd8eO.mjs";
|
|
2
2
|
export { ATTRIBUTE_MOVABLE, ATTRIBUTE_MOVABLE_HANDLE, OuiMovable, createMovable };
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import { attributable } from "../internal/attributable.mjs";
|
|
2
2
|
import { OuiDraggable, addDraggable, getDraggableStates, removeDraggable } from "../internal/draggable.mjs";
|
|
3
3
|
import { getPosition, on } from "@oscarpalmer/toretto/event";
|
|
4
|
+
import { setAttribute } from "@oscarpalmer/toretto/attribute";
|
|
4
5
|
import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
|
|
6
|
+
import { getStyles, setStyle, setStyles } from "@oscarpalmer/toretto/style";
|
|
5
7
|
//#region src/js/movable/movable.embedded.ts
|
|
6
8
|
var OuiMovable = class extends OuiDraggable {
|
|
7
9
|
#element;
|
|
8
10
|
#style;
|
|
9
11
|
constructor(element, options) {
|
|
10
|
-
const style =
|
|
11
|
-
inset: element.style.inset,
|
|
12
|
-
position: element.style.position
|
|
13
|
-
};
|
|
12
|
+
const style = getStyles(element, ["inset", "position"]);
|
|
14
13
|
super("movable", "move", ATTRIBUTE_MOVABLE, element, {
|
|
15
14
|
container: {
|
|
16
15
|
attribute: ATTRIBUTE_CONTAINER,
|
|
@@ -52,8 +51,7 @@ var OuiMovable = class extends OuiDraggable {
|
|
|
52
51
|
*/
|
|
53
52
|
destroy() {
|
|
54
53
|
MOVED.delete(this);
|
|
55
|
-
this.#element
|
|
56
|
-
this.#element.style.position = this.#style.position;
|
|
54
|
+
setStyles(this.#element, this.#style);
|
|
57
55
|
this.#element = void 0;
|
|
58
56
|
this.#style = void 0;
|
|
59
57
|
super.destroy();
|
|
@@ -98,11 +96,8 @@ function onCancel(globals, item) {
|
|
|
98
96
|
x: 0,
|
|
99
97
|
y: 0
|
|
100
98
|
};
|
|
101
|
-
if (moved) element
|
|
102
|
-
else
|
|
103
|
-
element.style.position = style.position;
|
|
104
|
-
element.style.inset = style.inset;
|
|
105
|
-
}
|
|
99
|
+
if (moved) setStyle(element, "inset", `${y}px auto auto ${x}px`);
|
|
100
|
+
else setStyles(element, style);
|
|
106
101
|
element.removeAttribute(ATTRIBUTE_MOVING);
|
|
107
102
|
}
|
|
108
103
|
function onEnd(event, globals, item, reset) {
|
|
@@ -129,7 +124,7 @@ function onEnd(event, globals, item, reset) {
|
|
|
129
124
|
});
|
|
130
125
|
}
|
|
131
126
|
function onMove(_, globals, __, position) {
|
|
132
|
-
globals.element?.node
|
|
127
|
+
setAttribute(globals.element?.node, ATTRIBUTE_MOVING, "");
|
|
133
128
|
return {
|
|
134
129
|
from: { ...globals.original },
|
|
135
130
|
to: { ...position.calculated }
|
|
@@ -153,7 +148,7 @@ function reposition(movable) {
|
|
|
153
148
|
const container = state.container.getBoundingClientRect();
|
|
154
149
|
const x = container.left + (state.offset?.x ?? 0);
|
|
155
150
|
const y = container.top + (state.offset?.y ?? 0);
|
|
156
|
-
state.element
|
|
151
|
+
setStyle(state.element, "inset", `${y}px auto auto ${x}px`);
|
|
157
152
|
}
|
|
158
153
|
function setOffset(state, container) {
|
|
159
154
|
state.offset = {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { g as createMovable, h as OuiMovable, t as CreateOuiDraggableOptions } from "../draggable-
|
|
1
|
+
import { g as createMovable, h as OuiMovable, t as CreateOuiDraggableOptions } from "../draggable-fIYXd8eO.mjs";
|
|
2
2
|
export { type CreateOuiDraggableOptions as CreateOuiMovableOptions, type OuiMovable, createMovable };
|
package/dist/js/popover.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { r as OuiFloatable } from "./floatable.embedded-DUR8bQBK.mjs";
|
|
2
2
|
import { i as OuiFocusTrap } from "./focus-trap.embedded-DR8NpZfr.mjs";
|
|
3
3
|
import { RemovableEventListener } from "@oscarpalmer/toretto/models";
|
|
4
4
|
|
package/dist/js/popover.mjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { createEmbeddedFloatable, getOnBeforeToggleListener } from "./floatable/floatable.embedded.mjs";
|
|
2
2
|
import { attributable } from "./internal/attributable.mjs";
|
|
3
3
|
import { createFocusTrap } from "./focus-trap/focus-trap.embedded.mjs";
|
|
4
|
+
import { getAria, setAria } from "@oscarpalmer/toretto/aria";
|
|
4
5
|
import { on } from "@oscarpalmer/toretto/event";
|
|
6
|
+
import { setAttribute } from "@oscarpalmer/toretto/attribute";
|
|
5
7
|
import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
|
|
6
8
|
//#region src/js/popover.ts
|
|
7
9
|
var OuiPopover = class {
|
|
@@ -18,6 +20,7 @@ var OuiPopover = class {
|
|
|
18
20
|
}
|
|
19
21
|
constructor(state) {
|
|
20
22
|
this.#state = state;
|
|
23
|
+
initialize(state);
|
|
21
24
|
this.#state.floatable.update();
|
|
22
25
|
}
|
|
23
26
|
/**
|
|
@@ -49,6 +52,14 @@ function destroyPopover(state) {
|
|
|
49
52
|
state.listeners = void 0;
|
|
50
53
|
state.popover = void 0;
|
|
51
54
|
}
|
|
55
|
+
function getId(element, value) {
|
|
56
|
+
let { id } = element;
|
|
57
|
+
if (id == null || id.trim().length === 0) {
|
|
58
|
+
id = value == null ? `oui_popover_${++index}` : `${value}_toggle`;
|
|
59
|
+
element.id = id;
|
|
60
|
+
}
|
|
61
|
+
return id;
|
|
62
|
+
}
|
|
52
63
|
/**
|
|
53
64
|
* Get the _OuiPopover_ for an element
|
|
54
65
|
*
|
|
@@ -63,23 +74,30 @@ function getState(anchor, content) {
|
|
|
63
74
|
anchor,
|
|
64
75
|
content,
|
|
65
76
|
floatable: createEmbeddedFloatable(anchor, content, options),
|
|
66
|
-
focusTrap: content
|
|
67
|
-
listeners: [getOnBeforeToggleListener(content), on(content,
|
|
68
|
-
|
|
77
|
+
focusTrap: getAria(content, "modal") === "true" ? createFocusTrap(content, { noescape: true }) : void 0,
|
|
78
|
+
listeners: [getOnBeforeToggleListener(content), on(content, "toggle", (event) => {
|
|
79
|
+
const expanded = event.newState === "open";
|
|
80
|
+
if (expanded) {
|
|
69
81
|
ignoreFocus = false;
|
|
70
82
|
state.floatable?.update();
|
|
71
|
-
content.setAttribute(ATTRIBUTE_OPEN, "");
|
|
72
83
|
content.focus();
|
|
73
|
-
} else
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
84
|
+
} else if (!ignoreFocus) anchor?.focus();
|
|
85
|
+
setAria(anchor, "expanded", expanded);
|
|
86
|
+
setAttribute(content, ATTRIBUTE_OPEN, expanded ? "" : void 0);
|
|
77
87
|
})],
|
|
78
88
|
popover: void 0
|
|
79
89
|
};
|
|
80
90
|
state.popover = new OuiPopover(state);
|
|
81
91
|
return state;
|
|
82
92
|
}
|
|
93
|
+
function initialize(state) {
|
|
94
|
+
const id = getId(state.content);
|
|
95
|
+
setAria(state.anchor, {
|
|
96
|
+
controls: id,
|
|
97
|
+
expanded: "false"
|
|
98
|
+
});
|
|
99
|
+
if ((getAria(state.content, "label") ?? getAria(state.content, "labelledby")) == null) setAria(state.content, "labelledby", getId(state.anchor, id));
|
|
100
|
+
}
|
|
83
101
|
function onPointerdown() {
|
|
84
102
|
ignoreFocus = true;
|
|
85
103
|
}
|
|
@@ -90,11 +108,7 @@ function removePopover(element) {
|
|
|
90
108
|
states.delete(element);
|
|
91
109
|
}
|
|
92
110
|
const ATTRIBUTE = "oui-popover";
|
|
93
|
-
const ARIA_MODAL = "aria-modal";
|
|
94
111
|
const ATTRIBUTE_OPEN = `${ATTRIBUTE}-open`;
|
|
95
|
-
const EVENT_TOGGLE = "toggle";
|
|
96
|
-
const STATE_OPEN = "open";
|
|
97
|
-
const TRUE = "true";
|
|
98
112
|
const options = {
|
|
99
113
|
attribute: `${ATTRIBUTE}position`,
|
|
100
114
|
position: "below-start",
|
|
@@ -102,6 +116,7 @@ const options = {
|
|
|
102
116
|
};
|
|
103
117
|
const states = /* @__PURE__ */ new WeakMap();
|
|
104
118
|
let ignoreFocus = false;
|
|
119
|
+
let index = 0;
|
|
105
120
|
on(document, "pointerdown", onPointerdown, { capture: true });
|
|
106
121
|
attributable(ATTRIBUTE, addPopover, removePopover);
|
|
107
122
|
//#endregion
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as createResizable, i as RESIZABLE_ATTRIBUTE_HANDLE, n as OuiResizable, r as RESIZABLE_ATTRIBUTE, t as CreateOuiResizableOptions } from "../resizable.embedded-CXrUVPzR.mjs";
|
|
2
|
+
export { CreateOuiResizableOptions, OuiResizable, RESIZABLE_ATTRIBUTE, RESIZABLE_ATTRIBUTE_HANDLE, createResizable };
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { attributable } from "../internal/attributable.mjs";
|
|
2
|
+
import { getPosition, on } from "@oscarpalmer/toretto/event";
|
|
3
|
+
import { isPlainObject } from "@oscarpalmer/atoms/is";
|
|
4
|
+
import { getAttribute, setAttribute } from "@oscarpalmer/toretto/attribute";
|
|
5
|
+
import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
|
|
6
|
+
import { setStyles, toggleStyles } from "@oscarpalmer/toretto/style";
|
|
7
|
+
import { getNumber } from "@oscarpalmer/atoms/number";
|
|
8
|
+
import { findAncestor } from "@oscarpalmer/toretto/find";
|
|
9
|
+
import supportsTouch from "@oscarpalmer/toretto/touch";
|
|
10
|
+
//#region src/js/resizable/resizable.embedded.ts
|
|
11
|
+
var OuiResizable = class {
|
|
12
|
+
#state;
|
|
13
|
+
constructor(state) {
|
|
14
|
+
this.#state = state;
|
|
15
|
+
}
|
|
16
|
+
destroy() {
|
|
17
|
+
destroyResizable(this.#state);
|
|
18
|
+
}
|
|
19
|
+
set() {
|
|
20
|
+
const [width, height] = getAndSetDimensions(this.#state.element, this.#state.options);
|
|
21
|
+
console.log("set", width, height);
|
|
22
|
+
this.#state.width = width;
|
|
23
|
+
this.#state.height = height;
|
|
24
|
+
}
|
|
25
|
+
reset() {
|
|
26
|
+
setStyles(this.#state.element, {
|
|
27
|
+
height: "",
|
|
28
|
+
width: ""
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
function addResizable(element, options) {
|
|
33
|
+
let item = items.get(element);
|
|
34
|
+
if (item == null) {
|
|
35
|
+
const handle = element.querySelector(SELECTOR_HANDLE_SCOPED);
|
|
36
|
+
if (!isHTMLOrSVGElement(handle)) return;
|
|
37
|
+
const state = getState(element, handle, options);
|
|
38
|
+
item = {
|
|
39
|
+
instance: new OuiResizable(state),
|
|
40
|
+
state
|
|
41
|
+
};
|
|
42
|
+
items.set(element, item);
|
|
43
|
+
}
|
|
44
|
+
return item?.instance;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Creates _(or retrieves)_ a _OuiResizable_ instance for an element
|
|
48
|
+
*
|
|
49
|
+
* @param element Element to make resizable
|
|
50
|
+
* @returns _OuiResizable_ instance
|
|
51
|
+
*/
|
|
52
|
+
function createResizable(element, options) {
|
|
53
|
+
if (!isHTMLOrSVGElement(element)) throw new TypeError(MESSAGE_ELEMENT);
|
|
54
|
+
if (!isHTMLOrSVGElement(element.querySelector(SELECTOR_HANDLE_SCOPED))) throw new Error(MESSAGE_HANDLE);
|
|
55
|
+
return addResizable(element, options ?? {});
|
|
56
|
+
}
|
|
57
|
+
function destroyResizable(state) {
|
|
58
|
+
state.element = void 0;
|
|
59
|
+
state.handle = void 0;
|
|
60
|
+
}
|
|
61
|
+
function getAndSetDimensions(element, options, input) {
|
|
62
|
+
let { height, width } = input ?? element.getBoundingClientRect();
|
|
63
|
+
if (options.maximumWidth > -1 && width > options.maximumWidth) width = options.maximumWidth;
|
|
64
|
+
else if (options.minimumWidth > -1 && width < options.minimumWidth) width = options.minimumWidth;
|
|
65
|
+
if (options.maximumHeight > -1 && height > options.maximumHeight) height = options.maximumHeight;
|
|
66
|
+
else if (options.minimumHeight > -1 && height < options.minimumHeight) height = options.minimumHeight;
|
|
67
|
+
if (element.checkVisibility()) setStyles(element, {
|
|
68
|
+
height: `${height}px`,
|
|
69
|
+
width: `${width}px`
|
|
70
|
+
});
|
|
71
|
+
return [width, height];
|
|
72
|
+
}
|
|
73
|
+
function getProperties(element, widthProperty, heightProperty) {
|
|
74
|
+
const computed = getComputedStyle(element);
|
|
75
|
+
return [computed[widthProperty], computed[heightProperty]];
|
|
76
|
+
}
|
|
77
|
+
function getRestrictions(maximum, minimum) {
|
|
78
|
+
const [maximumWidth, maximumHeight] = getXAndY.apply(null, typeof maximum === "string" ? [maximum] : maximum);
|
|
79
|
+
const [minimumWidth, minimumHeight] = getXAndY.apply(null, typeof minimum === "string" ? [minimum] : minimum);
|
|
80
|
+
if (maximumWidth > -1 && minimumWidth > -1 && maximumWidth <= minimumWidth) throw new Error(MESSAGE_WIDTH);
|
|
81
|
+
if (maximumHeight > -1 && minimumHeight > -1 && maximumHeight <= minimumHeight) throw new Error(MESSAGE_HEIGHT);
|
|
82
|
+
return {
|
|
83
|
+
maximumHeight,
|
|
84
|
+
maximumWidth,
|
|
85
|
+
minimumHeight,
|
|
86
|
+
minimumWidth
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function getState(element, handle, input) {
|
|
90
|
+
setAttribute(element, RESIZABLE_ATTRIBUTE, "");
|
|
91
|
+
const options = getValidOptions(element, input);
|
|
92
|
+
const [width, height] = getAndSetDimensions(element, options);
|
|
93
|
+
return {
|
|
94
|
+
element,
|
|
95
|
+
handle,
|
|
96
|
+
height,
|
|
97
|
+
options,
|
|
98
|
+
width,
|
|
99
|
+
styles: toggleStyles(element, styles)
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function getValidOptions(element, input) {
|
|
103
|
+
const original = isPlainObject(input) ? input : {};
|
|
104
|
+
return { ...getRestrictions(input == null ? getAttribute(element, ATTRIBUTE_MAXIMUM) ?? getProperties(element, "maxWidth", "maxHeight") : [original.maximumWidth, original.maximumHeight], input == null ? getAttribute(element, ATTRIBUTE_MINIMUM) ?? getProperties(element, "minWidth", "minHeight") : [original.minimumWidth, original.minimumHeight]) };
|
|
105
|
+
}
|
|
106
|
+
function getXAndY(first, second) {
|
|
107
|
+
const [x, y] = typeof first === "string" && second == null ? first.split(",") : [first, second];
|
|
108
|
+
let xAsNumber = typeof x === "string" ? Number.parseFloat(x) : getNumber(x);
|
|
109
|
+
let yAsNumber = typeof y === "string" ? Number.parseFloat(y) : getNumber(y);
|
|
110
|
+
if (Number.isNaN(xAsNumber) || xAsNumber <= 0) xAsNumber = -1;
|
|
111
|
+
if (Number.isNaN(yAsNumber) || yAsNumber <= 0) yAsNumber = -1;
|
|
112
|
+
return [xAsNumber, yAsNumber];
|
|
113
|
+
}
|
|
114
|
+
function onKeydown(event) {
|
|
115
|
+
if (current == null || event.key !== "Escape") return;
|
|
116
|
+
setStyles(current.state.element, {
|
|
117
|
+
height: `${current.state.height}px`,
|
|
118
|
+
width: `${current.state.width}px`
|
|
119
|
+
});
|
|
120
|
+
resetResizable();
|
|
121
|
+
}
|
|
122
|
+
function onPointerdown(event) {
|
|
123
|
+
if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey || (supportsTouch.value ? event.type === "mousedown" : event.type === "touchstart" || event.button !== 0)) return;
|
|
124
|
+
const handle = findAncestor(event, SELECTOR_HANDLE);
|
|
125
|
+
const element = handle && findAncestor(handle, SELECTOR);
|
|
126
|
+
const stored = element && items.get(element);
|
|
127
|
+
const position = getPosition(event);
|
|
128
|
+
if (stored == null || position == null) return;
|
|
129
|
+
if (supportsTouch.value) event.preventDefault();
|
|
130
|
+
current = stored;
|
|
131
|
+
start = position;
|
|
132
|
+
current.state.styles.set();
|
|
133
|
+
styleToggler.set();
|
|
134
|
+
}
|
|
135
|
+
function onPointermove(event) {
|
|
136
|
+
if (current == null) return;
|
|
137
|
+
const { x, y } = getPosition(event) ?? {};
|
|
138
|
+
if (x == null || y == null) return;
|
|
139
|
+
const width = current.state.width + (x - (start?.x ?? 0));
|
|
140
|
+
const height = current.state.height + (y - (start?.y ?? 0));
|
|
141
|
+
getAndSetDimensions(current.state.element, current.state.options, {
|
|
142
|
+
height,
|
|
143
|
+
width
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
function onPointerup() {
|
|
147
|
+
if (current == null) return;
|
|
148
|
+
const { height, width } = current.state.element.getBoundingClientRect();
|
|
149
|
+
current.state.height = height;
|
|
150
|
+
current.state.width = width;
|
|
151
|
+
resetResizable();
|
|
152
|
+
}
|
|
153
|
+
function removeResizable(element) {
|
|
154
|
+
items.get(element)?.instance.destroy();
|
|
155
|
+
items.delete(element);
|
|
156
|
+
}
|
|
157
|
+
function resetResizable() {
|
|
158
|
+
current?.state.styles.remove();
|
|
159
|
+
styleToggler.remove();
|
|
160
|
+
current = void 0;
|
|
161
|
+
start = void 0;
|
|
162
|
+
}
|
|
163
|
+
const RESIZABLE_ATTRIBUTE = "oui-resizable";
|
|
164
|
+
const RESIZABLE_ATTRIBUTE_HANDLE = `${RESIZABLE_ATTRIBUTE}-handle`;
|
|
165
|
+
const ATTRIBUTE_MAXIMUM = `${RESIZABLE_ATTRIBUTE}-maximum`;
|
|
166
|
+
const ATTRIBUTE_MINIMUM = `${RESIZABLE_ATTRIBUTE}-minimum`;
|
|
167
|
+
const MESSAGE_ELEMENT = "The element must be an instance of HTMLElement or SVGElement";
|
|
168
|
+
const MESSAGE_HEIGHT = "The maximum height must be greater than the minimum height";
|
|
169
|
+
const MESSAGE_HANDLE = `The element must contain a child with the attribute "${RESIZABLE_ATTRIBUTE_HANDLE}"`;
|
|
170
|
+
const MESSAGE_WIDTH = "The maximum width must be greater than the minimum width";
|
|
171
|
+
const SELECTOR = `[${RESIZABLE_ATTRIBUTE}]`;
|
|
172
|
+
const SELECTOR_HANDLE = `[${RESIZABLE_ATTRIBUTE_HANDLE}]`;
|
|
173
|
+
const SELECTOR_HANDLE_SCOPED = `:scope > ${SELECTOR_HANDLE}`;
|
|
174
|
+
const items = /* @__PURE__ */ new WeakMap();
|
|
175
|
+
const styles = {
|
|
176
|
+
touchAction: "none",
|
|
177
|
+
userSelect: "none",
|
|
178
|
+
webkitUserSelect: "none"
|
|
179
|
+
};
|
|
180
|
+
const styleToggler = toggleStyles(document.body, styles);
|
|
181
|
+
let current;
|
|
182
|
+
let start;
|
|
183
|
+
on(document, "keydown", onKeydown);
|
|
184
|
+
on(document, "mousedown", onPointerdown);
|
|
185
|
+
on(document, "pointermove", onPointermove);
|
|
186
|
+
on(document, "pointerup", onPointerup);
|
|
187
|
+
on(document, "touchcancel", onPointerup);
|
|
188
|
+
on(document, "touchstart", onPointerdown, { passive: false });
|
|
189
|
+
attributable(RESIZABLE_ATTRIBUTE, addResizable, removeResizable);
|
|
190
|
+
//#endregion
|
|
191
|
+
export { OuiResizable, RESIZABLE_ATTRIBUTE, RESIZABLE_ATTRIBUTE_HANDLE, createResizable };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { StyleToggler } from "@oscarpalmer/toretto/style";
|
|
2
|
+
|
|
3
|
+
//#region src/js/resizable/resizable.embedded.d.ts
|
|
4
|
+
type CreateOuiResizableOptions = {
|
|
5
|
+
maximumHeight?: number;
|
|
6
|
+
maximumWidth?: number;
|
|
7
|
+
minimumHeight?: number;
|
|
8
|
+
minimumWidth?: number;
|
|
9
|
+
};
|
|
10
|
+
declare class OuiResizable {
|
|
11
|
+
#private;
|
|
12
|
+
constructor(state: OuiResizableState);
|
|
13
|
+
destroy(): void;
|
|
14
|
+
set(): void;
|
|
15
|
+
reset(): void;
|
|
16
|
+
}
|
|
17
|
+
type OuiResizableState = {
|
|
18
|
+
element: HTMLElement;
|
|
19
|
+
handle: HTMLElement;
|
|
20
|
+
height: number;
|
|
21
|
+
options: Required<CreateOuiResizableOptions>;
|
|
22
|
+
styles: StyleToggler;
|
|
23
|
+
width: number;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Creates _(or retrieves)_ a _OuiResizable_ instance for an element
|
|
27
|
+
*
|
|
28
|
+
* @param element Element to make resizable
|
|
29
|
+
* @returns _OuiResizable_ instance
|
|
30
|
+
*/
|
|
31
|
+
declare function createResizable(element: HTMLElement, options?: CreateOuiResizableOptions): OuiResizable;
|
|
32
|
+
declare const RESIZABLE_ATTRIBUTE = "oui-resizable";
|
|
33
|
+
declare const RESIZABLE_ATTRIBUTE_HANDLE = "oui-resizable-handle";
|
|
34
|
+
//#endregion
|
|
35
|
+
export { createResizable as a, RESIZABLE_ATTRIBUTE_HANDLE as i, OuiResizable as n, RESIZABLE_ATTRIBUTE as r, CreateOuiResizableOptions as t };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { d as OuiSortable, f as createSortable } from "../draggable-
|
|
1
|
+
import { d as OuiSortable, f as createSortable } from "../draggable-fIYXd8eO.mjs";
|
|
2
2
|
export { OuiSortable, createSortable };
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { attributable } from "../internal/attributable.mjs";
|
|
2
2
|
import { OuiDraggable, addDraggable, getDraggableStates, removeDraggable } from "../internal/draggable.mjs";
|
|
3
3
|
import { getPosition } from "@oscarpalmer/toretto/event";
|
|
4
|
+
import { getAttribute, setAttribute, setAttributes } from "@oscarpalmer/toretto/attribute";
|
|
4
5
|
import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
|
|
6
|
+
import { setStyle } from "@oscarpalmer/toretto/style";
|
|
5
7
|
import { findAncestor, getElementFromPosition } from "@oscarpalmer/toretto/find";
|
|
6
8
|
import { createElement } from "@oscarpalmer/toretto/create";
|
|
7
9
|
//#region src/js/sortable/sortable.embedded.ts
|
|
@@ -26,7 +28,7 @@ var OuiSortable = class extends OuiDraggable {
|
|
|
26
28
|
},
|
|
27
29
|
getDragged: getDragPlaceholder,
|
|
28
30
|
getOrigin: () => (getDraggableStates(element)?.sortable)?.origin
|
|
29
|
-
}, { connections:
|
|
31
|
+
}, { connections: getAttribute(element, ATTRIBUTE_CONNECTIONS) });
|
|
30
32
|
}
|
|
31
33
|
};
|
|
32
34
|
function afterEnd(insert, from, events, elements, position, valid) {
|
|
@@ -72,15 +74,15 @@ function getOriginalPosition(_, __, position) {
|
|
|
72
74
|
}
|
|
73
75
|
function getPositionPlaceholder(item) {
|
|
74
76
|
placeholder.position ??= createElement("div");
|
|
75
|
-
placeholder.position
|
|
76
|
-
if (item.state.origin != null) placeholder.position
|
|
77
|
+
setAttribute(placeholder.position, ATTRIBUTE_PLACEHOLDER_POSITION, "");
|
|
78
|
+
if (item.state.origin != null) setStyle(placeholder.position, "--placeholder-height", `${item.state.origin.getBoundingClientRect().height}px`);
|
|
77
79
|
return placeholder.position;
|
|
78
80
|
}
|
|
79
81
|
function onBegin(_, globals, item, element) {
|
|
80
82
|
item.state.origin = element;
|
|
81
83
|
setPlaceholder(globals, item, element);
|
|
82
|
-
|
|
83
|
-
document.body
|
|
84
|
+
setAttribute(element, ATTRIBUTE_ORIGIN, "");
|
|
85
|
+
setAttribute(document.body, ATTRIBUTE_ACTIVE, "");
|
|
84
86
|
}
|
|
85
87
|
function onCancel(_, item) {
|
|
86
88
|
item.state.origin?.removeAttribute(ATTRIBUTE_ORIGIN);
|
|
@@ -96,7 +98,7 @@ function onEnd(event, globals, item, reset) {
|
|
|
96
98
|
};
|
|
97
99
|
const target = getElementFromPosition(position)[0];
|
|
98
100
|
let element = findAncestor(target, SELECTOR_ITEM);
|
|
99
|
-
if (element?.hasAttribute(ATTRIBUTE_PLACEHOLDER_POSITION)) if (
|
|
101
|
+
if (element?.hasAttribute(ATTRIBUTE_PLACEHOLDER_POSITION)) if (getAttribute(element, ATTRIBUTE_PLACEHOLDER_POSITION) === "after") element = element.previousElementSibling;
|
|
100
102
|
else element = element.nextElementSibling;
|
|
101
103
|
let insert = "insert";
|
|
102
104
|
let toInstance;
|
|
@@ -168,7 +170,7 @@ function onMove(event, globals, item, position) {
|
|
|
168
170
|
place = "after";
|
|
169
171
|
toElement.insertAdjacentElement(INSERT_AFTER, placeholder);
|
|
170
172
|
}
|
|
171
|
-
|
|
173
|
+
setAttribute(placeholder, ATTRIBUTE_PLACEHOLDER_POSITION, place);
|
|
172
174
|
} else placeholder.remove();
|
|
173
175
|
return {
|
|
174
176
|
from: {
|
|
@@ -216,14 +218,14 @@ function setPlaceholder(state, item, origin) {
|
|
|
216
218
|
});
|
|
217
219
|
}
|
|
218
220
|
function updatePlaceholder(item, element) {
|
|
219
|
-
element
|
|
220
|
-
element
|
|
221
|
+
setAttribute(element, ATTRIBUTE_PLACEHOLDER_DRAG, "");
|
|
222
|
+
setStyle(element, "position", "fixed");
|
|
221
223
|
const state = getDraggableStates(item.state.element)?.sortable;
|
|
222
224
|
if (state == null) return;
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
225
|
+
setAttributes(element, {
|
|
226
|
+
[ATTRIBUTE_HORIZONTAL]: state.horizontal ? "" : void 0,
|
|
227
|
+
[ATTRIBUTE_VERTICAL]: state.vertical ? "" : void 0
|
|
228
|
+
});
|
|
227
229
|
}
|
|
228
230
|
function validatePosition(_, from, to, position) {
|
|
229
231
|
let valid = true;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { d as OuiSortable, f as createSortable, t as CreateOuiDraggableOptions } from "../draggable-
|
|
1
|
+
import { d as OuiSortable, f as createSortable, t as CreateOuiDraggableOptions } from "../draggable-fIYXd8eO.mjs";
|
|
2
2
|
export { type CreateOuiDraggableOptions as CreateOuiSortableOptions, type OuiSortable, createSortable };
|