sv5ui 2.2.0 → 2.3.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/dist/components/Error/Error.svelte +89 -0
- package/dist/components/Error/Error.svelte.d.ts +5 -0
- package/dist/components/Error/error.types.d.ts +87 -0
- package/dist/components/Error/error.types.js +1 -0
- package/dist/components/Error/error.variants.d.ts +66 -0
- package/dist/components/Error/error.variants.js +16 -0
- package/dist/components/Error/index.d.ts +2 -0
- package/dist/components/Error/index.js +1 -0
- package/dist/components/Footer/Footer.svelte +71 -0
- package/dist/components/Footer/Footer.svelte.d.ts +5 -0
- package/dist/components/Footer/FooterColumns.svelte +110 -0
- package/dist/components/Footer/FooterColumns.svelte.d.ts +5 -0
- package/dist/components/Footer/footer-columns.types.d.ts +73 -0
- package/dist/components/Footer/footer-columns.types.js +1 -0
- package/dist/components/Footer/footer-columns.variants.d.ts +108 -0
- package/dist/components/Footer/footer-columns.variants.js +23 -0
- package/dist/components/Footer/footer.types.d.ts +46 -0
- package/dist/components/Footer/footer.types.js +1 -0
- package/dist/components/Footer/footer.variants.d.ts +66 -0
- package/dist/components/Footer/footer.variants.js +16 -0
- package/dist/components/Footer/index.d.ts +4 -0
- package/dist/components/Footer/index.js +2 -0
- package/dist/components/Header/Header.svelte +177 -0
- package/dist/components/Header/Header.svelte.d.ts +5 -0
- package/dist/components/Header/header.types.d.ts +124 -0
- package/dist/components/Header/header.types.js +1 -0
- package/dist/components/Header/header.variants.d.ts +108 -0
- package/dist/components/Header/header.variants.js +32 -0
- package/dist/components/Header/index.d.ts +2 -0
- package/dist/components/Header/index.js +1 -0
- package/dist/components/Main/Main.svelte +20 -0
- package/dist/components/Main/Main.svelte.d.ts +5 -0
- package/dist/components/Main/index.d.ts +2 -0
- package/dist/components/Main/index.js +1 -0
- package/dist/components/Main/main.types.d.ts +27 -0
- package/dist/components/Main/main.types.js +1 -0
- package/dist/components/Main/main.variants.d.ts +30 -0
- package/dist/components/Main/main.variants.js +10 -0
- package/dist/components/Tour/Tour.svelte +459 -0
- package/dist/components/Tour/Tour.svelte.d.ts +5 -0
- package/dist/components/Tour/index.d.ts +2 -0
- package/dist/components/Tour/index.js +1 -0
- package/dist/components/Tour/tour.types.d.ts +457 -0
- package/dist/components/Tour/tour.types.js +1 -0
- package/dist/components/Tour/tour.variants.d.ts +208 -0
- package/dist/components/Tour/tour.variants.js +56 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.js +2 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/useTour/index.d.ts +1 -0
- package/dist/hooks/useTour/index.js +1 -0
- package/dist/hooks/useTour/useTour.svelte.d.ts +29 -0
- package/dist/hooks/useTour/useTour.svelte.js +194 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/theme.css +3 -0
- package/package.json +1 -1
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
<script lang="ts" module></script>
|
|
2
|
+
|
|
3
|
+
<script lang="ts">import { errorVariants, errorDefaults } from "./error.variants.js";
|
|
4
|
+
import { getComponentConfig } from "../../config.js";
|
|
5
|
+
import Icon from "../Icon/Icon.svelte";
|
|
6
|
+
import Button from "../Button/Button.svelte";
|
|
7
|
+
const config = getComponentConfig("error", errorDefaults);
|
|
8
|
+
let {
|
|
9
|
+
ref = $bindable(null),
|
|
10
|
+
as = "main",
|
|
11
|
+
ui,
|
|
12
|
+
icon,
|
|
13
|
+
error,
|
|
14
|
+
redirect = "/",
|
|
15
|
+
clear = true,
|
|
16
|
+
onClear,
|
|
17
|
+
class: className,
|
|
18
|
+
leading,
|
|
19
|
+
statusCode,
|
|
20
|
+
statusMessage,
|
|
21
|
+
message,
|
|
22
|
+
links,
|
|
23
|
+
children,
|
|
24
|
+
...restProps
|
|
25
|
+
} = $props();
|
|
26
|
+
const slots = errorVariants();
|
|
27
|
+
const classes = $derived.by(() => {
|
|
28
|
+
const c = config.slots;
|
|
29
|
+
return {
|
|
30
|
+
root: slots.root({ class: [c.root, className, ui?.root] }),
|
|
31
|
+
leading: slots.leading({ class: [c.leading, ui?.leading] }),
|
|
32
|
+
leadingIcon: slots.leadingIcon({ class: [c.leadingIcon, ui?.leadingIcon] }),
|
|
33
|
+
statusCode: slots.statusCode({ class: [c.statusCode, ui?.statusCode] }),
|
|
34
|
+
statusMessage: slots.statusMessage({ class: [c.statusMessage, ui?.statusMessage] }),
|
|
35
|
+
message: slots.message({ class: [c.message, ui?.message] }),
|
|
36
|
+
links: slots.links({ class: [c.links, ui?.links] })
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
const clearButton = $derived({
|
|
40
|
+
label: "Back to home",
|
|
41
|
+
color: "primary",
|
|
42
|
+
size: "lg",
|
|
43
|
+
...onClear ? {} : { href: redirect },
|
|
44
|
+
...typeof clear === "object" ? clear : {}
|
|
45
|
+
});
|
|
46
|
+
const showMessage = $derived(!!error?.message && error.message !== error.statusMessage);
|
|
47
|
+
</script>
|
|
48
|
+
|
|
49
|
+
<svelte:element this={as} bind:this={ref} class={classes.root} {...restProps}>
|
|
50
|
+
{#if leading}
|
|
51
|
+
<div class={classes.leading}>
|
|
52
|
+
{@render leading()}
|
|
53
|
+
</div>
|
|
54
|
+
{:else if icon}
|
|
55
|
+
<div class={classes.leading}>
|
|
56
|
+
<Icon name={icon} class={classes.leadingIcon} />
|
|
57
|
+
</div>
|
|
58
|
+
{/if}
|
|
59
|
+
|
|
60
|
+
{#if statusCode}
|
|
61
|
+
{@render statusCode()}
|
|
62
|
+
{:else if error?.statusCode}
|
|
63
|
+
<p class={classes.statusCode}>{error.statusCode}</p>
|
|
64
|
+
{/if}
|
|
65
|
+
|
|
66
|
+
{#if statusMessage}
|
|
67
|
+
{@render statusMessage()}
|
|
68
|
+
{:else if error?.statusMessage}
|
|
69
|
+
<h1 class={classes.statusMessage}>{error.statusMessage}</h1>
|
|
70
|
+
{/if}
|
|
71
|
+
|
|
72
|
+
{#if message}
|
|
73
|
+
{@render message()}
|
|
74
|
+
{:else if showMessage}
|
|
75
|
+
<p class={classes.message}>{error?.message}</p>
|
|
76
|
+
{/if}
|
|
77
|
+
|
|
78
|
+
{#if links}
|
|
79
|
+
<div class={classes.links}>
|
|
80
|
+
{@render links()}
|
|
81
|
+
</div>
|
|
82
|
+
{:else if clear}
|
|
83
|
+
<div class={classes.links}>
|
|
84
|
+
<Button onclick={onClear} {...clearButton} />
|
|
85
|
+
</div>
|
|
86
|
+
{/if}
|
|
87
|
+
|
|
88
|
+
{@render children?.()}
|
|
89
|
+
</svelte:element>
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import type { ClassNameValue } from 'tailwind-merge';
|
|
4
|
+
import type { ErrorSlots } from './error.variants.js';
|
|
5
|
+
import type { ButtonProps } from '../Button/button.types.js';
|
|
6
|
+
export type ErrorData = {
|
|
7
|
+
/**
|
|
8
|
+
* HTTP status code of the error.
|
|
9
|
+
*/
|
|
10
|
+
statusCode?: number | string;
|
|
11
|
+
/**
|
|
12
|
+
* Short status text displayed as the main heading.
|
|
13
|
+
*/
|
|
14
|
+
statusMessage?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Detailed error description.
|
|
17
|
+
* Hidden automatically when identical to statusMessage.
|
|
18
|
+
*/
|
|
19
|
+
message?: string;
|
|
20
|
+
};
|
|
21
|
+
export type ErrorProps = Omit<HTMLAttributes<HTMLElement>, 'class'> & {
|
|
22
|
+
/**
|
|
23
|
+
* Bindable reference to the root DOM element.
|
|
24
|
+
*/
|
|
25
|
+
ref?: HTMLElement | null;
|
|
26
|
+
/**
|
|
27
|
+
* Renders the error state as a different HTML element.
|
|
28
|
+
* @default 'main'
|
|
29
|
+
*/
|
|
30
|
+
as?: keyof HTMLElementTagNameMap;
|
|
31
|
+
/**
|
|
32
|
+
* Override styles for specific error slots.
|
|
33
|
+
*/
|
|
34
|
+
ui?: Partial<Record<ErrorSlots, ClassNameValue>>;
|
|
35
|
+
/**
|
|
36
|
+
* Icon displayed above the status code.
|
|
37
|
+
*/
|
|
38
|
+
icon?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Error object containing statusCode, statusMessage, and message.
|
|
41
|
+
*/
|
|
42
|
+
error?: ErrorData;
|
|
43
|
+
/**
|
|
44
|
+
* URL the clear button navigates to.
|
|
45
|
+
* Ignored when onClear is provided.
|
|
46
|
+
* @default '/'
|
|
47
|
+
*/
|
|
48
|
+
redirect?: string;
|
|
49
|
+
/**
|
|
50
|
+
* Customize the clear button with ButtonProps or hide it with false.
|
|
51
|
+
* @default true
|
|
52
|
+
*/
|
|
53
|
+
clear?: boolean | ButtonProps;
|
|
54
|
+
/**
|
|
55
|
+
* Callback invoked when the clear button is clicked.
|
|
56
|
+
* When provided, the clear button renders as a button instead of a link.
|
|
57
|
+
*/
|
|
58
|
+
onClear?: () => void;
|
|
59
|
+
/**
|
|
60
|
+
* Additional CSS classes for the root element.
|
|
61
|
+
*/
|
|
62
|
+
class?: ClassNameValue;
|
|
63
|
+
/**
|
|
64
|
+
* Custom content to replace the default icon area.
|
|
65
|
+
*/
|
|
66
|
+
leading?: Snippet;
|
|
67
|
+
/**
|
|
68
|
+
* Custom content to replace the default status code rendering.
|
|
69
|
+
*/
|
|
70
|
+
statusCode?: Snippet;
|
|
71
|
+
/**
|
|
72
|
+
* Custom content to replace the default status message rendering.
|
|
73
|
+
*/
|
|
74
|
+
statusMessage?: Snippet;
|
|
75
|
+
/**
|
|
76
|
+
* Custom content to replace the default message rendering.
|
|
77
|
+
*/
|
|
78
|
+
message?: Snippet;
|
|
79
|
+
/**
|
|
80
|
+
* Custom content to replace the default clear button area.
|
|
81
|
+
*/
|
|
82
|
+
links?: Snippet;
|
|
83
|
+
/**
|
|
84
|
+
* Additional content rendered after the links area.
|
|
85
|
+
*/
|
|
86
|
+
children?: Snippet;
|
|
87
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export declare const errorVariants: import("tailwind-variants").TVReturnType<{
|
|
2
|
+
[key: string]: {
|
|
3
|
+
[key: string]: import("tailwind-merge").ClassNameValue | {
|
|
4
|
+
leadingIcon?: import("tailwind-merge").ClassNameValue;
|
|
5
|
+
leading?: import("tailwind-merge").ClassNameValue;
|
|
6
|
+
root?: import("tailwind-merge").ClassNameValue;
|
|
7
|
+
message?: import("tailwind-merge").ClassNameValue;
|
|
8
|
+
statusCode?: import("tailwind-merge").ClassNameValue;
|
|
9
|
+
statusMessage?: import("tailwind-merge").ClassNameValue;
|
|
10
|
+
links?: import("tailwind-merge").ClassNameValue;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
} | {
|
|
14
|
+
[x: string]: {
|
|
15
|
+
[x: string]: import("tailwind-merge").ClassNameValue | {
|
|
16
|
+
leadingIcon?: import("tailwind-merge").ClassNameValue;
|
|
17
|
+
leading?: import("tailwind-merge").ClassNameValue;
|
|
18
|
+
root?: import("tailwind-merge").ClassNameValue;
|
|
19
|
+
message?: import("tailwind-merge").ClassNameValue;
|
|
20
|
+
statusCode?: import("tailwind-merge").ClassNameValue;
|
|
21
|
+
statusMessage?: import("tailwind-merge").ClassNameValue;
|
|
22
|
+
links?: import("tailwind-merge").ClassNameValue;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
} | {}, {
|
|
26
|
+
root: string;
|
|
27
|
+
leading: string;
|
|
28
|
+
leadingIcon: string;
|
|
29
|
+
statusCode: string;
|
|
30
|
+
statusMessage: string;
|
|
31
|
+
message: string;
|
|
32
|
+
links: string;
|
|
33
|
+
}, undefined, {
|
|
34
|
+
[key: string]: {
|
|
35
|
+
[key: string]: import("tailwind-merge").ClassNameValue | {
|
|
36
|
+
leadingIcon?: import("tailwind-merge").ClassNameValue;
|
|
37
|
+
leading?: import("tailwind-merge").ClassNameValue;
|
|
38
|
+
root?: import("tailwind-merge").ClassNameValue;
|
|
39
|
+
message?: import("tailwind-merge").ClassNameValue;
|
|
40
|
+
statusCode?: import("tailwind-merge").ClassNameValue;
|
|
41
|
+
statusMessage?: import("tailwind-merge").ClassNameValue;
|
|
42
|
+
links?: import("tailwind-merge").ClassNameValue;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
} | {}, {
|
|
46
|
+
root: string;
|
|
47
|
+
leading: string;
|
|
48
|
+
leadingIcon: string;
|
|
49
|
+
statusCode: string;
|
|
50
|
+
statusMessage: string;
|
|
51
|
+
message: string;
|
|
52
|
+
links: string;
|
|
53
|
+
}, import("tailwind-variants").TVReturnType<unknown, {
|
|
54
|
+
root: string;
|
|
55
|
+
leading: string;
|
|
56
|
+
leadingIcon: string;
|
|
57
|
+
statusCode: string;
|
|
58
|
+
statusMessage: string;
|
|
59
|
+
message: string;
|
|
60
|
+
links: string;
|
|
61
|
+
}, undefined, unknown, unknown, undefined>>;
|
|
62
|
+
export type ErrorSlots = keyof ReturnType<typeof errorVariants>;
|
|
63
|
+
export declare const errorDefaults: {
|
|
64
|
+
defaultVariants: Record<string, never>;
|
|
65
|
+
slots: Partial<Record<ErrorSlots, string>>;
|
|
66
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { tv } from 'tailwind-variants';
|
|
2
|
+
export const errorVariants = tv({
|
|
3
|
+
slots: {
|
|
4
|
+
root: 'min-h-[calc(100svh-var(--ui-header-height,0px))] flex flex-col items-center justify-center text-center px-4',
|
|
5
|
+
leading: 'flex items-center justify-center mb-4',
|
|
6
|
+
leadingIcon: 'size-12 shrink-0 text-primary',
|
|
7
|
+
statusCode: 'text-base font-semibold text-primary',
|
|
8
|
+
statusMessage: 'mt-2 text-4xl sm:text-5xl font-bold text-on-surface text-balance',
|
|
9
|
+
message: 'mt-4 text-lg text-on-surface-variant text-balance',
|
|
10
|
+
links: 'mt-8 flex items-center justify-center gap-6'
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
export const errorDefaults = {
|
|
14
|
+
defaultVariants: {},
|
|
15
|
+
slots: {}
|
|
16
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Error } from './Error.svelte';
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
<script lang="ts" module></script>
|
|
2
|
+
|
|
3
|
+
<script lang="ts">import { footerVariants, footerDefaults } from "./footer.variants.js";
|
|
4
|
+
import { getComponentConfig } from "../../config.js";
|
|
5
|
+
import Container from "../Container/Container.svelte";
|
|
6
|
+
const config = getComponentConfig("footer", footerDefaults);
|
|
7
|
+
let {
|
|
8
|
+
ref = $bindable(null),
|
|
9
|
+
as = "footer",
|
|
10
|
+
ui,
|
|
11
|
+
class: className,
|
|
12
|
+
top,
|
|
13
|
+
left,
|
|
14
|
+
children,
|
|
15
|
+
right,
|
|
16
|
+
bottom,
|
|
17
|
+
...restProps
|
|
18
|
+
} = $props();
|
|
19
|
+
const slots = footerVariants();
|
|
20
|
+
const classes = $derived.by(() => {
|
|
21
|
+
const c = config.slots;
|
|
22
|
+
const u = ui ?? {};
|
|
23
|
+
return {
|
|
24
|
+
root: slots.root({ class: [c.root, className, u.root] }),
|
|
25
|
+
top: slots.top({ class: [c.top, u.top] }),
|
|
26
|
+
container: slots.container({ class: [c.container, u.container] }),
|
|
27
|
+
left: slots.left({ class: [c.left, u.left] }),
|
|
28
|
+
center: slots.center({ class: [c.center, u.center] }),
|
|
29
|
+
right: slots.right({ class: [c.right, u.right] }),
|
|
30
|
+
bottom: slots.bottom({ class: [c.bottom, u.bottom] })
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<svelte:element this={as} bind:this={ref} class={classes.root} {...restProps}>
|
|
36
|
+
{#if top}
|
|
37
|
+
<div class={classes.top}>
|
|
38
|
+
<Container>
|
|
39
|
+
{@render top()}
|
|
40
|
+
</Container>
|
|
41
|
+
</div>
|
|
42
|
+
{/if}
|
|
43
|
+
|
|
44
|
+
<Container class={classes.container}>
|
|
45
|
+
{#if right}
|
|
46
|
+
<div class={classes.right}>
|
|
47
|
+
{@render right()}
|
|
48
|
+
</div>
|
|
49
|
+
{/if}
|
|
50
|
+
|
|
51
|
+
{#if children}
|
|
52
|
+
<div class={classes.center}>
|
|
53
|
+
{@render children()}
|
|
54
|
+
</div>
|
|
55
|
+
{/if}
|
|
56
|
+
|
|
57
|
+
{#if left}
|
|
58
|
+
<div class={classes.left}>
|
|
59
|
+
{@render left()}
|
|
60
|
+
</div>
|
|
61
|
+
{/if}
|
|
62
|
+
</Container>
|
|
63
|
+
|
|
64
|
+
{#if bottom}
|
|
65
|
+
<div class={classes.bottom}>
|
|
66
|
+
<Container>
|
|
67
|
+
{@render bottom()}
|
|
68
|
+
</Container>
|
|
69
|
+
</div>
|
|
70
|
+
{/if}
|
|
71
|
+
</svelte:element>
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
<script lang="ts" module></script>
|
|
2
|
+
|
|
3
|
+
<script lang="ts">import { footerColumnsVariants, footerColumnsDefaults } from "./footer-columns.variants.js";
|
|
4
|
+
import { getComponentConfig, iconsDefaults } from "../../config.js";
|
|
5
|
+
import Link from "../Link/Link.svelte";
|
|
6
|
+
import Icon from "../Icon/Icon.svelte";
|
|
7
|
+
const config = getComponentConfig("footerColumns", footerColumnsDefaults);
|
|
8
|
+
const icons = getComponentConfig("icons", iconsDefaults);
|
|
9
|
+
let {
|
|
10
|
+
ref = $bindable(null),
|
|
11
|
+
as = "nav",
|
|
12
|
+
ui,
|
|
13
|
+
columns,
|
|
14
|
+
class: className,
|
|
15
|
+
columnLabel,
|
|
16
|
+
link,
|
|
17
|
+
left,
|
|
18
|
+
right,
|
|
19
|
+
children,
|
|
20
|
+
...restProps
|
|
21
|
+
} = $props();
|
|
22
|
+
const slots = footerColumnsVariants();
|
|
23
|
+
const classes = $derived.by(() => {
|
|
24
|
+
const c = config.slots;
|
|
25
|
+
const u = ui ?? {};
|
|
26
|
+
return {
|
|
27
|
+
root: slots.root({ class: [c.root, className, u.root] }),
|
|
28
|
+
left: slots.left({ class: [c.left, u.left] }),
|
|
29
|
+
center: slots.center({ class: [c.center, u.center] }),
|
|
30
|
+
right: slots.right({ class: [c.right, u.right] }),
|
|
31
|
+
column: slots.column({ class: [c.column, u.column] }),
|
|
32
|
+
label: slots.label({ class: [c.label, u.label] }),
|
|
33
|
+
list: slots.list({ class: [c.list, u.list] }),
|
|
34
|
+
item: slots.item({ class: [c.item, u.item] }),
|
|
35
|
+
link: slots.link({ class: [c.link, u.link] }),
|
|
36
|
+
linkActive: slots.linkActive({ class: [c.linkActive, u.linkActive] }),
|
|
37
|
+
linkInactive: slots.linkInactive({ class: [c.linkInactive, u.linkInactive] }),
|
|
38
|
+
linkLeadingIcon: slots.linkLeadingIcon({
|
|
39
|
+
class: [c.linkLeadingIcon, u.linkLeadingIcon]
|
|
40
|
+
}),
|
|
41
|
+
linkLabel: slots.linkLabel({ class: [c.linkLabel, u.linkLabel] }),
|
|
42
|
+
linkLabelExternalIcon: slots.linkLabelExternalIcon({
|
|
43
|
+
class: [c.linkLabelExternalIcon, u.linkLabelExternalIcon]
|
|
44
|
+
})
|
|
45
|
+
};
|
|
46
|
+
});
|
|
47
|
+
const hasColumns = $derived((columns?.length ?? 0) > 0 || !!children);
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
<svelte:element this={as} bind:this={ref} class={classes.root} {...restProps}>
|
|
51
|
+
{#if left}
|
|
52
|
+
<div class={classes.left}>
|
|
53
|
+
{@render left()}
|
|
54
|
+
</div>
|
|
55
|
+
{/if}
|
|
56
|
+
|
|
57
|
+
{#if hasColumns}
|
|
58
|
+
<div class={classes.center}>
|
|
59
|
+
{#each columns ?? [] as column, columnIndex (columnIndex)}
|
|
60
|
+
<div class={classes.column}>
|
|
61
|
+
{#if columnLabel}
|
|
62
|
+
{@render columnLabel({ column })}
|
|
63
|
+
{:else}
|
|
64
|
+
<p class={classes.label}>{column.label}</p>
|
|
65
|
+
{/if}
|
|
66
|
+
|
|
67
|
+
<ul class={classes.list}>
|
|
68
|
+
{#each column.children as columnLink, linkIndex (linkIndex)}
|
|
69
|
+
<li class={classes.item}>
|
|
70
|
+
{#if link}
|
|
71
|
+
{@render link({ link: columnLink })}
|
|
72
|
+
{:else}
|
|
73
|
+
{@const { label, icon, ...linkProps } = columnLink}
|
|
74
|
+
<Link
|
|
75
|
+
raw
|
|
76
|
+
activeClass={classes.linkActive}
|
|
77
|
+
inactiveClass={classes.linkInactive}
|
|
78
|
+
{...linkProps}
|
|
79
|
+
class={[classes.link, columnLink.class]}
|
|
80
|
+
>
|
|
81
|
+
{#if icon}
|
|
82
|
+
<Icon name={icon} class={classes.linkLeadingIcon} />
|
|
83
|
+
{/if}
|
|
84
|
+
<span class={classes.linkLabel}>
|
|
85
|
+
{label}
|
|
86
|
+
{#if columnLink.target === '_blank'}
|
|
87
|
+
<Icon
|
|
88
|
+
name={icons.external}
|
|
89
|
+
class={classes.linkLabelExternalIcon}
|
|
90
|
+
/>
|
|
91
|
+
{/if}
|
|
92
|
+
</span>
|
|
93
|
+
</Link>
|
|
94
|
+
{/if}
|
|
95
|
+
</li>
|
|
96
|
+
{/each}
|
|
97
|
+
</ul>
|
|
98
|
+
</div>
|
|
99
|
+
{/each}
|
|
100
|
+
|
|
101
|
+
{@render children?.()}
|
|
102
|
+
</div>
|
|
103
|
+
{/if}
|
|
104
|
+
|
|
105
|
+
{#if right}
|
|
106
|
+
<div class={classes.right}>
|
|
107
|
+
{@render right()}
|
|
108
|
+
</div>
|
|
109
|
+
{/if}
|
|
110
|
+
</svelte:element>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { FooterColumnsProps } from './footer-columns.types.js';
|
|
2
|
+
export type Props = FooterColumnsProps;
|
|
3
|
+
declare const FooterColumns: import("svelte").Component<FooterColumnsProps, {}, "ref">;
|
|
4
|
+
type FooterColumns = ReturnType<typeof FooterColumns>;
|
|
5
|
+
export default FooterColumns;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import type { ClassNameValue } from 'tailwind-merge';
|
|
4
|
+
import type { FooterColumnsSlots } from './footer-columns.variants.js';
|
|
5
|
+
import type { LinkProps } from '../Link/link.types.js';
|
|
6
|
+
export type FooterColumnLink = Omit<LinkProps, 'children' | 'ui'> & {
|
|
7
|
+
/**
|
|
8
|
+
* Link display text.
|
|
9
|
+
*/
|
|
10
|
+
label: string;
|
|
11
|
+
/**
|
|
12
|
+
* Icon displayed before the label.
|
|
13
|
+
*/
|
|
14
|
+
icon?: string;
|
|
15
|
+
};
|
|
16
|
+
export type FooterColumn = {
|
|
17
|
+
/**
|
|
18
|
+
* Column heading text.
|
|
19
|
+
*/
|
|
20
|
+
label: string;
|
|
21
|
+
/**
|
|
22
|
+
* Links rendered in the column.
|
|
23
|
+
*/
|
|
24
|
+
children: FooterColumnLink[];
|
|
25
|
+
};
|
|
26
|
+
export type FooterColumnsProps = Omit<HTMLAttributes<HTMLElement>, 'class'> & {
|
|
27
|
+
/**
|
|
28
|
+
* Bindable reference to the root DOM element.
|
|
29
|
+
*/
|
|
30
|
+
ref?: HTMLElement | null;
|
|
31
|
+
/**
|
|
32
|
+
* Renders the columns as a different HTML element.
|
|
33
|
+
* @default 'nav'
|
|
34
|
+
*/
|
|
35
|
+
as?: keyof HTMLElementTagNameMap;
|
|
36
|
+
/**
|
|
37
|
+
* Override styles for specific slots.
|
|
38
|
+
*/
|
|
39
|
+
ui?: Partial<Record<FooterColumnsSlots, ClassNameValue>>;
|
|
40
|
+
/**
|
|
41
|
+
* Columns of link groups to render.
|
|
42
|
+
*/
|
|
43
|
+
columns?: FooterColumn[];
|
|
44
|
+
/**
|
|
45
|
+
* Additional CSS classes for the root element.
|
|
46
|
+
*/
|
|
47
|
+
class?: ClassNameValue;
|
|
48
|
+
/**
|
|
49
|
+
* Custom rendering for a column heading.
|
|
50
|
+
*/
|
|
51
|
+
columnLabel?: Snippet<[{
|
|
52
|
+
column: FooterColumn;
|
|
53
|
+
}]>;
|
|
54
|
+
/**
|
|
55
|
+
* Custom rendering for a link, replacing the default Link element.
|
|
56
|
+
*/
|
|
57
|
+
link?: Snippet<[{
|
|
58
|
+
link: FooterColumnLink;
|
|
59
|
+
}]>;
|
|
60
|
+
/**
|
|
61
|
+
* Content beside the columns, before them on xl screens.
|
|
62
|
+
*/
|
|
63
|
+
left?: Snippet;
|
|
64
|
+
/**
|
|
65
|
+
* Content beside the columns, after them on xl screens.
|
|
66
|
+
* Designed for a newsletter or call to action block.
|
|
67
|
+
*/
|
|
68
|
+
right?: Snippet;
|
|
69
|
+
/**
|
|
70
|
+
* Extra content rendered as an additional column in the grid.
|
|
71
|
+
*/
|
|
72
|
+
children?: Snippet;
|
|
73
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
export declare const footerColumnsVariants: import("tailwind-variants").TVReturnType<{
|
|
2
|
+
[key: string]: {
|
|
3
|
+
[key: string]: import("tailwind-merge").ClassNameValue | {
|
|
4
|
+
link?: import("tailwind-merge").ClassNameValue;
|
|
5
|
+
list?: import("tailwind-merge").ClassNameValue;
|
|
6
|
+
label?: import("tailwind-merge").ClassNameValue;
|
|
7
|
+
root?: import("tailwind-merge").ClassNameValue;
|
|
8
|
+
center?: import("tailwind-merge").ClassNameValue;
|
|
9
|
+
item?: import("tailwind-merge").ClassNameValue;
|
|
10
|
+
left?: import("tailwind-merge").ClassNameValue;
|
|
11
|
+
right?: import("tailwind-merge").ClassNameValue;
|
|
12
|
+
column?: import("tailwind-merge").ClassNameValue;
|
|
13
|
+
linkActive?: import("tailwind-merge").ClassNameValue;
|
|
14
|
+
linkInactive?: import("tailwind-merge").ClassNameValue;
|
|
15
|
+
linkLeadingIcon?: import("tailwind-merge").ClassNameValue;
|
|
16
|
+
linkLabel?: import("tailwind-merge").ClassNameValue;
|
|
17
|
+
linkLabelExternalIcon?: import("tailwind-merge").ClassNameValue;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
} | {
|
|
21
|
+
[x: string]: {
|
|
22
|
+
[x: string]: import("tailwind-merge").ClassNameValue | {
|
|
23
|
+
link?: import("tailwind-merge").ClassNameValue;
|
|
24
|
+
list?: import("tailwind-merge").ClassNameValue;
|
|
25
|
+
label?: import("tailwind-merge").ClassNameValue;
|
|
26
|
+
root?: import("tailwind-merge").ClassNameValue;
|
|
27
|
+
center?: import("tailwind-merge").ClassNameValue;
|
|
28
|
+
item?: import("tailwind-merge").ClassNameValue;
|
|
29
|
+
left?: import("tailwind-merge").ClassNameValue;
|
|
30
|
+
right?: import("tailwind-merge").ClassNameValue;
|
|
31
|
+
column?: import("tailwind-merge").ClassNameValue;
|
|
32
|
+
linkActive?: import("tailwind-merge").ClassNameValue;
|
|
33
|
+
linkInactive?: import("tailwind-merge").ClassNameValue;
|
|
34
|
+
linkLeadingIcon?: import("tailwind-merge").ClassNameValue;
|
|
35
|
+
linkLabel?: import("tailwind-merge").ClassNameValue;
|
|
36
|
+
linkLabelExternalIcon?: import("tailwind-merge").ClassNameValue;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
} | {}, {
|
|
40
|
+
root: string;
|
|
41
|
+
left: string;
|
|
42
|
+
center: string;
|
|
43
|
+
right: string;
|
|
44
|
+
column: string;
|
|
45
|
+
label: string;
|
|
46
|
+
list: string;
|
|
47
|
+
item: string;
|
|
48
|
+
link: string;
|
|
49
|
+
linkActive: string;
|
|
50
|
+
linkInactive: string;
|
|
51
|
+
linkLeadingIcon: string;
|
|
52
|
+
linkLabel: string;
|
|
53
|
+
linkLabelExternalIcon: string;
|
|
54
|
+
}, undefined, {
|
|
55
|
+
[key: string]: {
|
|
56
|
+
[key: string]: import("tailwind-merge").ClassNameValue | {
|
|
57
|
+
link?: import("tailwind-merge").ClassNameValue;
|
|
58
|
+
list?: import("tailwind-merge").ClassNameValue;
|
|
59
|
+
label?: import("tailwind-merge").ClassNameValue;
|
|
60
|
+
root?: import("tailwind-merge").ClassNameValue;
|
|
61
|
+
center?: import("tailwind-merge").ClassNameValue;
|
|
62
|
+
item?: import("tailwind-merge").ClassNameValue;
|
|
63
|
+
left?: import("tailwind-merge").ClassNameValue;
|
|
64
|
+
right?: import("tailwind-merge").ClassNameValue;
|
|
65
|
+
column?: import("tailwind-merge").ClassNameValue;
|
|
66
|
+
linkActive?: import("tailwind-merge").ClassNameValue;
|
|
67
|
+
linkInactive?: import("tailwind-merge").ClassNameValue;
|
|
68
|
+
linkLeadingIcon?: import("tailwind-merge").ClassNameValue;
|
|
69
|
+
linkLabel?: import("tailwind-merge").ClassNameValue;
|
|
70
|
+
linkLabelExternalIcon?: import("tailwind-merge").ClassNameValue;
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
} | {}, {
|
|
74
|
+
root: string;
|
|
75
|
+
left: string;
|
|
76
|
+
center: string;
|
|
77
|
+
right: string;
|
|
78
|
+
column: string;
|
|
79
|
+
label: string;
|
|
80
|
+
list: string;
|
|
81
|
+
item: string;
|
|
82
|
+
link: string;
|
|
83
|
+
linkActive: string;
|
|
84
|
+
linkInactive: string;
|
|
85
|
+
linkLeadingIcon: string;
|
|
86
|
+
linkLabel: string;
|
|
87
|
+
linkLabelExternalIcon: string;
|
|
88
|
+
}, import("tailwind-variants").TVReturnType<unknown, {
|
|
89
|
+
root: string;
|
|
90
|
+
left: string;
|
|
91
|
+
center: string;
|
|
92
|
+
right: string;
|
|
93
|
+
column: string;
|
|
94
|
+
label: string;
|
|
95
|
+
list: string;
|
|
96
|
+
item: string;
|
|
97
|
+
link: string;
|
|
98
|
+
linkActive: string;
|
|
99
|
+
linkInactive: string;
|
|
100
|
+
linkLeadingIcon: string;
|
|
101
|
+
linkLabel: string;
|
|
102
|
+
linkLabelExternalIcon: string;
|
|
103
|
+
}, undefined, unknown, unknown, undefined>>;
|
|
104
|
+
export type FooterColumnsSlots = keyof ReturnType<typeof footerColumnsVariants>;
|
|
105
|
+
export declare const footerColumnsDefaults: {
|
|
106
|
+
defaultVariants: Record<string, never>;
|
|
107
|
+
slots: Partial<Record<FooterColumnsSlots, string>>;
|
|
108
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { tv } from 'tailwind-variants';
|
|
2
|
+
export const footerColumnsVariants = tv({
|
|
3
|
+
slots: {
|
|
4
|
+
root: 'xl:grid xl:grid-cols-3 xl:gap-8',
|
|
5
|
+
left: 'mb-10 xl:mb-0',
|
|
6
|
+
center: 'flex flex-col gap-8 lg:grid lg:auto-cols-fr lg:grid-flow-col xl:col-span-2',
|
|
7
|
+
right: 'mt-10 xl:mt-0',
|
|
8
|
+
column: '',
|
|
9
|
+
label: 'text-sm font-semibold text-on-surface',
|
|
10
|
+
list: 'mt-6 space-y-4',
|
|
11
|
+
item: 'relative',
|
|
12
|
+
link: 'group flex items-center gap-1.5 text-sm',
|
|
13
|
+
linkActive: 'font-medium text-primary',
|
|
14
|
+
linkInactive: 'text-on-surface-variant transition-colors hover:text-on-surface',
|
|
15
|
+
linkLeadingIcon: 'size-5 shrink-0',
|
|
16
|
+
linkLabel: 'truncate',
|
|
17
|
+
linkLabelExternalIcon: 'absolute top-0 inline-block size-3 text-on-surface-variant'
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
export const footerColumnsDefaults = {
|
|
21
|
+
defaultVariants: {},
|
|
22
|
+
slots: {}
|
|
23
|
+
};
|