@getmicdrop/svelte-components 5.12.0 → 5.13.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 (78) hide show
  1. package/dist/index.spec.js +0 -1
  2. package/dist/patterns/navigation/Header.svelte +23 -27
  3. package/dist/patterns/navigation/Header.svelte.d.ts.map +1 -1
  4. package/dist/primitives/AvatarButton/AvatarButton.svelte +57 -0
  5. package/dist/primitives/AvatarButton/AvatarButton.svelte.d.ts +18 -0
  6. package/dist/primitives/AvatarButton/AvatarButton.svelte.d.ts.map +1 -0
  7. package/dist/primitives/BottomSheet/BottomSheet.spec.js +19 -19
  8. package/dist/primitives/BottomSheet/BottomSheet.svelte +5 -5
  9. package/dist/primitives/BottomSheet/BottomSheet.svelte.d.ts +2 -2
  10. package/dist/primitives/BottomSheet/BottomSheet.svelte.d.ts.map +1 -1
  11. package/dist/primitives/BottomSheet/BottomSheetWrapper.test.svelte +3 -3
  12. package/dist/primitives/BottomSheet/BottomSheetWrapper.test.svelte.d.ts +1 -1
  13. package/dist/primitives/Button/Button.spec.js +8 -8
  14. package/dist/primitives/Button/Button.svelte +9 -45
  15. package/dist/primitives/Button/Button.svelte.d.ts.map +1 -1
  16. package/dist/primitives/CardAction/CardAction.svelte +68 -0
  17. package/dist/primitives/CardAction/CardAction.svelte.d.ts +20 -0
  18. package/dist/primitives/CardAction/CardAction.svelte.d.ts.map +1 -0
  19. package/dist/primitives/Drawer/Drawer.spec.js +33 -33
  20. package/dist/primitives/Drawer/Drawer.svelte +5 -9
  21. package/dist/primitives/Drawer/Drawer.svelte.d.ts +2 -3
  22. package/dist/primitives/Drawer/Drawer.svelte.d.ts.map +1 -1
  23. package/dist/primitives/LandingButton/LandingButton.svelte +92 -0
  24. package/dist/primitives/LandingButton/LandingButton.svelte.d.ts +22 -0
  25. package/dist/primitives/LandingButton/LandingButton.svelte.d.ts.map +1 -0
  26. package/dist/primitives/MenuItem/MenuItem.svelte +85 -0
  27. package/dist/primitives/MenuItem/MenuItem.svelte.d.ts +24 -0
  28. package/dist/primitives/MenuItem/MenuItem.svelte.d.ts.map +1 -0
  29. package/dist/primitives/Modal/Modal.spec.js +7 -7
  30. package/dist/primitives/Modal/Modal.stories.svelte +3 -3
  31. package/dist/primitives/Modal/Modal.svelte +25 -18
  32. package/dist/primitives/Modal/Modal.svelte.d.ts +5 -5
  33. package/dist/primitives/Modal/Modal.svelte.d.ts.map +1 -1
  34. package/dist/primitives/Modal/ModalTestWrapper.svelte +3 -3
  35. package/dist/primitives/Modal/ModalTestWrapper.svelte.d.ts +2 -2
  36. package/dist/primitives/NavItem/NavItem.svelte +75 -0
  37. package/dist/primitives/NavItem/NavItem.svelte.d.ts +20 -0
  38. package/dist/primitives/NavItem/NavItem.svelte.d.ts.map +1 -0
  39. package/dist/primitives/SearchResultItem/SearchResultItem.svelte +109 -0
  40. package/dist/primitives/SearchResultItem/SearchResultItem.svelte.d.ts +26 -0
  41. package/dist/primitives/SearchResultItem/SearchResultItem.svelte.d.ts.map +1 -0
  42. package/dist/primitives/SidebarToggle/SidebarToggle.svelte +55 -0
  43. package/dist/primitives/SidebarToggle/SidebarToggle.svelte.d.ts +18 -0
  44. package/dist/primitives/SidebarToggle/SidebarToggle.svelte.d.ts.map +1 -0
  45. package/dist/primitives/index.d.ts +7 -0
  46. package/dist/primitives/index.js +21 -0
  47. package/dist/recipes/SuperLogin/SuperLogin.svelte +3 -3
  48. package/dist/recipes/SuperLogin/SuperLogin.svelte.d.ts.map +1 -1
  49. package/dist/recipes/inputs/index.d.ts +0 -1
  50. package/dist/recipes/inputs/index.js +0 -1
  51. package/dist/recipes/modals/AlertModal.spec.js +2 -2
  52. package/dist/recipes/modals/AlertModal.svelte +6 -6
  53. package/dist/recipes/modals/AlertModal.svelte.d.ts +3 -3
  54. package/dist/recipes/modals/ConfirmationModal.spec.js +2 -2
  55. package/dist/recipes/modals/ConfirmationModal.svelte +5 -5
  56. package/dist/recipes/modals/ConfirmationModal.svelte.d.ts +3 -3
  57. package/dist/recipes/modals/InputModal.spec.js +2 -2
  58. package/dist/recipes/modals/InputModal.svelte +4 -4
  59. package/dist/recipes/modals/InputModal.svelte.d.ts +3 -3
  60. package/dist/recipes/modals/ModalTestWrapper.spec.js +49 -49
  61. package/dist/recipes/modals/ModalTestWrapper.svelte +3 -3
  62. package/dist/recipes/modals/ModalTestWrapper.svelte.d.ts +2 -2
  63. package/dist/recipes/modals/StatusModal.spec.js +2 -2
  64. package/dist/recipes/modals/StatusModal.svelte +4 -4
  65. package/dist/recipes/modals/StatusModal.svelte.d.ts +3 -3
  66. package/dist/stories/ComponentConsolidation.stories.svelte +10 -10
  67. package/dist/stories/PrimitivesGallery.svelte +25 -21
  68. package/dist/stories/PrimitivesGallery.svelte.d.ts.map +1 -1
  69. package/dist/stories/RecipesGallery.spec.js +9 -18
  70. package/dist/stories/RecipesGallery.svelte +5 -22
  71. package/dist/stories/RecipesGallery.svelte.d.ts.map +1 -1
  72. package/package.json +1 -1
  73. package/dist/recipes/inputs/SelectDropdown.spec.d.ts +0 -2
  74. package/dist/recipes/inputs/SelectDropdown.spec.d.ts.map +0 -1
  75. package/dist/recipes/inputs/SelectDropdown.spec.js +0 -518
  76. package/dist/recipes/inputs/SelectDropdown.svelte +0 -171
  77. package/dist/recipes/inputs/SelectDropdown.svelte.d.ts +0 -16
  78. package/dist/recipes/inputs/SelectDropdown.svelte.d.ts.map +0 -1
