@djcali570/component-lib 0.1.92 → 0.1.93

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.
@@ -1,8 +1,21 @@
1
1
  <script lang="ts">
2
2
  import { onMount } from 'svelte';
3
+ import { fly } from 'svelte/transition';
3
4
  import type { Snippet } from 'svelte';
4
5
  import type { ContextMenu5ColorScheme } from './types.js';
5
- import { fly } from 'svelte/transition';
6
+
7
+ // portal action
8
+ function portal(node: HTMLElement, target: HTMLElement = document.body) {
9
+ target.appendChild(node);
10
+
11
+ return {
12
+ destroy() {
13
+ if (node.parentNode) {
14
+ node.parentNode.removeChild(node);
15
+ }
16
+ }
17
+ };
18
+ }
6
19
 
7
20
  // Props
8
21
  let {
@@ -24,11 +37,11 @@
24
37
  // Default colors
25
38
  const defaultColorScheme: ContextMenu5ColorScheme = {
26
39
  contentBgColor: '#121212',
27
- contentBorderColor: '#191919',
28
40
  iconFillColor: '#121212',
29
41
  iconBorderColor: '#121212',
30
42
  iconColor: '#F5F5F5'
31
43
  };
44
+
32
45
  const colorScheme = $derived({
33
46
  ...defaultColorScheme,
34
47
  ...partialColorScheme
@@ -38,9 +51,32 @@
38
51
  let triggerEl: HTMLElement | null = null;
39
52
  let menuEl: HTMLElement | null = $state(null);
40
53
 
54
+ // menu position
55
+ let position = $state({
56
+ x: 0,
57
+ y: 0,
58
+ width: 0
59
+ });
60
+
61
+ function updatePosition() {
62
+ if (!triggerEl) return;
63
+
64
+ const rect = triggerEl.getBoundingClientRect();
65
+
66
+ position = {
67
+ x: rect.left,
68
+ y: rect.bottom,
69
+ width: rect.width
70
+ };
71
+ }
72
+
41
73
  // Toggle menu
42
74
  function toggle() {
43
75
  open = !open;
76
+
77
+ if (open) {
78
+ updatePosition();
79
+ }
44
80
  }
45
81
 
46
82
  // Close menu
@@ -53,6 +89,7 @@
53
89
  if (!open) return;
54
90
 
55
91
  const target = e.target as Node;
92
+
56
93
  if (menuEl && triggerEl && !menuEl.contains(target) && !triggerEl.contains(target)) {
57
94
  closeMenu();
58
95
  }
@@ -67,18 +104,23 @@
67
104
  document.addEventListener('pointerdown', handlePointerDown);
68
105
  document.addEventListener('keydown', handleKeyDown);
69
106
 
107
+ window.addEventListener('scroll', updatePosition, true);
108
+ window.addEventListener('resize', updatePosition);
109
+
70
110
  return () => {
71
111
  document.removeEventListener('pointerdown', handlePointerDown);
72
112
  document.removeEventListener('keydown', handleKeyDown);
113
+
114
+ window.removeEventListener('scroll', updatePosition, true);
115
+ window.removeEventListener('resize', updatePosition);
73
116
  };
74
117
  });
75
118
  </script>
76
119
 
120
+ <!-- Trigger -->
77
121
  <div
78
122
  class="context5"
79
123
  style="
80
- --context5__ContentBgColor: {colorScheme.contentBgColor};
81
- --context5__ContentBorderColor: {colorScheme.contentBorderColor};
82
124
  --context5__IconBorderColor: {colorScheme.iconBorderColor};
83
125
  --context5__IconColor: {colorScheme.iconColor};
84
126
  --context5__IconFillColor: {colorScheme.iconFillColor};
@@ -105,22 +147,30 @@
105
147
  </svg>
106
148
  {/if}
107
149
  </button>
150
+ </div>
108
151
 
109
- {#if open}
110
- <div
111
- bind:this={menuEl}
112
- role="menu"
113
- class="context5__menu"
114
- class:left={menuAlign === 'left'}
115
- class:right={menuAlign === 'right'}
116
- transition:fly={{ y: 10 }}
117
- >
118
- <div class="context5__content">
119
- {@render content()}
120
- </div>
152
+ <!-- Portal Menu -->
153
+ {#if open}
154
+ <div
155
+ use:portal
156
+ bind:this={menuEl}
157
+ role="menu"
158
+ class="context5__menu context5__portal"
159
+ style="
160
+ left:{menuAlign === 'right' ? position.x + position.width : position.x}px;
161
+ top:{position.y}px;
162
+ --context5__ContentBgColor: {colorScheme.contentBgColor};
163
+ --context5__ContentBorderColor: {colorScheme.contentBorderColor};
164
+ "
165
+ class:right={menuAlign === 'right'}
166
+ class:left={menuAlign === 'left'}
167
+ transition:fly={{ y: 8 }}
168
+ >
169
+ <div class="context5__content">
170
+ {@render content()}
121
171
  </div>
122
- {/if}
123
- </div>
172
+ </div>
173
+ {/if}
124
174
 
125
175
  <style>
126
176
  .context5 {
@@ -137,7 +187,6 @@
137
187
  flex-shrink: 0;
138
188
  }
139
189
 
140
- /* force ANY svg inside to obey the container */
141
190
  .context5__icon :global(*) {
142
191
  width: 100% !important;
143
192
  height: 100% !important;
@@ -145,39 +194,40 @@
145
194
  }
146
195
 
147
196
  .context5__btn {
148
- width: 30px; /* set width */
149
- height: 30px; /* set height (same as width for a perfect circle) */
150
- padding: 0; /* remove extra padding */
151
- border-radius: 50%; /* fully round */
197
+ width: 30px;
198
+ height: 30px;
199
+ padding: 0;
200
+ border-radius: 50%;
152
201
  cursor: pointer;
153
202
  background-color: var(--context5__IconFillColor);
154
- border: none;
155
- outline: none;
156
- -webkit-tap-highlight-color: transparent; /* removes blue flash on touch devices */
157
- display: flex; /* center the icon inside */
203
+ border: 1px solid var(--context5__IconBorderColor);
204
+ display: flex;
158
205
  align-items: center;
159
206
  justify-content: center;
160
- border: 1px solid var(--context5__IconBorderColor);
207
+ outline: none;
208
+ -webkit-tap-highlight-color: transparent;
161
209
  }
162
210
 
163
211
  .context5__btn > svg {
164
212
  color: var(--context5__IconColor);
165
213
  }
166
214
 
215
+ .context5__portal {
216
+ position: fixed;
217
+ z-index: 9999;
218
+ }
219
+
167
220
  .context5__menu {
168
- position: absolute;
169
- margin-top: 0.5rem;
170
- z-index: 1000;
221
+ margin-top: 0.25rem;
171
222
  transform-origin: top;
172
223
  }
173
224
 
174
225
  .context5__menu.right {
175
- right: 0;
226
+ transform: translateX(-100%);
176
227
  transform-origin: top right;
177
228
  }
178
229
 
179
230
  .context5__menu.left {
180
- left: 0;
181
231
  transform-origin: top left;
182
232
  }
183
233
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@djcali570/component-lib",
3
- "version": "0.1.92",
3
+ "version": "0.1.93",
4
4
  "files": [
5
5
  "dist",
6
6
  "!dist/**/*.test.*",