@valerius_petrini/corekit-ui 0.1.49 → 0.1.52
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/Analytics.svelte.d.ts +1 -1
- package/dist/components/Button.svelte +35 -18
- package/dist/components/Button.svelte.d.ts +1 -1
- package/dist/components/Card.svelte +46 -6
- package/dist/components/Card.svelte.d.ts +1 -1
- package/dist/components/Checkbox.svelte +2 -1
- package/dist/components/Checkbox.svelte.d.ts +1 -1
- package/dist/components/FloatingInput.svelte +142 -30
- package/dist/components/FloatingInput.svelte.d.ts +3 -2
- package/dist/components/FloatingSelect.svelte +3 -2
- package/dist/components/FloatingSelect.svelte.d.ts +1 -1
- package/dist/components/Navbar.svelte +2 -2
- package/dist/components/Navbar.svelte.d.ts +1 -1
- package/dist/components/NavbarElement.svelte +1 -1
- package/dist/components/NavbarElement.svelte.d.ts +1 -1
- package/dist/components/Progress.svelte +69 -0
- package/dist/components/Progress.svelte.d.ts +4 -0
- package/dist/components/SEO.svelte.d.ts +1 -1
- package/dist/components/Text.svelte +6 -6
- package/dist/components/Text.svelte.d.ts +1 -1
- package/dist/components/Typewriter.svelte +1 -1
- package/dist/components/Typewriter.svelte.d.ts +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -0
- package/dist/styles/color.d.ts +2 -2
- package/dist/styles/color.js +148 -6
- package/dist/styles/layout.css +31 -23
- package/dist/styles/size.d.ts +4 -3
- package/dist/styles/size.js +72 -18
- package/dist/types/Analytics.d.ts +1 -1
- package/dist/types/Analytics.js +1 -0
- package/dist/types/Button.d.ts +2 -2
- package/dist/types/Button.js +1 -0
- package/dist/types/Card.d.ts +8 -1
- package/dist/types/Card.js +4 -0
- package/dist/types/Checkbox.d.ts +2 -1
- package/dist/types/Checkbox.js +2 -0
- package/dist/types/FloatingInput.d.ts +14 -4
- package/dist/types/FloatingInput.js +2 -0
- package/dist/types/FloatingSelect.d.ts +7 -3
- package/dist/types/FloatingSelect.js +2 -0
- package/dist/types/Navbar.d.ts +2 -3
- package/dist/types/Navbar.js +2 -0
- package/dist/types/Progress.d.ts +20 -0
- package/dist/types/Progress.js +2 -0
- package/dist/types/SEO.d.ts +1 -1
- package/dist/types/SEO.js +1 -0
- package/dist/types/Text.d.ts +5 -4
- package/dist/types/Text.js +2 -0
- package/dist/types/Typewriter.d.ts +24 -9
- package/dist/types/Typewriter.js +2 -0
- package/dist/utils/link.d.ts +9 -0
- package/dist/utils/link.js +9 -0
- package/package.json +3 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AnalyticsProps } from '../types/Analytics.
|
|
1
|
+
import type { AnalyticsProps } from '../types/Analytics.ts';
|
|
2
2
|
declare const Analytics: import("svelte").Component<AnalyticsProps, {}, "">;
|
|
3
3
|
type Analytics = ReturnType<typeof Analytics>;
|
|
4
4
|
export default Analytics;
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { generateColorStyle } from "../styles/color.js";
|
|
3
|
-
import { sizeStyleParts, type
|
|
3
|
+
import { sizeStyleParts, type SizeStyleTheme } from "../styles/size.js";
|
|
4
4
|
import type { ButtonProps } from "../types/Button.js";
|
|
5
5
|
import { twMerge } from "tailwind-merge";
|
|
6
|
+
import { getLinkProps } from "../utils/link.js";
|
|
6
7
|
|
|
7
8
|
let {
|
|
8
9
|
children = undefined,
|
|
9
10
|
class: className = "",
|
|
10
11
|
pill = false,
|
|
11
12
|
icon = false,
|
|
13
|
+
square = false,
|
|
12
14
|
href = undefined,
|
|
13
15
|
color = "none",
|
|
14
16
|
variant = "full",
|
|
@@ -20,21 +22,37 @@
|
|
|
20
22
|
}: ButtonProps = $props();
|
|
21
23
|
|
|
22
24
|
const sizeClasses = $derived.by(() => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
const parts = typeof size === "string" ? sizeStyleParts[size as SizeStyleTheme] : null;
|
|
26
|
+
const radiusParts = typeof radius === "string" ? sizeStyleParts[radius as SizeStyleTheme] : null;
|
|
27
|
+
|
|
28
|
+
return twMerge(
|
|
29
|
+
icon ? "p-0 flex-none" : "h-fit",
|
|
30
|
+
parts?.[icon ? "buttonIcon" : "button"],
|
|
31
|
+
radiusParts?.radius,
|
|
32
|
+
pill || icon ? "rounded-full" : "",
|
|
33
|
+
square ? "aspect-square rounded-none" : ""
|
|
34
|
+
);
|
|
28
35
|
});
|
|
29
36
|
|
|
30
|
-
const customStyle = $derived(
|
|
31
|
-
|
|
32
|
-
? `width: ${size}px; height: ${size}px; flex: none;`
|
|
33
|
-
: ""
|
|
34
|
-
);
|
|
37
|
+
const customStyle = $derived.by(() => {
|
|
38
|
+
const styles: string[] = [];
|
|
35
39
|
|
|
36
|
-
|
|
37
|
-
|
|
40
|
+
if (typeof size === "number") {
|
|
41
|
+
styles.push(`height: ${size}px`);
|
|
42
|
+
styles.push(icon
|
|
43
|
+
? `width: ${size}px; padding: ${size / 8}px`
|
|
44
|
+
: `padding: ${size / 4}px ${size / 8}px`
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (typeof radius === "number") {
|
|
49
|
+
styles.push(`border-radius: ${radius}px`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return styles.join("; ");
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const defaultClass = "inline-flex items-center justify-center gap-2 transition-colors duration-300 ease-in-out text-white whitespace-nowrap";
|
|
38
56
|
const disabledClass = $derived(disabled ? "opacity-50 pointer-events-none" : "cursor-pointer");
|
|
39
57
|
|
|
40
58
|
const mergedClass = $derived(twMerge(
|
|
@@ -42,11 +60,12 @@
|
|
|
42
60
|
generateColorStyle(color, variant),
|
|
43
61
|
disabledClass,
|
|
44
62
|
sizeClasses,
|
|
45
|
-
radiusClass,
|
|
46
63
|
className
|
|
47
64
|
));
|
|
48
65
|
|
|
49
66
|
const mergedStyle = $derived([customStyle, restProps.style].filter(Boolean).join("; "));
|
|
67
|
+
|
|
68
|
+
const anchorProps = $derived(getLinkProps(href, external));
|
|
50
69
|
</script>
|
|
51
70
|
|
|
52
71
|
<svelte:element
|
|
@@ -56,9 +75,7 @@
|
|
|
56
75
|
aria-disabled={disabled}
|
|
57
76
|
type={href ? undefined : (restProps.type || "button")}
|
|
58
77
|
style={mergedStyle}
|
|
59
|
-
|
|
60
|
-
rel={external ? "noopener noreferrer" : undefined}
|
|
61
|
-
{...(href ? { href } : {})}
|
|
78
|
+
{...anchorProps}
|
|
62
79
|
{...restProps}>
|
|
63
80
|
{@render children?.()}
|
|
64
|
-
</svelte:element>
|
|
81
|
+
</svelte:element>
|
|
@@ -1,24 +1,64 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import type
|
|
3
|
-
import type
|
|
2
|
+
import { sizeStyleParts, type SizeStyleTheme } from "../styles/size.js";
|
|
3
|
+
import { cardVariantStyles, type CardProps } from "../types/Card.js";
|
|
4
4
|
import { twMerge } from "tailwind-merge";
|
|
5
5
|
|
|
6
6
|
let {
|
|
7
7
|
children = undefined,
|
|
8
8
|
class: className = "",
|
|
9
9
|
href = undefined,
|
|
10
|
+
external = false,
|
|
11
|
+
variant = "bordered",
|
|
12
|
+
size = "md",
|
|
13
|
+
radius = "md",
|
|
10
14
|
...restProps
|
|
11
15
|
}: CardProps = $props();
|
|
12
16
|
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
const sizeClasses = $derived.by(() => {
|
|
18
|
+
const parts = typeof size === "string" ? sizeStyleParts[size as SizeStyleTheme] : null;
|
|
19
|
+
const radiusParts = typeof radius === "string" ? sizeStyleParts[radius as SizeStyleTheme] : null;
|
|
20
|
+
|
|
21
|
+
return twMerge(
|
|
22
|
+
parts?.card,
|
|
23
|
+
radiusParts?.radius,
|
|
24
|
+
);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const customStyle = $derived.by(() => {
|
|
28
|
+
const styles: string[] = [];
|
|
29
|
+
|
|
30
|
+
if (typeof size === "number")
|
|
31
|
+
styles.push(`width: ${size}px`);
|
|
32
|
+
|
|
33
|
+
if (typeof radius === "number")
|
|
34
|
+
styles.push(`border-radius: ${radius}px`);
|
|
35
|
+
|
|
36
|
+
return styles.join("; ");
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
let defaultClass = "text-main-text rounded-lg transition-colors ease-in-out bg-sub-background p-4";
|
|
40
|
+
let linkClass = "hover:bg-sub-background-hover cursor-pointer";
|
|
41
|
+
let combinedClass = $derived(twMerge(
|
|
42
|
+
defaultClass,
|
|
43
|
+
href ? linkClass : "",
|
|
44
|
+
cardVariantStyles[variant],
|
|
45
|
+
sizeClasses,
|
|
46
|
+
className
|
|
47
|
+
));
|
|
48
|
+
|
|
49
|
+
const anchorProps = $derived(href ? {
|
|
50
|
+
href,
|
|
51
|
+
target: external ? "_blank" : undefined,
|
|
52
|
+
rel: external ? "noopener noreferrer" : undefined,
|
|
53
|
+
} : {});
|
|
15
54
|
</script>
|
|
16
55
|
|
|
17
56
|
<svelte:element
|
|
18
57
|
this={href ? "a" : "div"}
|
|
19
58
|
class={combinedClass}
|
|
20
|
-
{
|
|
59
|
+
style={customStyle}
|
|
60
|
+
{...anchorProps}
|
|
21
61
|
{...restProps}
|
|
22
62
|
>
|
|
23
63
|
{@render children?.()}
|
|
24
|
-
</svelte:element>
|
|
64
|
+
</svelte:element>
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
let {
|
|
7
7
|
children = undefined,
|
|
8
8
|
class: className = "",
|
|
9
|
+
label = "",
|
|
9
10
|
labelClass = "",
|
|
10
11
|
divClass = "",
|
|
11
12
|
checked = $bindable(),
|
|
@@ -30,6 +31,6 @@
|
|
|
30
31
|
class={combinedClass}
|
|
31
32
|
{...restProps}/>
|
|
32
33
|
<Text tag="label" for={id} class={combinedLabelClass}>
|
|
33
|
-
{
|
|
34
|
+
{label}
|
|
34
35
|
</Text>
|
|
35
36
|
</div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CheckboxProps } from "../types/Checkbox.
|
|
1
|
+
import type { CheckboxProps } from "../types/Checkbox.ts";
|
|
2
2
|
declare const Checkbox: import("svelte").Component<CheckboxProps, {}, "checked">;
|
|
3
3
|
type Checkbox = ReturnType<typeof Checkbox>;
|
|
4
4
|
export default Checkbox;
|
|
@@ -2,43 +2,116 @@
|
|
|
2
2
|
import type { FloatingInputProps } from "../types/FloatingInput.js";
|
|
3
3
|
import { twMerge } from "tailwind-merge";
|
|
4
4
|
import Text from "./Text.svelte";
|
|
5
|
+
import { sizeStyleParts, type SizeStyleTheme } from "../styles/size.js";
|
|
6
|
+
import { type Component } from "svelte";
|
|
7
|
+
import Button from "./Button.svelte";
|
|
8
|
+
|
|
9
|
+
import Mail from "@lucide/svelte/icons/mail";
|
|
10
|
+
import Lock from "@lucide/svelte/icons/lock";
|
|
11
|
+
import Phone from "@lucide/svelte/icons/phone";
|
|
12
|
+
import Eye from "@lucide/svelte/icons/eye";
|
|
13
|
+
import EyeOff from "@lucide/svelte/icons/eye-off";
|
|
5
14
|
|
|
6
15
|
let {
|
|
7
16
|
children = undefined,
|
|
8
17
|
class: className = "",
|
|
18
|
+
label = "",
|
|
9
19
|
labelClass = "",
|
|
10
20
|
divClass = "",
|
|
21
|
+
icon = undefined,
|
|
22
|
+
variant = "default",
|
|
23
|
+
placeholder = "",
|
|
11
24
|
value = $bindable(),
|
|
12
25
|
onfocus = undefined,
|
|
13
26
|
onblur = undefined,
|
|
14
|
-
|
|
27
|
+
required = false,
|
|
28
|
+
disabled = false,
|
|
15
29
|
validInputRegex = undefined,
|
|
30
|
+
size = "md",
|
|
31
|
+
radius = "md",
|
|
16
32
|
id = crypto.randomUUID(),
|
|
17
33
|
...restProps
|
|
18
34
|
}: FloatingInputProps = $props();
|
|
19
35
|
|
|
36
|
+
const sizeParts = $derived(typeof size === "string" ? sizeStyleParts[size as SizeStyleTheme] : null);
|
|
37
|
+
const radiusParts = $derived(typeof radius === "string" ? sizeStyleParts[radius as SizeStyleTheme] : null);
|
|
38
|
+
|
|
39
|
+
const sizeClasses = $derived.by(() => {
|
|
40
|
+
const parts = typeof size === "string" ? sizeStyleParts[size as SizeStyleTheme] : null;
|
|
41
|
+
|
|
42
|
+
return twMerge(
|
|
43
|
+
parts?.form
|
|
44
|
+
);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const labelSizeClass = $derived.by(() => {
|
|
48
|
+
const parts = typeof size === "string" ? sizeStyleParts[size as SizeStyleTheme] : null;
|
|
49
|
+
return parts?.formLabel || "";
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const divSizeClass = $derived.by(() => {
|
|
53
|
+
const radiusParts = typeof radius === "string" ? sizeStyleParts[radius as SizeStyleTheme] : null;
|
|
54
|
+
return twMerge(
|
|
55
|
+
radiusParts?.radius
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const selectedLabelSizeClass = $derived.by(() => {
|
|
60
|
+
const parts = typeof size === "string" ? sizeStyleParts[size as SizeStyleTheme] : null;
|
|
61
|
+
return parts?.formLabelSelected || "";
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const customStyle = $derived.by(() => {
|
|
65
|
+
const styles: string[] = [];
|
|
66
|
+
|
|
67
|
+
if (typeof size === "number")
|
|
68
|
+
styles.push(`width: ${size}px`);
|
|
69
|
+
|
|
70
|
+
if (typeof radius === "number")
|
|
71
|
+
styles.push(`border-radius: ${radius}px`);
|
|
72
|
+
|
|
73
|
+
return styles.join("; ");
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const customLabelStyle = $derived.by(() => {
|
|
77
|
+
const styles: string[] = [];
|
|
78
|
+
|
|
79
|
+
if (typeof size === "number")
|
|
80
|
+
styles.push(`font-size: ${size / 4}px`);
|
|
81
|
+
|
|
82
|
+
return styles.join("; ");
|
|
83
|
+
});
|
|
84
|
+
|
|
20
85
|
let isFocused = $state(false);
|
|
21
86
|
let touched = $state(false);
|
|
22
87
|
|
|
23
|
-
let
|
|
24
|
-
let isValid = $derived(!touched || !validInputRegex || validInputRegex.test(value || ""));
|
|
88
|
+
let canSeePassword = $state(false);
|
|
25
89
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
90
|
+
const isFloating = $derived(variant === "floating");
|
|
91
|
+
const hasContent = $derived(value !== undefined && value !== null && value.toString().length > 0);
|
|
92
|
+
const isValid = $derived(!touched || !validInputRegex || validInputRegex.test(value || ""));
|
|
93
|
+
const lifted = $derived(isFloating && (isFocused || hasContent));
|
|
29
94
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
95
|
+
const Icon = $derived(icon ?? ({
|
|
96
|
+
mail: Mail, password: Lock, tel: Phone
|
|
97
|
+
}[restProps.type as string] as Component ?? null));
|
|
98
|
+
|
|
99
|
+
let defaultClass = "text-main-text w-full rounded outline-none px-1.5 w-full";
|
|
100
|
+
let defaultLabelClass = "block text-sub-text rounded-md font-medium mb-1 duration-100 pointer-events-none truncate w-fit";
|
|
101
|
+
let defaultDivClass = "relative *:transition-all flex-center bg-form-background border-[1px] border-form-border focus-within:ring-1 focus-within:ring-blue-500";
|
|
102
|
+
let iconContainerClass = "h-5 aspect-square px-1 py-0!";
|
|
103
|
+
let floatingLabelClass = "absolute w-full";
|
|
104
|
+
let iconClass = "h-full aspect-square text-sub-text";
|
|
34
105
|
|
|
35
|
-
let
|
|
106
|
+
let originalLabelClass = "z-0";
|
|
107
|
+
let originalLabelClassInput = "top-1/2 transform -translate-y-1/2";
|
|
108
|
+
let originalSelectedLabelClass = "z-30";
|
|
36
109
|
|
|
37
|
-
let
|
|
110
|
+
let invalidClass = "border border-red-500 focus:ring-red-500 bg-[#2E1F1F]";
|
|
38
111
|
|
|
39
|
-
let
|
|
40
|
-
let
|
|
41
|
-
let
|
|
112
|
+
let floatingLabelClassFull = $derived(twMerge(originalLabelClassInput, originalLabelClass, floatingLabelClass));
|
|
113
|
+
let divFullClass = $derived(size === "full" ? "w-full" : "");
|
|
114
|
+
let disabledClass = $derived(disabled ? "opacity-50 pointer-events-none" : "cursor-pointer");
|
|
42
115
|
|
|
43
116
|
function handleFocus(e: FocusEvent) {
|
|
44
117
|
isFocused = true;
|
|
@@ -50,29 +123,68 @@
|
|
|
50
123
|
touched = true;
|
|
51
124
|
onblur?.(e);
|
|
52
125
|
}
|
|
126
|
+
|
|
127
|
+
let labelClassIcon = $derived(Icon !== null ? "pl-[32px] pr-2" : "px-1.5");
|
|
128
|
+
let inputClassIcon = $derived(Icon !== null ? "pl-0 pr-1" : "");
|
|
129
|
+
|
|
130
|
+
let defaultInputClassCheck = $derived(variant !== "floating" ? "py-0" : "");
|
|
131
|
+
let floatingLabelClassCheck = $derived(variant === "floating" ? floatingLabelClassFull : "");
|
|
132
|
+
let defaultLabelClassCheck = $derived(variant !== "floating" ? "px-1.5" : "");
|
|
133
|
+
let selectedLabelClass = $derived(twMerge((isFocused || hasContent) && variant === "floating" ? `${originalSelectedLabelClass} ${selectedLabelSizeClass}` : ""));
|
|
134
|
+
let combinedLabelClass = $derived(twMerge(defaultLabelClass, floatingLabelClassCheck, labelSizeClass, selectedLabelClass, labelClassIcon, defaultLabelClassCheck, labelClass));
|
|
135
|
+
let combinedClass = $derived(twMerge(defaultClass, sizeClasses, defaultInputClassCheck, labelSizeClass, inputClassIcon, className, isValid ? "" : invalidClass));
|
|
136
|
+
let combinedDivClass = $derived(twMerge(defaultDivClass, divSizeClass, divFullClass, divClass, disabledClass));
|
|
137
|
+
let combinedOuterDivClass = $derived(twMerge("flex flex-col bg-transparent border-0 p-0", divSizeClass, divFullClass, divClass, disabledClass));
|
|
138
|
+
|
|
139
|
+
let EyeComponent = $derived(canSeePassword ? Eye : EyeOff);
|
|
53
140
|
</script>
|
|
54
141
|
|
|
55
|
-
|
|
56
|
-
<Text tag="label" for={id} class={combinedLabelClass}>
|
|
57
|
-
{
|
|
142
|
+
{#snippet labelElement()}
|
|
143
|
+
<Text tag="label" for={id} class={combinedLabelClass} style={customLabelStyle}>
|
|
144
|
+
{label}
|
|
145
|
+
{#if required}
|
|
146
|
+
<span class="text-[#E05555]">*</span>
|
|
147
|
+
{/if}
|
|
58
148
|
</Text>
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
149
|
+
{/snippet}
|
|
150
|
+
|
|
151
|
+
{#snippet innerDivElement()}
|
|
152
|
+
<div class={combinedDivClass}>
|
|
153
|
+
{#if Icon}
|
|
154
|
+
<div class={iconContainerClass}>
|
|
155
|
+
<Icon class={iconClass}></Icon>
|
|
156
|
+
</div>
|
|
157
|
+
{/if}
|
|
158
|
+
{#if variant === "floating"}
|
|
159
|
+
{@render labelElement()}
|
|
160
|
+
{/if}
|
|
69
161
|
<input
|
|
70
162
|
{id}
|
|
71
163
|
bind:value={value}
|
|
72
164
|
onfocus={handleFocus}
|
|
73
165
|
onblur={handleBlur}
|
|
74
166
|
class={combinedClass}
|
|
167
|
+
{required}
|
|
168
|
+
{disabled}
|
|
169
|
+
placeholder={variant === "floating" ? "" : placeholder}
|
|
170
|
+
aria-disabled={disabled}
|
|
171
|
+
style={customStyle}
|
|
75
172
|
{...restProps}
|
|
173
|
+
type={canSeePassword ? "text" : restProps.type}
|
|
76
174
|
/>
|
|
77
|
-
|
|
78
|
-
|
|
175
|
+
{#if restProps.type === "password"}
|
|
176
|
+
<Button class={iconContainerClass} onclick={() => { canSeePassword = !canSeePassword; }}>
|
|
177
|
+
<EyeComponent class={iconClass}></EyeComponent>
|
|
178
|
+
</Button>
|
|
179
|
+
{/if}
|
|
180
|
+
</div>
|
|
181
|
+
{/snippet}
|
|
182
|
+
|
|
183
|
+
{#if variant !== "floating"}
|
|
184
|
+
<div class={combinedOuterDivClass}>
|
|
185
|
+
{@render labelElement()}
|
|
186
|
+
{@render innerDivElement()}
|
|
187
|
+
</div>
|
|
188
|
+
{:else}
|
|
189
|
+
{@render innerDivElement()}
|
|
190
|
+
{/if}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { FloatingInputProps } from "../types/FloatingInput.
|
|
2
|
-
|
|
1
|
+
import type { FloatingInputProps } from "../types/FloatingInput.ts";
|
|
2
|
+
import { type Component } from "svelte";
|
|
3
|
+
declare const FloatingInput: Component<FloatingInputProps, {}, "value">;
|
|
3
4
|
type FloatingInput = ReturnType<typeof FloatingInput>;
|
|
4
5
|
export default FloatingInput;
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
let {
|
|
7
7
|
children = undefined,
|
|
8
8
|
class: className = "",
|
|
9
|
+
label = "",
|
|
9
10
|
divClass = "",
|
|
10
11
|
optionClass = "",
|
|
11
12
|
value = $bindable(),
|
|
@@ -14,7 +15,7 @@
|
|
|
14
15
|
...restProps
|
|
15
16
|
}: FloatingSelectProps = $props();
|
|
16
17
|
|
|
17
|
-
let defaultSelectClass = "cursor-pointer bg-form-
|
|
18
|
+
let defaultSelectClass = "cursor-pointer bg-form-background border-[1px] border-form-border text-main-text z-20 w-full rounded px-1 pt-4 pb-1 text-xs outline-none focus:ring-2 focus:ring-blue-500 transition-all";
|
|
18
19
|
let defaultLabelClass = "block text-sub-text rounded-md text-sm font-medium mb-1 absolute transition-all duration-100 pointer-events-none";
|
|
19
20
|
let defaultDivClass = "relative w-fit";
|
|
20
21
|
|
|
@@ -27,7 +28,7 @@
|
|
|
27
28
|
|
|
28
29
|
<div class={combinedDivClass}>
|
|
29
30
|
<Text tag="label" for={id} class={combinedLabelClass}>
|
|
30
|
-
{
|
|
31
|
+
{label}
|
|
31
32
|
</Text>
|
|
32
33
|
<select {id} class={combinedSelectClass} {...restProps} bind:value={value}>
|
|
33
34
|
{#each options as option}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FloatingSelectProps } from "../types/FloatingSelect.
|
|
1
|
+
import type { FloatingSelectProps } from "../types/FloatingSelect.ts";
|
|
2
2
|
declare const FloatingSelect: import("svelte").Component<FloatingSelectProps, {}, "value">;
|
|
3
3
|
type FloatingSelect = ReturnType<typeof FloatingSelect>;
|
|
4
4
|
export default FloatingSelect;
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
...restProps
|
|
12
12
|
}: NavbarProps = $props();
|
|
13
13
|
|
|
14
|
-
let defaultClass = "transition-colors duration-300 fixed top-0 left-0 w-full h-14 z-[100] flex items-center bg-
|
|
14
|
+
let defaultClass = "transition-colors duration-300 fixed top-0 left-0 w-full h-14 z-[100] flex items-center bg-sub-background/99 border-b border-box border-b-sub-background-hover";
|
|
15
15
|
|
|
16
16
|
let scrollY = $state(0);
|
|
17
17
|
let isAtTop = $derived(scrollY <= threshold);
|
|
@@ -27,4 +27,4 @@
|
|
|
27
27
|
|
|
28
28
|
<nav class={combinedClass} {...restProps}>
|
|
29
29
|
{@render children?.()}
|
|
30
|
-
</nav>
|
|
30
|
+
</nav>
|
|
@@ -30,6 +30,6 @@
|
|
|
30
30
|
|
|
31
31
|
<svelte:window bind:scrollY={scrollY}/>
|
|
32
32
|
|
|
33
|
-
<Button radius=
|
|
33
|
+
<Button radius="none" {href} color="none" class={combinedClass} {...restProps} aria-current={isActive ? 'page' : undefined}>
|
|
34
34
|
{@render children?.()}
|
|
35
35
|
</Button>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { NavbarElementProps } from "../types/Navbar.
|
|
1
|
+
import type { NavbarElementProps } from "../types/Navbar.ts";
|
|
2
2
|
declare const NavbarElement: import("svelte").Component<NavbarElementProps, {}, "">;
|
|
3
3
|
type NavbarElement = ReturnType<typeof NavbarElement>;
|
|
4
4
|
export default NavbarElement;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { onMount } from "svelte";
|
|
3
|
+
import type { ProgressProps } from "../types/Progress.js";
|
|
4
|
+
import { twMerge } from "tailwind-merge";
|
|
5
|
+
import { colorStyleParts } from "../styles/color.js";
|
|
6
|
+
import { sizeStyleParts, type SizeStyleTheme } from "../styles/size.js";
|
|
7
|
+
|
|
8
|
+
let {
|
|
9
|
+
children = undefined,
|
|
10
|
+
class: className = "",
|
|
11
|
+
divClass = "",
|
|
12
|
+
progress = 100,
|
|
13
|
+
animate = undefined,
|
|
14
|
+
color = "blue",
|
|
15
|
+
size = "md",
|
|
16
|
+
radius = "full",
|
|
17
|
+
...restProps
|
|
18
|
+
}: ProgressProps = $props();
|
|
19
|
+
|
|
20
|
+
let currentProgress = $state(0);
|
|
21
|
+
|
|
22
|
+
let defaultDivClass = "w-full bg-sub-background overflow-hidden";
|
|
23
|
+
|
|
24
|
+
const sizeClasses = $derived.by(() => {
|
|
25
|
+
const parts = typeof size === "string" ? sizeStyleParts[size as SizeStyleTheme] : null;
|
|
26
|
+
const radiusParts = typeof radius === "string" ? sizeStyleParts[radius as SizeStyleTheme] : null;
|
|
27
|
+
|
|
28
|
+
return twMerge(
|
|
29
|
+
parts?.progress,
|
|
30
|
+
radiusParts?.radius
|
|
31
|
+
);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const customStyle = $derived.by(() => {
|
|
35
|
+
const styles: string[] = [];
|
|
36
|
+
|
|
37
|
+
if (typeof size === "number")
|
|
38
|
+
styles.push(`height: ${size}px`);
|
|
39
|
+
|
|
40
|
+
if (typeof radius === "number")
|
|
41
|
+
styles.push(`border-radius: ${radius}px`);
|
|
42
|
+
|
|
43
|
+
return styles.join("; ");
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
let combinedDivClass = $derived(twMerge(
|
|
48
|
+
defaultDivClass,
|
|
49
|
+
sizeClasses,
|
|
50
|
+
divClass
|
|
51
|
+
));
|
|
52
|
+
|
|
53
|
+
let combinedInnerClass = $derived(twMerge(
|
|
54
|
+
"h-full",
|
|
55
|
+
colorStyleParts[color]?.base,
|
|
56
|
+
className
|
|
57
|
+
))
|
|
58
|
+
|
|
59
|
+
onMount(() => {
|
|
60
|
+
if (!animate) return;
|
|
61
|
+
currentProgress = animate.from;
|
|
62
|
+
requestAnimationFrame(() => currentProgress = animate.to);
|
|
63
|
+
if (animate.onend) setTimeout(animate.onend, animate.duration);
|
|
64
|
+
});
|
|
65
|
+
</script>
|
|
66
|
+
|
|
67
|
+
<div class={combinedDivClass} {...restProps} style={customStyle}>
|
|
68
|
+
<div class={combinedInnerClass} style="width: {animate ? currentProgress : progress}%; transition: width {animate?.duration ?? 500}ms ease;"></div>
|
|
69
|
+
</div>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { sizeStyleParts, textStyle, type SizeStyle } from "../styles/size.js";
|
|
2
|
+
import { sizeStyleParts, textStyle, type SizeStyle, type SizeStyleTheme } from "../styles/size.js";
|
|
3
3
|
import type { TextProps } from "../types/Text.js";
|
|
4
4
|
import { twMerge } from "tailwind-merge";
|
|
5
5
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
children = undefined,
|
|
8
8
|
class: className = "",
|
|
9
9
|
tag = "p",
|
|
10
|
-
shrink =
|
|
10
|
+
shrink = undefined,
|
|
11
11
|
size = "none",
|
|
12
12
|
...restProps
|
|
13
13
|
}: TextProps = $props();
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"p": { class: "", size: "text-base" },
|
|
17
17
|
"div": { class: "", size: "text-base" },
|
|
18
18
|
"span": { class: "", size: "text-base" },
|
|
19
|
-
"label": { class: "", size: "text-
|
|
19
|
+
"label": { class: "text-sub-text font-semibold", size: "text-xs" },
|
|
20
20
|
"strong": { class: "font-bold", size: "text-base" },
|
|
21
21
|
"b": { class: "font-bold", size: "text-base" },
|
|
22
22
|
"em": { class: "italic", size: "text-base" },
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
|
|
39
39
|
function getTextSizeInRem(): string {
|
|
40
40
|
if (size !== "none") {
|
|
41
|
-
const sizeKey = (sizeStyleParts[size as
|
|
41
|
+
const sizeKey = (sizeStyleParts[size as SizeStyleTheme]?.text ?? "text-base") as keyof typeof textStyle;
|
|
42
42
|
return textStyle[sizeKey] ?? textStyle["text-base"];
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
let shrinkStyle = $derived(shrink
|
|
49
|
-
? `font-size: clamp(8px,
|
|
49
|
+
? `font-size: clamp(8px, ${shrink}cqi, ${getTextSizeInRem()}); white-space: nowrap; display: block; width: fit-content;`
|
|
50
50
|
: ""
|
|
51
51
|
);
|
|
52
52
|
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
defaultClass,
|
|
56
56
|
tagStyles[tag]?.class || "",
|
|
57
57
|
tagStyles[tag]?.size || "",
|
|
58
|
-
sizeStyleParts[size]?.text || "",
|
|
58
|
+
sizeStyleParts[size as SizeStyleTheme]?.text || "",
|
|
59
59
|
className
|
|
60
60
|
));
|
|
61
61
|
</script>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { twMerge } from "tailwind-merge";
|
|
3
3
|
import { onMount } from "svelte";
|
|
4
4
|
|
|
5
|
-
import type { DisplaySegment, TypewriterProps } from "../types/Typewriter.
|
|
5
|
+
import type { DisplaySegment, TypewriterProps } from "../types/Typewriter.js";
|
|
6
6
|
import Text from "./Text.svelte";
|
|
7
7
|
|
|
8
8
|
let {
|