@x33025/sveltely 0.0.26 → 0.0.28

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,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import { tick } from 'svelte';
2
3
  import type { Snippet } from 'svelte';
3
4
  import { portalContent } from '../../actions/portal';
4
5
 
@@ -23,9 +24,11 @@
23
24
  let isOpen = $state(false);
24
25
  let triggerEl = $state<HTMLElement | null>(null);
25
26
  let menuEl = $state<HTMLElement | null>(null);
27
+ let contentEl = $state<HTMLElement | null>(null);
26
28
  let menuCoords = $state({ top: 0, left: 0 });
27
29
  let menuTransform = $state('none');
28
30
  let resolvedAnchor = $state<'top' | 'bottom' | 'leading' | 'trailing'>('bottom');
31
+ let computedMenuRadius = $state<string | null>(null);
29
32
 
30
33
  type Point = { x: number; y: number };
31
34
 
@@ -87,7 +90,46 @@
87
90
  ];
88
91
  };
89
92
 
90
- function open() {
93
+ const parsePx = (value: string) => {
94
+ const first = value.split(' ')[0];
95
+ const parsed = Number.parseFloat(first);
96
+ return Number.isFinite(parsed) ? parsed : 0;
97
+ };
98
+
99
+ function updateComputedMenuRadius() {
100
+ if (!menuEl || !contentEl) {
101
+ computedMenuRadius = null;
102
+ return;
103
+ }
104
+
105
+ const itemEl = contentEl.querySelector<HTMLElement>('.dropdown-item');
106
+ if (!itemEl) {
107
+ computedMenuRadius = null;
108
+ return;
109
+ }
110
+
111
+ const itemRect = itemEl.getBoundingClientRect();
112
+ const itemStyle = getComputedStyle(itemEl);
113
+ const itemRadius = parsePx(itemStyle.borderTopLeftRadius);
114
+ const effectiveItemRadius = Math.min(itemRadius, itemRect.height / 2, itemRect.width / 2);
115
+
116
+ const contentStyle = getComputedStyle(contentEl);
117
+ const contentPadding = Math.min(
118
+ parsePx(contentStyle.paddingTop),
119
+ parsePx(contentStyle.paddingLeft)
120
+ );
121
+
122
+ const menuRect = menuEl.getBoundingClientRect();
123
+ const outerRadius = Math.min(
124
+ effectiveItemRadius + contentPadding,
125
+ menuRect.height / 2,
126
+ menuRect.width / 2
127
+ );
128
+
129
+ computedMenuRadius = `${outerRadius}px`;
130
+ }
131
+
132
+ async function open() {
91
133
  if (triggerEl) {
92
134
  const rect = triggerEl.getBoundingClientRect();
93
135
  const spaceAbove = rect.top;
@@ -125,10 +167,13 @@
125
167
  }
126
168
  }
127
169
  isOpen = true;
170
+ await tick();
171
+ updateComputedMenuRadius();
128
172
  }
129
173
 
130
174
  function close() {
131
175
  isOpen = false;
176
+ computedMenuRadius = null;
132
177
  }
133
178
 
134
179
  function toggle() {
@@ -170,6 +215,11 @@
170
215
  function handleSelect() {
171
216
  if (closeOnSelect) close();
172
217
  }
218
+
219
+ $effect(() => {
220
+ if (!isOpen) return;
221
+ updateComputedMenuRadius();
222
+ });
173
223
  </script>
174
224
 
175
225
  <svelte:window
@@ -197,7 +247,8 @@
197
247
  <div
198
248
  use:portalContent
199
249
  class="dropdown-menu fixed z-50 border border-gray-200 focus:outline-none"
200
- style="top: {menuCoords.top}px; left: {menuCoords.left}px; transform: {menuTransform}; border-radius: var(--dropdown-border-radius); background: var(--dropdown-background); box-shadow: var(--dropdown-shadow);"
250
+ style="top: {menuCoords.top}px; left: {menuCoords.left}px; transform: {menuTransform}; border-radius: {computedMenuRadius ??
251
+ 'var(--dropdown-border-radius)'}; background: var(--dropdown-background); box-shadow: var(--dropdown-shadow);"
201
252
  role="menu"
202
253
  aria-orientation="vertical"
203
254
  tabindex="-1"
@@ -208,6 +259,7 @@
208
259
  style="padding: var(--dropdown-content-padding);"
209
260
  role="none"
210
261
  onclick={handleSelect}
262
+ bind:this={contentEl}
211
263
  >
212
264
  {@render children()}
213
265
  </div>
@@ -49,7 +49,7 @@
49
49
  }
50
50
 
51
51
  .dropdown-item {
52
- border-radius: max(0px, calc(var(--dropdown-border-radius) - var(--dropdown-content-padding)));
52
+ border-radius: var(--dropdown-item-border-radius);
53
53
  }
54
54
 
55
55
  .dropdown-item:hover {
@@ -67,8 +67,9 @@
67
67
  --sheet-blur: var(--blur-sm);
68
68
  --sheet-shadow: var(--shadow-md);
69
69
 
70
- --dropdown-border-radius: var(--radius-md);
71
70
  --dropdown-content-padding: calc(var(--spacing));
71
+ --dropdown-item-border-radius: var(--radius-md);
72
+ --dropdown-border-radius: var(--radius-md);
72
73
  --dropdown-background: var(--color-white);
73
74
  --dropdown-shadow: var(--shadow-md);
74
75
  --dropdown-item-highlight: var(--color-zinc-100);
package/dist/style.css CHANGED
@@ -586,7 +586,7 @@
586
586
  padding: 0;
587
587
  }
588
588
  .dropdown-item {
589
- border-radius: max(0px, calc(var(--dropdown-border-radius) - var(--dropdown-content-padding)));
589
+ border-radius: var(--dropdown-item-border-radius);
590
590
  }
591
591
  .dropdown-item:hover {
592
592
  background: var(--dropdown-item-highlight);
@@ -603,8 +603,9 @@
603
603
  }
604
604
  --sheet-blur: var(--blur-sm);
605
605
  --sheet-shadow: var(--shadow-md);
606
- --dropdown-border-radius: var(--radius-md);
607
606
  --dropdown-content-padding: calc(var(--spacing));
607
+ --dropdown-item-border-radius: var(--radius-md);
608
+ --dropdown-border-radius: var(--radius-md);
608
609
  --dropdown-background: var(--color-white);
609
610
  --dropdown-shadow: var(--shadow-md);
610
611
  --dropdown-item-highlight: var(--color-zinc-100);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@x33025/sveltely",
3
- "version": "0.0.26",
3
+ "version": "0.0.28",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build && npm run prepack",