sveltacular 1.0.9 → 1.0.11
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/dist/generic/header/header.svelte +9 -3
- package/dist/generic/header/header.svelte.d.ts +4 -3
- package/dist/layout/flex-col.svelte +89 -58
- package/dist/layout/flex-col.svelte.d.ts +25 -9
- package/dist/layout/flex-item.svelte +30 -8
- package/dist/layout/flex-item.svelte.d.ts +11 -5
- package/dist/layout/flex-row.svelte +88 -73
- package/dist/layout/flex-row.svelte.d.ts +25 -11
- package/dist/layout/index.d.ts +1 -0
- package/dist/layout/index.js +1 -0
- package/dist/layout/main/main.svelte +58 -0
- package/dist/layout/main/main.svelte.d.ts +7 -0
- package/dist/modals/dialog-footer.svelte +1 -1
- package/dist/navigation/accordion/accordion.svelte +14 -6
- package/package.json +1 -1
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import Headline from '../../typography/headline.svelte';
|
|
5
5
|
import Subtitle from '../../typography/subtitle.svelte';
|
|
6
6
|
import { getContext } from 'svelte';
|
|
7
|
+
import Paragraph from '../../typography/paragraph.svelte';
|
|
7
8
|
|
|
8
9
|
const section: { title: string; level: SectionLevel } | undefined = getContext('section');
|
|
9
10
|
|
|
@@ -11,14 +12,16 @@
|
|
|
11
12
|
level = (section?.level || 2) as SectionLevel,
|
|
12
13
|
title = section?.title || '',
|
|
13
14
|
subtitle = '',
|
|
15
|
+
description = '',
|
|
14
16
|
underline = false,
|
|
15
17
|
children = undefined
|
|
16
18
|
}: {
|
|
17
19
|
level?: SectionLevel;
|
|
18
|
-
title?: string;
|
|
19
|
-
subtitle?: string;
|
|
20
|
+
title?: string | undefined;
|
|
21
|
+
subtitle?: string | undefined;
|
|
22
|
+
description?: string | undefined;
|
|
20
23
|
underline?: boolean;
|
|
21
|
-
children?: Snippet;
|
|
24
|
+
children?: Snippet | undefined;
|
|
22
25
|
} = $props();
|
|
23
26
|
</script>
|
|
24
27
|
|
|
@@ -28,6 +31,9 @@
|
|
|
28
31
|
{#if subtitle}
|
|
29
32
|
<Subtitle {level}>{subtitle}</Subtitle>
|
|
30
33
|
{/if}
|
|
34
|
+
{#if description}
|
|
35
|
+
<Paragraph>{description}</Paragraph>
|
|
36
|
+
{/if}
|
|
31
37
|
</hgroup>
|
|
32
38
|
<div>
|
|
33
39
|
{#if children}
|
|
@@ -2,10 +2,11 @@ import type { Snippet } from 'svelte';
|
|
|
2
2
|
import type { SectionLevel } from '../../types/generic.js';
|
|
3
3
|
type $$ComponentProps = {
|
|
4
4
|
level?: SectionLevel;
|
|
5
|
-
title?: string;
|
|
6
|
-
subtitle?: string;
|
|
5
|
+
title?: string | undefined;
|
|
6
|
+
subtitle?: string | undefined;
|
|
7
|
+
description?: string | undefined;
|
|
7
8
|
underline?: boolean;
|
|
8
|
-
children?: Snippet;
|
|
9
|
+
children?: Snippet | undefined;
|
|
9
10
|
};
|
|
10
11
|
declare const Header: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
11
12
|
type Header = ReturnType<typeof Header>;
|
|
@@ -1,75 +1,106 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
alignContent = 'stretch' as 'start' | 'center' | 'end' | 'between' | 'around' | 'stretch',
|
|
19
|
-
children
|
|
20
|
-
}: {
|
|
21
|
-
marginBottom?: string | number;
|
|
22
|
-
marginTop?: string | number;
|
|
23
|
-
gap?: string | number;
|
|
24
|
-
justifyContent?:
|
|
25
|
-
| 'start'
|
|
26
|
-
| 'center'
|
|
27
|
-
| 'end'
|
|
28
|
-
| 'between'
|
|
29
|
-
| 'around'
|
|
30
|
-
| 'evenly'
|
|
31
|
-
| 'stretch'
|
|
32
|
-
| 'baseline';
|
|
33
|
-
alignItems?: 'start' | 'center' | 'end' | 'stretch' | 'auto';
|
|
34
|
-
alignContent?: 'start' | 'center' | 'end' | 'between' | 'around' | 'stretch';
|
|
4
|
+
type JustifyContent =
|
|
5
|
+
| 'flex-start'
|
|
6
|
+
| 'flex-end'
|
|
7
|
+
| 'center'
|
|
8
|
+
| 'space-between'
|
|
9
|
+
| 'space-around'
|
|
10
|
+
| 'space-evenly';
|
|
11
|
+
|
|
12
|
+
type AlignItems = 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline';
|
|
13
|
+
|
|
14
|
+
type SpacingSize = 'xs' | 'sm' | 'md' | 'base' | 'lg' | 'xl' | '2xl';
|
|
15
|
+
|
|
16
|
+
interface Props {
|
|
17
|
+
/** Content to display in the flex column */
|
|
35
18
|
children: Snippet;
|
|
36
|
-
|
|
19
|
+
/** Gap between items (standard size token or custom CSS value) */
|
|
20
|
+
gap?: SpacingSize | string | number;
|
|
21
|
+
/** Whether to wrap items to next line */
|
|
22
|
+
wrap?: boolean;
|
|
23
|
+
/** Justify content along the main axis */
|
|
24
|
+
justify?: JustifyContent;
|
|
25
|
+
/** Align items along the cross axis */
|
|
26
|
+
align?: AlignItems;
|
|
27
|
+
/** Whether to take full width (default: true) */
|
|
28
|
+
fullWidth?: boolean;
|
|
29
|
+
/** Margin on all sides (standard size token or custom CSS value) */
|
|
30
|
+
margin?: SpacingSize | string | number;
|
|
31
|
+
/** Top margin override (standard size token or custom CSS value) */
|
|
32
|
+
marginTop?: SpacingSize | string | number;
|
|
33
|
+
/** Bottom margin override (standard size token or custom CSS value) */
|
|
34
|
+
marginBottom?: SpacingSize | string | number;
|
|
35
|
+
/** Additional CSS classes */
|
|
36
|
+
class?: string;
|
|
37
|
+
}
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
39
|
+
const spacingTokenMap: Record<SpacingSize, string> = {
|
|
40
|
+
xs: 'var(--spacing-xs)',
|
|
41
|
+
sm: 'var(--spacing-sm)',
|
|
42
|
+
md: 'var(--spacing-md)',
|
|
43
|
+
base: 'var(--spacing-base)',
|
|
44
|
+
lg: 'var(--spacing-lg)',
|
|
45
|
+
xl: 'var(--spacing-xl)',
|
|
46
|
+
'2xl': 'var(--spacing-2xl)'
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const normalizeSpacing = (value: SpacingSize | string | number | undefined): string | undefined => {
|
|
50
|
+
if (value === undefined) return undefined;
|
|
51
|
+
if (typeof value === 'number') return `${value}px`;
|
|
52
|
+
if (value in spacingTokenMap) return spacingTokenMap[value as SpacingSize];
|
|
53
|
+
return value;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
let {
|
|
57
|
+
children,
|
|
58
|
+
gap = 'base',
|
|
59
|
+
wrap = false,
|
|
60
|
+
justify = 'flex-start',
|
|
61
|
+
align = 'stretch',
|
|
62
|
+
fullWidth = true,
|
|
63
|
+
margin,
|
|
64
|
+
marginTop,
|
|
65
|
+
marginBottom,
|
|
66
|
+
class: className = ''
|
|
67
|
+
}: Props = $props();
|
|
68
|
+
|
|
69
|
+
const gapValue = $derived(normalizeSpacing(gap) ?? 'var(--spacing-base)');
|
|
70
|
+
const marginValue = $derived(normalizeSpacing(margin));
|
|
71
|
+
const marginTopValue = $derived(
|
|
72
|
+
marginTop !== undefined ? normalizeSpacing(marginTop) : marginValue
|
|
55
73
|
);
|
|
56
|
-
|
|
57
|
-
|
|
74
|
+
const marginBottomValue = $derived(
|
|
75
|
+
marginBottom !== undefined ? normalizeSpacing(marginBottom) : marginValue
|
|
58
76
|
);
|
|
59
|
-
let _gap = $derived(typeof gap === 'number' ? `${gap}px` : gap);
|
|
60
77
|
</script>
|
|
61
78
|
|
|
62
79
|
<div
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
80
|
+
class="flex-col {wrap ? 'wrap' : ''} {!fullWidth ? 'auto-width' : ''} {className}"
|
|
81
|
+
style="
|
|
82
|
+
--gap: {gapValue};
|
|
83
|
+
--justify: {justify};
|
|
84
|
+
--align: {align};
|
|
85
|
+
{marginTopValue ? `margin-top: ${marginTopValue};` : ''}
|
|
86
|
+
{marginBottomValue ? `margin-bottom: ${marginBottomValue};` : ''}
|
|
87
|
+
"
|
|
67
88
|
>
|
|
68
|
-
{@render children
|
|
89
|
+
{@render children()}
|
|
69
90
|
</div>
|
|
70
91
|
|
|
71
|
-
<style
|
|
92
|
+
<style>.flex-col {
|
|
72
93
|
display: flex;
|
|
73
94
|
flex-direction: column;
|
|
74
95
|
width: 100%;
|
|
96
|
+
gap: var(--gap, var(--spacing-base));
|
|
97
|
+
justify-content: var(--justify, flex-start);
|
|
98
|
+
align-items: var(--align, stretch);
|
|
99
|
+
flex-wrap: nowrap;
|
|
100
|
+
}
|
|
101
|
+
.flex-col.wrap {
|
|
102
|
+
flex-wrap: wrap;
|
|
103
|
+
}
|
|
104
|
+
.flex-col.auto-width {
|
|
105
|
+
width: auto;
|
|
75
106
|
}</style>
|
|
@@ -1,13 +1,29 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
|
-
type
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
alignItems?: 'start' | 'center' | 'end' | 'stretch' | 'auto';
|
|
8
|
-
alignContent?: 'start' | 'center' | 'end' | 'between' | 'around' | 'stretch';
|
|
2
|
+
type JustifyContent = 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around' | 'space-evenly';
|
|
3
|
+
type AlignItems = 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline';
|
|
4
|
+
type SpacingSize = 'xs' | 'sm' | 'md' | 'base' | 'lg' | 'xl' | '2xl';
|
|
5
|
+
interface Props {
|
|
6
|
+
/** Content to display in the flex column */
|
|
9
7
|
children: Snippet;
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
/** Gap between items (standard size token or custom CSS value) */
|
|
9
|
+
gap?: SpacingSize | string | number;
|
|
10
|
+
/** Whether to wrap items to next line */
|
|
11
|
+
wrap?: boolean;
|
|
12
|
+
/** Justify content along the main axis */
|
|
13
|
+
justify?: JustifyContent;
|
|
14
|
+
/** Align items along the cross axis */
|
|
15
|
+
align?: AlignItems;
|
|
16
|
+
/** Whether to take full width (default: true) */
|
|
17
|
+
fullWidth?: boolean;
|
|
18
|
+
/** Margin on all sides (standard size token or custom CSS value) */
|
|
19
|
+
margin?: SpacingSize | string | number;
|
|
20
|
+
/** Top margin override (standard size token or custom CSS value) */
|
|
21
|
+
marginTop?: SpacingSize | string | number;
|
|
22
|
+
/** Bottom margin override (standard size token or custom CSS value) */
|
|
23
|
+
marginBottom?: SpacingSize | string | number;
|
|
24
|
+
/** Additional CSS classes */
|
|
25
|
+
class?: string;
|
|
26
|
+
}
|
|
27
|
+
declare const FlexCol: import("svelte").Component<Props, {}, "">;
|
|
12
28
|
type FlexCol = ReturnType<typeof FlexCol>;
|
|
13
29
|
export default FlexCol;
|
|
@@ -1,17 +1,39 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
|
|
4
|
+
type AlignSelf = 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline' | 'auto';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
/** Content to display in the flex item */
|
|
8
|
+
children: Snippet;
|
|
9
|
+
/** Whether the item should grow to fill available space */
|
|
10
|
+
grow?: boolean;
|
|
11
|
+
/** Align this item along the cross axis */
|
|
12
|
+
align?: AlignSelf;
|
|
13
|
+
/** Additional CSS classes */
|
|
14
|
+
class?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
4
17
|
let {
|
|
18
|
+
children,
|
|
5
19
|
grow = false,
|
|
6
20
|
align = 'auto',
|
|
7
|
-
|
|
8
|
-
}:
|
|
9
|
-
|
|
10
|
-
align?: 'start' | 'center' | 'end' | 'stretch' | 'auto';
|
|
11
|
-
children: Snippet;
|
|
12
|
-
} = $props();
|
|
21
|
+
class: className = ''
|
|
22
|
+
}: Props = $props();
|
|
23
|
+
|
|
13
24
|
</script>
|
|
14
25
|
|
|
15
|
-
<div
|
|
16
|
-
{
|
|
26
|
+
<div
|
|
27
|
+
class="flex-item {grow ? 'grow' : ''} {className}"
|
|
28
|
+
style="
|
|
29
|
+
--align-self: {align};
|
|
30
|
+
flex: {grow ? 1 : 0};
|
|
31
|
+
align-self: var(--align-self);
|
|
32
|
+
"
|
|
33
|
+
>
|
|
34
|
+
{@render children()}
|
|
17
35
|
</div>
|
|
36
|
+
|
|
37
|
+
<style>.flex-item {
|
|
38
|
+
display: block;
|
|
39
|
+
}</style>
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
|
-
type
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
type AlignSelf = 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline' | 'auto';
|
|
3
|
+
interface Props {
|
|
4
|
+
/** Content to display in the flex item */
|
|
5
5
|
children: Snippet;
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
/** Whether the item should grow to fill available space */
|
|
7
|
+
grow?: boolean;
|
|
8
|
+
/** Align this item along the cross axis */
|
|
9
|
+
align?: AlignSelf;
|
|
10
|
+
/** Additional CSS classes */
|
|
11
|
+
class?: string;
|
|
12
|
+
}
|
|
13
|
+
declare const FlexItem: import("svelte").Component<Props, {}, "">;
|
|
8
14
|
type FlexItem = ReturnType<typeof FlexItem>;
|
|
9
15
|
export default FlexItem;
|
|
@@ -1,93 +1,108 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
|
|
4
|
+
type JustifyContent =
|
|
5
|
+
| 'flex-start'
|
|
6
|
+
| 'flex-end'
|
|
7
|
+
| 'center'
|
|
8
|
+
| 'space-between'
|
|
9
|
+
| 'space-around'
|
|
10
|
+
| 'space-evenly';
|
|
11
|
+
|
|
12
|
+
type AlignItems = 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline';
|
|
13
|
+
|
|
14
|
+
type SpacingSize = 'xs' | 'sm' | 'md' | 'base' | 'lg' | 'xl' | '2xl';
|
|
15
|
+
|
|
16
|
+
interface Props {
|
|
17
|
+
/** Content to display in the flex row */
|
|
18
|
+
children: Snippet;
|
|
19
|
+
/** Gap between items (standard size token or custom CSS value) */
|
|
20
|
+
gap?: SpacingSize | string | number;
|
|
21
|
+
/** Whether to wrap items to next line */
|
|
22
|
+
wrap?: boolean;
|
|
23
|
+
/** Justify content along the main axis */
|
|
24
|
+
justify?: JustifyContent;
|
|
25
|
+
/** Align items along the cross axis */
|
|
26
|
+
align?: AlignItems;
|
|
27
|
+
/** Whether to take full width (default: true) */
|
|
28
|
+
fullWidth?: boolean;
|
|
29
|
+
/** Margin on all sides (standard size token or custom CSS value) */
|
|
30
|
+
margin?: SpacingSize | string | number;
|
|
31
|
+
/** Top margin override (standard size token or custom CSS value) */
|
|
32
|
+
marginTop?: SpacingSize | string | number;
|
|
33
|
+
/** Bottom margin override (standard size token or custom CSS value) */
|
|
34
|
+
marginBottom?: SpacingSize | string | number;
|
|
35
|
+
/** Additional CSS classes */
|
|
36
|
+
class?: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const spacingTokenMap: Record<SpacingSize, string> = {
|
|
40
|
+
xs: 'var(--spacing-xs)',
|
|
41
|
+
sm: 'var(--spacing-sm)',
|
|
42
|
+
md: 'var(--spacing-md)',
|
|
43
|
+
base: 'var(--spacing-base)',
|
|
44
|
+
lg: 'var(--spacing-lg)',
|
|
45
|
+
xl: 'var(--spacing-xl)',
|
|
46
|
+
'2xl': 'var(--spacing-2xl)'
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const normalizeSpacing = (
|
|
50
|
+
value: SpacingSize | string | number | undefined
|
|
51
|
+
): string | undefined => {
|
|
52
|
+
if (value === undefined) return undefined;
|
|
53
|
+
if (typeof value === 'number') return `${value}px`;
|
|
54
|
+
if (value in spacingTokenMap) return spacingTokenMap[value as SpacingSize];
|
|
55
|
+
return value;
|
|
56
|
+
};
|
|
57
|
+
|
|
4
58
|
let {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
gap = '1rem',
|
|
8
|
-
size = 'full' as 'auto' | 'full',
|
|
59
|
+
children,
|
|
60
|
+
gap = 'base',
|
|
9
61
|
wrap = false,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
| 'baseline',
|
|
19
|
-
alignItems = 'stretch' as 'start' | 'center' | 'end' | 'stretch' | 'auto',
|
|
20
|
-
alignContent = 'stretch' as
|
|
21
|
-
| 'start'
|
|
22
|
-
| 'center'
|
|
23
|
-
| 'end'
|
|
24
|
-
| 'space-between'
|
|
25
|
-
| 'space-around'
|
|
26
|
-
| 'stretch',
|
|
27
|
-
children
|
|
28
|
-
}: {
|
|
29
|
-
marginBottom?: string | number;
|
|
30
|
-
marginTop?: string | number;
|
|
31
|
-
gap?: string | number;
|
|
32
|
-
size?: 'auto' | 'full';
|
|
33
|
-
wrap?: boolean;
|
|
34
|
-
justifyContent?:
|
|
35
|
-
| 'start'
|
|
36
|
-
| 'center'
|
|
37
|
-
| 'end'
|
|
38
|
-
| 'space-between'
|
|
39
|
-
| 'space-around'
|
|
40
|
-
| 'space-evenly'
|
|
41
|
-
| 'stretch'
|
|
42
|
-
| 'baseline';
|
|
43
|
-
alignItems?: 'start' | 'center' | 'end' | 'stretch' | 'auto';
|
|
44
|
-
alignContent?: 'start' | 'center' | 'end' | 'space-between' | 'space-around' | 'stretch';
|
|
45
|
-
children: Snippet;
|
|
46
|
-
} = $props();
|
|
62
|
+
justify = 'flex-start',
|
|
63
|
+
align = 'stretch',
|
|
64
|
+
fullWidth = true,
|
|
65
|
+
margin,
|
|
66
|
+
marginTop,
|
|
67
|
+
marginBottom,
|
|
68
|
+
class: className = ''
|
|
69
|
+
}: Props = $props();
|
|
47
70
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
let _justifyContent = $derived(
|
|
53
|
-
['start', 'end'].includes(justifyContent)
|
|
54
|
-
? `flex-${justifyContent}`
|
|
55
|
-
: ['between', 'around', 'evenly'].includes(justifyContent)
|
|
56
|
-
? `space-${justifyContent}`
|
|
57
|
-
: justifyContent
|
|
58
|
-
);
|
|
59
|
-
let _alignContent = $derived(
|
|
60
|
-
['start', 'end'].includes(alignContent)
|
|
61
|
-
? `flex-${alignContent}`
|
|
62
|
-
: ['between', 'around'].includes(alignContent)
|
|
63
|
-
? `space-${alignContent}`
|
|
64
|
-
: alignContent
|
|
71
|
+
const gapValue = $derived(normalizeSpacing(gap) ?? 'var(--spacing-base)');
|
|
72
|
+
const marginValue = $derived(normalizeSpacing(margin));
|
|
73
|
+
const marginTopValue = $derived(
|
|
74
|
+
marginTop !== undefined ? normalizeSpacing(marginTop) : marginValue
|
|
65
75
|
);
|
|
66
|
-
|
|
67
|
-
|
|
76
|
+
const marginBottomValue = $derived(
|
|
77
|
+
marginBottom !== undefined ? normalizeSpacing(marginBottom) : marginValue
|
|
68
78
|
);
|
|
69
|
-
let _gap = $derived(typeof gap === 'number' ? `${gap}px` : gap);
|
|
70
79
|
</script>
|
|
71
80
|
|
|
72
81
|
<div
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
82
|
+
class="flex-row {wrap ? 'wrap' : ''} {!fullWidth ? 'auto-width' : ''} {className}"
|
|
83
|
+
style="
|
|
84
|
+
--gap: {gapValue};
|
|
85
|
+
--justify: {justify};
|
|
86
|
+
--align: {align};
|
|
87
|
+
{marginTopValue ? `margin-top: ${marginTopValue};` : ''}
|
|
88
|
+
{marginBottomValue ? `margin-bottom: ${marginBottomValue};` : ''}
|
|
89
|
+
"
|
|
78
90
|
>
|
|
79
|
-
{@render children
|
|
91
|
+
{@render children()}
|
|
80
92
|
</div>
|
|
81
93
|
|
|
82
|
-
<style
|
|
94
|
+
<style>.flex-row {
|
|
83
95
|
display: flex;
|
|
96
|
+
flex-direction: row;
|
|
84
97
|
width: 100%;
|
|
98
|
+
gap: var(--gap, var(--spacing-base));
|
|
99
|
+
justify-content: var(--justify, flex-start);
|
|
100
|
+
align-items: var(--align, stretch);
|
|
85
101
|
flex-wrap: nowrap;
|
|
86
|
-
column-gap: 1rem;
|
|
87
102
|
}
|
|
88
|
-
|
|
89
|
-
width: auto;
|
|
90
|
-
}
|
|
91
|
-
div.wrap {
|
|
103
|
+
.flex-row.wrap {
|
|
92
104
|
flex-wrap: wrap;
|
|
105
|
+
}
|
|
106
|
+
.flex-row.auto-width {
|
|
107
|
+
width: auto;
|
|
93
108
|
}</style>
|
|
@@ -1,15 +1,29 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
|
-
type
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
wrap?: boolean;
|
|
8
|
-
justifyContent?: 'start' | 'center' | 'end' | 'space-between' | 'space-around' | 'space-evenly' | 'stretch' | 'baseline';
|
|
9
|
-
alignItems?: 'start' | 'center' | 'end' | 'stretch' | 'auto';
|
|
10
|
-
alignContent?: 'start' | 'center' | 'end' | 'space-between' | 'space-around' | 'stretch';
|
|
2
|
+
type JustifyContent = 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around' | 'space-evenly';
|
|
3
|
+
type AlignItems = 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline';
|
|
4
|
+
type SpacingSize = 'xs' | 'sm' | 'md' | 'base' | 'lg' | 'xl' | '2xl';
|
|
5
|
+
interface Props {
|
|
6
|
+
/** Content to display in the flex row */
|
|
11
7
|
children: Snippet;
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
/** Gap between items (standard size token or custom CSS value) */
|
|
9
|
+
gap?: SpacingSize | string | number;
|
|
10
|
+
/** Whether to wrap items to next line */
|
|
11
|
+
wrap?: boolean;
|
|
12
|
+
/** Justify content along the main axis */
|
|
13
|
+
justify?: JustifyContent;
|
|
14
|
+
/** Align items along the cross axis */
|
|
15
|
+
align?: AlignItems;
|
|
16
|
+
/** Whether to take full width (default: true) */
|
|
17
|
+
fullWidth?: boolean;
|
|
18
|
+
/** Margin on all sides (standard size token or custom CSS value) */
|
|
19
|
+
margin?: SpacingSize | string | number;
|
|
20
|
+
/** Top margin override (standard size token or custom CSS value) */
|
|
21
|
+
marginTop?: SpacingSize | string | number;
|
|
22
|
+
/** Bottom margin override (standard size token or custom CSS value) */
|
|
23
|
+
marginBottom?: SpacingSize | string | number;
|
|
24
|
+
/** Additional CSS classes */
|
|
25
|
+
class?: string;
|
|
26
|
+
}
|
|
27
|
+
declare const FlexRow: import("svelte").Component<Props, {}, "">;
|
|
14
28
|
type FlexRow = ReturnType<typeof FlexRow>;
|
|
15
29
|
export default FlexRow;
|
package/dist/layout/index.d.ts
CHANGED
|
@@ -2,3 +2,4 @@ export { default as FlexCol } from './flex-col.svelte';
|
|
|
2
2
|
export { default as FlexRow } from './flex-row.svelte';
|
|
3
3
|
export { default as FlexItem } from './flex-item.svelte';
|
|
4
4
|
export { default as Grid } from './grid.svelte';
|
|
5
|
+
export { default as Main } from './main/main.svelte';
|
package/dist/layout/index.js
CHANGED
|
@@ -2,3 +2,4 @@ export { default as FlexCol } from './flex-col.svelte';
|
|
|
2
2
|
export { default as FlexRow } from './flex-row.svelte';
|
|
3
3
|
export { default as FlexItem } from './flex-item.svelte';
|
|
4
4
|
export { default as Grid } from './grid.svelte';
|
|
5
|
+
export { default as Main } from './main/main.svelte';
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
let {
|
|
5
|
+
children
|
|
6
|
+
}: {
|
|
7
|
+
children: Snippet;
|
|
8
|
+
} = $props();
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<main>
|
|
12
|
+
<a
|
|
13
|
+
id="top"
|
|
14
|
+
aria-hidden="true"
|
|
15
|
+
style="position: absolute; top: 0; left: 0; width: 1px; height: 1px; opacity: 0; pointer-events: none;"
|
|
16
|
+
></a>
|
|
17
|
+
{@render children?.()}
|
|
18
|
+
</main>
|
|
19
|
+
|
|
20
|
+
<style>/* ============================================
|
|
21
|
+
BREAKPOINTS - Responsive Design
|
|
22
|
+
============================================ */
|
|
23
|
+
main {
|
|
24
|
+
position: relative;
|
|
25
|
+
display: flex;
|
|
26
|
+
flex-direction: column;
|
|
27
|
+
align-items: stretch;
|
|
28
|
+
width: 100%;
|
|
29
|
+
max-width: 1000px; /* Desktop: good for 1366px-1920px screens */
|
|
30
|
+
margin: 0 auto;
|
|
31
|
+
padding: 0 var(--spacing-base, 1rem);
|
|
32
|
+
/* Improve touch scrolling on iOS */
|
|
33
|
+
-webkit-overflow-scrolling: touch;
|
|
34
|
+
overflow-x: hidden; /* Prevent horizontal scroll */
|
|
35
|
+
/* Responsive padding for larger screens */
|
|
36
|
+
}
|
|
37
|
+
@media (min-width: 641px) {
|
|
38
|
+
main {
|
|
39
|
+
padding: 0 var(--spacing-xl, 2rem);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
main {
|
|
43
|
+
/* Increase max-width on large screens to better utilize space */
|
|
44
|
+
/* 1440px provides good readability while using more of the screen */
|
|
45
|
+
}
|
|
46
|
+
@media (min-width: 1280px) {
|
|
47
|
+
main {
|
|
48
|
+
max-width: 1440px;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
main {
|
|
52
|
+
/* Add extra bottom padding on mobile for better UX */
|
|
53
|
+
}
|
|
54
|
+
@media (max-width: 319.98px) {
|
|
55
|
+
main {
|
|
56
|
+
padding-bottom: 2rem;
|
|
57
|
+
}
|
|
58
|
+
}</style>
|
|
@@ -56,9 +56,14 @@
|
|
|
56
56
|
<style>.accordion {
|
|
57
57
|
background: #eee;
|
|
58
58
|
color: #000;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
display: flex;
|
|
60
|
+
flex-direction: column;
|
|
61
|
+
align-items: stretch;
|
|
62
|
+
min-height: fit-content;
|
|
63
|
+
}
|
|
64
|
+
.accordion h3 {
|
|
65
|
+
margin: 0;
|
|
66
|
+
padding: 0;
|
|
62
67
|
}
|
|
63
68
|
.accordion button {
|
|
64
69
|
appearance: none;
|
|
@@ -72,12 +77,15 @@
|
|
|
72
77
|
justify-content: space-between;
|
|
73
78
|
align-items: center;
|
|
74
79
|
font-size: 1rem;
|
|
80
|
+
box-sizing: border-box;
|
|
81
|
+
min-height: fit-content;
|
|
75
82
|
}
|
|
76
83
|
.accordion button .icon {
|
|
77
84
|
width: 1rem;
|
|
78
85
|
height: 1rem;
|
|
79
86
|
display: block;
|
|
80
87
|
transition: transform 0.3s linear;
|
|
88
|
+
flex-shrink: 0;
|
|
81
89
|
}
|
|
82
90
|
.accordion button:hover {
|
|
83
91
|
background: #ccc;
|
|
@@ -86,12 +94,12 @@
|
|
|
86
94
|
padding: 1rem;
|
|
87
95
|
opacity: 0;
|
|
88
96
|
transition: opacity 0.3s linear;
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
max-height: 800px;
|
|
97
|
+
max-height: 0;
|
|
98
|
+
overflow: hidden;
|
|
92
99
|
}
|
|
93
100
|
.accordion.expanded .menu {
|
|
94
101
|
opacity: 1;
|
|
102
|
+
max-height: none;
|
|
95
103
|
}
|
|
96
104
|
.accordion.expanded .icon {
|
|
97
105
|
transform: rotate(180deg);
|