@mrintel/villain-ui 0.2.2 → 0.6.3
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/LICENSE +21 -21
- package/README.md +3490 -1296
- package/dist/components/buttons/Button.svelte +27 -0
- package/dist/components/buttons/Button.svelte.d.ts +14 -0
- package/dist/components/buttons/ButtonGroup.svelte +17 -0
- package/dist/components/buttons/ButtonGroup.svelte.d.ts +8 -0
- package/dist/components/buttons/FloatingActionButton.svelte +20 -0
- package/dist/components/buttons/FloatingActionButton.svelte.d.ts +12 -0
- package/dist/components/buttons/IconButton.svelte +23 -0
- package/dist/components/buttons/IconButton.svelte.d.ts +14 -0
- package/dist/components/buttons/LinkButton.svelte +24 -0
- package/dist/components/buttons/LinkButton.svelte.d.ts +15 -0
- package/dist/components/buttons/buttonClasses.d.ts +15 -0
- package/dist/components/buttons/buttonClasses.js +15 -0
- package/dist/components/buttons/index.d.ts +5 -0
- package/dist/components/buttons/index.js +5 -0
- package/dist/components/cards/Card.svelte +60 -0
- package/dist/components/cards/Card.svelte.d.ts +15 -0
- package/dist/components/cards/Container.svelte +17 -0
- package/dist/components/cards/Container.svelte.d.ts +10 -0
- package/dist/components/cards/Divider.svelte +36 -0
- package/dist/components/cards/Divider.svelte.d.ts +11 -0
- package/dist/components/cards/Grid.svelte +55 -0
- package/dist/components/cards/Grid.svelte.d.ts +10 -0
- package/dist/components/cards/Panel.svelte +18 -0
- package/dist/components/cards/Panel.svelte.d.ts +11 -0
- package/dist/components/cards/SectionHeader.svelte +24 -0
- package/dist/components/cards/SectionHeader.svelte.d.ts +12 -0
- package/dist/components/cards/index.d.ts +6 -0
- package/dist/components/cards/index.js +6 -0
- package/dist/components/data/Avatar.svelte +48 -0
- package/dist/components/data/Avatar.svelte.d.ts +10 -0
- package/dist/components/data/Badge.svelte +45 -0
- package/dist/components/data/Badge.svelte.d.ts +14 -0
- package/dist/components/data/CalendarGrid.svelte +433 -0
- package/dist/components/data/CalendarGrid.svelte.d.ts +25 -0
- package/dist/components/data/CalendarGrid.types.d.ts +7 -0
- package/dist/components/data/CalendarGrid.types.js +1 -0
- package/dist/components/data/CodeBlock.svelte +119 -0
- package/dist/components/data/CodeBlock.svelte.d.ts +40 -0
- package/dist/components/data/List.svelte +87 -0
- package/dist/components/data/List.svelte.d.ts +15 -0
- package/dist/components/data/Pagination.svelte +121 -0
- package/dist/components/data/Pagination.svelte.d.ts +14 -0
- package/dist/components/data/Sparkline.svelte +117 -0
- package/dist/components/data/Sparkline.svelte.d.ts +43 -0
- package/dist/components/data/Stat.svelte +92 -0
- package/dist/components/data/Stat.svelte.d.ts +11 -0
- package/dist/components/data/Table.svelte +443 -0
- package/dist/components/data/Table.svelte.d.ts +30 -0
- package/dist/components/data/Table.types.d.ts +14 -0
- package/dist/components/data/Table.types.js +1 -0
- package/dist/components/data/Tag.svelte +51 -0
- package/dist/components/data/Tag.svelte.d.ts +13 -0
- package/dist/components/data/index.d.ts +12 -0
- package/dist/components/data/index.js +10 -0
- package/dist/components/forms/Checkbox.svelte +39 -0
- package/dist/components/forms/Checkbox.svelte.d.ts +12 -0
- package/dist/components/forms/DatePicker.svelte +61 -0
- package/dist/components/forms/DatePicker.svelte.d.ts +15 -0
- package/dist/components/forms/DateTimePicker.svelte +63 -0
- package/dist/components/forms/DateTimePicker.svelte.d.ts +16 -0
- package/dist/components/forms/FileUpload.svelte +136 -0
- package/dist/components/forms/FileUpload.svelte.d.ts +23 -0
- package/dist/components/forms/Input.svelte +282 -0
- package/dist/components/forms/Input.svelte.d.ts +19 -0
- package/dist/components/forms/InputGroup.svelte +7 -0
- package/dist/components/forms/InputGroup.svelte.d.ts +20 -0
- package/dist/components/forms/RadioGroup.svelte +77 -0
- package/dist/components/forms/RadioGroup.svelte.d.ts +17 -0
- package/dist/components/forms/RangeSlider.svelte +90 -0
- package/dist/components/forms/RangeSlider.svelte.d.ts +14 -0
- package/dist/components/forms/Select.svelte +106 -0
- package/dist/components/forms/Select.svelte.d.ts +18 -0
- package/dist/components/forms/Switch.svelte +44 -0
- package/dist/components/forms/Switch.svelte.d.ts +12 -0
- package/dist/components/forms/Textarea.svelte +52 -0
- package/dist/components/forms/Textarea.svelte.d.ts +15 -0
- package/dist/components/forms/TimePicker.svelte +63 -0
- package/dist/components/forms/TimePicker.svelte.d.ts +16 -0
- package/dist/components/forms/formClasses.d.ts +3 -0
- package/dist/components/forms/formClasses.js +3 -0
- package/dist/components/forms/index.d.ts +12 -0
- package/dist/components/forms/index.js +12 -0
- package/dist/components/navigation/Breadcrumbs.svelte +56 -0
- package/dist/components/navigation/Breadcrumbs.svelte.d.ts +15 -0
- package/dist/components/navigation/ContextMenu.svelte +133 -0
- package/dist/components/navigation/ContextMenu.svelte.d.ts +18 -0
- package/dist/components/navigation/DropdownMenu.svelte +139 -0
- package/dist/components/navigation/DropdownMenu.svelte.d.ts +17 -0
- package/dist/components/navigation/Menu.svelte +72 -0
- package/dist/components/navigation/Menu.svelte.d.ts +15 -0
- package/dist/components/navigation/Navbar.svelte +111 -0
- package/dist/components/navigation/Navbar.svelte.d.ts +15 -0
- package/dist/components/navigation/Sidebar.svelte +236 -0
- package/dist/components/navigation/Sidebar.svelte.d.ts +12 -0
- package/dist/components/navigation/Tabs.svelte +86 -0
- package/dist/components/navigation/Tabs.svelte.d.ts +19 -0
- package/dist/components/navigation/index.d.ts +7 -0
- package/dist/components/navigation/index.js +7 -0
- package/dist/components/overlays/Alert.svelte +81 -0
- package/dist/components/overlays/Alert.svelte.d.ts +15 -0
- package/dist/components/overlays/CommandPalette.svelte +182 -0
- package/dist/components/overlays/CommandPalette.svelte.d.ts +16 -0
- package/dist/components/overlays/Drawer.svelte +158 -0
- package/dist/components/overlays/Drawer.svelte.d.ts +16 -0
- package/dist/components/overlays/Dropdown.svelte +62 -0
- package/dist/components/overlays/Dropdown.svelte.d.ts +11 -0
- package/dist/components/overlays/Modal.svelte +125 -0
- package/dist/components/overlays/Modal.svelte.d.ts +15 -0
- package/dist/components/overlays/Popover.svelte +106 -0
- package/dist/components/overlays/Popover.svelte.d.ts +11 -0
- package/dist/components/overlays/ProgressBar.svelte +29 -0
- package/dist/components/overlays/ProgressBar.svelte.d.ts +10 -0
- package/dist/components/overlays/SkeletonLoader.svelte +66 -0
- package/dist/components/overlays/SkeletonLoader.svelte.d.ts +9 -0
- package/dist/components/overlays/Spinner.svelte +33 -0
- package/dist/components/overlays/Spinner.svelte.d.ts +7 -0
- package/dist/components/overlays/Toast.svelte +111 -0
- package/dist/components/overlays/Toast.svelte.d.ts +16 -0
- package/dist/components/overlays/Tooltip.svelte +94 -0
- package/dist/components/overlays/Tooltip.svelte.d.ts +12 -0
- package/dist/components/overlays/index.d.ts +11 -0
- package/dist/components/overlays/index.js +11 -0
- package/dist/components/typography/Code.svelte +10 -0
- package/dist/components/typography/Code.svelte.d.ts +6 -0
- package/dist/components/typography/Heading.svelte +15 -0
- package/dist/components/typography/Heading.svelte.d.ts +10 -0
- package/dist/components/typography/Text.svelte +21 -0
- package/dist/components/typography/Text.svelte.d.ts +10 -0
- package/dist/components/typography/index.d.ts +3 -0
- package/dist/components/typography/index.js +3 -0
- package/dist/components/utilities/Accordion.svelte +54 -0
- package/dist/components/utilities/Accordion.svelte.d.ts +17 -0
- package/dist/components/utilities/Carousel.svelte +124 -0
- package/dist/components/utilities/Carousel.svelte.d.ts +16 -0
- package/dist/components/utilities/Collapse.svelte +46 -0
- package/dist/components/utilities/Collapse.svelte.d.ts +10 -0
- package/dist/components/utilities/Hero.svelte +42 -0
- package/dist/components/utilities/Hero.svelte.d.ts +10 -0
- package/dist/components/utilities/Portal.svelte +47 -0
- package/dist/components/utilities/Portal.svelte.d.ts +21 -0
- package/dist/components/utilities/ScrollArea.svelte +33 -0
- package/dist/components/utilities/ScrollArea.svelte.d.ts +8 -0
- package/dist/components/utilities/SystemConsole.svelte +310 -0
- package/dist/components/utilities/SystemConsole.svelte.d.ts +20 -0
- package/dist/components/utilities/SystemInterface.svelte +726 -0
- package/dist/components/utilities/SystemInterface.svelte.d.ts +19 -0
- package/dist/components/utilities/index.d.ts +9 -0
- package/dist/components/utilities/index.js +8 -0
- package/dist/components/utilities/utilities.types.d.ts +46 -0
- package/dist/components/utilities/utilities.types.js +4 -0
- package/dist/index.d.ts +60 -175
- package/dist/index.js +24 -4560
- package/dist/lib/internal/id.d.ts +12 -0
- package/dist/lib/internal/id.js +15 -0
- package/dist/theme.css +2821 -0
- package/package.json +83 -75
- package/dist/index.css +0 -1
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<script lang="ts">import { variantClasses, sizeClasses, disabledClasses } from './buttonClasses';
|
|
2
|
+
let { variant = 'primary', size = 'md', disabled = false, type = 'button', onclick, iconBefore, iconAfter, class: className = '', children, ...restProps } = $props();
|
|
3
|
+
const baseClasses = 'inline-flex items-center justify-center rounded-[var(--radius-lg)] font-[var(--font-body)] transition-all duration-300 ease-[var(--ease-luxe)] cursor-pointer gap-2';
|
|
4
|
+
const classes = $derived(`${baseClasses} ${variantClasses[variant]} ${sizeClasses[size]} ${disabled ? disabledClasses : ''} ${className}`);
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<button
|
|
8
|
+
{type}
|
|
9
|
+
{disabled}
|
|
10
|
+
onclick={onclick}
|
|
11
|
+
class={classes}
|
|
12
|
+
{...restProps}
|
|
13
|
+
>
|
|
14
|
+
{#if iconBefore}
|
|
15
|
+
<span class="inline-flex items-center justify-center">
|
|
16
|
+
{@render iconBefore()}
|
|
17
|
+
</span>
|
|
18
|
+
{/if}
|
|
19
|
+
{#if children}
|
|
20
|
+
{@render children()}
|
|
21
|
+
{/if}
|
|
22
|
+
{#if iconAfter}
|
|
23
|
+
<span class="inline-flex items-center justify-center">
|
|
24
|
+
{@render iconAfter()}
|
|
25
|
+
</span>
|
|
26
|
+
{/if}
|
|
27
|
+
</button>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface Props {
|
|
2
|
+
variant?: 'primary' | 'secondary' | 'ghost';
|
|
3
|
+
size?: 'sm' | 'md' | 'lg';
|
|
4
|
+
disabled?: boolean;
|
|
5
|
+
type?: 'button' | 'submit' | 'reset';
|
|
6
|
+
onclick?: (event: MouseEvent) => void;
|
|
7
|
+
iconBefore?: import('svelte').Snippet;
|
|
8
|
+
iconAfter?: import('svelte').Snippet;
|
|
9
|
+
children?: import('svelte').Snippet;
|
|
10
|
+
class?: string;
|
|
11
|
+
}
|
|
12
|
+
declare const Button: import("svelte").Component<Props, {}, "">;
|
|
13
|
+
type Button = ReturnType<typeof Button>;
|
|
14
|
+
export default Button;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script lang="ts">"use strict";
|
|
2
|
+
let { orientation = 'horizontal', spacing = false, children } = $props();
|
|
3
|
+
const orientationClasses = {
|
|
4
|
+
horizontal: 'flex-row',
|
|
5
|
+
vertical: 'flex-col'
|
|
6
|
+
};
|
|
7
|
+
const mergedBorderClasses = {
|
|
8
|
+
horizontal: '[&>*:not(:first-child)]:ml-[-1px] [&>*:not(:first-child):not(:last-child)]:rounded-none [&>*:first-child]:rounded-r-none [&>*:last-child]:rounded-l-none',
|
|
9
|
+
vertical: '[&>*:not(:first-child)]:mt-[-1px] [&>*:not(:first-child):not(:last-child)]:rounded-none [&>*:first-child]:rounded-b-none [&>*:last-child]:rounded-t-none'
|
|
10
|
+
};
|
|
11
|
+
const spacingClasses = 'gap-2';
|
|
12
|
+
const baseClasses = 'flex bg-transparent';
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<div class="{baseClasses} {orientationClasses[orientation]} {spacing ? spacingClasses : mergedBorderClasses[orientation]}">
|
|
16
|
+
{@render children?.()}
|
|
17
|
+
</div>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
orientation?: 'horizontal' | 'vertical';
|
|
3
|
+
spacing?: boolean;
|
|
4
|
+
children?: import('svelte').Snippet;
|
|
5
|
+
}
|
|
6
|
+
declare const ButtonGroup: import("svelte").Component<Props, {}, "">;
|
|
7
|
+
type ButtonGroup = ReturnType<typeof ButtonGroup>;
|
|
8
|
+
export default ButtonGroup;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script lang="ts">import { fabSizeClasses, disabledClasses } from './buttonClasses';
|
|
2
|
+
let { position = 'bottom-right', size = 'lg', disabled = false, ariaLabel, onclick, children, class: className = '' } = $props();
|
|
3
|
+
const positionClasses = {
|
|
4
|
+
'bottom-right': 'bottom-6 right-6',
|
|
5
|
+
'bottom-left': 'bottom-6 left-6',
|
|
6
|
+
'top-right': 'top-6 right-6',
|
|
7
|
+
'top-left': 'top-6 left-6'
|
|
8
|
+
};
|
|
9
|
+
const baseClasses = 'fixed z-[var(--z-50)] flex items-center justify-center rounded-[var(--radius-pill)] bg-[var(--color-accent)] text-[var(--color-text)] accent-glow hover-lift shadow-[var(--shadow-deep)] transition-all duration-300 ease-[var(--ease-luxe)] cursor-pointer animate-[glow-pulse_3s_ease-in-out_infinite] hover:scale-110';
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<button
|
|
13
|
+
type="button"
|
|
14
|
+
{disabled}
|
|
15
|
+
aria-label={ariaLabel}
|
|
16
|
+
onclick={onclick}
|
|
17
|
+
class="{baseClasses} {positionClasses[position]} {fabSizeClasses[size]} {disabled ? disabledClasses : ''} {className}"
|
|
18
|
+
>
|
|
19
|
+
{@render children?.()}
|
|
20
|
+
</button>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface Props {
|
|
2
|
+
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
|
|
3
|
+
size?: 'md' | 'lg';
|
|
4
|
+
disabled?: boolean;
|
|
5
|
+
ariaLabel: string;
|
|
6
|
+
onclick?: (event: MouseEvent) => void;
|
|
7
|
+
children?: import('svelte').Snippet;
|
|
8
|
+
class?: string;
|
|
9
|
+
}
|
|
10
|
+
declare const FloatingActionButton: import("svelte").Component<Props, {}, "">;
|
|
11
|
+
type FloatingActionButton = ReturnType<typeof FloatingActionButton>;
|
|
12
|
+
export default FloatingActionButton;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script lang="ts">import { variantClasses, disabledClasses } from './buttonClasses';
|
|
2
|
+
let { variant = 'ghost', size = 'md', shape = 'circle', disabled = false, type = 'button', ariaLabel, onclick, children, class: className = '' } = $props();
|
|
3
|
+
const iconSizeClasses = {
|
|
4
|
+
sm: 'w-10 h-10 text-sm',
|
|
5
|
+
md: 'w-12 h-12 text-base',
|
|
6
|
+
lg: 'w-14 h-14 text-lg'
|
|
7
|
+
};
|
|
8
|
+
const shapeClasses = {
|
|
9
|
+
circle: 'rounded-[var(--radius-pill)]',
|
|
10
|
+
square: 'rounded-[var(--radius-lg)]'
|
|
11
|
+
};
|
|
12
|
+
const baseClasses = 'inline-flex items-center justify-center font-[var(--font-body)] transition-all duration-300 ease-[var(--ease-luxe)] cursor-pointer hover-lift';
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<button
|
|
16
|
+
{type}
|
|
17
|
+
{disabled}
|
|
18
|
+
aria-label={ariaLabel}
|
|
19
|
+
onclick={onclick}
|
|
20
|
+
class="{baseClasses} {variantClasses[variant]} {iconSizeClasses[size]} {shapeClasses[shape]} {disabled ? disabledClasses : ''} {className}"
|
|
21
|
+
>
|
|
22
|
+
{@render children?.()}
|
|
23
|
+
</button>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface Props {
|
|
2
|
+
variant?: 'primary' | 'secondary' | 'ghost';
|
|
3
|
+
size?: 'sm' | 'md' | 'lg';
|
|
4
|
+
shape?: 'circle' | 'square';
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
type?: 'button' | 'submit' | 'reset';
|
|
7
|
+
ariaLabel: string;
|
|
8
|
+
onclick?: (event: MouseEvent) => void;
|
|
9
|
+
children?: import('svelte').Snippet;
|
|
10
|
+
class?: string;
|
|
11
|
+
}
|
|
12
|
+
declare const IconButton: import("svelte").Component<Props, {}, "">;
|
|
13
|
+
type IconButton = ReturnType<typeof IconButton>;
|
|
14
|
+
export default IconButton;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script lang="ts">import { variantClasses, sizeClasses, disabledClasses } from './buttonClasses';
|
|
2
|
+
let { href, variant = 'primary', size = 'md', disabled = false, target, rel, children, iconBefore, iconAfter, class: className = '' } = $props();
|
|
3
|
+
const baseClasses = 'inline-flex items-center justify-center rounded-[var(--radius-lg)] font-[var(--font-body)] transition-all duration-300 ease-[var(--ease-luxe)] no-underline gap-2';
|
|
4
|
+
const computedRel = $derived(target === '_blank' ? (rel || 'noopener noreferrer') : rel);
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<a
|
|
8
|
+
href={disabled ? undefined : href}
|
|
9
|
+
{target}
|
|
10
|
+
rel={computedRel}
|
|
11
|
+
class="{baseClasses} {variantClasses[variant]} {sizeClasses[size]} {disabled ? disabledClasses : ''} {className}"
|
|
12
|
+
>
|
|
13
|
+
{#if iconBefore}
|
|
14
|
+
<span class="inline-flex items-center justify-center">
|
|
15
|
+
{@render iconBefore()}
|
|
16
|
+
</span>
|
|
17
|
+
{/if}
|
|
18
|
+
{@render children?.()}
|
|
19
|
+
{#if iconAfter}
|
|
20
|
+
<span class="inline-flex items-center justify-center">
|
|
21
|
+
{@render iconAfter()}
|
|
22
|
+
</span>
|
|
23
|
+
{/if}
|
|
24
|
+
</a>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface Props {
|
|
2
|
+
href: string;
|
|
3
|
+
variant?: 'primary' | 'secondary' | 'ghost';
|
|
4
|
+
size?: 'sm' | 'md' | 'lg';
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
target?: '_self' | '_blank' | '_parent' | '_top';
|
|
7
|
+
rel?: string;
|
|
8
|
+
children?: import('svelte').Snippet;
|
|
9
|
+
iconBefore?: import('svelte').Snippet;
|
|
10
|
+
iconAfter?: import('svelte').Snippet;
|
|
11
|
+
class?: string;
|
|
12
|
+
}
|
|
13
|
+
declare const LinkButton: import("svelte").Component<Props, {}, "">;
|
|
14
|
+
type LinkButton = ReturnType<typeof LinkButton>;
|
|
15
|
+
export default LinkButton;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare const variantClasses: {
|
|
2
|
+
primary: string;
|
|
3
|
+
secondary: string;
|
|
4
|
+
ghost: string;
|
|
5
|
+
};
|
|
6
|
+
export declare const sizeClasses: {
|
|
7
|
+
sm: string;
|
|
8
|
+
md: string;
|
|
9
|
+
lg: string;
|
|
10
|
+
};
|
|
11
|
+
export declare const disabledClasses = "opacity-50 cursor-not-allowed pointer-events-none";
|
|
12
|
+
export declare const fabSizeClasses: {
|
|
13
|
+
md: string;
|
|
14
|
+
lg: string;
|
|
15
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const variantClasses = {
|
|
2
|
+
primary: 'bg-[var(--color-accent)] text-[var(--color-text)] accent-glow hover-lift',
|
|
3
|
+
secondary: 'bg-transparent text-[var(--color-text)] border border-[var(--color-border-strong)] hover:border-[var(--color-accent)] hover-lift',
|
|
4
|
+
ghost: 'bg-transparent text-[var(--color-text)] hover:bg-[var(--color-base-2)] hover-lift'
|
|
5
|
+
};
|
|
6
|
+
export const sizeClasses = {
|
|
7
|
+
sm: 'px-3 py-1.5 text-sm font-medium',
|
|
8
|
+
md: 'px-4 py-2 text-base font-medium',
|
|
9
|
+
lg: 'px-5 py-2.5 text-lg font-semibold'
|
|
10
|
+
};
|
|
11
|
+
export const disabledClasses = 'opacity-50 cursor-not-allowed pointer-events-none';
|
|
12
|
+
export const fabSizeClasses = {
|
|
13
|
+
md: 'w-16 h-16 text-base',
|
|
14
|
+
lg: 'w-18 h-18 text-lg'
|
|
15
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default as Button } from './Button.svelte';
|
|
2
|
+
export { default as IconButton } from './IconButton.svelte';
|
|
3
|
+
export { default as ButtonGroup } from './ButtonGroup.svelte';
|
|
4
|
+
export { default as LinkButton } from './LinkButton.svelte';
|
|
5
|
+
export { default as FloatingActionButton } from './FloatingActionButton.svelte';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default as Button } from './Button.svelte';
|
|
2
|
+
export { default as IconButton } from './IconButton.svelte';
|
|
3
|
+
export { default as ButtonGroup } from './ButtonGroup.svelte';
|
|
4
|
+
export { default as LinkButton } from './LinkButton.svelte';
|
|
5
|
+
export { default as FloatingActionButton } from './FloatingActionButton.svelte';
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<script lang="ts">let { padding = 'md', href, target = '_self', rel, class: className = '', children, header, footer, iconBefore, ...restProps } = $props();
|
|
2
|
+
// Compute rel attribute: use explicit rel if provided, otherwise default to 'noopener noreferrer' for target='_blank'
|
|
3
|
+
const relValue = $derived(rel ?? (target === '_blank' ? 'noopener noreferrer' : undefined));
|
|
4
|
+
const paddingClasses = {
|
|
5
|
+
none: 'p-0',
|
|
6
|
+
sm: 'p-4',
|
|
7
|
+
md: 'p-6',
|
|
8
|
+
lg: 'p-8'
|
|
9
|
+
};
|
|
10
|
+
const baseClasses = $derived(`panel-raised rounded-[var(--radius-lg)] transition-all duration-300 ease-[var(--ease-luxe)] ${href ? 'no-underline' : ''}`);
|
|
11
|
+
export {};
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
{#if href}
|
|
15
|
+
<a {href} {target} rel={relValue} class="{baseClasses} {paddingClasses[padding]} {className}" {...restProps}>
|
|
16
|
+
{#if iconBefore}
|
|
17
|
+
<div class="card-icon">
|
|
18
|
+
{@render iconBefore()}
|
|
19
|
+
</div>
|
|
20
|
+
{/if}
|
|
21
|
+
{#if header}
|
|
22
|
+
<div class="pb-3 mb-3 border-b border-border-strong">
|
|
23
|
+
{@render header()}
|
|
24
|
+
</div>
|
|
25
|
+
{/if}
|
|
26
|
+
|
|
27
|
+
<div>
|
|
28
|
+
{@render children?.()}
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
{#if footer}
|
|
32
|
+
<div class="pt-3 mt-3 border-t border-border-strong">
|
|
33
|
+
{@render footer()}
|
|
34
|
+
</div>
|
|
35
|
+
{/if}
|
|
36
|
+
</a>
|
|
37
|
+
{:else}
|
|
38
|
+
<div class="{baseClasses} {paddingClasses[padding]} {className}" {...restProps}>
|
|
39
|
+
{#if iconBefore}
|
|
40
|
+
<div class="card-icon">
|
|
41
|
+
{@render iconBefore()}
|
|
42
|
+
</div>
|
|
43
|
+
{/if}
|
|
44
|
+
{#if header}
|
|
45
|
+
<div class="pb-3 mb-3 border-b border-border-strong">
|
|
46
|
+
{@render header()}
|
|
47
|
+
</div>
|
|
48
|
+
{/if}
|
|
49
|
+
|
|
50
|
+
<div>
|
|
51
|
+
{@render children?.()}
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
{#if footer}
|
|
55
|
+
<div class="pt-3 mt-3 border-t border-border-strong">
|
|
56
|
+
{@render footer()}
|
|
57
|
+
</div>
|
|
58
|
+
{/if}
|
|
59
|
+
</div>
|
|
60
|
+
{/if}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
export interface Props {
|
|
3
|
+
padding?: 'none' | 'sm' | 'md' | 'lg';
|
|
4
|
+
href?: string;
|
|
5
|
+
target?: '_blank' | '_self' | '_parent' | '_top';
|
|
6
|
+
rel?: string;
|
|
7
|
+
class?: string;
|
|
8
|
+
children?: Snippet;
|
|
9
|
+
header?: Snippet;
|
|
10
|
+
footer?: Snippet;
|
|
11
|
+
iconBefore?: Snippet;
|
|
12
|
+
}
|
|
13
|
+
declare const Card: import("svelte").Component<Props, {}, "">;
|
|
14
|
+
type Card = ReturnType<typeof Card>;
|
|
15
|
+
export default Card;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script lang="ts">let { size = 'lg', centered = true, padding = true, class: className = '', children, ...restProps } = $props();
|
|
2
|
+
const sizeClasses = {
|
|
3
|
+
sm: 'max-w-screen-sm',
|
|
4
|
+
md: 'max-w-screen-md',
|
|
5
|
+
lg: 'max-w-screen-lg',
|
|
6
|
+
xl: 'max-w-screen-xl',
|
|
7
|
+
full: 'max-w-full'
|
|
8
|
+
};
|
|
9
|
+
const centeredClasses = centered ? 'mx-auto' : '';
|
|
10
|
+
const paddingClasses = padding ? 'px-4 md:px-6 lg:px-8 py-8 md:py-12 lg:py-16' : '';
|
|
11
|
+
const baseClasses = 'w-full';
|
|
12
|
+
export {};
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<div class="{baseClasses} {sizeClasses[size]} {centeredClasses} {paddingClasses} {className}" {...restProps}>
|
|
16
|
+
{@render children?.()}
|
|
17
|
+
</div>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';
|
|
4
|
+
centered?: boolean;
|
|
5
|
+
padding?: boolean;
|
|
6
|
+
children?: Snippet;
|
|
7
|
+
}
|
|
8
|
+
declare const Container: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
type Container = ReturnType<typeof Container>;
|
|
10
|
+
export default Container;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<script lang="ts">"use strict";
|
|
2
|
+
let { orientation = 'horizontal', spacing = 'md', thickness = 'normal', variant = 'default', height, class: className = '', ...restProps } = $props();
|
|
3
|
+
const horizontalThicknessMap = {
|
|
4
|
+
thin: 'border-t-[1px]',
|
|
5
|
+
normal: 'border-t-[1px]',
|
|
6
|
+
thick: 'border-t-[2px]'
|
|
7
|
+
};
|
|
8
|
+
const verticalThicknessMap = {
|
|
9
|
+
thin: 'border-l-[1px]',
|
|
10
|
+
normal: 'border-l-[1px]',
|
|
11
|
+
thick: 'border-l-[2px]'
|
|
12
|
+
};
|
|
13
|
+
const horizontalSpacing = {
|
|
14
|
+
none: 'my-0',
|
|
15
|
+
sm: 'my-2',
|
|
16
|
+
md: 'my-4',
|
|
17
|
+
lg: 'my-6'
|
|
18
|
+
};
|
|
19
|
+
const verticalSpacing = {
|
|
20
|
+
none: 'mx-0',
|
|
21
|
+
sm: 'mx-2',
|
|
22
|
+
md: 'mx-4',
|
|
23
|
+
lg: 'mx-6'
|
|
24
|
+
};
|
|
25
|
+
const borderColor = variant === 'strong' ? 'border-[var(--color-border-strong)]' : 'border-[var(--color-border)]';
|
|
26
|
+
const horizontalClasses = `w-full ${horizontalThicknessMap[thickness]} ${borderColor} ${horizontalSpacing[spacing]} ${className}`;
|
|
27
|
+
const verticalClasses = `self-stretch ${verticalThicknessMap[thickness]} ${borderColor} ${verticalSpacing[spacing]} ${className}`;
|
|
28
|
+
// For vertical dividers, use custom height or default min-height
|
|
29
|
+
const verticalStyle = height ? `height: ${height}` : 'min-height: 2rem';
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
{#if orientation === 'horizontal'}
|
|
33
|
+
<hr class={horizontalClasses} {...restProps} />
|
|
34
|
+
{:else}
|
|
35
|
+
<div class={verticalClasses} style={verticalStyle} {...restProps}></div>
|
|
36
|
+
{/if}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
orientation?: 'horizontal' | 'vertical';
|
|
3
|
+
spacing?: 'none' | 'sm' | 'md' | 'lg';
|
|
4
|
+
thickness?: 'thin' | 'normal' | 'thick';
|
|
5
|
+
variant?: 'default' | 'strong';
|
|
6
|
+
height?: string;
|
|
7
|
+
class?: string;
|
|
8
|
+
}
|
|
9
|
+
declare const Divider: import("svelte").Component<Props, {}, "">;
|
|
10
|
+
type Divider = ReturnType<typeof Divider>;
|
|
11
|
+
export default Divider;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<script lang="ts">let { cols = 3, gap = 'md', responsive = true, class: className = '', children, ...restProps } = $props();
|
|
2
|
+
const gapClasses = {
|
|
3
|
+
none: 'gap-0',
|
|
4
|
+
sm: 'gap-2',
|
|
5
|
+
md: 'gap-4',
|
|
6
|
+
lg: 'gap-6',
|
|
7
|
+
xl: 'gap-8'
|
|
8
|
+
};
|
|
9
|
+
const baseClasses = 'grid w-full';
|
|
10
|
+
// Build complete class string with all possible classes visible to Tailwind
|
|
11
|
+
const gridClasses = $derived.by(() => {
|
|
12
|
+
const classes = [];
|
|
13
|
+
if (responsive) {
|
|
14
|
+
// Mobile: always 1 column
|
|
15
|
+
classes.push('grid-cols-1');
|
|
16
|
+
// Tablet: 2 columns if cols >= 2
|
|
17
|
+
if (cols >= 2)
|
|
18
|
+
classes.push('md:grid-cols-2');
|
|
19
|
+
// Desktop: use specified cols
|
|
20
|
+
if (cols === 1)
|
|
21
|
+
classes.push('lg:grid-cols-1');
|
|
22
|
+
if (cols === 2)
|
|
23
|
+
classes.push('lg:grid-cols-2');
|
|
24
|
+
if (cols === 3)
|
|
25
|
+
classes.push('lg:grid-cols-3');
|
|
26
|
+
if (cols === 4)
|
|
27
|
+
classes.push('lg:grid-cols-4');
|
|
28
|
+
if (cols === 6)
|
|
29
|
+
classes.push('lg:grid-cols-6');
|
|
30
|
+
if (cols === 12)
|
|
31
|
+
classes.push('lg:grid-cols-12');
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
// Non-responsive: use specified cols at all breakpoints
|
|
35
|
+
if (cols === 1)
|
|
36
|
+
classes.push('grid-cols-1');
|
|
37
|
+
if (cols === 2)
|
|
38
|
+
classes.push('grid-cols-2');
|
|
39
|
+
if (cols === 3)
|
|
40
|
+
classes.push('grid-cols-3');
|
|
41
|
+
if (cols === 4)
|
|
42
|
+
classes.push('grid-cols-4');
|
|
43
|
+
if (cols === 6)
|
|
44
|
+
classes.push('grid-cols-6');
|
|
45
|
+
if (cols === 12)
|
|
46
|
+
classes.push('grid-cols-12');
|
|
47
|
+
}
|
|
48
|
+
return classes.join(' ');
|
|
49
|
+
});
|
|
50
|
+
export {};
|
|
51
|
+
</script>
|
|
52
|
+
|
|
53
|
+
<div class="{baseClasses} {gridClasses} {gapClasses[gap]} {className}" {...restProps}>
|
|
54
|
+
{@render children?.()}
|
|
55
|
+
</div>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
cols?: 1 | 2 | 3 | 4 | 6 | 12;
|
|
4
|
+
gap?: 'none' | 'sm' | 'md' | 'lg' | 'xl';
|
|
5
|
+
responsive?: boolean;
|
|
6
|
+
children?: Snippet;
|
|
7
|
+
}
|
|
8
|
+
declare const Grid: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
type Grid = ReturnType<typeof Grid>;
|
|
10
|
+
export default Grid;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<script lang="ts">let { padding = 'md', rounded = true, variant = 'default', class: className = '', children, ...restProps } = $props();
|
|
2
|
+
const paddingClasses = {
|
|
3
|
+
none: 'p-0',
|
|
4
|
+
sm: 'p-5',
|
|
5
|
+
md: 'p-8',
|
|
6
|
+
lg: 'p-10'
|
|
7
|
+
};
|
|
8
|
+
const glassClasses = $derived(variant === 'glass'
|
|
9
|
+
? 'glass-panel bg-[var(--color-accent-overlay-5)] border-[var(--color-border-glow)]'
|
|
10
|
+
: 'panel-raised');
|
|
11
|
+
const roundedClasses = $derived(rounded ? 'rounded-[var(--radius-lg)]' : '');
|
|
12
|
+
const baseClasses = 'transition-all duration-300 ease-[var(--ease-luxe)]';
|
|
13
|
+
export {};
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<div class="{baseClasses} {glassClasses} {roundedClasses} {paddingClasses[padding]} {className}" {...restProps}>
|
|
17
|
+
{@render children?.()}
|
|
18
|
+
</div>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
padding?: 'none' | 'sm' | 'md' | 'lg';
|
|
4
|
+
rounded?: boolean;
|
|
5
|
+
variant?: 'default' | 'glass';
|
|
6
|
+
class?: string;
|
|
7
|
+
children?: Snippet;
|
|
8
|
+
}
|
|
9
|
+
declare const Panel: import("svelte").Component<Props, {}, "">;
|
|
10
|
+
type Panel = ReturnType<typeof Panel>;
|
|
11
|
+
export default Panel;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script lang="ts">let { title, level = 2, glow = true, subtitle, align = 'left', children } = $props();
|
|
2
|
+
const headingTag = $derived(`h${level}`);
|
|
3
|
+
const glowClasses = $derived(glow ? 'text-glow' : '');
|
|
4
|
+
const alignClasses = $derived(`text-${align}`);
|
|
5
|
+
const headingClasses = $derived(`font-[var(--font-heading)] text-[length:var(--text-h${level}-size)] font-[number:var(--text-h${level}-weight)] leading-[var(--text-h${level}-line-height)] text-[var(--color-text)] ${glowClasses} ${alignClasses}`);
|
|
6
|
+
const subtitleClasses = $derived(`mt-2 font-[var(--font-body)] text-[length:var(--text-body-size)] text-[var(--color-text-soft)] ${alignClasses}`);
|
|
7
|
+
export {};
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<div class="mb-8">
|
|
11
|
+
<svelte:element this={headingTag} class={headingClasses}>
|
|
12
|
+
{#if title}
|
|
13
|
+
{title}
|
|
14
|
+
{:else}
|
|
15
|
+
{@render children?.()}
|
|
16
|
+
{/if}
|
|
17
|
+
</svelte:element>
|
|
18
|
+
|
|
19
|
+
{#if subtitle}
|
|
20
|
+
<p class={subtitleClasses}>
|
|
21
|
+
{subtitle}
|
|
22
|
+
</p>
|
|
23
|
+
{/if}
|
|
24
|
+
</div>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
title?: string;
|
|
4
|
+
level?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
5
|
+
glow?: boolean;
|
|
6
|
+
subtitle?: string;
|
|
7
|
+
align?: 'left' | 'center' | 'right';
|
|
8
|
+
children?: Snippet;
|
|
9
|
+
}
|
|
10
|
+
declare const SectionHeader: import("svelte").Component<Props, {}, "">;
|
|
11
|
+
type SectionHeader = ReturnType<typeof SectionHeader>;
|
|
12
|
+
export default SectionHeader;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { default as Card } from './Card.svelte';
|
|
2
|
+
export { default as Panel } from './Panel.svelte';
|
|
3
|
+
export { default as Grid } from './Grid.svelte';
|
|
4
|
+
export { default as Container } from './Container.svelte';
|
|
5
|
+
export { default as SectionHeader } from './SectionHeader.svelte';
|
|
6
|
+
export { default as Divider } from './Divider.svelte';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { default as Card } from './Card.svelte';
|
|
2
|
+
export { default as Panel } from './Panel.svelte';
|
|
3
|
+
export { default as Grid } from './Grid.svelte';
|
|
4
|
+
export { default as Container } from './Container.svelte';
|
|
5
|
+
export { default as SectionHeader } from './SectionHeader.svelte';
|
|
6
|
+
export { default as Divider } from './Divider.svelte';
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<script lang="ts">"use strict";
|
|
2
|
+
let { src, alt, size = 'md', fallback, glow = false } = $props();
|
|
3
|
+
let imageLoaded = $state(!!src);
|
|
4
|
+
let imageError = $state(false);
|
|
5
|
+
const sizeClasses = {
|
|
6
|
+
sm: 'w-8 h-8',
|
|
7
|
+
md: 'w-12 h-12',
|
|
8
|
+
lg: 'w-16 h-16',
|
|
9
|
+
xl: 'w-24 h-24'
|
|
10
|
+
};
|
|
11
|
+
const fontSizes = {
|
|
12
|
+
sm: '0.75rem',
|
|
13
|
+
md: '1rem',
|
|
14
|
+
lg: '1.25rem',
|
|
15
|
+
xl: '1.5rem'
|
|
16
|
+
};
|
|
17
|
+
const classes = $derived(`${sizeClasses[size]} rounded-full overflow-hidden inline-flex items-center justify-center transition-all duration-300 hover:scale-105 ${glow ? 'border-2 border-[var(--color-accent)] accent-glow' : ''}`);
|
|
18
|
+
const fallbackText = $derived(fallback || alt.charAt(0).toUpperCase());
|
|
19
|
+
function handleImageError() {
|
|
20
|
+
imageError = true;
|
|
21
|
+
imageLoaded = false;
|
|
22
|
+
}
|
|
23
|
+
function handleImageLoad() {
|
|
24
|
+
imageLoaded = true;
|
|
25
|
+
imageError = false;
|
|
26
|
+
}
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
{#if src && !imageError}
|
|
30
|
+
<div class={classes}>
|
|
31
|
+
<img
|
|
32
|
+
{src}
|
|
33
|
+
{alt}
|
|
34
|
+
class="w-full h-full object-cover"
|
|
35
|
+
onerror={handleImageError}
|
|
36
|
+
onload={handleImageLoad}
|
|
37
|
+
/>
|
|
38
|
+
</div>
|
|
39
|
+
{:else}
|
|
40
|
+
<div
|
|
41
|
+
class={classes}
|
|
42
|
+
style="background: linear-gradient(135deg, var(--color-accent) 0%, var(--color-accent-overlay-70) 100%); color: var(--color-text); font-weight: 600; text-transform: uppercase; font-size: {fontSizes[size]};"
|
|
43
|
+
role="img"
|
|
44
|
+
aria-label={alt}
|
|
45
|
+
>
|
|
46
|
+
{fallbackText}
|
|
47
|
+
</div>
|
|
48
|
+
{/if}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
src?: string;
|
|
3
|
+
alt: string;
|
|
4
|
+
size?: 'sm' | 'md' | 'lg' | 'xl';
|
|
5
|
+
fallback?: string;
|
|
6
|
+
glow?: boolean;
|
|
7
|
+
}
|
|
8
|
+
declare const Avatar: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
type Avatar = ReturnType<typeof Avatar>;
|
|
10
|
+
export default Avatar;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<script lang="ts">"use strict";
|
|
2
|
+
let { variant = 'default', size = 'md', icon, children, hover = false, glow = false, statusDot = false, uppercase = false, class: className = '', ...restProps } = $props();
|
|
3
|
+
const variantClasses = {
|
|
4
|
+
default: 'bg-[var(--color-base-3)] text-[var(--color-text-soft)] border-[var(--color-border)]',
|
|
5
|
+
success: 'bg-[var(--color-success-overlay-15)] text-[var(--color-success)] border-[var(--color-success)]',
|
|
6
|
+
warning: 'bg-[var(--color-warning-overlay-15)] text-[var(--color-warning)] border-[var(--color-warning)]',
|
|
7
|
+
error: 'bg-[var(--color-error-overlay-15)] text-[var(--color-error)] border-[var(--color-error)]',
|
|
8
|
+
accent: 'bg-[var(--color-secondary-overlay-10)] text-[var(--color-accent-soft)] border-[var(--color-accent)]',
|
|
9
|
+
feature: 'bg-[var(--color-accent-overlay-20)] text-[var(--color-accent-soft)] border-[var(--color-border-glow)]'
|
|
10
|
+
};
|
|
11
|
+
const hoverClasses = {
|
|
12
|
+
default: 'hover:bg-[var(--color-base-2)]',
|
|
13
|
+
success: 'hover:bg-[var(--color-success-overlay-30)]',
|
|
14
|
+
warning: 'hover:bg-[var(--color-warning-overlay-30)]',
|
|
15
|
+
error: 'hover:bg-[var(--color-error-overlay-30)]',
|
|
16
|
+
accent: 'hover:bg-[var(--color-secondary-overlay-20)] hover:shadow-[var(--shadow-accent-glow)]',
|
|
17
|
+
feature: 'hover:bg-[var(--color-accent-overlay-30)] hover:shadow-[var(--shadow-accent-glow)]'
|
|
18
|
+
};
|
|
19
|
+
const sizeClasses = {
|
|
20
|
+
sm: 'px-2 py-0.5 text-[var(--text-xs)] gap-1',
|
|
21
|
+
md: 'px-3 py-1 text-[0.75rem] gap-1.5'
|
|
22
|
+
};
|
|
23
|
+
const classes = $derived(`inline-flex items-center justify-center rounded-[var(--radius-pill)] border font-[var(--font-body)] font-semibold transition-all duration-[var(--duration-300)] ease-[var(--ease-sharp)] ${variantClasses[variant]} ${sizeClasses[size]} ${hover ? hoverClasses[variant] : ''} ${glow ? 'accent-glow' : ''} ${uppercase ? 'uppercase tracking-wider' : ''} ${className}`.trim());
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<span class={classes} {...restProps}>
|
|
27
|
+
{#if statusDot}
|
|
28
|
+
<span class="status-dot"></span>
|
|
29
|
+
{/if}
|
|
30
|
+
{#if icon}
|
|
31
|
+
<span class="inline-flex items-center justify-center">
|
|
32
|
+
{@render icon()}
|
|
33
|
+
</span>
|
|
34
|
+
{/if}
|
|
35
|
+
{@render children?.()}
|
|
36
|
+
</span>
|
|
37
|
+
|
|
38
|
+
<style>
|
|
39
|
+
.status-dot {
|
|
40
|
+
width: 0.5rem;
|
|
41
|
+
height: 0.5rem;
|
|
42
|
+
border-radius: 9999px;
|
|
43
|
+
background: currentColor;
|
|
44
|
+
box-shadow: 0 0 8px currentColor;
|
|
45
|
+
}</style>
|