@webamoki/web-svelte 0.8.0 → 1.0.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.
Files changed (120) hide show
  1. package/README.md +83 -3
  2. package/dist/components/form/Button.svelte +24 -23
  3. package/dist/components/form/Button.svelte.d.ts +2 -2
  4. package/dist/components/form/Errors.svelte +13 -13
  5. package/dist/components/form/FieldWrapper.svelte +57 -55
  6. package/dist/components/form/FieldWrapper.svelte.d.ts +4 -4
  7. package/dist/components/form/Form.svelte +18 -14
  8. package/dist/components/form/Form.svelte.d.ts +31 -22
  9. package/dist/components/form/IconInputWrapper.svelte +30 -29
  10. package/dist/components/form/IconInputWrapper.svelte.d.ts +7 -7
  11. package/dist/components/form/fields/ChoiceField.svelte +45 -43
  12. package/dist/components/form/fields/ChoiceField.svelte.d.ts +28 -23
  13. package/dist/components/form/fields/ChoiceMultiField.svelte +44 -42
  14. package/dist/components/form/fields/ChoiceMultiField.svelte.d.ts +28 -23
  15. package/dist/components/form/fields/DateField.svelte +42 -40
  16. package/dist/components/form/fields/DateField.svelte.d.ts +29 -22
  17. package/dist/components/form/fields/HexColorField.svelte +21 -19
  18. package/dist/components/form/fields/HexColorField.svelte.d.ts +24 -19
  19. package/dist/components/form/fields/MessageField.svelte +39 -60
  20. package/dist/components/form/fields/MessageField.svelte.d.ts +33 -24
  21. package/dist/components/form/fields/NumberField.svelte +38 -36
  22. package/dist/components/form/fields/NumberField.svelte.d.ts +32 -23
  23. package/dist/components/form/fields/PasswordField.svelte +45 -39
  24. package/dist/components/form/fields/PasswordField.svelte.d.ts +28 -21
  25. package/dist/components/form/fields/SelectField.svelte +84 -79
  26. package/dist/components/form/fields/SelectField.svelte.d.ts +39 -26
  27. package/dist/components/form/fields/SelectMultiField.svelte +90 -85
  28. package/dist/components/form/fields/SelectMultiField.svelte.d.ts +38 -25
  29. package/dist/components/form/fields/TextField.svelte +31 -29
  30. package/dist/components/form/fields/TextField.svelte.d.ts +32 -23
  31. package/dist/components/form/fields/TextFieldNullable.svelte +49 -47
  32. package/dist/components/form/fields/TextFieldNullable.svelte.d.ts +32 -23
  33. package/dist/components/form/fields/TimeField.svelte +66 -64
  34. package/dist/components/form/fields/TimeField.svelte.d.ts +33 -24
  35. package/dist/components/form/fields/WeekdayChoiceField.svelte +37 -35
  36. package/dist/components/form/fields/WeekdayChoiceField.svelte.d.ts +27 -22
  37. package/dist/components/form/fields/WeekdayChoiceMultiField.svelte +37 -35
  38. package/dist/components/form/fields/WeekdayChoiceMultiField.svelte.d.ts +27 -22
  39. package/dist/components/showcase/CodeBlock.svelte +41 -41
  40. package/dist/components/showcase/Container.svelte +7 -7
  41. package/dist/components/showcase/Preview.svelte +4 -4
  42. package/dist/components/showcase/Sidebar.svelte +4 -4
  43. package/dist/components/showcase/SidebarLink.svelte +3 -3
  44. package/dist/components/ui/choice/Choice.svelte +25 -25
  45. package/dist/components/ui/choice/Choice.svelte.d.ts +7 -7
  46. package/dist/components/ui/choice/ChoiceInternal.svelte +73 -72
  47. package/dist/components/ui/choice/ChoiceInternal.svelte.d.ts +9 -9
  48. package/dist/components/ui/choice/ChoiceMulti.svelte +59 -56
  49. package/dist/components/ui/choice/ChoiceMulti.svelte.d.ts +7 -7
  50. package/dist/components/ui/choice/WeekdayChoice.svelte +22 -21
  51. package/dist/components/ui/choice/WeekdayChoice.svelte.d.ts +6 -6
  52. package/dist/components/ui/choice/WeekdayChoiceMulti.svelte +24 -22
  53. package/dist/components/ui/choice/WeekdayChoiceMulti.svelte.d.ts +6 -6
  54. package/dist/components/ui/context-menu/ContextMenu.svelte +51 -50
  55. package/dist/components/ui/context-menu/ContextMenu.svelte.d.ts +1 -1
  56. package/dist/components/ui/context-menu/ContextMenuContent.svelte +92 -91
  57. package/dist/components/ui/context-menu/ContextMenuItem.svelte +26 -25
  58. package/dist/components/ui/context-menu/ContextMenuItem.svelte.d.ts +1 -1
  59. package/dist/components/ui/context-menu/ContextMenuTrigger.svelte +16 -15
  60. package/dist/components/ui/context-menu/context-menu-state.svelte.d.ts +3 -3
  61. package/dist/components/ui/context-menu/context-menu-state.svelte.js +15 -15
  62. package/dist/components/ui/drag-drop/Draggable.svelte +73 -72
  63. package/dist/components/ui/drag-drop/Draggable.svelte.d.ts +2 -2
  64. package/dist/components/ui/drag-drop/Dropzone.svelte +56 -54
  65. package/dist/components/ui/drag-drop/Dropzone.svelte.d.ts +3 -3
  66. package/dist/components/ui/drag-drop/drag-manager.d.ts +2 -2
  67. package/dist/components/ui/drag-drop/drag-manager.js +9 -9
  68. package/dist/components/ui/index.d.ts +2 -2
  69. package/dist/components/ui/index.js +5 -5
  70. package/dist/components/ui/search/SearchBar.svelte +18 -18
  71. package/dist/components/ui/search/SearchBar.svelte.d.ts +2 -2
  72. package/dist/highlight.js +2 -2
  73. package/dist/server/form-handler.d.ts +12 -12
  74. package/dist/server/form-handler.js +17 -17
  75. package/dist/server/form-processor.d.ts +1 -1
  76. package/dist/server/form-processor.js +0 -1
  77. package/dist/shadcn/components/ui/button/button.svelte +72 -71
  78. package/dist/shadcn/components/ui/button/button.svelte.d.ts +23 -23
  79. package/dist/shadcn/components/ui/button/index.d.ts +1 -1
  80. package/dist/shadcn/components/ui/button/index.js +2 -2
  81. package/dist/shadcn/components/ui/input/index.d.ts +1 -1
  82. package/dist/shadcn/components/ui/input/index.js +2 -2
  83. package/dist/shadcn/components/ui/input/input.svelte +35 -32
  84. package/dist/shadcn/components/ui/input/input.svelte.d.ts +2 -2
  85. package/dist/shadcn/components/ui/select/index.d.ts +6 -6
  86. package/dist/shadcn/components/ui/select/index.js +7 -7
  87. package/dist/shadcn/components/ui/select/select-content.svelte +35 -34
  88. package/dist/shadcn/components/ui/select/select-content.svelte.d.ts +1 -1
  89. package/dist/shadcn/components/ui/select/select-group-heading.svelte +15 -14
  90. package/dist/shadcn/components/ui/select/select-group.svelte +2 -2
  91. package/dist/shadcn/components/ui/select/select-item.svelte +31 -31
  92. package/dist/shadcn/components/ui/select/select-label.svelte +14 -13
  93. package/dist/shadcn/components/ui/select/select-label.svelte.d.ts +1 -1
  94. package/dist/shadcn/components/ui/select/select-scroll-down-button.svelte +13 -13
  95. package/dist/shadcn/components/ui/select/select-scroll-up-button.svelte +13 -13
  96. package/dist/shadcn/components/ui/select/select-separator.svelte +13 -12
  97. package/dist/shadcn/components/ui/select/select-trigger.svelte +26 -26
  98. package/dist/shadcn/components/ui/select/select-trigger.svelte.d.ts +2 -2
  99. package/dist/shadcn/components/ui/separator/separator.svelte +14 -14
  100. package/dist/shadcn/components/ui/textarea/textarea.svelte +22 -21
  101. package/dist/shadcn/components/ui/textarea/textarea.svelte.d.ts +1 -1
  102. package/dist/shadcn/utils.d.ts +4 -4
  103. package/dist/utils/datetime/index.d.ts +66 -66
  104. package/dist/utils/datetime/index.js +124 -124
  105. package/dist/utils/email/README.md +60 -60
  106. package/dist/utils/email/aws-signer.d.ts +1 -1
  107. package/dist/utils/email/aws-signer.js +39 -39
  108. package/dist/utils/email/ses.d.ts +8 -8
  109. package/dist/utils/email/ses.js +9 -9
  110. package/dist/utils/form/index.d.ts +11 -11
  111. package/dist/utils/form/index.js +23 -24
  112. package/dist/utils/form/virtual-form.d.ts +5 -5
  113. package/dist/utils/form/virtual-form.js +58 -58
  114. package/dist/utils/search.d.ts +1 -1
  115. package/dist/utils/search.js +22 -22
  116. package/dist/utils/types/arktype.d.ts +2 -2
  117. package/dist/utils/types/arktype.js +3 -3
  118. package/dist/utils/types/db.d.ts +2 -1
  119. package/dist/utils/types/db.js +7 -7
  120. package/package.json +46 -31
