@valerius_petrini/corekit-ui 0.1.61 → 0.1.63
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/Input.svelte +63 -42
- package/dist/components/Input.svelte.d.ts +1 -1
- package/dist/components/NavbarDropdown.svelte +82 -0
- package/dist/components/NavbarDropdown.svelte.d.ts +4 -0
- package/dist/components/NavbarSeparator.svelte +11 -1
- package/dist/components/NavbarSeparator.svelte.d.ts +3 -25
- package/dist/components/Tooltip.svelte +124 -0
- package/dist/components/Tooltip.svelte.d.ts +4 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/styles/layout.css +1 -0
- package/dist/styles/posititon.d.ts +1 -0
- package/dist/types/Input.d.ts +6 -1
- package/dist/types/Input.js +1 -0
- package/dist/types/Navbar.d.ts +14 -1
- package/dist/types/Navbar.js +5 -1
- package/dist/types/Tooltip.d.ts +7 -0
- package/dist/types/Tooltip.js +1 -0
- package/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import type { InputProps } from "../types/Input.js";
|
|
2
|
+
import type { InputProps, InputRequirements } from "../types/Input.js";
|
|
3
3
|
import { twMerge } from "tailwind-merge";
|
|
4
4
|
import Text from "./Text.svelte";
|
|
5
|
-
import { sizeStyleParts, type SizeStyleTheme } from "../styles/size.js";
|
|
5
|
+
import { getSizeStyleClass, sizeStyleParts, type SizeStyleTheme } from "../styles/size.js";
|
|
6
6
|
import { type Component } from "svelte";
|
|
7
7
|
import Button from "./Button.svelte";
|
|
8
8
|
|
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
import EyeOff from "@lucide/svelte/icons/eye-off";
|
|
14
14
|
import ChevronUp from "@lucide/svelte/icons/chevron-up";
|
|
15
15
|
import ChevronDown from "@lucide/svelte/icons/chevron-down";
|
|
16
|
+
import X from "@lucide/svelte/icons/x";
|
|
17
|
+
import Check from "@lucide/svelte/icons/check";
|
|
18
|
+
import { slide } from "svelte/transition";
|
|
16
19
|
|
|
17
20
|
let {
|
|
18
21
|
children = undefined,
|
|
@@ -29,7 +32,8 @@
|
|
|
29
32
|
onblur = undefined,
|
|
30
33
|
required = false,
|
|
31
34
|
disabled = false,
|
|
32
|
-
|
|
35
|
+
requirements = undefined,
|
|
36
|
+
valid = $bindable(true),
|
|
33
37
|
size = "md",
|
|
34
38
|
radius = "md",
|
|
35
39
|
id = crypto.randomUUID(),
|
|
@@ -41,33 +45,10 @@
|
|
|
41
45
|
|
|
42
46
|
let isHovered = $state(false);
|
|
43
47
|
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
const parts = typeof size === "string" ? sizeStyleParts[size as SizeStyleTheme] : null;
|
|
49
|
-
|
|
50
|
-
return twMerge(
|
|
51
|
-
parts?.form
|
|
52
|
-
);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
const labelSizeClass = $derived.by(() => {
|
|
56
|
-
const parts = typeof size === "string" ? sizeStyleParts[size as SizeStyleTheme] : null;
|
|
57
|
-
return parts?.formLabel || "";
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
const divSizeClass = $derived.by(() => {
|
|
61
|
-
const radiusParts = typeof radius === "string" ? sizeStyleParts[radius as SizeStyleTheme] : null;
|
|
62
|
-
return twMerge(
|
|
63
|
-
radiusParts?.radius
|
|
64
|
-
);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
const selectedLabelSizeClass = $derived.by(() => {
|
|
68
|
-
const parts = typeof size === "string" ? sizeStyleParts[size as SizeStyleTheme] : null;
|
|
69
|
-
return parts?.formLabelSelected || "";
|
|
70
|
-
});
|
|
48
|
+
const sizeClasses = $derived(getSizeStyleClass(size, "form"));
|
|
49
|
+
const labelSizeClass = $derived(getSizeStyleClass(size, "formLabel"));
|
|
50
|
+
const divSizeClass = $derived(getSizeStyleClass(radius, "radius"));
|
|
51
|
+
const selectedLabelSizeClass = $derived(getSizeStyleClass(size, "formLabelSelected"));
|
|
71
52
|
|
|
72
53
|
const customStyle = $derived.by(() => {
|
|
73
54
|
const styles: string[] = [];
|
|
@@ -97,20 +78,25 @@
|
|
|
97
78
|
|
|
98
79
|
const isFloating = $derived(variant === "floating");
|
|
99
80
|
const hasContent = $derived(value !== undefined && value !== null && value.toString().length > 0);
|
|
100
|
-
const isValid = $derived(!touched || !validInputRegex || validInputRegex.test(value || ""));
|
|
101
81
|
const lifted = $derived(isFloating && (isFocused || hasContent));
|
|
102
82
|
|
|
103
83
|
const Icon = $derived(icon ?? ({
|
|
104
84
|
email: Mail, password: Lock, tel: Phone
|
|
105
85
|
}[restProps.type as string] as Component ?? null));
|
|
106
86
|
|
|
107
|
-
let defaultClass = "text-main-text w-full
|
|
87
|
+
let defaultClass = "text-main-text w-full outline-none px-1.5 w-full bg-inherit border-0 focus:ring-0 focus-visible:ring-0";
|
|
108
88
|
let defaultLabelClass = "block text-sub-text font-medium mb-1 duration-100 pointer-events-none truncate w-fit";
|
|
109
|
-
let defaultDivClass = "relative *:transition-all flex-center bg-form-background border-[1px] border-form-border focus-within:ring-1 focus-within:ring-blue-500";
|
|
89
|
+
let defaultDivClass = "relative *:transition-all transition-colors flex-center bg-form-background border-[1px] border-form-border focus-within:ring-1 focus-within:ring-blue-500";
|
|
110
90
|
let iconContainerClass = "h-5 aspect-square px-1 py-0!";
|
|
111
91
|
let floatingLabelClass = "absolute w-full";
|
|
112
92
|
let iconClass = "h-full aspect-square text-sub-text";
|
|
113
93
|
|
|
94
|
+
let inputRadius = $derived.by(() => {
|
|
95
|
+
if (restProps.type === "password") return "rounded-none";
|
|
96
|
+
if (Icon !== null) return "rounded-r-full"
|
|
97
|
+
else return "rounded-full";
|
|
98
|
+
});
|
|
99
|
+
|
|
114
100
|
let originalLabelClass = "z-0";
|
|
115
101
|
let originalLabelClassInput = "top-1/2 transform -translate-y-1/2";
|
|
116
102
|
let originalSelectedLabelClass = "z-30";
|
|
@@ -123,12 +109,12 @@
|
|
|
123
109
|
|
|
124
110
|
function handleFocus(e: FocusEvent) {
|
|
125
111
|
isFocused = true;
|
|
112
|
+
touched = true;
|
|
126
113
|
onfocus?.(e);
|
|
127
114
|
}
|
|
128
115
|
|
|
129
116
|
function handleBlur(e: FocusEvent) {
|
|
130
117
|
isFocused = false;
|
|
131
|
-
touched = true;
|
|
132
118
|
onblur?.(e);
|
|
133
119
|
}
|
|
134
120
|
|
|
@@ -140,8 +126,8 @@
|
|
|
140
126
|
let defaultLabelClassCheck = $derived(variant !== "floating" ? "px-0" : "");
|
|
141
127
|
let selectedLabelClass = $derived(twMerge((isFocused || hasContent) && variant === "floating" ? `${originalSelectedLabelClass} ${selectedLabelSizeClass}` : ""));
|
|
142
128
|
let combinedLabelClass = $derived(twMerge(defaultLabelClass, floatingLabelClassCheck, labelSizeClass, selectedLabelClass, labelClassIcon, defaultLabelClassCheck, labelClass));
|
|
143
|
-
let combinedClass = $derived(twMerge(defaultClass, sizeClasses, defaultInputClassCheck, labelSizeClass, inputClassIcon, className
|
|
144
|
-
let combinedDivClass = $derived(twMerge(defaultDivClass, divSizeClass, divFullClass, divClass, disabledClass));
|
|
129
|
+
let combinedClass = $derived(twMerge(defaultClass, inputRadius, sizeClasses, defaultInputClassCheck, labelSizeClass, inputClassIcon, className));
|
|
130
|
+
let combinedDivClass = $derived(twMerge(defaultDivClass, divSizeClass, divFullClass, divClass, disabledClass, !isValidInput() && touched && invalidClass));
|
|
145
131
|
let combinedOuterDivClass = $derived(twMerge("flex flex-col bg-transparent border-0 p-0", divSizeClass, divFullClass, outerDivClass, disabledClass));
|
|
146
132
|
|
|
147
133
|
let EyeComponent = $derived(canSeePassword ? Eye : EyeOff);
|
|
@@ -183,6 +169,25 @@
|
|
|
183
169
|
decrementInterval = null;
|
|
184
170
|
}
|
|
185
171
|
}
|
|
172
|
+
|
|
173
|
+
function testRequirement(requirement: RegExp | ((value: any) => boolean)) {
|
|
174
|
+
if (typeof requirement === "function")
|
|
175
|
+
return requirement(value || "");
|
|
176
|
+
else if (requirement instanceof RegExp)
|
|
177
|
+
return requirement.test(value || "");
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function isValidInput() {
|
|
182
|
+
for (const requirement of requirements || [])
|
|
183
|
+
if (!testRequirement(requirement.requirements))
|
|
184
|
+
return false;
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
$effect(() => {
|
|
189
|
+
valid = isValidInput();
|
|
190
|
+
});
|
|
186
191
|
</script>
|
|
187
192
|
|
|
188
193
|
{#snippet labelElement()}
|
|
@@ -251,11 +256,27 @@
|
|
|
251
256
|
</div>
|
|
252
257
|
{/snippet}
|
|
253
258
|
|
|
254
|
-
{
|
|
255
|
-
|
|
259
|
+
<div class={combinedOuterDivClass}>
|
|
260
|
+
{#if variant !== "floating"}
|
|
256
261
|
{@render labelElement()}
|
|
257
262
|
{@render innerDivElement()}
|
|
258
|
-
|
|
259
|
-
{
|
|
260
|
-
{
|
|
261
|
-
|
|
263
|
+
{:else}
|
|
264
|
+
{@render innerDivElement()}
|
|
265
|
+
{/if}
|
|
266
|
+
|
|
267
|
+
{#if touched && requirements}
|
|
268
|
+
<div class="mt-1 text-xs" transition:slide={{ duration: 300 }}>
|
|
269
|
+
{#each requirements as req}
|
|
270
|
+
{@const isReqMet = testRequirement(req.requirements)}
|
|
271
|
+
{@const reqClass = isReqMet ? "text-green-500" : "text-red-500"}
|
|
272
|
+
<div class="flex w-full items-center gap-1 transition-colors {reqClass}">
|
|
273
|
+
<div class="relative w-4 h-4">
|
|
274
|
+
<Check class="w-4 h-4 absolute transition-all duration-150 {isReqMet ? 'opacity-100 scale-100' : 'opacity-0 scale-0'}"/>
|
|
275
|
+
<X class="w-4 h-4 absolute transition-all duration-150 {isReqMet ? 'opacity-0 scale-0' : 'opacity-100 scale-100'}"/>
|
|
276
|
+
</div>
|
|
277
|
+
<Text tag="span" class="text-xs text-inherit">{req.label}</Text>
|
|
278
|
+
</div>
|
|
279
|
+
{/each}
|
|
280
|
+
</div>
|
|
281
|
+
{/if}
|
|
282
|
+
</div>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { InputProps } from "../types/Input.ts";
|
|
2
2
|
import { type Component } from "svelte";
|
|
3
|
-
declare const Input: Component<InputProps, {}, "value">;
|
|
3
|
+
declare const Input: Component<InputProps, {}, "value" | "valid">;
|
|
4
4
|
type Input = ReturnType<typeof Input>;
|
|
5
5
|
export default Input;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { fly } from "svelte/transition";
|
|
3
|
+
import NavbarElement from "./NavbarElement.svelte";
|
|
4
|
+
import { tick } from "svelte";
|
|
5
|
+
import type { NavbarDropdownProps } from "../types/Navbar.js";
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
children = undefined,
|
|
9
|
+
class: className = "",
|
|
10
|
+
wrapperClass = "",
|
|
11
|
+
label = "",
|
|
12
|
+
element = undefined,
|
|
13
|
+
...restProps
|
|
14
|
+
}: NavbarDropdownProps = $props();
|
|
15
|
+
|
|
16
|
+
let open = $state(false);
|
|
17
|
+
let dropdownRef: HTMLButtonElement | null = $state(null);
|
|
18
|
+
let wrapperRef: HTMLDivElement | null = $state(null);
|
|
19
|
+
let offsetX = $state(0);
|
|
20
|
+
let flipUp = $state(false);
|
|
21
|
+
|
|
22
|
+
function calculateOverflow() {
|
|
23
|
+
if (!dropdownRef) return;
|
|
24
|
+
|
|
25
|
+
offsetX = 0;
|
|
26
|
+
|
|
27
|
+
const menuRect = dropdownRef.getBoundingClientRect();
|
|
28
|
+
const vw = window.innerWidth;
|
|
29
|
+
const padding = 12;
|
|
30
|
+
|
|
31
|
+
flipUp = menuRect.bottom > window.innerHeight - padding;
|
|
32
|
+
|
|
33
|
+
if (menuRect.right > vw - padding)
|
|
34
|
+
offsetX = -(menuRect.right - (vw - padding));
|
|
35
|
+
else if (menuRect.left < padding)
|
|
36
|
+
offsetX = padding - menuRect.left;
|
|
37
|
+
else
|
|
38
|
+
offsetX = 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async function toggle() {
|
|
42
|
+
open = !open;
|
|
43
|
+
if (open) {
|
|
44
|
+
await tick();
|
|
45
|
+
calculateOverflow();
|
|
46
|
+
} else {
|
|
47
|
+
offsetX = 0;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function handleClickOutside(event: MouseEvent) {
|
|
52
|
+
if (dropdownRef && !dropdownRef.contains(event.target as Node) && wrapperRef && !wrapperRef.contains(event.target as Node)) {
|
|
53
|
+
open = false;
|
|
54
|
+
offsetX = 0;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
</script>
|
|
58
|
+
|
|
59
|
+
<svelte:window onclick={handleClickOutside}/>
|
|
60
|
+
|
|
61
|
+
<div class="relative" bind:this={wrapperRef}>
|
|
62
|
+
<NavbarElement onclick={toggle} class={className} {...restProps} aria-haspopup="true" aria-expanded={open}>
|
|
63
|
+
{label}
|
|
64
|
+
{#if element}
|
|
65
|
+
{@render element()}
|
|
66
|
+
{/if}
|
|
67
|
+
</NavbarElement>
|
|
68
|
+
|
|
69
|
+
{#if open}
|
|
70
|
+
<div
|
|
71
|
+
class="absolute {flipUp ? 'bottom-full' : 'top-full'} left-0 z-100 mt-1 overflow-hidden shadow-lg"
|
|
72
|
+
style="transform: translateX({offsetX}px); visibility: {open ? 'visible' : 'hidden'};">
|
|
73
|
+
<button
|
|
74
|
+
bind:this={dropdownRef}
|
|
75
|
+
transition:fly={{ y: flipUp ? 5 : -5, duration: 200 }}
|
|
76
|
+
class="bg-sub-background p-2 min-w-max flex flex-col *:px-0 rounded border-sub-background-hover border"
|
|
77
|
+
onclick={() => open = false}>
|
|
78
|
+
{@render children?.()}
|
|
79
|
+
</button>
|
|
80
|
+
</div>
|
|
81
|
+
{/if}
|
|
82
|
+
</div>
|
|
@@ -1 +1,11 @@
|
|
|
1
|
-
<
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { NavbarSeparatorClasses, type NavbarSeparatorProps } from "../types/Navbar.js";
|
|
3
|
+
|
|
4
|
+
let {
|
|
5
|
+
variant = "dynamic",
|
|
6
|
+
class: className = "",
|
|
7
|
+
...restProps
|
|
8
|
+
}: NavbarSeparatorProps = $props();
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<div class={NavbarSeparatorClasses[variant]} {...restProps}></div>
|
|
@@ -1,26 +1,4 @@
|
|
|
1
|
+
import { type NavbarSeparatorProps } from "../types/Navbar.js";
|
|
2
|
+
declare const NavbarSeparator: import("svelte").Component<NavbarSeparatorProps, {}, "">;
|
|
3
|
+
type NavbarSeparator = ReturnType<typeof NavbarSeparator>;
|
|
1
4
|
export default NavbarSeparator;
|
|
2
|
-
type NavbarSeparator = SvelteComponent<{
|
|
3
|
-
[x: string]: never;
|
|
4
|
-
}, {
|
|
5
|
-
[evt: string]: CustomEvent<any>;
|
|
6
|
-
}, {}> & {
|
|
7
|
-
$$bindings?: string | undefined;
|
|
8
|
-
};
|
|
9
|
-
declare const NavbarSeparator: $$__sveltets_2_IsomorphicComponent<{
|
|
10
|
-
[x: string]: never;
|
|
11
|
-
}, {
|
|
12
|
-
[evt: string]: CustomEvent<any>;
|
|
13
|
-
}, {}, {}, string>;
|
|
14
|
-
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
15
|
-
new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
|
|
16
|
-
$$bindings?: Bindings;
|
|
17
|
-
} & Exports;
|
|
18
|
-
(internal: unknown, props: {
|
|
19
|
-
$$events?: Events;
|
|
20
|
-
$$slots?: Slots;
|
|
21
|
-
}): Exports & {
|
|
22
|
-
$set?: any;
|
|
23
|
-
$on?: any;
|
|
24
|
-
};
|
|
25
|
-
z_$$bindings?: Bindings;
|
|
26
|
-
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { TooltipComponent } from "../types/Tooltip.js";
|
|
3
|
+
import { type Snippet } from "svelte";
|
|
4
|
+
import { fly } from "svelte/transition";
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
text,
|
|
8
|
+
position = "top",
|
|
9
|
+
delay = 0,
|
|
10
|
+
children
|
|
11
|
+
}: TooltipComponent = $props();
|
|
12
|
+
|
|
13
|
+
let visible = $state(false);
|
|
14
|
+
let resolvedPosition: string | null = $state(null);
|
|
15
|
+
let offsetX = $state(0);
|
|
16
|
+
let trigger: HTMLDivElement;
|
|
17
|
+
let tooltip: HTMLDivElement | null = $state(null);
|
|
18
|
+
let timeout: ReturnType<typeof setTimeout>;
|
|
19
|
+
let arrowX = $derived(-offsetX);
|
|
20
|
+
|
|
21
|
+
function calculatePosition() {
|
|
22
|
+
resolvedPosition = position;
|
|
23
|
+
if (!trigger) return;
|
|
24
|
+
|
|
25
|
+
const rect = trigger.getBoundingClientRect();
|
|
26
|
+
const vw = window.innerWidth;
|
|
27
|
+
const vh = window.innerHeight;
|
|
28
|
+
|
|
29
|
+
if (position === "top" && rect.top < 40) resolvedPosition = "bottom";
|
|
30
|
+
else if (position === "bottom" && rect.bottom > vh - 40) resolvedPosition = "top";
|
|
31
|
+
else if (position === "left" && rect.left < 120) resolvedPosition = "right";
|
|
32
|
+
else if (position === "right" && rect.right > vw - 120) resolvedPosition = "left";
|
|
33
|
+
else resolvedPosition = position;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function calculateOverflow() {
|
|
37
|
+
if (!tooltip || !trigger) return;
|
|
38
|
+
|
|
39
|
+
const triggerRect = trigger.getBoundingClientRect();
|
|
40
|
+
const tooltipRect = tooltip.getBoundingClientRect();
|
|
41
|
+
const vw = window.innerWidth;
|
|
42
|
+
|
|
43
|
+
const triggerCenter = triggerRect.left + triggerRect.width / 2;
|
|
44
|
+
|
|
45
|
+
const tooltipLeft = triggerCenter - tooltipRect.width / 2;
|
|
46
|
+
const tooltipRight = triggerCenter + tooltipRect.width / 2;
|
|
47
|
+
|
|
48
|
+
const padding = 8;
|
|
49
|
+
|
|
50
|
+
if (tooltipRight > vw - padding)
|
|
51
|
+
offsetX = -(tooltipRight - (vw - padding));
|
|
52
|
+
else if (tooltipLeft < padding)
|
|
53
|
+
offsetX = padding - tooltipLeft;
|
|
54
|
+
else
|
|
55
|
+
offsetX = 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function show() {
|
|
59
|
+
calculatePosition();
|
|
60
|
+
timeout = setTimeout(() => {
|
|
61
|
+
visible = true;
|
|
62
|
+
requestAnimationFrame(calculateOverflow);
|
|
63
|
+
}, delay);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function hide() {
|
|
67
|
+
clearTimeout(timeout);
|
|
68
|
+
visible = false;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const positionClasses: Record<string, string> = {
|
|
72
|
+
top: "bottom-full left-1/2 -translate-x-1/2 mb-2",
|
|
73
|
+
bottom: "top-full left-1/2 -translate-x-1/2 mt-2",
|
|
74
|
+
left: "right-full top-1/2 -translate-y-1/2 mr-2",
|
|
75
|
+
right: "left-full top-1/2 -translate-y-1/2 ml-2"
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const arrowClasses: Record<string, string> = {
|
|
79
|
+
top: "top-full left-1/2 -translate-x-1/2 border-t-form-background",
|
|
80
|
+
bottom: "bottom-full left-1/2 -translate-x-1/2 border-b-form-background",
|
|
81
|
+
left: "left-full top-1/2 -translate-y-1/2 border-l-form-background",
|
|
82
|
+
right: "right-full top-1/2 -translate-y-1/2 border-r-form-background"
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const flyParams = $derived.by(() => {
|
|
86
|
+
const pos = resolvedPosition || position;
|
|
87
|
+
|
|
88
|
+
const duration = 100;
|
|
89
|
+
const distance = 8;
|
|
90
|
+
if (pos == "top")
|
|
91
|
+
return { y: distance, duration };
|
|
92
|
+
else if (pos == "bottom")
|
|
93
|
+
return { y: -distance, duration };
|
|
94
|
+
const x = pos == "right" ? -distance : distance;
|
|
95
|
+
return { x, duration };
|
|
96
|
+
});
|
|
97
|
+
</script>
|
|
98
|
+
|
|
99
|
+
<div
|
|
100
|
+
bind:this={trigger}
|
|
101
|
+
class="relative inline-flex w-fit h-fit"
|
|
102
|
+
onmouseenter={show}
|
|
103
|
+
onmouseleave={hide}
|
|
104
|
+
role="tooltip">
|
|
105
|
+
{@render children()}
|
|
106
|
+
|
|
107
|
+
{#if visible}
|
|
108
|
+
<div
|
|
109
|
+
bind:this={tooltip}
|
|
110
|
+
style="transform: translateX(calc(-50% + {offsetX}px));"
|
|
111
|
+
class="absolute z-999999 {positionClasses[resolvedPosition || position]} translate-x-0! pointer-events-none">
|
|
112
|
+
<div
|
|
113
|
+
transition:fly={flyParams}
|
|
114
|
+
class="px-2 py-1 text-xs text-main-text bg-form-background rounded whitespace-nowrap">
|
|
115
|
+
{text}
|
|
116
|
+
|
|
117
|
+
<div
|
|
118
|
+
class="absolute {arrowClasses[resolvedPosition || position]} border-4 border-transparent w-0 h-0"
|
|
119
|
+
style="transform: translateX(calc(-50% + {arrowX}px));"
|
|
120
|
+
></div>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
{/if}
|
|
124
|
+
</div>
|
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export { default as SEO } from "./components/SEO.svelte";
|
|
|
5
5
|
export { default as Navbar } from "./components/Navbar.svelte";
|
|
6
6
|
export { default as NavbarSeparator } from "./components/NavbarSeparator.svelte";
|
|
7
7
|
export { default as NavbarElement } from "./components/NavbarElement.svelte";
|
|
8
|
+
export { default as NavbarDropdown } from "./components/NavbarDropdown.svelte";
|
|
8
9
|
export { default as Input } from "./components/Input.svelte";
|
|
9
10
|
export { default as FileInput } from "./components/FileInput.svelte";
|
|
10
11
|
export { default as Select } from "./components/Select.svelte";
|
|
@@ -17,6 +18,7 @@ export { default as Table } from "./components/Table.svelte";
|
|
|
17
18
|
export { default as Toast } from "./components/Toast.svelte";
|
|
18
19
|
export { default as Toaster } from "./components/Toaster.svelte";
|
|
19
20
|
export { default as SideNavbar } from "./components/SideNavbar.svelte";
|
|
21
|
+
export { default as Tooltip } from "./components/Tooltip.svelte";
|
|
20
22
|
export { fbmBackground } from "./actions/fbm.ts";
|
|
21
23
|
export { toast } from "./actions/toast.svelte.ts";
|
|
22
24
|
export type { TypewriterAction, DisplaySegment } from "./types/Typewriter.ts";
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ export { default as SEO } from "./components/SEO.svelte";
|
|
|
5
5
|
export { default as Navbar } from "./components/Navbar.svelte";
|
|
6
6
|
export { default as NavbarSeparator } from "./components/NavbarSeparator.svelte";
|
|
7
7
|
export { default as NavbarElement } from "./components/NavbarElement.svelte";
|
|
8
|
+
export { default as NavbarDropdown } from "./components/NavbarDropdown.svelte";
|
|
8
9
|
export { default as Input } from "./components/Input.svelte";
|
|
9
10
|
export { default as FileInput } from "./components/FileInput.svelte";
|
|
10
11
|
export { default as Select } from "./components/Select.svelte";
|
|
@@ -17,5 +18,6 @@ export { default as Table } from "./components/Table.svelte";
|
|
|
17
18
|
export { default as Toast } from "./components/Toast.svelte";
|
|
18
19
|
export { default as Toaster } from "./components/Toaster.svelte";
|
|
19
20
|
export { default as SideNavbar } from "./components/SideNavbar.svelte";
|
|
21
|
+
export { default as Tooltip } from "./components/Tooltip.svelte";
|
|
20
22
|
export { fbmBackground } from "./actions/fbm.js";
|
|
21
23
|
export { toast } from "./actions/toast.svelte.js";
|
package/dist/styles/layout.css
CHANGED
package/dist/types/Input.d.ts
CHANGED
|
@@ -2,6 +2,10 @@ import type { Component } from "svelte";
|
|
|
2
2
|
import type { SizeStyle } from "../styles/size.ts";
|
|
3
3
|
import type { BaseComponentProps } from "./BaseComponent.ts";
|
|
4
4
|
export type InputVariant = "default" | "floating";
|
|
5
|
+
export interface InputRequirements {
|
|
6
|
+
label: string;
|
|
7
|
+
requirements: RegExp | ((value: any) => boolean);
|
|
8
|
+
}
|
|
5
9
|
export interface InputProps extends BaseComponentProps {
|
|
6
10
|
label?: string;
|
|
7
11
|
labelClass?: string;
|
|
@@ -18,7 +22,8 @@ export interface InputProps extends BaseComponentProps {
|
|
|
18
22
|
step?: number;
|
|
19
23
|
onfocus?: (e?: FocusEvent) => void;
|
|
20
24
|
onblur?: (e?: FocusEvent) => void;
|
|
21
|
-
|
|
25
|
+
requirements?: InputRequirements[];
|
|
26
|
+
valid?: boolean;
|
|
22
27
|
size?: SizeStyle;
|
|
23
28
|
radius?: SizeStyle;
|
|
24
29
|
id?: `${string}-${string}-${string}-${string}-${string}`;
|
package/dist/types/Input.js
CHANGED
package/dist/types/Navbar.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Component } from "svelte";
|
|
1
|
+
import type { Component, Snippet } from "svelte";
|
|
2
2
|
import type { BaseComponentProps } from "./BaseComponent.ts";
|
|
3
3
|
export interface NavbarProps extends BaseComponentProps {
|
|
4
4
|
classTop?: string;
|
|
@@ -13,8 +13,21 @@ export interface NavbarElementProps extends BaseComponentProps {
|
|
|
13
13
|
export interface SideNavbarProps extends BaseComponentProps {
|
|
14
14
|
items?: SideNavbarItem[];
|
|
15
15
|
}
|
|
16
|
+
export type NavbarSeparatorVariant = "vertical" | "horizontal" | "dynamic";
|
|
17
|
+
export declare const NavbarSeparatorClasses: Record<NavbarSeparatorVariant, string>;
|
|
18
|
+
export interface NavbarSeparatorProps extends BaseComponentProps {
|
|
19
|
+
variant?: NavbarSeparatorVariant;
|
|
20
|
+
}
|
|
16
21
|
export interface SideNavbarItem {
|
|
17
22
|
href: string;
|
|
18
23
|
label: string;
|
|
19
24
|
icon: Component;
|
|
20
25
|
}
|
|
26
|
+
export interface NavbarDropdownProps extends BaseComponentProps {
|
|
27
|
+
label?: string;
|
|
28
|
+
element?: Snippet;
|
|
29
|
+
classTop?: string;
|
|
30
|
+
wrapperClass?: string;
|
|
31
|
+
activeClass?: string;
|
|
32
|
+
threshold?: number;
|
|
33
|
+
}
|
package/dist/types/Navbar.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|