@x33025/sveltely 0.0.11 → 0.0.13

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.
@@ -7,6 +7,7 @@
7
7
  children: Snippet;
8
8
  class?: string;
9
9
  align?: 'left' | 'right';
10
+ anchor?: 'top' | 'bottom' | 'leading' | 'trailing';
10
11
  closeOnSelect?: boolean;
11
12
  }
12
13
 
@@ -15,21 +16,51 @@
15
16
  children,
16
17
  class: className = '',
17
18
  align = 'left',
19
+ anchor = 'bottom',
18
20
  closeOnSelect = true
19
21
  }: Props = $props();
20
22
 
21
23
  let isOpen = $state(false);
22
24
  let triggerEl = $state<HTMLElement | null>(null);
23
- let menuCoords = $state({ top: 0, left: 0, width: 0 });
25
+ let menuCoords = $state({ top: 0, left: 0 });
26
+ let menuTransform = $state('none');
24
27
 
25
28
  function open() {
26
29
  if (triggerEl) {
27
30
  const rect = triggerEl.getBoundingClientRect();
28
- menuCoords = {
29
- top: rect.bottom + window.scrollY,
30
- left: align === 'left' ? rect.left + window.scrollX : rect.right + window.scrollX,
31
- width: rect.width
32
- };
31
+ const spaceAbove = rect.top;
32
+ const spaceBelow = window.innerHeight - rect.bottom;
33
+ const spaceLeft = rect.left;
34
+ const spaceRight = window.innerWidth - rect.right;
35
+ let resolvedAnchor = anchor;
36
+
37
+ if (anchor === 'bottom' && spaceBelow < spaceAbove) {
38
+ resolvedAnchor = 'top';
39
+ } else if (anchor === 'top' && spaceAbove < spaceBelow) {
40
+ resolvedAnchor = 'bottom';
41
+ } else if (anchor === 'leading' && spaceLeft < spaceRight) {
42
+ resolvedAnchor = 'trailing';
43
+ } else if (anchor === 'trailing' && spaceRight < spaceLeft) {
44
+ resolvedAnchor = 'leading';
45
+ }
46
+
47
+ if (resolvedAnchor === 'top' || resolvedAnchor === 'bottom') {
48
+ const left = align === 'left' ? rect.left + window.scrollX : rect.right + window.scrollX;
49
+ const top =
50
+ resolvedAnchor === 'bottom' ? rect.bottom + window.scrollY : rect.top + window.scrollY;
51
+ menuCoords = { top, left };
52
+ if (resolvedAnchor === 'top' && align === 'right')
53
+ menuTransform = 'translate(-100%, -100%)';
54
+ else if (resolvedAnchor === 'top') menuTransform = 'translateY(-100%)';
55
+ else if (align === 'right') menuTransform = 'translateX(-100%)';
56
+ else menuTransform = 'none';
57
+ } else if (resolvedAnchor === 'leading') {
58
+ menuCoords = { top: rect.top + window.scrollY, left: rect.left + window.scrollX };
59
+ menuTransform = 'translateX(-100%)';
60
+ } else {
61
+ menuCoords = { top: rect.top + window.scrollY, left: rect.right + window.scrollX };
62
+ menuTransform = 'none';
63
+ }
33
64
  }
34
65
  isOpen = true;
35
66
  }
@@ -71,9 +102,7 @@
71
102
  <div
72
103
  use:portal
73
104
  class="dropdown-menu fixed z-50 border border-gray-200 focus:outline-none"
74
- style="top: {menuCoords.top}px; {align === 'left'
75
- ? `left: ${menuCoords.left}px;`
76
- : `right: ${window.innerWidth - menuCoords.left}px;`}; border-radius: var(--dropdown-border-radius); background: var(--dropdown-background); box-shadow: var(--dropdown-shadow);"
105
+ 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);"
77
106
  role="menu"
78
107
  aria-orientation="vertical"
79
108
  tabindex="-1"
@@ -4,6 +4,7 @@ interface Props {
4
4
  children: Snippet;
5
5
  class?: string;
6
6
  align?: 'left' | 'right';
7
+ anchor?: 'top' | 'bottom' | 'leading' | 'trailing';
7
8
  closeOnSelect?: boolean;
8
9
  }
9
10
  declare const Dropdown: import("svelte").Component<Props, {}, "">;
@@ -42,15 +42,18 @@
42
42
  {#if left}
43
43
  <div
44
44
  class="h-full overflow-hidden border-r border-gray-200 transition-all duration-300 ease-in-out"
45
- style="width: {leftOpen ? '16rem' : '0'}; opacity: {leftOpen ? '1' : '0'}"
45
+ style="width: {leftOpen ? 'var(--navigation-stack-sidebar-width)' : '0'}"
46
46
  >
47
- <div class="vstack h-full w-64 overflow-auto bg-gray-50 p-4">
47
+ <div
48
+ class="vstack h-full overflow-auto bg-gray-50 p-4"
49
+ style="width: var(--navigation-stack-sidebar-width);"
50
+ >
48
51
  {@render left()}
49
52
  </div>
50
53
  </div>
51
54
  {/if}
52
55
 
53
- <div class="vstack w-full">
56
+ <div class="vstack flex-1">
54
57
  {#if children}
55
58
  {@render children()}
56
59
  {/if}
@@ -59,9 +62,12 @@
59
62
  {#if right}
60
63
  <div
61
64
  class="h-full overflow-hidden border-l border-gray-200 transition-all duration-300 ease-in-out"
62
- style="width: {rightOpen ? '16rem' : '0'}; opacity: {rightOpen ? '1' : '0'}"
65
+ style="width: {rightOpen ? 'var(--navigation-stack-sidebar-width)' : '0'}"
63
66
  >
64
- <div class="vstack h-full w-64 overflow-auto bg-gray-50 p-4">
67
+ <div
68
+ class="vstack h-full overflow-auto bg-gray-50 p-4"
69
+ style="width: var(--navigation-stack-sidebar-width);"
70
+ >
65
71
  {@render right()}
66
72
  </div>
67
73
  </div>
@@ -64,5 +64,7 @@
64
64
  --tooltip-font-size: 12px;
65
65
  --tooltip-background: var(--color-black);
66
66
  --tooltip-text: var(--color-white);
67
+
68
+ --navigation-stack-sidebar-width: 16rem;
67
69
  }
68
70
  }
package/dist/style.css CHANGED
@@ -256,9 +256,6 @@
256
256
  .w-5 {
257
257
  width: calc(var(--spacing) * 5);
258
258
  }
259
- .w-64 {
260
- width: calc(var(--spacing) * 64);
261
- }
262
259
  .w-full {
263
260
  width: 100%;
264
261
  }
@@ -562,6 +559,7 @@
562
559
  --tooltip-font-size: 12px;
563
560
  --tooltip-background: var(--color-black);
564
561
  --tooltip-text: var(--color-white);
562
+ --navigation-stack-sidebar-width: 16rem;
565
563
  }
566
564
  }
567
565
  @property --tw-rotate-x {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@x33025/sveltely",
3
- "version": "0.0.11",
3
+ "version": "0.0.13",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build && npm run prepack",