@@ -0,0 +1,20 @@
1
+ import type { Snippet } from 'svelte';
2
+ interface Props {
3
+ /** Size variant */
4
+ size?: 'sm' | 'md' | 'lg';
5
+ /** Disabled state */
6
+ disabled?: boolean;
7
+ /** Selected/active state */
8
+ selected?: boolean;
9
+ /** Content */
10
+ children?: Snippet;
11
+ /** Additional classes */
12
+ class?: string;
13
+ /** Click handler */
14
+ onclick?: (e: MouseEvent) => void;
15
+ [key: string]: unknown;
16
+ }
17
+ declare const CardAction: import("svelte").Component<Props, {}, "">;
18
+ type CardAction = ReturnType<typeof CardAction>;
19
+ export default CardAction;
20
+ //# sourceMappingURL=CardAction.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CardAction.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/CardAction/CardAction.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAIpC,UAAU,KAAK;IACb,mBAAmB;IACnB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,qBAAqB;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IAClC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AA8CH,QAAA,MAAM,UAAU,2CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
@@ -14,52 +14,52 @@ describe('Drawer Component', () => {
14
14
  document.body.style.overflow = '';
15
15
  });
16
16
 
17
- test('does not render when show is false and hidden is true', () => {
18
- const { container } = render(Drawer, { props: { show: false, hidden: true } });
17
+ test('does not render when open is false', () => {
18
+ const { container } = render(Drawer, { props: { open: false } });
19
19
  expect(container.querySelector('[role="dialog"]')).not.toBeInTheDocument();
20
20
  });
21
21
 
22
- test('renders when show is true', () => {
23
- const { container } = render(Drawer, { props: { show: true } });
22
+ test('renders when open is true', () => {
23
+ const { container } = render(Drawer, { props: { open: true } });
24
24
  expect(container.querySelector('[role="dialog"]')).toBeInTheDocument();
25
25
  });
26
26
 
27
- test('renders when hidden is false', () => {
28
- const { container } = render(Drawer, { props: { hidden: false } });
27
+ test('renders when open is true (explicit)', () => {
28
+ const { container } = render(Drawer, { props: { open: true } });
29
29
  expect(container.querySelector('[role="dialog"]')).toBeInTheDocument();
30
30
  });
31
31
 
32
32
  test('has role="dialog" and aria-modal="true"', () => {
33
- const { container } = render(Drawer, { props: { show: true } });
33
+ const { container } = render(Drawer, { props: { open: true } });
34
34
  const dialog = container.querySelector('[role="dialog"]');
35
35
  expect(dialog).toHaveAttribute('aria-modal', 'true');
36
36
  });
37
37
 
38
38
  test('renders title when provided', () => {
39
- render(Drawer, { props: { show: true, title: 'Test Drawer', id: 'test-drawer' } });
39
+ render(Drawer, { props: { open: true, title: 'Test Drawer', id: 'test-drawer' } });
40
40
  expect(screen.getByText('Test Drawer')).toBeInTheDocument();
41
41
  });
42
42
 
43
43
  test('applies custom className', () => {
44
- const { container } = render(Drawer, { props: { show: true, class: 'custom-drawer' } });
44
+ const { container } = render(Drawer, { props: { open: true, class: 'custom-drawer' } });
45
45
  const dialog = container.querySelector('[role="dialog"]');
46
46
  expect(dialog).toHaveClass('custom-drawer');
47
47
  });
48
48
 
49
49
  test('renders backdrop by default when visible', () => {
50
- const { container } = render(Drawer, { props: { show: true } });
50
+ const { container } = render(Drawer, { props: { open: true } });
51
51
  const backdrop = container.querySelector('[role="presentation"]');
52
52
  expect(backdrop).toBeInTheDocument();
53
53
  });
54
54
 
55
55
  test('does not render backdrop when backdrop is false', () => {
56
- const { container } = render(Drawer, { props: { show: true, backdrop: false } });
56
+ const { container } = render(Drawer, { props: { open: true, backdrop: false } });
57
57
  const backdrop = container.querySelector('[role="presentation"]');
58
58
  expect(backdrop).not.toBeInTheDocument();
59
59
  });
60
60
 
61
61
  test('passes through id prop', () => {
62
- const { container } = render(Drawer, { props: { show: true, id: 'my-drawer' } });
62
+ const { container } = render(Drawer, { props: { open: true, id: 'my-drawer' } });
63
63
  const dialog = container.querySelector('#my-drawer');
64
64
  expect(dialog).toBeInTheDocument();
65
65
  });
@@ -67,25 +67,25 @@ describe('Drawer Component', () => {
67
67
 
68
68
  describe('Drawer Placements', () => {
69
69
  test('left placement has left-0 class', () => {
70
- const { container } = render(Drawer, { props: { show: true, placement: 'left' } });
70
+ const { container } = render(Drawer, { props: { open: true, placement: 'left' } });
71
71
  const dialog = container.querySelector('[role="dialog"]');
72
72
  expect(dialog).toHaveClass('left-0');
73
73
  });
74
74
 
75
75
  test('right placement has right-0 class', () => {
76
- const { container } = render(Drawer, { props: { show: true, placement: 'right' } });
76
+ const { container } = render(Drawer, { props: { open: true, placement: 'right' } });
77
77
  const dialog = container.querySelector('[role="dialog"]');
78
78
  expect(dialog).toHaveClass('right-0');
79
79
  });
80
80
 
81
81
  test('top placement has top-0 class', () => {
82
- const { container } = render(Drawer, { props: { show: true, placement: 'top' } });
82
+ const { container } = render(Drawer, { props: { open: true, placement: 'top' } });
83
83
  const dialog = container.querySelector('[role="dialog"]');
84
84
  expect(dialog).toHaveClass('top-0');
85
85
  });
86
86
 
87
87
  test('bottom placement has bottom-0 class', () => {
88
- const { container } = render(Drawer, { props: { show: true, placement: 'bottom' } });
88
+ const { container } = render(Drawer, { props: { open: true, placement: 'bottom' } });
89
89
  const dialog = container.querySelector('[role="dialog"]');
90
90
  expect(dialog).toHaveClass('bottom-0');
91
91
  });
@@ -93,25 +93,25 @@ describe('Drawer Placements', () => {
93
93
 
94
94
  describe('Drawer Widths', () => {
95
95
  test('sm width applies w-64', () => {
96
- const { container } = render(Drawer, { props: { show: true, width: 'sm' } });
96
+ const { container } = render(Drawer, { props: { open: true, width: 'sm' } });
97
97
  const dialog = container.querySelector('[role="dialog"]');
98
98
  expect(dialog).toHaveClass('w-64');
99
99
  });
100
100
 
101
101
  test('md width applies w-80 (default)', () => {
102
- const { container } = render(Drawer, { props: { show: true } });
102
+ const { container } = render(Drawer, { props: { open: true } });
103
103
  const dialog = container.querySelector('[role="dialog"]');
104
104
  expect(dialog).toHaveClass('w-80');
105
105
  });
106
106
 
107
107
  test('lg width applies w-96', () => {
108
- const { container } = render(Drawer, { props: { show: true, width: 'lg' } });
108
+ const { container } = render(Drawer, { props: { open: true, width: 'lg' } });
109
109
  const dialog = container.querySelector('[role="dialog"]');
110
110
  expect(dialog).toHaveClass('w-96');
111
111
  });
112
112
 
113
113
  test('full width applies w-full', () => {
114
- const { container } = render(Drawer, { props: { show: true, width: 'full' } });
114
+ const { container } = render(Drawer, { props: { open: true, width: 'full' } });
115
115
  const dialog = container.querySelector('[role="dialog"]');
116
116
  expect(dialog).toHaveClass('w-full');
117
117
  });
@@ -119,13 +119,13 @@ describe('Drawer Widths', () => {
119
119
 
120
120
  describe('Drawer Accessibility', () => {
121
121
  test('has tabindex="-1" for focus management', () => {
122
- const { container } = render(Drawer, { props: { show: true } });
122
+ const { container } = render(Drawer, { props: { open: true } });
123
123
  const dialog = container.querySelector('[role="dialog"]');
124
124
  expect(dialog).toHaveAttribute('tabindex', '-1');
125
125
  });
126
126
 
127
127
  test('has aria-labelledby when title and id are provided', () => {
128
- const { container } = render(Drawer, { props: { show: true, title: 'Test', id: 'test-drawer' } });
128
+ const { container } = render(Drawer, { props: { open: true, title: 'Test', id: 'test-drawer' } });
129
129
  const dialog = container.querySelector('[role="dialog"]');
130
130
  expect(dialog).toHaveAttribute('aria-labelledby', 'test-drawer-label');
131
131
  });
@@ -133,32 +133,32 @@ describe('Drawer Accessibility', () => {
133
133
 
134
134
  describe('Drawer Styling', () => {
135
135
  test('has fixed positioning', () => {
136
- const { container } = render(Drawer, { props: { show: true } });
136
+ const { container } = render(Drawer, { props: { open: true } });
137
137
  const dialog = container.querySelector('[role="dialog"]');
138
138
  expect(dialog).toHaveClass('fixed');
139
139
  });
140
140
 
141
141
  test('has z-40 for stacking', () => {
142
- const { container } = render(Drawer, { props: { show: true } });
142
+ const { container } = render(Drawer, { props: { open: true } });
143
143
  const dialog = container.querySelector('[role="dialog"]');
144
144
  expect(dialog).toHaveClass('z-40');
145
145
  });
146
146
 
147
147
  test('has flex flex-col layout', () => {
148
- const { container } = render(Drawer, { props: { show: true } });
148
+ const { container } = render(Drawer, { props: { open: true } });
149
149
  const dialog = container.querySelector('[role="dialog"]');
150
150
  expect(dialog).toHaveClass('flex');
151
151
  expect(dialog).toHaveClass('flex-col');
152
152
  });
153
153
 
154
154
  test('has bg-white background', () => {
155
- const { container } = render(Drawer, { props: { show: true } });
155
+ const { container } = render(Drawer, { props: { open: true } });
156
156
  const dialog = container.querySelector('[role="dialog"]');
157
157
  expect(dialog).toHaveClass('bg-white');
158
158
  });
159
159
 
160
160
  test('has dark mode background', () => {
161
- const { container } = render(Drawer, { props: { show: true } });
161
+ const { container } = render(Drawer, { props: { open: true } });
162
162
  const dialog = container.querySelector('[role="dialog"]');
163
163
  expect(dialog).toHaveClass('dark:bg-gray-800');
164
164
  });
@@ -166,13 +166,13 @@ describe('Drawer Styling', () => {
166
166
 
167
167
  describe('Drawer Edge Mode', () => {
168
168
  test('shows edge trigger when edge=true, placement=bottom, and not visible', () => {
169
- const { container } = render(Drawer, { props: { edge: true, placement: 'bottom', show: false, hidden: true } });
169
+ const { container } = render(Drawer, { props: { edge: true, placement: 'bottom', open: false } });
170
170
  const edgeTrigger = container.querySelector('.cursor-pointer');
171
171
  expect(edgeTrigger).toBeInTheDocument();
172
172
  });
173
173
 
174
174
  test('hides edge trigger when drawer is visible', () => {
175
- const { container } = render(Drawer, { props: { edge: true, placement: 'bottom', show: true } });
175
+ const { container } = render(Drawer, { props: { edge: true, placement: 'bottom', open: true } });
176
176
  // Edge trigger should not be visible when drawer is open
177
177
  const edgeTriggers = container.querySelectorAll('.cursor-pointer.fixed');
178
178
  // The drawer itself might have cursor classes, so check for the specific edge trigger pattern
@@ -184,20 +184,20 @@ describe('Drawer Callbacks', () => {
184
184
  test('onclose prop is accepted', () => {
185
185
  const onclose = vi.fn();
186
186
  const { container } = render(Drawer, {
187
- props: { show: true, closeOnBackdropClick: true, onclose }
187
+ props: { open: true, closeOnBackdropClick: true, onclose }
188
188
  });
189
189
  // Verify drawer renders with onclose callback
190
190
  expect(container.querySelector('[role="dialog"]')).toBeInTheDocument();
191
191
  });
192
192
 
193
193
  test('closeOnBackdropClick prop defaults to true', () => {
194
- const { container } = render(Drawer, { props: { show: true } });
194
+ const { container } = render(Drawer, { props: { open: true } });
195
195
  // Drawer renders with default closeOnBackdropClick behavior
196
196
  expect(container.querySelector('[role="presentation"]')).toBeInTheDocument();
197
197
  });
198
198
 
199
199
  test('closeOnEscape prop defaults to true', () => {
200
- const { container } = render(Drawer, { props: { show: true } });
200
+ const { container } = render(Drawer, { props: { open: true } });
201
201
  // Drawer accepts closeOnEscape prop
202
202
  expect(container.querySelector('[role="dialog"]')).toBeInTheDocument();
203
203
  });
@@ -205,7 +205,7 @@ describe('Drawer Callbacks', () => {
205
205
  test('onopen prop is accepted', () => {
206
206
  const onopen = vi.fn();
207
207
  const { container } = render(Drawer, {
208
- props: { show: true, onopen }
208
+ props: { open: true, onopen }
209
209
  });
210
210
  expect(container.querySelector('[role="dialog"]')).toBeInTheDocument();
211
211
  });
@@ -5,8 +5,7 @@
5
5
  import type { Snippet } from "svelte";
6
6
 
7
7
  interface Props {
8
- show?: boolean;
9
- hidden?: boolean;
8
+ open?: boolean;
10
9
  title?: string;
11
10
  placement?: string;
12
11
  width?: string;
@@ -26,8 +25,7 @@
26
25
  }
27
26
 
28
27
  let {
29
- show = $bindable(false),
30
- hidden = $bindable(true),
28
+ open = $bindable(false),
31
29
  title = "",
32
30
  placement = "left",
33
31
  width = "md",
@@ -46,7 +44,7 @@
46
44
  ...restProps
47
45
  }: Props = $props();
48
46
 
49
- let isVisible = $derived(show || !hidden);
47
+ let isVisible = $derived(open);
50
48
  let drawerElement: HTMLElement | null = $state(null);
51
49
  let previouslyFocusedElement: Element | null = $state(null);
52
50
 
@@ -89,8 +87,7 @@
89
87
  });
90
88
 
91
89
  function close() {
92
- hidden = true;
93
- show = false;
90
+ open = false;
94
91
  onclose?.();
95
92
  }
96
93
 
@@ -128,8 +125,7 @@
128
125
 
129
126
  function handleEdgeClick() {
130
127
  if (edge && placement === "bottom") {
131
- hidden = false;
132
- show = true;
128
+ open = true;
133
129
  onopen?.();
134
130
  }
135
131
  }
@@ -1,7 +1,6 @@
1
1
  import type { Snippet } from "svelte";
2
2
  interface Props {
3
- show?: boolean;
4
- hidden?: boolean;
3
+ open?: boolean;
5
4
  title?: string;
6
5
  placement?: string;
7
6
  width?: string;
@@ -19,7 +18,7 @@ interface Props {
19
18
  class?: string;
20
19
  [key: string]: unknown;
21
20
  }
22
- declare const Drawer: import("svelte").Component<Props, {}, "show" | "hidden">;
21
+ declare const Drawer: import("svelte").Component<Props, {}, "open">;
23
22
  type Drawer = ReturnType<typeof Drawer>;
24
23
  export default Drawer;
25
24
  //# sourceMappingURL=Drawer.svelte.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Drawer.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Drawer/Drawer.svelte.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGpC,UAAU,KAAK;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAsMH,QAAA,MAAM,MAAM,0DAAwC,CAAC;AACrD,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC;AACxC,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"Drawer.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Drawer/Drawer.svelte.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGpC,UAAU,KAAK;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAmMH,QAAA,MAAM,MAAM,+CAAwC,CAAC;AACrD,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC;AACxC,eAAe,MAAM,CAAC"}
@@ -0,0 +1,92 @@
1
+ <script lang="ts">
2
+ /**
3
+ * LandingButton Component
4
+ * Hero/landing page CTA buttons with shadow and prominent styling.
5
+ *
6
+ * Replaces: Button variant="landing" and variant="landing-secondary"
7
+ */
8
+ import { twMerge } from 'tailwind-merge';
9
+ import type { Snippet } from 'svelte';
10
+ import { buttonSizes } from '../../tokens/sizing.js';
11
+
12
+ interface Props {
13
+ /** Visual style: primary (blue) or secondary (outline) */
14
+ variant?: 'primary' | 'secondary';
15
+ /** Disabled state */
16
+ disabled?: boolean;
17
+ /** Loading state */
18
+ loading?: boolean;
19
+ /** Link href (renders as <a> if provided) */
20
+ href?: string | null;
21
+ /** Content */
22
+ children?: Snippet;
23
+ /** Additional classes */
24
+ class?: string;
25
+ /** Click handler */
26
+ onclick?: (e: MouseEvent) => void;
27
+ [key: string]: unknown;
28
+ }
29
+
30
+ let {
31
+ variant = 'primary',
32
+ disabled = false,
33
+ loading = false,
34
+ href = null,
35
+ children,
36
+ class: className = '',
37
+ onclick,
38
+ ...restProps
39
+ }: Props = $props();
40
+
41
+ let effectiveDisabled = $derived(disabled || loading);
42
+
43
+ const baseClasses = 'inline-flex items-center justify-center rounded-xl font-medium leading-none focus:outline-hidden transition-all duration-150 ease-out select-none no-underline hover:no-underline shadow hover:shadow-md';
44
+
45
+ const variantClasses = {
46
+ primary: 'text-white bg-blue-600 border border-blue-600 hover:bg-blue-700 dark:bg-blue-600 dark:border-blue-600 dark:hover:bg-blue-700',
47
+ secondary: 'text-gray-700 bg-white border border-gray-200 hover:border-gray-400 hover:text-gray-900 dark:text-gray-300 dark:bg-gray-800 dark:border-gray-600 dark:hover:border-gray-500 dark:hover:text-gray-100',
48
+ };
49
+
50
+ const disabledClasses = 'bg-gray-200 border-gray-200 text-gray-400 cursor-not-allowed shadow-none dark:bg-gray-700 dark:border-gray-700 dark:text-gray-500';
51
+
52
+ // Landing size from tokens
53
+ let sizeClass = $derived(buttonSizes.landing);
54
+
55
+ let variantClass = $derived(() => {
56
+ if (effectiveDisabled) return disabledClasses;
57
+ return variantClasses[variant] || variantClasses.primary;
58
+ });
59
+
60
+ let classes = $derived(twMerge(
61
+ baseClasses,
62
+ sizeClass,
63
+ variantClass(),
64
+ effectiveDisabled ? 'cursor-not-allowed' : 'cursor-pointer active:scale-[0.97] active:opacity-90',
65
+ className
66
+ ));
67
+ </script>
68
+
69
+ {#if href}
70
+ <a
71
+ {href}
72
+ class={classes}
73
+ {onclick}
74
+ {...restProps}
75
+ >
76
+ <span class="inline-flex items-center gap-1.5" class:invisible={loading}>
77
+ {#if typeof children === 'function'}{@render children()}{:else if children}{children}{/if}
78
+ </span>
79
+ </a>
80
+ {:else}
81
+ <button
82
+ type="button"
83
+ class={classes}
84
+ disabled={effectiveDisabled}
85
+ {onclick}
86
+ {...restProps}
87
+ >
88
+ <span class="inline-flex items-center gap-1.5" class:invisible={loading}>
89
+ {#if typeof children === 'function'}{@render children()}{:else if children}{children}{/if}
90
+ </span>
91
+ </button>
92
+ {/if}
@@ -0,0 +1,22 @@
1
+ import type { Snippet } from 'svelte';
2
+ interface Props {
3
+ /** Visual style: primary (blue) or secondary (outline) */
4
+ variant?: 'primary' | 'secondary';
5
+ /** Disabled state */
6
+ disabled?: boolean;
7
+ /** Loading state */
8
+ loading?: boolean;
9
+ /** Link href (renders as <a> if provided) */
10
+ href?: string | null;
11
+ /** Content */
12
+ children?: Snippet;
13
+ /** Additional classes */
14
+ class?: string;
15
+ /** Click handler */
16
+ onclick?: (e: MouseEvent) => void;
17
+ [key: string]: unknown;
18
+ }
19
+ declare const LandingButton: import("svelte").Component<Props, {}, "">;
20
+ type LandingButton = ReturnType<typeof LandingButton>;
21
+ export default LandingButton;
22
+ //# sourceMappingURL=LandingButton.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LandingButton.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/LandingButton/LandingButton.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAIpC,UAAU,KAAK;IACb,0DAA0D;IAC1D,OAAO,CAAC,EAAE,SAAS,GAAG,WAAW,CAAC;IAClC,qBAAqB;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oBAAoB;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,cAAc;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IAClC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AA+DH,QAAA,MAAM,aAAa,2CAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
@@ -0,0 +1,85 @@
1
+ <script lang="ts">
2
+ /**
3
+ * MenuItem Component
4
+ * For dropdown menus, action sheets, and sidebar navigation items.
5
+ *
6
+ * Replaces: Button variant="menu-item" and variant="menu-item-danger"
7
+ */
8
+ import { twMerge } from 'tailwind-merge';
9
+ import type { Snippet } from 'svelte';
10
+ import { buttonMenuItemSizes } from '../../tokens/sizing.js';
11
+
12
+ interface Props {
13
+ /** Destructive/danger styling (red text) */
14
+ danger?: boolean;
15
+ /** Size variant */
16
+ size?: 'sm' | 'md' | 'lg' | 'nav';
17
+ /** Disabled state */
18
+ disabled?: boolean;
19
+ /** Active/selected state */
20
+ active?: boolean;
21
+ /** Content */
22
+ children?: Snippet;
23
+ /** Trailing content (icons, badges) */
24
+ trailing?: Snippet;
25
+ /** Additional classes */
26
+ class?: string;
27
+ /** Click handler */
28
+ onclick?: (e: MouseEvent) => void;
29
+ [key: string]: unknown;
30
+ }
31
+
32
+ let {
33
+ danger = false,
34
+ size = 'md',
35
+ disabled = false,
36
+ active = false,
37
+ children,
38
+ trailing,
39
+ class: className = '',
40
+ onclick,
41
+ ...restProps
42
+ }: Props = $props();
43
+
44
+ const baseClasses = 'w-full text-left whitespace-nowrap bg-transparent border-transparent rounded-lg font-medium leading-none focus:outline-hidden transition-all duration-150 ease-out select-none';
45
+
46
+ const variantClasses = {
47
+ default: 'text-gray-900 hover:bg-gray-100 dark:text-white dark:hover:bg-gray-600',
48
+ danger: 'text-red-600 hover:bg-red-50 dark:text-red-500 dark:hover:bg-gray-600',
49
+ };
50
+
51
+ const activeClasses = 'bg-blue-50 dark:bg-gray-700';
52
+ const disabledClasses = 'text-gray-400 cursor-not-allowed dark:text-gray-500';
53
+
54
+ let sizeClass = $derived(buttonMenuItemSizes[size] || buttonMenuItemSizes.md);
55
+
56
+ let variantClass = $derived(() => {
57
+ if (disabled) return disabledClasses;
58
+ if (active) return `${variantClasses[danger ? 'danger' : 'default']} ${activeClasses}`;
59
+ return variantClasses[danger ? 'danger' : 'default'];
60
+ });
61
+
62
+ let hasTrailing = $derived(typeof trailing === 'function' || trailing);
63
+
64
+ let classes = $derived(twMerge(
65
+ baseClasses,
66
+ hasTrailing ? 'flex items-center justify-between' : 'flex items-center justify-start',
67
+ sizeClass,
68
+ variantClass(),
69
+ disabled ? 'cursor-not-allowed' : 'cursor-pointer active:scale-[0.97] active:opacity-90',
70
+ className
71
+ ));
72
+ </script>
73
+
74
+ <button
75
+ type="button"
76
+ class={classes}
77
+ {disabled}
78
+ {onclick}
79
+ {...restProps}
80
+ >
81
+ <span class="inline-flex items-center gap-1.5">
82
+ {#if typeof children === 'function'}{@render children()}{:else if children}{children}{/if}
83
+ </span>
84
+ {#if typeof trailing === 'function'}{@render trailing()}{:else if trailing}{trailing}{/if}
85
+ </button>
@@ -0,0 +1,24 @@
1
+ import type { Snippet } from 'svelte';
2
+ interface Props {
3
+ /** Destructive/danger styling (red text) */
4
+ danger?: boolean;
5
+ /** Size variant */
6
+ size?: 'sm' | 'md' | 'lg' | 'nav';
7
+ /** Disabled state */
8
+ disabled?: boolean;
9
+ /** Active/selected state */
10
+ active?: boolean;
11
+ /** Content */
12
+ children?: Snippet;
13
+ /** Trailing content (icons, badges) */
14
+ trailing?: Snippet;
15
+ /** Additional classes */
16
+ class?: string;
17
+ /** Click handler */
18
+ onclick?: (e: MouseEvent) => void;
19
+ [key: string]: unknown;
20
+ }
21
+ declare const MenuItem: import("svelte").Component<Props, {}, "">;
22
+ type MenuItem = ReturnType<typeof MenuItem>;
23
+ export default MenuItem;
24
+ //# sourceMappingURL=MenuItem.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MenuItem.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/MenuItem/MenuItem.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAIpC,UAAU,KAAK;IACb,4CAA4C;IAC5C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,mBAAmB;IACnB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC;IAClC,qBAAqB;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4BAA4B;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,cAAc;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IAClC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AA2DH,QAAA,MAAM,QAAQ,2CAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
@@ -14,9 +14,9 @@ describe('Modal Component Tests', () => {
14
14
  // CSS hides one based on viewport, but in tests both are in DOM
15
15
  // Use getAllByText and check that at least one exists
16
16
 
17
- test('Renders Modal when show is true', () => {
17
+ test('Renders Modal when open is true', () => {
18
18
  setupTest({
19
- show: true,
19
+ open: true,
20
20
  title: 'Test Title',
21
21
  description: 'Test Description',
22
22
  warningText: 'Test Warning'
@@ -29,9 +29,9 @@ describe('Modal Component Tests', () => {
29
29
  expect(screen.getAllByRole('button', { name: /Confirm/i }).length).toBeGreaterThan(0);
30
30
  });
31
31
 
32
- test('Does not render Modal when show is false', () => {
32
+ test('Does not render Modal when open is false', () => {
33
33
  setupTest({
34
- show: false,
34
+ open: false,
35
35
  title: 'Test Title',
36
36
  description: 'Test Description',
37
37
  warningText: 'Test Warning'
@@ -46,7 +46,7 @@ describe('Modal Component Tests', () => {
46
46
  const description = 'Correct Description';
47
47
  const warningText = 'Correct Warning';
48
48
  setupTest({
49
- show: true,
49
+ open: true,
50
50
  title,
51
51
  description,
52
52
  warningText,
@@ -62,7 +62,7 @@ describe('Modal Component Tests', () => {
62
62
  const oncancel = vi.fn();
63
63
 
64
64
  const { user } = setupTest({
65
- show: true,
65
+ open: true,
66
66
  title: 'Test Title',
67
67
  oncancel
68
68
  });
@@ -79,7 +79,7 @@ describe('Modal Component Tests', () => {
79
79
 
80
80
  test('Prevents propagation of click events within modal', async () => {
81
81
  const { user } = setupTest({
82
- show: true,
82
+ open: true,
83
83
  title: 'Test Title'
84
84
  });
85
85
 
@@ -22,7 +22,7 @@
22
22
  >
23
23
  Open Basic Modal
24
24
  </button>
25
- <ModalProgress bind:show={show1}>
25
+ <ModalProgress bind:open={show1}>
26
26
  {#snippet header()}
27
27
  <h2 class="text-xl font-semibold mb-2">Modal Title</h2>
28
28
  {/snippet}
@@ -47,7 +47,7 @@
47
47
  >
48
48
  Open Processing Modal
49
49
  </button>
50
- <ModalProgress bind:show={show2} isProcessing={true}>
50
+ <ModalProgress bind:open={show2} isProcessing={true}>
51
51
  {#snippet body()}
52
52
  <div class="flex flex-col items-center gap-4">
53
53
  <div
@@ -66,7 +66,7 @@
66
66
  >
67
67
  Open Success Modal
68
68
  </button>
69
- <ModalProgress bind:show={show3} isSuccess={true}>
69
+ <ModalProgress bind:open={show3} isSuccess={true}>
70
70
  {#snippet body()}
71
71
  <div class="flex flex-col items-center gap-4 text-center">
72
72
  <div class="text-green-600 dark:text-green-400 text-5xl">✓</div>