@peter.prib/renderengine 0.2.2 → 0.2.3
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.
|
@@ -7041,6 +7041,21 @@
|
|
|
7041
7041
|
};
|
|
7042
7042
|
}
|
|
7043
7043
|
|
|
7044
|
+
/**
|
|
7045
|
+
* Where a submenu opens beside its item (the item's box `{left, right, top}`),
|
|
7046
|
+
* to be all inside the window: to the right, or to the left when the right
|
|
7047
|
+
* would pass the edge (and there is more room on the left); level with the
|
|
7048
|
+
* item, or lifted by as much as it would pass the bottom. `top` is relative
|
|
7049
|
+
* to the item, as the submenu is positioned.
|
|
7050
|
+
*/
|
|
7051
|
+
static submenuPlacement(item, width, height, windowWidth, windowHeight, margin = 4) {
|
|
7052
|
+
const fitsRight = item.right + width + margin <= windowWidth;
|
|
7053
|
+
const side = fitsRight || item.left < windowWidth - item.right ? 'right' : 'left';
|
|
7054
|
+
const top = -4;
|
|
7055
|
+
const overflow = item.top + top + height + margin - windowHeight;
|
|
7056
|
+
return { side, top: overflow > 0 ? Math.max(top - overflow, margin - item.top) : top };
|
|
7057
|
+
}
|
|
7058
|
+
|
|
7044
7059
|
static close() {
|
|
7045
7060
|
const open = PopupMenu._open;
|
|
7046
7061
|
if (!open) return;
|
|
@@ -7078,7 +7093,16 @@
|
|
|
7078
7093
|
...base,
|
|
7079
7094
|
attrs: { ...base.attrs, 'aria-haspopup': 'menu' },
|
|
7080
7095
|
on: {
|
|
7081
|
-
mouseenter: (e) => {
|
|
7096
|
+
mouseenter: (e) => {
|
|
7097
|
+
e.currentTarget.style.background = hover;
|
|
7098
|
+
sub.style.display = 'block';
|
|
7099
|
+
// Opened near the window's right or bottom edge, it opens left, or lifts.
|
|
7100
|
+
const win = e.currentTarget.ownerDocument.defaultView;
|
|
7101
|
+
const box = sub.getBoundingClientRect?.();
|
|
7102
|
+
if (!win || !box?.width) return;
|
|
7103
|
+
const at = PopupMenu.submenuPlacement(e.currentTarget.getBoundingClientRect(), box.width, box.height, win.innerWidth, win.innerHeight);
|
|
7104
|
+
Object.assign(sub.style, at.side === 'left' ? { left: 'auto', right: '100%' } : { left: '100%', right: 'auto' }, { top: `${at.top}px` });
|
|
7105
|
+
},
|
|
7082
7106
|
mouseleave: (e) => { e.currentTarget.style.background = ''; sub.style.display = 'none'; },
|
|
7083
7107
|
click: (e) => e.stopPropagation(),
|
|
7084
7108
|
},
|
package/dist/renderengine.umd.js
CHANGED
|
@@ -4277,6 +4277,21 @@
|
|
|
4277
4277
|
};
|
|
4278
4278
|
}
|
|
4279
4279
|
|
|
4280
|
+
/**
|
|
4281
|
+
* Where a submenu opens beside its item (the item's box `{left, right, top}`),
|
|
4282
|
+
* to be all inside the window: to the right, or to the left when the right
|
|
4283
|
+
* would pass the edge (and there is more room on the left); level with the
|
|
4284
|
+
* item, or lifted by as much as it would pass the bottom. `top` is relative
|
|
4285
|
+
* to the item, as the submenu is positioned.
|
|
4286
|
+
*/
|
|
4287
|
+
static submenuPlacement(item, width, height, windowWidth, windowHeight, margin = 4) {
|
|
4288
|
+
const fitsRight = item.right + width + margin <= windowWidth;
|
|
4289
|
+
const side = fitsRight || item.left < windowWidth - item.right ? 'right' : 'left';
|
|
4290
|
+
const top = -4;
|
|
4291
|
+
const overflow = item.top + top + height + margin - windowHeight;
|
|
4292
|
+
return { side, top: overflow > 0 ? Math.max(top - overflow, margin - item.top) : top };
|
|
4293
|
+
}
|
|
4294
|
+
|
|
4280
4295
|
static close() {
|
|
4281
4296
|
const open = PopupMenu._open;
|
|
4282
4297
|
if (!open) return;
|
|
@@ -4314,7 +4329,16 @@
|
|
|
4314
4329
|
...base,
|
|
4315
4330
|
attrs: { ...base.attrs, 'aria-haspopup': 'menu' },
|
|
4316
4331
|
on: {
|
|
4317
|
-
mouseenter: (e) => {
|
|
4332
|
+
mouseenter: (e) => {
|
|
4333
|
+
e.currentTarget.style.background = hover;
|
|
4334
|
+
sub.style.display = 'block';
|
|
4335
|
+
// Opened near the window's right or bottom edge, it opens left, or lifts.
|
|
4336
|
+
const win = e.currentTarget.ownerDocument.defaultView;
|
|
4337
|
+
const box = sub.getBoundingClientRect?.();
|
|
4338
|
+
if (!win || !box?.width) return;
|
|
4339
|
+
const at = PopupMenu.submenuPlacement(e.currentTarget.getBoundingClientRect(), box.width, box.height, win.innerWidth, win.innerHeight);
|
|
4340
|
+
Object.assign(sub.style, at.side === 'left' ? { left: 'auto', right: '100%' } : { left: '100%', right: 'auto' }, { top: `${at.top}px` });
|
|
4341
|
+
},
|
|
4318
4342
|
mouseleave: (e) => { e.currentTarget.style.background = ''; sub.style.display = 'none'; },
|
|
4319
4343
|
click: (e) => e.stopPropagation(),
|
|
4320
4344
|
},
|
package/package.json
CHANGED
|
@@ -48,6 +48,21 @@ export class PopupMenu {
|
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Where a submenu opens beside its item (the item's box `{left, right, top}`),
|
|
53
|
+
* to be all inside the window: to the right, or to the left when the right
|
|
54
|
+
* would pass the edge (and there is more room on the left); level with the
|
|
55
|
+
* item, or lifted by as much as it would pass the bottom. `top` is relative
|
|
56
|
+
* to the item, as the submenu is positioned.
|
|
57
|
+
*/
|
|
58
|
+
static submenuPlacement(item, width, height, windowWidth, windowHeight, margin = 4) {
|
|
59
|
+
const fitsRight = item.right + width + margin <= windowWidth;
|
|
60
|
+
const side = fitsRight || item.left < windowWidth - item.right ? 'right' : 'left';
|
|
61
|
+
const top = -4;
|
|
62
|
+
const overflow = item.top + top + height + margin - windowHeight;
|
|
63
|
+
return { side, top: overflow > 0 ? Math.max(top - overflow, margin - item.top) : top };
|
|
64
|
+
}
|
|
65
|
+
|
|
51
66
|
static close() {
|
|
52
67
|
const open = PopupMenu._open;
|
|
53
68
|
if (!open) return;
|
|
@@ -85,7 +100,16 @@ export class PopupMenu {
|
|
|
85
100
|
...base,
|
|
86
101
|
attrs: { ...base.attrs, 'aria-haspopup': 'menu' },
|
|
87
102
|
on: {
|
|
88
|
-
mouseenter: (e) => {
|
|
103
|
+
mouseenter: (e) => {
|
|
104
|
+
e.currentTarget.style.background = hover;
|
|
105
|
+
sub.style.display = 'block';
|
|
106
|
+
// Opened near the window's right or bottom edge, it opens left, or lifts.
|
|
107
|
+
const win = e.currentTarget.ownerDocument.defaultView;
|
|
108
|
+
const box = sub.getBoundingClientRect?.();
|
|
109
|
+
if (!win || !box?.width) return;
|
|
110
|
+
const at = PopupMenu.submenuPlacement(e.currentTarget.getBoundingClientRect(), box.width, box.height, win.innerWidth, win.innerHeight);
|
|
111
|
+
Object.assign(sub.style, at.side === 'left' ? { left: 'auto', right: '100%' } : { left: '100%', right: 'auto' }, { top: `${at.top}px` });
|
|
112
|
+
},
|
|
89
113
|
mouseleave: (e) => { e.currentTarget.style.background = ''; sub.style.display = 'none'; },
|
|
90
114
|
click: (e) => e.stopPropagation(),
|
|
91
115
|
},
|