@@ -1,57 +1,58 @@
1
1
  <script lang="ts" module>
2
- export type ContextMenuState = {
3
- position: { x: number; y: number };
4
- open: boolean;
5
- };
2
+ export type ContextMenuState = {
3
+ open: boolean;
4
+ position: { x: number; y: number };
5
+ };
6
6
  </script>
7
7
 
8
8
  <script lang="ts">
9
- import { setContext, onDestroy, type Snippet } from 'svelte';
10
- import { contextMenuState } from './context-menu-state.svelte';
11
-
12
- interface Props {
13
- children: Snippet<[]>;
14
- onOpenChange?: (open: boolean) => void;
15
- }
16
-
17
- let { children, onOpenChange }: Props = $props();
18
-
19
- const menuId = Symbol('context-menu');
20
-
21
- let menuState = $state<ContextMenuState>({
22
- position: { x: 0, y: 0 },
23
- open: false
24
- });
25
-
26
- // Watch for changes to menuState.open and sync with global store
27
- $effect(() => {
28
- if (menuState.open) {
29
- contextMenuState.openMenu(menuId);
30
- } else if (contextMenuState.isThisMenuOpen(menuId)) {
31
- contextMenuState.closeMenu();
32
- }
33
- });
34
-
35
- // Watch for global store changes and close this menu if another opens
36
- $effect(() => {
37
- if (contextMenuState.open && !contextMenuState.isThisMenuOpen(menuId)) {
38
- menuState.open = false;
39
- }
40
- });
41
-
42
- // Call onOpenChange callback when open state changes
43
- $effect(() => {
44
- onOpenChange?.(menuState.open);
45
- });
46
-
47
- // Cleanup scroll lock when component is destroyed
48
- onDestroy(() => {
49
- if (contextMenuState.isThisMenuOpen(menuId)) {
50
- contextMenuState.closeMenu();
51
- }
52
- });
53
-
54
- setContext('context-menu', menuState);
9
+ import { onDestroy, setContext, type Snippet } from 'svelte';
10
+
11
+ import { contextMenuState } from './context-menu-state.svelte';
12
+
13
+ interface Props {
14
+ children: Snippet<[]>;
15
+ onOpenChange?: (open: boolean) => void;
16
+ }
17
+
18
+ let { children, onOpenChange }: Props = $props();
19
+
20
+ const menuId = Symbol('context-menu');
21
+
22
+ let menuState = $state<ContextMenuState>({
23
+ open: false,
24
+ position: { x: 0, y: 0 }
25
+ });
26
+
27
+ // Watch for changes to menuState.open and sync with global store
28
+ $effect(() => {
29
+ if (menuState.open) {
30
+ contextMenuState.openMenu(menuId);
31
+ } else if (contextMenuState.isThisMenuOpen(menuId)) {
32
+ contextMenuState.closeMenu();
33
+ }
34
+ });
35
+
36
+ // Watch for global store changes and close this menu if another opens
37
+ $effect(() => {
38
+ if (contextMenuState.open && !contextMenuState.isThisMenuOpen(menuId)) {
39
+ menuState.open = false;
40
+ }
41
+ });
42
+
43
+ // Call onOpenChange callback when open state changes
44
+ $effect(() => {
45
+ onOpenChange?.(menuState.open);
46
+ });
47
+
48
+ // Cleanup scroll lock when component is destroyed
49
+ onDestroy(() => {
50
+ if (contextMenuState.isThisMenuOpen(menuId)) {
51
+ contextMenuState.closeMenu();
52
+ }
53
+ });
54
+
55
+ setContext('context-menu', menuState);
55
56
  </script>
