@mrintel/villain-ui 0.3.0 → 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 -33
- package/dist/components/buttons/Button.svelte.d.ts +4 -1
- package/dist/components/buttons/ButtonGroup.svelte +17 -30
- package/dist/components/buttons/FloatingActionButton.svelte +20 -44
- package/dist/components/buttons/FloatingActionButton.svelte.d.ts +2 -1
- package/dist/components/buttons/IconButton.svelte +23 -53
- package/dist/components/buttons/IconButton.svelte.d.ts +2 -1
- package/dist/components/buttons/LinkButton.svelte +24 -37
- package/dist/components/buttons/LinkButton.svelte.d.ts +4 -1
- package/dist/components/buttons/buttonClasses.d.ts +5 -0
- package/dist/components/buttons/buttonClasses.js +8 -3
- package/dist/components/cards/Card.svelte +60 -46
- package/dist/components/cards/Card.svelte.d.ts +6 -2
- package/dist/components/cards/Container.svelte +17 -33
- package/dist/components/cards/Divider.svelte +36 -52
- package/dist/components/cards/Divider.svelte.d.ts +2 -0
- package/dist/components/cards/Grid.svelte +55 -44
- package/dist/components/cards/Panel.svelte +18 -32
- package/dist/components/cards/Panel.svelte.d.ts +2 -1
- package/dist/components/cards/SectionHeader.svelte +24 -38
- package/dist/components/cards/SectionHeader.svelte.d.ts +1 -0
- package/dist/components/data/Avatar.svelte +48 -67
- package/dist/components/data/Badge.svelte +45 -32
- package/dist/components/data/Badge.svelte.d.ts +7 -1
- 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 -121
- package/dist/components/data/CodeBlock.svelte.d.ts +8 -0
- package/dist/components/data/List.svelte +87 -64
- package/dist/components/data/List.svelte.d.ts +7 -0
- package/dist/components/data/Pagination.svelte +121 -123
- package/dist/components/data/Pagination.svelte.d.ts +5 -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 -103
- package/dist/components/data/Table.svelte +443 -76
- package/dist/components/data/Table.svelte.d.ts +23 -2
- 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 -53
- package/dist/components/data/Tag.svelte.d.ts +5 -1
- package/dist/components/data/index.d.ts +4 -0
- package/dist/components/data/index.js +2 -0
- package/dist/components/forms/Checkbox.svelte +39 -51
- package/dist/components/forms/Checkbox.svelte.d.ts +3 -1
- 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 -164
- package/dist/components/forms/FileUpload.svelte.d.ts +1 -0
- package/dist/components/forms/Input.svelte +282 -57
- package/dist/components/forms/Input.svelte.d.ts +9 -3
- package/dist/components/forms/InputGroup.svelte +7 -7
- package/dist/components/forms/RadioGroup.svelte +77 -87
- package/dist/components/forms/RadioGroup.svelte.d.ts +3 -1
- package/dist/components/forms/RangeSlider.svelte +90 -116
- package/dist/components/forms/Select.svelte +106 -71
- package/dist/components/forms/Select.svelte.d.ts +3 -1
- package/dist/components/forms/Switch.svelte +44 -56
- package/dist/components/forms/Switch.svelte.d.ts +3 -1
- package/dist/components/forms/Textarea.svelte +52 -57
- package/dist/components/forms/Textarea.svelte.d.ts +3 -1
- 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 +3 -0
- package/dist/components/forms/index.js +3 -0
- package/dist/components/navigation/Breadcrumbs.svelte +56 -59
- package/dist/components/navigation/Breadcrumbs.svelte.d.ts +1 -0
- package/dist/components/navigation/ContextMenu.svelte +133 -83
- package/dist/components/navigation/ContextMenu.svelte.d.ts +8 -1
- package/dist/components/navigation/DropdownMenu.svelte +139 -80
- package/dist/components/navigation/DropdownMenu.svelte.d.ts +8 -1
- package/dist/components/navigation/Menu.svelte +72 -48
- package/dist/components/navigation/Navbar.svelte +111 -32
- package/dist/components/navigation/Navbar.svelte.d.ts +6 -0
- package/dist/components/navigation/Sidebar.svelte +236 -35
- package/dist/components/navigation/Sidebar.svelte.d.ts +2 -0
- package/dist/components/navigation/Tabs.svelte +86 -54
- package/dist/components/navigation/Tabs.svelte.d.ts +5 -1
- package/dist/components/overlays/Alert.svelte +81 -99
- package/dist/components/overlays/Alert.svelte.d.ts +5 -1
- package/dist/components/overlays/CommandPalette.svelte +182 -217
- package/dist/components/overlays/Drawer.svelte +158 -167
- package/dist/components/overlays/Drawer.svelte.d.ts +3 -1
- package/dist/components/overlays/Dropdown.svelte +62 -30
- package/dist/components/overlays/Dropdown.svelte.d.ts +2 -0
- package/dist/components/overlays/Modal.svelte +125 -130
- package/dist/components/overlays/Modal.svelte.d.ts +3 -1
- package/dist/components/overlays/Popover.svelte +106 -131
- package/dist/components/overlays/ProgressBar.svelte +29 -45
- package/dist/components/overlays/SkeletonLoader.svelte +66 -82
- package/dist/components/overlays/Spinner.svelte +33 -43
- package/dist/components/overlays/Toast.svelte +111 -140
- package/dist/components/overlays/Toast.svelte.d.ts +3 -0
- package/dist/components/overlays/Tooltip.svelte +94 -115
- package/dist/components/overlays/Tooltip.svelte.d.ts +3 -1
- package/dist/components/typography/Code.svelte +10 -14
- package/dist/components/typography/Heading.svelte +15 -22
- package/dist/components/typography/Heading.svelte.d.ts +1 -0
- package/dist/components/typography/Text.svelte +21 -24
- package/dist/components/typography/Text.svelte.d.ts +2 -1
- package/dist/components/utilities/Accordion.svelte +54 -67
- package/dist/components/utilities/Accordion.svelte.d.ts +4 -1
- package/dist/components/utilities/Carousel.svelte +124 -152
- package/dist/components/utilities/Collapse.svelte +46 -60
- 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 -72
- package/dist/components/utilities/ScrollArea.svelte +33 -41
- 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 +4 -0
- package/dist/components/utilities/index.js +3 -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 +49 -4
- package/dist/index.js +4 -4
- package/dist/theme.css +2821 -218
- package/package.json +83 -76
|
@@ -1,52 +1,36 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
sm: 'mx-2',
|
|
38
|
-
md: 'mx-4',
|
|
39
|
-
lg: 'mx-6'
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
const borderColor = variant === 'strong' ? 'border-[var(--color-border-strong)]' : 'border-[var(--color-border)]';
|
|
43
|
-
|
|
44
|
-
const horizontalClasses = `w-full ${horizontalThicknessMap[thickness]} ${borderColor} ${horizontalSpacing[spacing]}`;
|
|
45
|
-
const verticalClasses = `h-full ${verticalThicknessMap[thickness]} ${borderColor} ${verticalSpacing[spacing]}`;
|
|
46
|
-
</script>
|
|
47
|
-
|
|
48
|
-
{#if orientation === 'horizontal'}
|
|
49
|
-
<hr class={horizontalClasses} />
|
|
50
|
-
{:else}
|
|
51
|
-
<div class={verticalClasses}></div>
|
|
52
|
-
{/if}
|
|
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}
|
|
@@ -3,6 +3,8 @@ interface Props {
|
|
|
3
3
|
spacing?: 'none' | 'sm' | 'md' | 'lg';
|
|
4
4
|
thickness?: 'thin' | 'normal' | 'thick';
|
|
5
5
|
variant?: 'default' | 'strong';
|
|
6
|
+
height?: string;
|
|
7
|
+
class?: string;
|
|
6
8
|
}
|
|
7
9
|
declare const Divider: import("svelte").Component<Props, {}, "">;
|
|
8
10
|
type Divider = ReturnType<typeof Divider>;
|
|
@@ -1,44 +1,55 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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>
|
|
@@ -1,32 +1,18 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
none: 'p-0',
|
|
20
|
-
sm: 'p-4',
|
|
21
|
-
md: 'p-6',
|
|
22
|
-
lg: 'p-8'
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const glassClasses = glass ? 'glass-panel' : 'bg-[var(--color-panel)]';
|
|
26
|
-
const roundedClasses = rounded ? 'rounded-[var(--radius-lg)]' : '';
|
|
27
|
-
const baseClasses = 'transition-all duration-300 ease-[var(--ease-luxe)]';
|
|
28
|
-
</script>
|
|
29
|
-
|
|
30
|
-
<div class="{baseClasses} {glassClasses} {roundedClasses} {paddingClasses[padding]}">
|
|
31
|
-
{@render children?.()}
|
|
32
|
-
</div>
|
|
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>
|
|
@@ -2,7 +2,8 @@ import type { Snippet } from 'svelte';
|
|
|
2
2
|
interface Props {
|
|
3
3
|
padding?: 'none' | 'sm' | 'md' | 'lg';
|
|
4
4
|
rounded?: boolean;
|
|
5
|
-
|
|
5
|
+
variant?: 'default' | 'glass';
|
|
6
|
+
class?: string;
|
|
6
7
|
children?: Snippet;
|
|
7
8
|
}
|
|
8
9
|
declare const Panel: import("svelte").Component<Props, {}, "">;
|
|
@@ -1,38 +1,24 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const subtitleClasses = `mt-2 font-[var(--font-body)] text-[length:var(--text-body-size)] text-[var(--color-text-soft)] ${alignClasses}`;
|
|
26
|
-
</script>
|
|
27
|
-
|
|
28
|
-
<div class="mb-8">
|
|
29
|
-
<svelte:element this={headingTag} class={headingClasses}>
|
|
30
|
-
{@render children?.()}
|
|
31
|
-
</svelte:element>
|
|
32
|
-
|
|
33
|
-
{#if subtitle}
|
|
34
|
-
<p class={subtitleClasses}>
|
|
35
|
-
{subtitle}
|
|
36
|
-
</p>
|
|
37
|
-
{/if}
|
|
38
|
-
</div>
|
|
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>
|
|
@@ -1,67 +1,48 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
{
|
|
49
|
-
<div class={classes}>
|
|
50
|
-
<img
|
|
51
|
-
{src}
|
|
52
|
-
{alt}
|
|
53
|
-
class="w-full h-full object-cover"
|
|
54
|
-
onerror={handleImageError}
|
|
55
|
-
onload={handleImageLoad}
|
|
56
|
-
/>
|
|
57
|
-
</div>
|
|
58
|
-
{:else}
|
|
59
|
-
<div
|
|
60
|
-
class={classes}
|
|
61
|
-
style="background: linear-gradient(135deg, var(--color-accent) 0%, rgba(127, 61, 255, 0.7) 100%); color: var(--color-text); font-weight: 600; text-transform: uppercase; font-size: {fontSizes[size]};"
|
|
62
|
-
role="img"
|
|
63
|
-
aria-label={alt}
|
|
64
|
-
>
|
|
65
|
-
{fallbackText}
|
|
66
|
-
</div>
|
|
67
|
-
{/if}
|
|
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}
|
|
@@ -1,32 +1,45 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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>
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
interface Props {
|
|
2
|
-
variant?: 'default' | 'success' | 'warning' | 'error' | 'accent';
|
|
2
|
+
variant?: 'default' | 'success' | 'warning' | 'error' | 'accent' | 'feature';
|
|
3
3
|
size?: 'sm' | 'md';
|
|
4
|
+
icon?: import('svelte').Snippet;
|
|
4
5
|
children?: import('svelte').Snippet;
|
|
6
|
+
hover?: boolean;
|
|
7
|
+
glow?: boolean;
|
|
8
|
+
statusDot?: boolean;
|
|
9
|
+
uppercase?: boolean;
|
|
10
|
+
class?: string;
|
|
5
11
|
}
|
|
6
12
|
declare const Badge: import("svelte").Component<Props, {}, "">;
|
|
7
13
|
type Badge = ReturnType<typeof Badge>;
|