@ainsleydev/sveltekit-helper 0.1.4 → 0.2.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.
- package/README.md +188 -6
- package/dist/components/Grid/Column.svelte +2 -3
- package/dist/components/Grid/Container.svelte +2 -5
- package/dist/components/Grid/Row.svelte +2 -3
- package/dist/components/Hamburger.svelte +62 -0
- package/dist/components/Hamburger.svelte.d.ts +27 -0
- package/dist/components/Hamburger.svelte.d.ts.map +1 -0
- package/dist/components/Sidebar.svelte +274 -0
- package/dist/components/Sidebar.svelte.d.ts +41 -0
- package/dist/components/Sidebar.svelte.d.ts.map +1 -0
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +2 -0
- package/dist/components/payload/PayloadForm.svelte +23 -37
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/package.json +9 -2
package/README.md
CHANGED
|
@@ -11,12 +11,43 @@ pnpm add @ainsleydev/sveltekit-helper
|
|
|
11
11
|
## Features
|
|
12
12
|
|
|
13
13
|
- **Grid System**: Responsive Container, Row, and Column components with CSS variables
|
|
14
|
+
- **Navigation Components**: Mobile-first Sidebar and Hamburger menu components
|
|
14
15
|
- **Form Utilities**: Schema generation and error helpers for Zod validation
|
|
15
16
|
- **Payload CMS Integration**: Ready-to-use components for Payload CMS forms and media
|
|
16
17
|
- **SCSS with BEM**: All components use SCSS with BEM naming convention
|
|
17
18
|
|
|
18
19
|
## Grid Components
|
|
19
20
|
|
|
21
|
+
### CSS Variable Customization
|
|
22
|
+
|
|
23
|
+
All Grid components use CSS variables with fallback values, allowing flexible customization:
|
|
24
|
+
|
|
25
|
+
**Override Priority (highest to lowest):**
|
|
26
|
+
1. Inline styles: `<Container style="--container-padding: 2rem">`
|
|
27
|
+
2. Page/component-scoped: `.pricing-page { --container-padding: 3rem; }`
|
|
28
|
+
3. Global: `:root { --container-padding: 2rem; }`
|
|
29
|
+
4. Component defaults: Defined in each component's `<style>` block
|
|
30
|
+
|
|
31
|
+
**Responsive Variables:**
|
|
32
|
+
|
|
33
|
+
Row and Column components include mobile-specific overrides (< 568px). You can customise responsive behaviour using:
|
|
34
|
+
|
|
35
|
+
```css
|
|
36
|
+
:root {
|
|
37
|
+
/* Override both desktop and mobile */
|
|
38
|
+
--row-gap: 1.5rem;
|
|
39
|
+
|
|
40
|
+
/* Override mobile only */
|
|
41
|
+
--row-gap-mobile: 0.75rem;
|
|
42
|
+
--col-gap-mobile: 0.75rem;
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Fallback chain on mobile:**
|
|
47
|
+
1. `--row-gap-mobile` (if set)
|
|
48
|
+
2. `--row-gap` (if set)
|
|
49
|
+
3. `0.5rem` (component default)
|
|
50
|
+
|
|
20
51
|
### Container
|
|
21
52
|
|
|
22
53
|
Center content horizontally with predefined max-width and support for breakout layouts.
|
|
@@ -37,14 +68,28 @@ Center content horizontally with predefined max-width and support for breakout l
|
|
|
37
68
|
|
|
38
69
|
#### Customisation
|
|
39
70
|
|
|
40
|
-
Override CSS variables
|
|
71
|
+
Override CSS variables globally from `:root`:
|
|
41
72
|
|
|
42
73
|
```css
|
|
43
|
-
|
|
74
|
+
/* Global override for ALL containers */
|
|
75
|
+
:root {
|
|
44
76
|
--container-padding: 2rem;
|
|
45
77
|
--container-max-width: 1400px;
|
|
46
78
|
--container-breakout-max-width: 1600px;
|
|
47
79
|
}
|
|
80
|
+
|
|
81
|
+
/* Page-specific override */
|
|
82
|
+
.pricing-page {
|
|
83
|
+
--container-padding: 3rem;
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Or use inline styles for single instances:
|
|
88
|
+
|
|
89
|
+
```svelte
|
|
90
|
+
<Container style="--container-padding: 2rem">
|
|
91
|
+
<Row>...</Row>
|
|
92
|
+
</Container>
|
|
48
93
|
```
|
|
49
94
|
|
|
50
95
|
### Row
|
|
@@ -70,11 +115,21 @@ Flexbox row container with gap management.
|
|
|
70
115
|
#### Customisation
|
|
71
116
|
|
|
72
117
|
```css
|
|
73
|
-
|
|
118
|
+
/* Global override */
|
|
119
|
+
:root {
|
|
74
120
|
--row-gap: 1.5rem;
|
|
121
|
+
--row-gap-mobile: 0.75rem; /* Optional: mobile-specific gap (< 568px) */
|
|
75
122
|
}
|
|
76
123
|
```
|
|
77
124
|
|
|
125
|
+
Or use inline styles:
|
|
126
|
+
|
|
127
|
+
```svelte
|
|
128
|
+
<Row style="--row-gap: 0.5rem">
|
|
129
|
+
<Column>...</Column>
|
|
130
|
+
</Row>
|
|
131
|
+
```
|
|
132
|
+
|
|
78
133
|
### Column
|
|
79
134
|
|
|
80
135
|
Base column component with customisable gap. Consumers should define their own grid classes in global styles.
|
|
@@ -88,8 +143,10 @@ Base column component with customisable gap. Consumers should define their own g
|
|
|
88
143
|
#### Customisation
|
|
89
144
|
|
|
90
145
|
```css
|
|
91
|
-
|
|
146
|
+
/* Global column gap */
|
|
147
|
+
:root {
|
|
92
148
|
--col-gap: 1.5rem;
|
|
149
|
+
--col-gap-mobile: 0.75rem; /* Optional: mobile-specific gap (< 568px) */
|
|
93
150
|
}
|
|
94
151
|
|
|
95
152
|
/* Define your own grid classes */
|
|
@@ -101,6 +158,128 @@ Base column component with customisable gap. Consumers should define their own g
|
|
|
101
158
|
}
|
|
102
159
|
```
|
|
103
160
|
|
|
161
|
+
## Navigation Components
|
|
162
|
+
|
|
163
|
+
### Sidebar
|
|
164
|
+
|
|
165
|
+
Mobile-first sidebar navigation component with toggle and hamburger display modes. Automatically collapses on mobile and remains visible on desktop.
|
|
166
|
+
|
|
167
|
+
```svelte
|
|
168
|
+
<script>
|
|
169
|
+
import { Sidebar } from '@ainsleydev/sveltekit-helper/components'
|
|
170
|
+
</script>
|
|
171
|
+
|
|
172
|
+
<Sidebar bind:isOpen>
|
|
173
|
+
<nav>
|
|
174
|
+
<a href="/">Home</a>
|
|
175
|
+
<a href="/about">About</a>
|
|
176
|
+
<a href="/contact">Contact</a>
|
|
177
|
+
</nav>
|
|
178
|
+
</Sidebar>
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
#### Props
|
|
182
|
+
|
|
183
|
+
- `menuLabel?: string` - Label for toggle button (default: 'Menu')
|
|
184
|
+
- `isOpen?: boolean` - Bindable open/closed state
|
|
185
|
+
- `position?: 'left' | 'right'` - Sidebar position (default: 'left')
|
|
186
|
+
- `width?: string` - Sidebar width on mobile (default: '50vw')
|
|
187
|
+
- `top?: number` - Sticky position offset on desktop (default: 160)
|
|
188
|
+
- `closeOnOverlayClick?: boolean` - Close when overlay is clicked (default: true)
|
|
189
|
+
- `overlayOpacity?: number` - Overlay opacity when open (default: 0.3)
|
|
190
|
+
- `toggleStyle?: 'toggle' | 'hamburger'` - Toggle display mode (default: 'toggle')
|
|
191
|
+
- `class?: string` - Additional CSS classes
|
|
192
|
+
- `onOpen?: () => void` - Callback when sidebar opens
|
|
193
|
+
- `onClose?: () => void` - Callback when sidebar closes
|
|
194
|
+
- `onToggle?: (isOpen: boolean) => void` - Callback when sidebar toggles
|
|
195
|
+
|
|
196
|
+
#### Examples
|
|
197
|
+
|
|
198
|
+
With hamburger menu:
|
|
199
|
+
|
|
200
|
+
```svelte
|
|
201
|
+
<Sidebar toggleStyle="hamburger" bind:isOpen>
|
|
202
|
+
<nav>...</nav>
|
|
203
|
+
</Sidebar>
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Right-side with custom width:
|
|
207
|
+
|
|
208
|
+
```svelte
|
|
209
|
+
<Sidebar position="right" width="300px">
|
|
210
|
+
<nav>...</nav>
|
|
211
|
+
</Sidebar>
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
#### Customisation
|
|
215
|
+
|
|
216
|
+
Override CSS variables globally from `:root`:
|
|
217
|
+
|
|
218
|
+
```css
|
|
219
|
+
:root {
|
|
220
|
+
--sidebar-width: 400px;
|
|
221
|
+
--sidebar-min-width: 300px;
|
|
222
|
+
--sidebar-background: #1a1a1a;
|
|
223
|
+
--sidebar-border-colour: rgba(255, 255, 255, 0.2);
|
|
224
|
+
--sidebar-overlay-colour: #000;
|
|
225
|
+
--sidebar-overlay-opacity: 0.5;
|
|
226
|
+
|
|
227
|
+
/* Toggle button */
|
|
228
|
+
--sidebar-toggle-background: #2a2a2a;
|
|
229
|
+
--sidebar-toggle-colour: #fff;
|
|
230
|
+
--sidebar-toggle-padding: 0.5rem 1.5rem;
|
|
231
|
+
--sidebar-toggle-radius: 8px;
|
|
232
|
+
--sidebar-toggle-font-size: 1rem;
|
|
233
|
+
|
|
234
|
+
/* Inner spacing */
|
|
235
|
+
--sidebar-inner-padding: 2rem 2rem 0 2rem;
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Or use inline styles:
|
|
240
|
+
|
|
241
|
+
```svelte
|
|
242
|
+
<Sidebar style="--sidebar-background: #2a2a2a; --sidebar-width: 400px">
|
|
243
|
+
<nav>...</nav>
|
|
244
|
+
</Sidebar>
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Hamburger
|
|
248
|
+
|
|
249
|
+
Hamburger menu icon with animation for mobile navigation. Uses `svelte-hamburgers` under the hood.
|
|
250
|
+
|
|
251
|
+
```svelte
|
|
252
|
+
<script>
|
|
253
|
+
import { Hamburger } from '@ainsleydev/sveltekit-helper/components'
|
|
254
|
+
|
|
255
|
+
let isOpen = $state(false)
|
|
256
|
+
</script>
|
|
257
|
+
|
|
258
|
+
<Hamburger bind:isOpen />
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
#### Props
|
|
262
|
+
|
|
263
|
+
- `isOpen?: boolean` - Bindable open/closed state
|
|
264
|
+
- `gap?: string` - Distance from top/right edges (default: '0.8rem')
|
|
265
|
+
- `class?: string` - Additional CSS classes
|
|
266
|
+
- `ariaLabel?: string` - Accessibility label (default: 'Toggle menu')
|
|
267
|
+
- `onChange?: (isOpen: boolean) => void` - Callback when state changes
|
|
268
|
+
|
|
269
|
+
#### Customisation
|
|
270
|
+
|
|
271
|
+
```css
|
|
272
|
+
:root {
|
|
273
|
+
--hamburger-gap: 1rem;
|
|
274
|
+
--hamburger-z-index: 10000;
|
|
275
|
+
--hamburger-colour: #fff;
|
|
276
|
+
--hamburger-layer-width: 28px;
|
|
277
|
+
--hamburger-layer-height: 3px;
|
|
278
|
+
--hamburger-layer-spacing: 6px;
|
|
279
|
+
--hamburger-border-radius: 3px;
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
104
283
|
## Form Utilities
|
|
105
284
|
|
|
106
285
|
### generateFormSchema
|
|
@@ -170,10 +349,11 @@ Renders a form dynamically from Payload CMS form builder fields.
|
|
|
170
349
|
|
|
171
350
|
#### Customisation
|
|
172
351
|
|
|
173
|
-
|
|
352
|
+
Override CSS variables globally:
|
|
174
353
|
|
|
175
354
|
```css
|
|
176
|
-
|
|
355
|
+
/* Global form styling */
|
|
356
|
+
:root {
|
|
177
357
|
--form-gap: 1.5rem;
|
|
178
358
|
--form-input-padding: 1rem;
|
|
179
359
|
--form-input-border: 1px solid #e5e7eb;
|
|
@@ -181,7 +361,9 @@ Style the form using CSS variables:
|
|
|
181
361
|
--form-input-bg: #ffffff;
|
|
182
362
|
--form-input-text: #111827;
|
|
183
363
|
--form-error-color: #ef4444;
|
|
364
|
+
--form-error-bg: #fee2e2;
|
|
184
365
|
--form-success-color: #10b981;
|
|
366
|
+
--form-success-bg: #d1fae5;
|
|
185
367
|
--form-button-bg: #3b82f6;
|
|
186
368
|
--form-button-text: #ffffff;
|
|
187
369
|
--form-button-hover-bg: #2563eb;
|
|
@@ -21,13 +21,12 @@ const { ...restProps } = $props();
|
|
|
21
21
|
</div>
|
|
22
22
|
|
|
23
23
|
<style>.col {
|
|
24
|
-
--col-gap: 1rem;
|
|
25
24
|
position: relative;
|
|
26
25
|
width: 100%;
|
|
27
|
-
padding-inline: var(--col-gap);
|
|
26
|
+
padding-inline: var(--col-gap, 1rem);
|
|
28
27
|
}
|
|
29
28
|
@media (max-width: 568px) {
|
|
30
29
|
.col {
|
|
31
|
-
--col-gap
|
|
30
|
+
padding-inline: var(--col-gap-mobile, var(--col-gap, 0.5rem));
|
|
32
31
|
}
|
|
33
32
|
}</style>
|
|
@@ -13,16 +13,13 @@ const { ...restProps } = $props();
|
|
|
13
13
|
</div>
|
|
14
14
|
|
|
15
15
|
<style>.container {
|
|
16
|
-
--container-padding: 1rem;
|
|
17
|
-
--container-max-width: 1328px;
|
|
18
|
-
--container-breakout-max-width: 1500px;
|
|
19
16
|
--container-breakout-size: calc(
|
|
20
|
-
(var(--container-breakout-max-width) - var(--container-max-width)) / 2
|
|
17
|
+
(var(--container-breakout-max-width, 1500px) - var(--container-max-width, 1328px)) / 2
|
|
21
18
|
);
|
|
22
19
|
display: grid;
|
|
23
20
|
width: 100%;
|
|
24
21
|
position: relative;
|
|
25
|
-
grid-template-columns: [full-width-start] minmax(var(--container-padding), 1fr) [breakout-start] minmax(0, var(--container-breakout-size)) [content-start] min(100% - var(--container-padding) * 2, var(--container-max-width)) [content-end] minmax(0, var(--container-breakout-size)) [breakout-end] minmax(var(--container-padding), 1fr) [full-width-end];
|
|
22
|
+
grid-template-columns: [full-width-start] minmax(var(--container-padding, 1rem), 1fr) [breakout-start] minmax(0, var(--container-breakout-size)) [content-start] min(100% - var(--container-padding, 1rem) * 2, var(--container-max-width, 1328px)) [content-end] minmax(0, var(--container-breakout-size)) [breakout-end] minmax(var(--container-padding, 1rem), 1fr) [full-width-end];
|
|
26
23
|
}
|
|
27
24
|
.container :global(> *) {
|
|
28
25
|
grid-column: content;
|
|
@@ -32,10 +32,9 @@ const { noGaps = false, ...restProps }: RowProps = $props();
|
|
|
32
32
|
</div>
|
|
33
33
|
|
|
34
34
|
<style>.row {
|
|
35
|
-
--row-gap: 1rem;
|
|
36
35
|
display: flex;
|
|
37
36
|
flex-wrap: wrap;
|
|
38
|
-
margin-inline: calc(var(--row-gap) * -1);
|
|
37
|
+
margin-inline: calc(var(--row-gap, 1rem) * -1);
|
|
39
38
|
}
|
|
40
39
|
.row--no-gaps {
|
|
41
40
|
margin-inline: 0;
|
|
@@ -46,6 +45,6 @@ const { noGaps = false, ...restProps }: RowProps = $props();
|
|
|
46
45
|
}
|
|
47
46
|
@media (max-width: 568px) {
|
|
48
47
|
.row {
|
|
49
|
-
--row-gap
|
|
48
|
+
margin-inline: calc(var(--row-gap-mobile, var(--row-gap, 0.5rem)) * -1);
|
|
50
49
|
}
|
|
51
50
|
}</style>
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import type { HamburgerType as HamburgerTypeLib } from 'svelte-hamburgers';
|
|
3
|
+
|
|
4
|
+
export type HamburgerType = HamburgerTypeLib;
|
|
5
|
+
|
|
6
|
+
export type HamburgerProps = {
|
|
7
|
+
// See: https://github.com/ghostdevv/svelte-hamburgers/blob/main/types.md
|
|
8
|
+
style?: HamburgerType;
|
|
9
|
+
isOpen?: boolean;
|
|
10
|
+
gap?: string;
|
|
11
|
+
class?: string;
|
|
12
|
+
onChange?: (isOpen: boolean) => void;
|
|
13
|
+
};
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<script lang="ts">
|
|
17
|
+
import { Hamburger as SvelteHamburger } from 'svelte-hamburgers';
|
|
18
|
+
|
|
19
|
+
let {
|
|
20
|
+
style = 'spin',
|
|
21
|
+
isOpen = $bindable(false),
|
|
22
|
+
gap = '0.8rem',
|
|
23
|
+
class: className = '',
|
|
24
|
+
onChange
|
|
25
|
+
}: HamburgerProps = $props();
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<!--
|
|
29
|
+
@component
|
|
30
|
+
|
|
31
|
+
Hamburger menu icon with animation for mobile navigation.
|
|
32
|
+
Uses svelte-hamburgers under the hood.
|
|
33
|
+
|
|
34
|
+
@example
|
|
35
|
+
```svelte
|
|
36
|
+
<Hamburger bind:isOpen />
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
@example
|
|
40
|
+
```svelte
|
|
41
|
+
<Hamburger gap="1rem">
|
|
42
|
+
```
|
|
43
|
+
-->
|
|
44
|
+
<div class="hamburger-wrapper {className}" style="--hamburger-gap: {gap}" aria-label="Toggle Menu">
|
|
45
|
+
<SvelteHamburger
|
|
46
|
+
type={style}
|
|
47
|
+
bind:open={isOpen}
|
|
48
|
+
on:change={() => onChange?.(isOpen)}
|
|
49
|
+
--color="var(--hamburger-colour, var(--colour-base-light))"
|
|
50
|
+
--layer-width="var(--hamburger-layer-width, 24px)"
|
|
51
|
+
--layer-height="var(--hamburger-layer-height, 2px)"
|
|
52
|
+
--layer-spacing="var(--hamburger-layer-spacing, 5px)"
|
|
53
|
+
--border-radius="var(--hamburger-border-radius, 2px)"
|
|
54
|
+
/>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
<style>.hamburger-wrapper {
|
|
58
|
+
position: fixed;
|
|
59
|
+
top: var(--hamburger-gap, 0.8rem);
|
|
60
|
+
right: var(--hamburger-gap, 0.8rem);
|
|
61
|
+
z-index: var(--hamburger-z-index, 10000);
|
|
62
|
+
}</style>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { HamburgerType as HamburgerTypeLib } from 'svelte-hamburgers';
|
|
2
|
+
export type HamburgerType = HamburgerTypeLib;
|
|
3
|
+
export type HamburgerProps = {
|
|
4
|
+
style?: HamburgerType;
|
|
5
|
+
isOpen?: boolean;
|
|
6
|
+
gap?: string;
|
|
7
|
+
class?: string;
|
|
8
|
+
onChange?: (isOpen: boolean) => void;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Hamburger menu icon with animation for mobile navigation.
|
|
12
|
+
* Uses svelte-hamburgers under the hood.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```svelte
|
|
16
|
+
* <Hamburger bind:isOpen />
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```svelte
|
|
21
|
+
* <Hamburger gap="1rem">
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
declare const Hamburger: import("svelte").Component<HamburgerProps, {}, "isOpen">;
|
|
25
|
+
type Hamburger = ReturnType<typeof Hamburger>;
|
|
26
|
+
export default Hamburger;
|
|
27
|
+
//# sourceMappingURL=Hamburger.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Hamburger.svelte.d.ts","sourceRoot":"","sources":["../../src/components/Hamburger.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,IAAI,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE3E,MAAM,MAAM,aAAa,GAAG,gBAAgB,CAAC;AAE7C,MAAM,MAAM,cAAc,GAAG;IAE5B,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;CACrC,CAAC;AA4BF;;;;;;;;;;;;;GAaG;AACH,QAAA,MAAM,SAAS,0DAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
export type SidebarProps = {
|
|
5
|
+
menuLabel?: string;
|
|
6
|
+
children: Snippet;
|
|
7
|
+
isOpen?: boolean;
|
|
8
|
+
position?: 'left' | 'right';
|
|
9
|
+
width?: string;
|
|
10
|
+
top?: number;
|
|
11
|
+
closeOnOverlayClick?: boolean;
|
|
12
|
+
overlayOpacity?: number;
|
|
13
|
+
toggleStyle?: 'toggle' | 'hamburger';
|
|
14
|
+
class?: string;
|
|
15
|
+
onOpen?: () => void;
|
|
16
|
+
onClose?: () => void;
|
|
17
|
+
onToggle?: (isOpen: boolean) => void;
|
|
18
|
+
};
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<script lang="ts">
|
|
22
|
+
import { onMount } from 'svelte';
|
|
23
|
+
import Hamburger from './Hamburger.svelte';
|
|
24
|
+
|
|
25
|
+
let {
|
|
26
|
+
menuLabel = 'Menu',
|
|
27
|
+
children,
|
|
28
|
+
isOpen = $bindable(false),
|
|
29
|
+
position = 'left',
|
|
30
|
+
width = '50vw',
|
|
31
|
+
top = 160,
|
|
32
|
+
closeOnOverlayClick = true,
|
|
33
|
+
overlayOpacity = 0.3,
|
|
34
|
+
toggleStyle = 'toggle',
|
|
35
|
+
class: className = '',
|
|
36
|
+
onOpen,
|
|
37
|
+
onClose,
|
|
38
|
+
onToggle
|
|
39
|
+
}: SidebarProps = $props();
|
|
40
|
+
|
|
41
|
+
const uniqueId = `sidebar-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
42
|
+
let checkboxRef = $state<HTMLInputElement>();
|
|
43
|
+
let overlayRef = $state<HTMLLabelElement>();
|
|
44
|
+
let contentRef = $state<HTMLDivElement>();
|
|
45
|
+
let previousActiveElement = $state<HTMLElement>();
|
|
46
|
+
|
|
47
|
+
// Sync checkbox with isOpen state.
|
|
48
|
+
$effect(() => {
|
|
49
|
+
if (checkboxRef && checkboxRef.checked !== isOpen) {
|
|
50
|
+
checkboxRef.checked = isOpen;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// Watch for changes to isOpen and call callbacks.
|
|
55
|
+
$effect(() => {
|
|
56
|
+
if (isOpen) {
|
|
57
|
+
onOpen?.();
|
|
58
|
+
} else {
|
|
59
|
+
onClose?.();
|
|
60
|
+
}
|
|
61
|
+
onToggle?.(isOpen);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// Focus management.
|
|
65
|
+
$effect(() => {
|
|
66
|
+
if (isOpen && contentRef) {
|
|
67
|
+
previousActiveElement = document.activeElement as HTMLElement;
|
|
68
|
+
const firstFocusable = contentRef.querySelector<HTMLElement>(
|
|
69
|
+
'a, button, input, textarea, select, [tabindex]:not([tabindex="-1"])'
|
|
70
|
+
);
|
|
71
|
+
firstFocusable?.focus();
|
|
72
|
+
} else if (!isOpen && previousActiveElement) {
|
|
73
|
+
previousActiveElement.focus();
|
|
74
|
+
previousActiveElement = undefined;
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
onMount(() => {
|
|
79
|
+
// Capture refs in local variables to ensure proper cleanup.
|
|
80
|
+
const overlay = overlayRef;
|
|
81
|
+
const checkbox = checkboxRef;
|
|
82
|
+
|
|
83
|
+
if (!overlay || !checkbox) return;
|
|
84
|
+
|
|
85
|
+
const handleOverlayClick = (e: Event) => {
|
|
86
|
+
if (!closeOnOverlayClick) return;
|
|
87
|
+
e.preventDefault();
|
|
88
|
+
checkbox.checked = false;
|
|
89
|
+
isOpen = false;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const handleCheckboxChange = () => {
|
|
93
|
+
isOpen = checkbox.checked;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const handleKeydown = (e: KeyboardEvent) => {
|
|
97
|
+
if (e.key === 'Escape' && isOpen) {
|
|
98
|
+
e.preventDefault();
|
|
99
|
+
checkbox.checked = false;
|
|
100
|
+
isOpen = false;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
overlay.addEventListener('click', handleOverlayClick);
|
|
105
|
+
checkbox.addEventListener('change', handleCheckboxChange);
|
|
106
|
+
document.addEventListener('keydown', handleKeydown);
|
|
107
|
+
|
|
108
|
+
return () => {
|
|
109
|
+
overlay.removeEventListener('click', handleOverlayClick);
|
|
110
|
+
checkbox.removeEventListener('change', handleCheckboxChange);
|
|
111
|
+
document.removeEventListener('keydown', handleKeydown);
|
|
112
|
+
};
|
|
113
|
+
});
|
|
114
|
+
</script>
|
|
115
|
+
|
|
116
|
+
<!--
|
|
117
|
+
@component
|
|
118
|
+
|
|
119
|
+
Mobile-first sidebar navigation component with toggle and hamburger options.
|
|
120
|
+
Automatically collapses on mobile and remains visible on desktop.
|
|
121
|
+
|
|
122
|
+
@example
|
|
123
|
+
```svelte
|
|
124
|
+
<Sidebar bind:isOpen>
|
|
125
|
+
<nav>
|
|
126
|
+
<a href="/">Home</a>
|
|
127
|
+
<a href="/about">About</a>
|
|
128
|
+
</nav>
|
|
129
|
+
</Sidebar>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
@example
|
|
133
|
+
```svelte
|
|
134
|
+
<Sidebar toggleStyle="hamburger" position="right" width="300px">
|
|
135
|
+
<nav>...</nav>
|
|
136
|
+
</Sidebar>
|
|
137
|
+
```
|
|
138
|
+
-->
|
|
139
|
+
<aside
|
|
140
|
+
class="sidebar sidebar--{toggleStyle} sidebar--{position} {className}"
|
|
141
|
+
style="--sidebar-width: {width}; --sidebar-top: {top}px; --sidebar-overlay-opacity: {overlayOpacity}"
|
|
142
|
+
>
|
|
143
|
+
<!-- Click Logic -->
|
|
144
|
+
<input
|
|
145
|
+
bind:this={checkboxRef}
|
|
146
|
+
type="checkbox"
|
|
147
|
+
class="sidebar__checkbox"
|
|
148
|
+
id={uniqueId}
|
|
149
|
+
aria-label={menuLabel}
|
|
150
|
+
/>
|
|
151
|
+
<label bind:this={overlayRef} for={uniqueId} class="sidebar__overlay"></label>
|
|
152
|
+
<!-- Hamburger -->
|
|
153
|
+
{#if toggleStyle === 'hamburger'}
|
|
154
|
+
<Hamburger bind:isOpen />
|
|
155
|
+
{/if}
|
|
156
|
+
<!-- Content -->
|
|
157
|
+
<div bind:this={contentRef} class="sidebar__content" role="navigation" aria-label={menuLabel}>
|
|
158
|
+
{#if toggleStyle === 'toggle'}
|
|
159
|
+
<label for={uniqueId} class="sidebar__toggle">
|
|
160
|
+
{menuLabel}
|
|
161
|
+
</label>
|
|
162
|
+
{/if}
|
|
163
|
+
<div class="sidebar__inner">
|
|
164
|
+
{@render children()}
|
|
165
|
+
</div>
|
|
166
|
+
</div>
|
|
167
|
+
</aside>
|
|
168
|
+
|
|
169
|
+
<style>.sidebar__toggle {
|
|
170
|
+
position: absolute;
|
|
171
|
+
display: none;
|
|
172
|
+
bottom: 0;
|
|
173
|
+
right: 1px;
|
|
174
|
+
background-color: var(--sidebar-toggle-background, var(--colour-base-black));
|
|
175
|
+
color: var(--sidebar-toggle-colour, var(--colour-base-light));
|
|
176
|
+
padding: var(--sidebar-toggle-padding, 0.25rem 1.5rem);
|
|
177
|
+
border-top-right-radius: var(--sidebar-toggle-radius, 0.375rem);
|
|
178
|
+
border-top-left-radius: var(--sidebar-toggle-radius, 0.375rem);
|
|
179
|
+
font-size: var(--sidebar-toggle-font-size, 0.9rem);
|
|
180
|
+
transform: rotate(90deg) translate(0%, -100%);
|
|
181
|
+
transform-origin: right top;
|
|
182
|
+
cursor: pointer;
|
|
183
|
+
user-select: none;
|
|
184
|
+
transition: box-shadow 200ms linear;
|
|
185
|
+
border: 1px solid var(--sidebar-border-colour, rgba(255, 255, 255, 0.1));
|
|
186
|
+
}
|
|
187
|
+
.sidebar__toggle::before {
|
|
188
|
+
content: "";
|
|
189
|
+
position: absolute;
|
|
190
|
+
top: calc(90% + 2px);
|
|
191
|
+
left: 1px;
|
|
192
|
+
width: calc(100% - 2px);
|
|
193
|
+
height: 10%;
|
|
194
|
+
background: var(--sidebar-toggle-background, var(--colour-base-black));
|
|
195
|
+
}
|
|
196
|
+
.sidebar__overlay {
|
|
197
|
+
position: fixed;
|
|
198
|
+
top: 0;
|
|
199
|
+
left: 0;
|
|
200
|
+
width: 100%;
|
|
201
|
+
height: 100%;
|
|
202
|
+
background-color: var(--sidebar-overlay-colour, var(--colour-grey-900));
|
|
203
|
+
z-index: -100;
|
|
204
|
+
opacity: 0;
|
|
205
|
+
transition: opacity 400ms ease, z-index 400ms step-end;
|
|
206
|
+
}
|
|
207
|
+
.sidebar__checkbox {
|
|
208
|
+
position: fixed;
|
|
209
|
+
top: 0;
|
|
210
|
+
display: none;
|
|
211
|
+
}
|
|
212
|
+
.sidebar__checkbox:checked ~ .sidebar__content {
|
|
213
|
+
translate: 0;
|
|
214
|
+
z-index: 9999999;
|
|
215
|
+
}
|
|
216
|
+
.sidebar__checkbox:checked ~ .sidebar__content .sidebar__toggle {
|
|
217
|
+
box-shadow: none;
|
|
218
|
+
}
|
|
219
|
+
.sidebar__checkbox:checked ~ .sidebar__overlay {
|
|
220
|
+
transition: opacity 600ms ease, z-index 600ms step-start;
|
|
221
|
+
opacity: var(--sidebar-overlay-opacity, 0.3);
|
|
222
|
+
z-index: 999999;
|
|
223
|
+
}
|
|
224
|
+
@media (max-width: 1023px) {
|
|
225
|
+
.sidebar__content {
|
|
226
|
+
position: fixed;
|
|
227
|
+
display: grid;
|
|
228
|
+
top: 0;
|
|
229
|
+
height: 100%;
|
|
230
|
+
width: var(--sidebar-width, 50vw);
|
|
231
|
+
min-width: var(--sidebar-min-width, 270px);
|
|
232
|
+
background-color: var(--sidebar-background, var(--colour-base-black));
|
|
233
|
+
border-color: var(--sidebar-border-colour, rgba(255, 255, 255, 0.1));
|
|
234
|
+
z-index: 1000;
|
|
235
|
+
transition: translate 600ms cubic-bezier(0.1, 0.7, 0.1, 1);
|
|
236
|
+
}
|
|
237
|
+
.sidebar__inner {
|
|
238
|
+
overflow: auto;
|
|
239
|
+
display: flex;
|
|
240
|
+
flex-direction: column;
|
|
241
|
+
padding: var(--sidebar-inner-padding, 2rem 1.8rem 0 1.8rem);
|
|
242
|
+
}
|
|
243
|
+
.sidebar__toggle {
|
|
244
|
+
display: flex;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
@media (min-width: 1024px) {
|
|
248
|
+
.sidebar {
|
|
249
|
+
position: sticky;
|
|
250
|
+
top: var(--sidebar-top, 160px);
|
|
251
|
+
}
|
|
252
|
+
.sidebar__overlay {
|
|
253
|
+
display: none;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
@media (max-width: 1023px) {
|
|
257
|
+
.sidebar--left .sidebar__content {
|
|
258
|
+
left: 0;
|
|
259
|
+
border-right-style: solid;
|
|
260
|
+
border-right-width: 1px;
|
|
261
|
+
translate: -100%;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
@media (max-width: 1023px) {
|
|
265
|
+
.sidebar--right .sidebar__content {
|
|
266
|
+
right: 0;
|
|
267
|
+
border-left-style: solid;
|
|
268
|
+
border-left-width: 1px;
|
|
269
|
+
translate: 100%;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
.sidebar--hamburger .sidebar__toggle {
|
|
273
|
+
display: none;
|
|
274
|
+
}</style>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
export type SidebarProps = {
|
|
3
|
+
menuLabel?: string;
|
|
4
|
+
children: Snippet;
|
|
5
|
+
isOpen?: boolean;
|
|
6
|
+
position?: 'left' | 'right';
|
|
7
|
+
width?: string;
|
|
8
|
+
top?: number;
|
|
9
|
+
closeOnOverlayClick?: boolean;
|
|
10
|
+
overlayOpacity?: number;
|
|
11
|
+
toggleStyle?: 'toggle' | 'hamburger';
|
|
12
|
+
class?: string;
|
|
13
|
+
onOpen?: () => void;
|
|
14
|
+
onClose?: () => void;
|
|
15
|
+
onToggle?: (isOpen: boolean) => void;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Mobile-first sidebar navigation component with toggle and hamburger options.
|
|
19
|
+
* Automatically collapses on mobile and remains visible on desktop.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```svelte
|
|
23
|
+
* <Sidebar bind:isOpen>
|
|
24
|
+
* <nav>
|
|
25
|
+
* <a href="/">Home</a>
|
|
26
|
+
* <a href="/about">About</a>
|
|
27
|
+
* </nav>
|
|
28
|
+
* </Sidebar>
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```svelte
|
|
33
|
+
* <Sidebar toggleStyle="hamburger" position="right" width="300px">
|
|
34
|
+
* <nav>...</nav>
|
|
35
|
+
* </Sidebar>
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
declare const Sidebar: import("svelte").Component<SidebarProps, {}, "isOpen">;
|
|
39
|
+
type Sidebar = ReturnType<typeof Sidebar>;
|
|
40
|
+
export default Sidebar;
|
|
41
|
+
//# sourceMappingURL=Sidebar.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Sidebar.svelte.d.ts","sourceRoot":"","sources":["../../src/components/Sidebar.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,MAAM,MAAM,YAAY,GAAG;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;CACrC,CAAC;AAiIF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,QAAA,MAAM,OAAO,wDAAwC,CAAC;AACtD,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;AAC1C,eAAe,OAAO,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -186,23 +186,9 @@ async function handleSubmit(event: SubmitEvent) {
|
|
|
186
186
|
</form>
|
|
187
187
|
|
|
188
188
|
<style>.payload-form {
|
|
189
|
-
--form-gap: 1rem;
|
|
190
|
-
--form-input-padding: 0.75rem;
|
|
191
|
-
--form-input-border: 1px solid #d1d5db;
|
|
192
|
-
--form-input-border-radius: 0.375rem;
|
|
193
|
-
--form-input-bg: #ffffff;
|
|
194
|
-
--form-input-text: #111827;
|
|
195
|
-
--form-error-color: #ef4444;
|
|
196
|
-
--form-error-bg: #fee2e2;
|
|
197
|
-
--form-success-color: #10b981;
|
|
198
|
-
--form-success-bg: #d1fae5;
|
|
199
|
-
--form-button-bg: #3b82f6;
|
|
200
|
-
--form-button-text: #ffffff;
|
|
201
|
-
--form-button-hover-bg: #2563eb;
|
|
202
|
-
--form-button-disabled-bg: #9ca3af;
|
|
203
189
|
display: flex;
|
|
204
190
|
flex-direction: column;
|
|
205
|
-
gap: var(--form-gap);
|
|
191
|
+
gap: var(--form-gap, 1rem);
|
|
206
192
|
}
|
|
207
193
|
.payload-form__group {
|
|
208
194
|
display: flex;
|
|
@@ -212,31 +198,31 @@ async function handleSubmit(event: SubmitEvent) {
|
|
|
212
198
|
.payload-form__label {
|
|
213
199
|
font-size: 0.875rem;
|
|
214
200
|
font-weight: 500;
|
|
215
|
-
color: var(--form-input-text);
|
|
201
|
+
color: var(--form-input-text, #111827);
|
|
216
202
|
}
|
|
217
203
|
.payload-form__label--checkbox {
|
|
218
204
|
font-weight: 400;
|
|
219
205
|
cursor: pointer;
|
|
220
206
|
}
|
|
221
207
|
.payload-form__required {
|
|
222
|
-
color: var(--form-error-color);
|
|
208
|
+
color: var(--form-error-color, #ef4444);
|
|
223
209
|
margin-left: 0.25rem;
|
|
224
210
|
}
|
|
225
211
|
.payload-form__input, .payload-form__textarea {
|
|
226
|
-
padding: var(--form-input-padding);
|
|
227
|
-
border: var(--form-input-border);
|
|
228
|
-
border-radius: var(--form-input-border-radius);
|
|
229
|
-
background: var(--form-input-bg);
|
|
230
|
-
color: var(--form-input-text);
|
|
212
|
+
padding: var(--form-input-padding, 0.75rem);
|
|
213
|
+
border: var(--form-input-border, 1px solid #d1d5db);
|
|
214
|
+
border-radius: var(--form-input-border-radius, 0.375rem);
|
|
215
|
+
background: var(--form-input-bg, #ffffff);
|
|
216
|
+
color: var(--form-input-text, #111827);
|
|
231
217
|
font-size: 1rem;
|
|
232
218
|
font-family: inherit;
|
|
233
219
|
}
|
|
234
220
|
.payload-form__input:focus, .payload-form__textarea:focus {
|
|
235
|
-
outline: 2px solid var(--form-button-bg);
|
|
221
|
+
outline: 2px solid var(--form-button-bg, #3b82f6);
|
|
236
222
|
outline-offset: 2px;
|
|
237
223
|
}
|
|
238
224
|
.payload-form__input--error, .payload-form__textarea--error {
|
|
239
|
-
border-color: var(--form-error-color);
|
|
225
|
+
border-color: var(--form-error-color, #ef4444);
|
|
240
226
|
}
|
|
241
227
|
.payload-form__textarea {
|
|
242
228
|
resize: vertical;
|
|
@@ -255,28 +241,28 @@ async function handleSubmit(event: SubmitEvent) {
|
|
|
255
241
|
}
|
|
256
242
|
.payload-form__error {
|
|
257
243
|
font-size: 0.875rem;
|
|
258
|
-
color: var(--form-error-color);
|
|
244
|
+
color: var(--form-error-color, #ef4444);
|
|
259
245
|
}
|
|
260
246
|
.payload-form__success {
|
|
261
247
|
padding: 1rem;
|
|
262
|
-
background-color: var(--form-success-bg);
|
|
263
|
-
color: var(--form-success-color);
|
|
264
|
-
border-radius: var(--form-input-border-radius);
|
|
248
|
+
background-color: var(--form-success-bg, #d1fae5);
|
|
249
|
+
color: var(--form-success-color, #10b981);
|
|
250
|
+
border-radius: var(--form-input-border-radius, 0.375rem);
|
|
265
251
|
font-weight: 500;
|
|
266
252
|
}
|
|
267
253
|
.payload-form__alert {
|
|
268
254
|
padding: 1rem;
|
|
269
|
-
background-color: var(--form-error-bg);
|
|
270
|
-
color: var(--form-error-color);
|
|
271
|
-
border-radius: var(--form-input-border-radius);
|
|
255
|
+
background-color: var(--form-error-bg, #fee2e2);
|
|
256
|
+
color: var(--form-error-color, #ef4444);
|
|
257
|
+
border-radius: var(--form-input-border-radius, 0.375rem);
|
|
272
258
|
font-weight: 500;
|
|
273
259
|
}
|
|
274
260
|
.payload-form__submit {
|
|
275
|
-
padding: var(--form-input-padding) 1.5rem;
|
|
276
|
-
background-color: var(--form-button-bg);
|
|
277
|
-
color: var(--form-button-text);
|
|
261
|
+
padding: var(--form-input-padding, 0.75rem) 1.5rem;
|
|
262
|
+
background-color: var(--form-button-bg, #3b82f6);
|
|
263
|
+
color: var(--form-button-text, #ffffff);
|
|
278
264
|
border: none;
|
|
279
|
-
border-radius: var(--form-input-border-radius);
|
|
265
|
+
border-radius: var(--form-input-border-radius, 0.375rem);
|
|
280
266
|
font-size: 1rem;
|
|
281
267
|
font-weight: 500;
|
|
282
268
|
cursor: pointer;
|
|
@@ -287,10 +273,10 @@ async function handleSubmit(event: SubmitEvent) {
|
|
|
287
273
|
transition: background-color 0.2s;
|
|
288
274
|
}
|
|
289
275
|
.payload-form__submit:hover:not(:disabled) {
|
|
290
|
-
background-color: var(--form-button-hover-bg);
|
|
276
|
+
background-color: var(--form-button-hover-bg, #2563eb);
|
|
291
277
|
}
|
|
292
278
|
.payload-form__submit:disabled {
|
|
293
|
-
background-color: var(--form-button-disabled-bg);
|
|
279
|
+
background-color: var(--form-button-disabled-bg, #9ca3af);
|
|
294
280
|
cursor: not-allowed;
|
|
295
281
|
}
|
|
296
282
|
.payload-form__loader {
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* SvelteKit utilities, components and helpers for ainsley.dev builds.
|
|
5
5
|
* Provides form utilities, grid components, and Payload CMS integrations.
|
|
6
6
|
*/
|
|
7
|
+
export * from './components/index.js';
|
|
7
8
|
export * from './components/Grid/index.js';
|
|
8
9
|
export * from './components/payload/index.js';
|
|
9
10
|
export * from './utils/forms/index.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,cAAc,4BAA4B,CAAC;AAC3C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wBAAwB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* Provides form utilities, grid components, and Payload CMS integrations.
|
|
6
6
|
*/
|
|
7
7
|
// Re-export all exports from submodules
|
|
8
|
+
export * from './components/index.js';
|
|
8
9
|
export * from './components/Grid/index.js';
|
|
9
10
|
export * from './components/payload/index.js';
|
|
10
11
|
export * from './utils/forms/index.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ainsleydev/sveltekit-helper",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "SvelteKit utilities, components and helpers for ainsley.dev builds",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -29,6 +29,11 @@
|
|
|
29
29
|
"svelte": "./dist/index.js",
|
|
30
30
|
"default": "./dist/index.js"
|
|
31
31
|
},
|
|
32
|
+
"./components": {
|
|
33
|
+
"types": "./dist/components/index.d.ts",
|
|
34
|
+
"svelte": "./dist/components/index.js",
|
|
35
|
+
"default": "./dist/components/index.js"
|
|
36
|
+
},
|
|
32
37
|
"./components/Grid": {
|
|
33
38
|
"types": "./dist/components/Grid/index.d.ts",
|
|
34
39
|
"svelte": "./dist/components/Grid/index.js",
|
|
@@ -67,7 +72,9 @@
|
|
|
67
72
|
"optional": true
|
|
68
73
|
}
|
|
69
74
|
},
|
|
70
|
-
"dependencies": {
|
|
75
|
+
"dependencies": {
|
|
76
|
+
"svelte-hamburgers": "^4.1.0"
|
|
77
|
+
},
|
|
71
78
|
"devDependencies": {
|
|
72
79
|
"@sveltejs/kit": "^2.0.0",
|
|
73
80
|
"@sveltejs/package": "^2.0.0",
|