56
57
 
57
58
  {@render children()}
@@ -1,9 +1,9 @@
1
1
  export type ContextMenuState = {
2
+ open: boolean;
2
3
  position: {
3
4
  x: number;
4
5
  y: number;
5
6
  };
6
- open: boolean;
7
7
  };
8
8
  import { type Snippet } from 'svelte';
9
9
  interface Props {
@@ -1,99 +1,100 @@
1
1
  <script lang="ts">
2
- import { getContext, onMount, type Snippet } from 'svelte';
3
- import { scale } from 'svelte/transition';
4
- import type { ContextMenuState } from './ContextMenu.svelte';
5
- import { cn } from '../../../shadcn/utils.js';
6
-
7
- interface Props {
8
- children: Snippet<[]>;
9
- class?: string;
10
- }
11
-
12
- let { children, class: className }: Props = $props();
13
-
14
- const menuState: ContextMenuState = getContext('context-menu');
15
-
16
- let menuElement: HTMLDivElement | null = $state(null);
17
- let adjustedPosition = $state({ x: 0, y: 0 });
18
-
19
- function handleDocumentClick(event: MouseEvent) {
20
- if (menuElement && !menuElement.contains(event.target as Node)) {
21
- menuState.open = false;
22
- }
23
- }
24
-
25
- function adjustPositionToFitScreen() {
26
- if (!menuElement) return;
27
-
28
- const rect = menuElement.getBoundingClientRect();
29
- const viewportWidth = window.innerWidth;
30
- const viewportHeight = window.innerHeight;
31
-
32
- let x = menuState.position.x;
33
- let y = menuState.position.y;
34
-
35
- // Adjust horizontal position if menu goes off right edge
36
- if (x + rect.width > viewportWidth) {
37
- x = viewportWidth - rect.width - 8; // 8px padding from edge
38
- }
39
-
40
- // Adjust horizontal position if menu goes off left edge
41
- if (x < 0) {
42
- x = 8; // 8px padding from edge
43
- }
44
-
45
- // Adjust vertical position if menu goes off bottom edge
46
- if (y + rect.height > viewportHeight) {
47
- y = viewportHeight - rect.height - 8; // 8px padding from edge
48
- }
49
-
50
- // Adjust vertical position if menu goes off top edge
51
- if (y < 0) {
52
- y = 8; // 8px padding from edge
53
- }
54
-
55
- adjustedPosition = { x, y };
56
- }
57
-
58
- $effect(() => {
59
- if (menuState.open && menuElement) {
60
- // Use requestAnimationFrame to ensure DOM has updated
61
- requestAnimationFrame(() => {
62
- adjustPositionToFitScreen();
63
- });
64
- }
65
- });
66
-
67
- onMount(() => {
68
- document.addEventListener('click', handleDocumentClick);
69
-
70
- return () => {
71
- document.removeEventListener('click', handleDocumentClick);
72
- };
73
- });
2
+ import { cn } from '../../../shadcn/utils.js';
3
+ import { getContext, onMount, type Snippet } from 'svelte';
4
+ import { scale } from 'svelte/transition';
5
+
6
+ import type { ContextMenuState } from './ContextMenu.svelte';
7
+
8
+ interface Props {
9
+ children: Snippet<[]>;
10
+ class?: string;
11
+ }
12
+
13
+ let { children, class: className }: Props = $props();
14
+
15
+ const menuState: ContextMenuState = getContext('context-menu');
16
+
17
+ let menuElement: HTMLDivElement | null = $state(null);
18
+ let adjustedPosition = $state({ x: 0, y: 0 });
19
+
20
+ function handleDocumentClick(event: MouseEvent) {
21
+ if (menuElement && !menuElement.contains(event.target as Node)) {
22
+ menuState.open = false;
23
+ }
24
+ }
25
+
26
+ function adjustPositionToFitScreen() {
27
+ if (!menuElement) return;
28
+
29
+ const rect = menuElement.getBoundingClientRect();
30
+ const viewportWidth = window.innerWidth;
31
+ const viewportHeight = window.innerHeight;
32
+
33
+ let x = menuState.position.x;
34
+ let y = menuState.position.y;
35
+
36
+ // Adjust horizontal position if menu goes off right edge
37
+ if (x + rect.width > viewportWidth) {
38
+ x = viewportWidth - rect.width - 8; // 8px padding from edge
39
+ }
40
+
41
+ // Adjust horizontal position if menu goes off left edge
42
+ if (x < 0) {
43
+ x = 8; // 8px padding from edge
44
+ }
45
+
46
+ // Adjust vertical position if menu goes off bottom edge
47
+ if (y + rect.height > viewportHeight) {
48
+ y = viewportHeight - rect.height - 8; // 8px padding from edge
49
+ }
50
+
51
+ // Adjust vertical position if menu goes off top edge
52
+ if (y < 0) {
53
+ y = 8; // 8px padding from edge
54
+ }
55
+
56
+ adjustedPosition = { x, y };
57
+ }
58
+
59
+ $effect(() => {
60
+ if (menuState.open && menuElement) {
61
+ // Use requestAnimationFrame to ensure DOM has updated
62
+ requestAnimationFrame(() => {
63
+ adjustPositionToFitScreen();
64
+ });
65
+ }
66
+ });
67
+
68
+ onMount(() => {
69
+ document.addEventListener('click', handleDocumentClick);
70
+
71
+ return () => {
72
+ document.removeEventListener('click', handleDocumentClick);
73
+ };
74
+ });
74
75
  </script>
75
76
 
76
77
  {#if menuState.open}
77
- <div
78
- bind:this={menuElement}
79
- class={cn('context-menu-content', className)}
80
- style="left: {adjustedPosition.x}px; top: {adjustedPosition.y}px;"
81
- transition:scale={{ duration: 150, start: 0.95 }}
82
- >
83
- {@render children()}
84
- </div>
78
+ <div
79
+ bind:this={menuElement}
80
+ style="left: {adjustedPosition.x}px; top: {adjustedPosition.y}px;"
81
+ class={cn('context-menu-content', className)}
82
+ transition:scale={{ duration: 150, start: 0.95 }}
83
+ >
84
+ {@render children()}
85
+ </div>
85
86
  {/if}
86
87
 
87
88
  <style>
88
- .context-menu-content {
89
- position: fixed;
90
- background-color: white;
91
- border: 1px solid #ddd;
92
- border-radius: 8px;
93
- box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
94
- padding: 4px;
95
- min-width: 150px;
96
- z-index: 50;
97
- transform-origin: top left;
98
- }
89
+ .context-menu-content {
90
+ position: fixed;
91
+ background-color: white;
92
+ border: 1px solid #ddd;
93
+ border-radius: 8px;
94
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
95
+ padding: 4px;
96
+ min-width: 150px;
97
+ z-index: 50;
98
+ transform-origin: top left;
99
+ }
99
100
  </style>
@@ -1,33 +1,34 @@
1
1
  <script lang="ts">
2
- import type { HTMLAttributes } from 'svelte/elements';
3
- import { cn } from '../../../shadcn/utils.js';
2
+ import type { HTMLAttributes } from 'svelte/elements';
4
3
 
5
- interface Props extends HTMLAttributes<HTMLDivElement> {
6
- variant?: 'default' | 'destructive';
7
- disabled?: boolean;
8
- }
4
+ import { cn } from '../../../shadcn/utils.js';
9
5
 
10
- let {
11
- class: className,
12
- variant = 'default',
13
- disabled = false,
14
- onclick,
15
- children,
16
- ...restProps
17
- }: Props = $props();
6
+ interface Props extends HTMLAttributes<HTMLDivElement> {
7
+ disabled?: boolean;
8
+ variant?: 'default' | 'destructive';
9
+ }
10
+
11
+ let {
12
+ children,
13
+ class: className,
14
+ disabled = false,
15
+ onclick,
16
+ variant = 'default',
17
+ ...restProps
18
+ }: Props = $props();
18
19
  </script>
19
20
 
20
21
  <div
21
- role="menuitem"
22
- tabindex={disabled ? -1 : 0}
23
- class={cn(
24
- 'flex cursor-pointer items-center gap-2 rounded px-3 py-2 text-sm hover:bg-gray-100',
25
- variant === 'destructive' && 'text-red-600 hover:bg-red-50',
26
- disabled && 'pointer-events-none opacity-50',
27
- className
28
- )}
29
- {onclick}
30
- {...restProps}
22
+ class={cn(
23
+ 'flex cursor-pointer items-center gap-2 rounded px-3 py-2 text-sm hover:bg-gray-100',
24
+ variant === 'destructive' && 'text-red-600 hover:bg-red-50',
25
+ disabled && 'pointer-events-none opacity-50',
26
+ className
27
+ )}
28
+ {onclick}
29
+ role="menuitem"
30
+ tabindex={disabled ? -1 : 0}
31
+ {...restProps}
31
32
  >
32
- {@render children?.()}
33
+ {@render children?.()}
33
34
  </div>
@@ -1,7 +1,7 @@
1
1
  import type { HTMLAttributes } from 'svelte/elements';
2
2
  interface Props extends HTMLAttributes<HTMLDivElement> {
3
- variant?: 'default' | 'destructive';
4
3
  disabled?: boolean;
4
+ variant?: 'default' | 'destructive';
5
5
  }
6
6
  declare const ContextMenuItem: import("svelte").Component<Props, {}, "">;
7
7
  type ContextMenuItem = ReturnType<typeof ContextMenuItem>;
@@ -1,23 +1,24 @@
1
1
  <script lang="ts">
2
- import { getContext, type Snippet } from 'svelte';
3
- import type { ContextMenuState } from './ContextMenu.svelte';
2
+ import { getContext, type Snippet } from 'svelte';
4
3
 
5
- interface Props {
6
- children: Snippet<[]>;
7
- }
4
+ import type { ContextMenuState } from './ContextMenu.svelte';
8
5
 
9
- let { children }: Props = $props();
6
+ interface Props {
7
+ children: Snippet<[]>;
8
+ }
10
9
 
11
- const menuState: ContextMenuState = getContext('context-menu');
10
+ let { children }: Props = $props();
12
11
 
13
- function handleContextMenu(event: MouseEvent) {
14
- event.preventDefault();
15
- menuState.position.x = event.clientX;
16
- menuState.position.y = event.clientY;
17
- menuState.open = true;
18
- }
12
+ const menuState: ContextMenuState = getContext('context-menu');
13
+
14
+ function handleContextMenu(event: MouseEvent) {
15
+ event.preventDefault();
16
+ menuState.position.x = event.clientX;
17
+ menuState.position.y = event.clientY;
18
+ menuState.open = true;
19
+ }
19
20
  </script>
20
21
 
21
- <div role="button" tabindex="-1" oncontextmenu={handleContextMenu}>
22
- {@render children()}
22
+ <div oncontextmenu={handleContextMenu} role="button" tabindex="-1">
23
+ {@render children()}
23
24
  </div>
@@ -1,7 +1,7 @@
1
1
  export declare const contextMenuState: {
2
- readonly open: boolean;
3
- readonly currentId: symbol | null;
4
- openMenu(id: symbol): void;
5
2
  closeMenu(): void;
3
+ readonly currentId: symbol | null;
6
4
  isThisMenuOpen(id: symbol): boolean;
5
+ readonly open: boolean;
6
+ openMenu(id: symbol): void;
7
7
  };
@@ -1,14 +1,25 @@
1
1
  const globalMenuState = $state({
2
- open: false,
3
- id: null
2
+ id: null,
3
+ open: false
4
4
  });
5
5
  export const contextMenuState = {
6
- get open() {
7
- return globalMenuState.open;
6
+ closeMenu() {
7
+ globalMenuState.open = false;
8
+ globalMenuState.id = null;
9
+ // Restore scrolling when menu closes
10
+ if (typeof document !== 'undefined') {
11
+ document.body.style.overflow = '';
12
+ }
8
13
  },
9
14
  get currentId() {
10
15
  return globalMenuState.id;
11
16
  },
17
+ isThisMenuOpen(id) {
18
+ return globalMenuState.open && globalMenuState.id === id;
19
+ },
20
+ get open() {
21
+ return globalMenuState.open;
22
+ },
12
23
  openMenu(id) {
13
24
  globalMenuState.open = true;
14
25
  globalMenuState.id = id;
@@ -16,16 +27,5 @@ export const contextMenuState = {
16
27
  if (typeof document !== 'undefined') {
17
28
  document.body.style.overflow = 'hidden';
18
29
  }
19
- },
20
- closeMenu() {
21
- globalMenuState.open = false;
22
- globalMenuState.id = null;
23
- // Restore scrolling when menu closes
24
- if (typeof document !== 'undefined') {
25
- document.body.style.overflow = '';
26
- }
27
- },
28
- isThisMenuOpen(id) {
29
- return globalMenuState.open && globalMenuState.id === id;
30
30
  }
31
31
  };
@@ -1,80 +1,81 @@
1
- <script lang="ts" generics="T">
2
- import { onDestroy, type Snippet } from 'svelte';
3
- import type { DragManager } from './drag-manager.js';
4
-
5
- interface Props {
6
- data: T;
7
- manager: DragManager<T>;
8
- children: Snippet<[]>;
9
- class?: string;
10
- }
11
-
12
- let { manager, children, class: className, data }: Props = $props();
13
-
14
- let isDragging = $state(false);
15
- let mouseX = $state(0);
16
- let mouseY = $state(0);
17
-
18
- function startDrag(e: MouseEvent) {
19
- if (e.button !== 0) return;
20
-
21
- e.preventDefault();
22
- isDragging = true;
23
- manager.drag(data);
24
-
25
- mouseX = e.clientX;
26
- mouseY = e.clientY;
27
-
28
- // Force grabbing cursor on the body
29
- document.body.style.cursor = 'grabbing';
30
-
31
- window.addEventListener('mousemove', moveDrag);
32
- window.addEventListener('mouseup', endDrag);
33
- }
34
-
35
- function moveDrag(e: MouseEvent) {
36
- mouseX = e.clientX;
37
- mouseY = e.clientY;
38
- }
39
-
40
- function endDrag() {
41
- isDragging = false;
42
- manager.stop();
43
-
44
- // Reset cursor
45
- document.body.style.cursor = '';
46
-
47
- window.removeEventListener('mousemove', moveDrag);
48
- window.removeEventListener('mouseup', endDrag);
49
- }
50
-
51
- onDestroy(() => {
52
- if (isDragging) {
53
- manager.stop();
54
- }
55
- if (typeof window !== 'undefined') {
56
- window.removeEventListener('mousemove', moveDrag);
57
- window.removeEventListener('mouseup', endDrag);
58
- document.body.style.cursor = ''; // safe in browser only
59
- }
60
- });
1
+ <script generics="T" lang="ts">
2
+ import { onDestroy, type Snippet } from 'svelte';
3
+
4
+ import type { DragManager } from './drag-manager.js';
5
+
6
+ interface Props {
7
+ children: Snippet<[]>;
8
+ class?: string;
9
+ data: T;
10
+ manager: DragManager<T>;
11
+ }
12
+
13
+ let { children, class: className, data, manager }: Props = $props();
14
+
15
+ let isDragging = $state(false);
16
+ let mouseX = $state(0);
17
+ let mouseY = $state(0);
18
+
19
+ function startDrag(e: MouseEvent) {
20
+ if (e.button !== 0) return;
21
+
22
+ e.preventDefault();
23
+ isDragging = true;
24
+ manager.drag(data);
25
+
26
+ mouseX = e.clientX;
27
+ mouseY = e.clientY;
28
+
29
+ // Force grabbing cursor on the body
30
+ document.body.style.cursor = 'grabbing';
31
+
32
+ window.addEventListener('mousemove', moveDrag);
33
+ window.addEventListener('mouseup', endDrag);
34
+ }
35
+
36
+ function moveDrag(e: MouseEvent) {
37
+ mouseX = e.clientX;
38
+ mouseY = e.clientY;
39
+ }
40
+
41
+ function endDrag() {
42
+ isDragging = false;
43
+ manager.stop();
44
+
45
+ // Reset cursor
46
+ document.body.style.cursor = '';
47
+
48
+ window.removeEventListener('mousemove', moveDrag);
49
+ window.removeEventListener('mouseup', endDrag);
50
+ }
51
+
52
+ onDestroy(() => {
53
+ if (isDragging) {
54
+ manager.stop();
55
+ }
56
+ if (typeof window !== 'undefined') {
57
+ window.removeEventListener('mousemove', moveDrag);
58
+ window.removeEventListener('mouseup', endDrag);
59
+ document.body.style.cursor = ''; // safe in browser only
60
+ }
61
+ });
61
62
  </script>
62
63
 
63
64
  <div
64
- onmousedown={startDrag}
65
- class={`relative select-none ${isDragging ? 'opacity-30 grayscale' : 'cursor-grab'} ${className ?? ''}`}
66
- role="button"
67
- tabindex="0"
68
- aria-label="Draggable item"
65
+ class={`relative select-none ${isDragging ? 'opacity-30 grayscale' : 'cursor-grab'} ${className ?? ''}`}
66
+ aria-label="Draggable item"
67
+ onmousedown={startDrag}
68
+ role="button"
69
+ tabindex="0"
69
70
  >
70
- {@render children()}
71
+ {@render children()}
71
72
  </div>
72
73
 
73
74
  {#if isDragging}
74
- <div
75
- class="pointer-events-none fixed z-9999 -translate-x-1/2 -translate-y-1/2 scale-115 transform opacity-95 shadow-xl"
76
- style={`top:${mouseY}px; left:${mouseX}px;`}
77
- >
78
- {@render children()}
79
- </div>
75
+ <div
76
+ style={`top:${mouseY}px; left:${mouseX}px;`}
77
+ class="pointer-events-none fixed z-9999 -translate-x-1/2 -translate-y-1/2 scale-115 transform opacity-95 shadow-xl"
78
+ >
79
+ {@render children()}
80
+ </div>
80
81
  {/if}
@@ -2,10 +2,10 @@ import { type Snippet } from 'svelte';
2
2
  import type { DragManager } from './drag-manager.js';
3
3
  declare function $$render<T>(): {
4
4
  props: {
5
- data: T;
6
- manager: DragManager<T>;
7
5
  children: Snippet<[]>;
8
6
  class?: string;
7
+ data: T;
8
+ manager: DragManager<T>;
9
9
  };
10
10
  exports: {};
11
11
  bindings: "";